From 356027b7097abb90538a5794da30af16326518d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 17 Apr 2024 19:21:11 +0000 Subject: [PATCH 001/217] ast_passes/validation: update module docs - Syntax extensions are replaced by proc macros. - Add rationale for why AST validation pass need to be run post-expansion and why the pass is needed in the first place. --- compiler/rustc_ast_passes/src/ast_validation.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 495e90e967b93..0592837e42caa 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1,10 +1,13 @@ -// Validate AST before lowering it to HIR. -// -// This pass is supposed to catch things that fit into AST data structures, -// but not permitted by the language. It runs after expansion when AST is frozen, -// so it can check for erroneous constructions produced by syntax extensions. -// This pass is supposed to perform only simple checks not requiring name resolution -// or type checking or some other kind of complex analysis. +//! Validate AST before lowering it to HIR. +//! +//! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest +//! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async +//! fn` within a trait (before async-fn-in-trait was introduced). +//! +//! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous +//! constructions produced by proc macros. This pass is only intended for simple checks that do not +//! require name resolution or type checking, or other kinds of complex analysis. use itertools::{Either, Itertools}; use rustc_ast::ptr::P; From 0e3521605dff967199347565dde4d4daeb36fe6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 17 Apr 2024 19:37:27 +0000 Subject: [PATCH 002/217] ast_passes/validation: update attribute macro example --- compiler/rustc_ast_passes/src/ast_validation.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0592837e42caa..eadfd3b98e24a 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -2,8 +2,15 @@ //! //! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest //! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing -//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async -//! fn` within a trait (before async-fn-in-trait was introduced). +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as a +//! function without body outside of a trait definition: +//! +//! ```ignore (illustrative) +//! #[my_attribute] +//! mod foo { +//! fn missing_body(); +//! } +//! ``` //! //! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous //! constructions produced by proc macros. This pass is only intended for simple checks that do not From 0a298ed00bcd1c134ca60c0c81f1192dc5f5b8d1 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sat, 6 Apr 2024 11:22:21 -0400 Subject: [PATCH 003/217] Show files produced by --emit foo in json artifact notifications --- src/driver/aot.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e8c96486041b1..aff9448a89c30 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -287,6 +287,29 @@ fn produce_final_output_artifacts( } } + if sess.opts.json_artifact_notifications { + if codegen_results.modules.len() == 1 { + codegen_results.modules[0].for_each_output(|_path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + // for single cgu file is renamed to drop cgu specific suffix + // so we regenerate it the same way + let path = crate_output.path(ty); + sess.dcx().emit_artifact_notification(path.as_path(), descr); + } + }); + } else { + for module in &codegen_results.modules { + module.for_each_output(|path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + sess.dcx().emit_artifact_notification(&path, descr); + } + }); + } + } + } + // We leave the following files around by default: // - #crate#.o // - #crate#.crate.metadata.o From 9aec5c5bcecad566a76fc7dbb819aa0e58a23671 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 9 Apr 2024 23:17:45 +0000 Subject: [PATCH 004/217] Add test for fn pointer duplication. --- tests/ui/mir/auxiliary/static_fnptr.rs | 10 ++++++++++ tests/ui/mir/static_fnptr.rs | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/ui/mir/auxiliary/static_fnptr.rs create mode 100644 tests/ui/mir/static_fnptr.rs diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs new file mode 100644 index 0000000000000..a48ee6c012105 --- /dev/null +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -0,0 +1,10 @@ +//@ compile-flags:-O + +fn foo() {} + +pub static ADDR: fn() = foo; + +#[inline(always)] +pub fn bar(x: fn()) -> bool { + x == ADDR +} diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs new file mode 100644 index 0000000000000..571dcf4463e12 --- /dev/null +++ b/tests/ui/mir/static_fnptr.rs @@ -0,0 +1,14 @@ +//@ run-pass +//@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 +//@ aux-build:static_fnptr.rs + +extern crate static_fnptr; +use static_fnptr::{ADDR, bar}; + +fn baz() -> bool { + bar(ADDR) +} + +fn main() { + assert!(baz()) +} From d223ba6233455544818e0998d3352de8e237c896 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 10 Apr 2024 10:15:26 +0000 Subject: [PATCH 005/217] Document test. --- tests/ui/mir/static_fnptr.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs index 571dcf4463e12..6b1ec021629b8 100644 --- a/tests/ui/mir/static_fnptr.rs +++ b/tests/ui/mir/static_fnptr.rs @@ -1,3 +1,10 @@ +//! Verify that we correctly handle fn pointer provenance in MIR optimizations. +//! By asking to inline `static_fnptr::bar`, we have two copies of `static_fnptr::foo`, one in the +//! auxiliary crate and one in the local crate CGU. +//! `baz` must only consider the versions from upstream crate, and not try to compare with the +//! address of the CGU-local copy. +//! Related issue: #123670 + //@ run-pass //@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 //@ aux-build:static_fnptr.rs From 4c779d75bff7c7c83f4955c3f448198f6dd3c1db Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 4 May 2024 19:27:27 +0000 Subject: [PATCH 006/217] Mark `foo` as explicitly inline. --- tests/ui/mir/auxiliary/static_fnptr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs index a48ee6c012105..8c7347175f4b8 100644 --- a/tests/ui/mir/auxiliary/static_fnptr.rs +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -1,5 +1,6 @@ //@ compile-flags:-O +#[inline] fn foo() {} pub static ADDR: fn() = foo; From ed7d97e4c8806d0fced2fbcec44b668d5528efbe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 13 May 2024 13:26:33 +0000 Subject: [PATCH 007/217] Merge commit '3270432f4b0583104c8b9b6f695bf97d6bbf3ac2' into sync_cg_clif-2024-05-13 --- .github/workflows/abi-cafe.yml | 8 ++ .github/workflows/main.yml | 16 +++ .github/workflows/rustc.yml | 4 +- .gitignore | 4 - build_system/Cargo.toml | 3 + build_system/build_sysroot.rs | 37 +++++- build_system/main.rs | 8 +- build_system/tests.rs | 2 +- example/mini_core_hello_world.rs | 10 ++ example/std_example.rs | 29 +++++ patches/stdlib-lock.toml | 4 +- rust-toolchain | 2 +- scripts/test_rustc_tests.sh | 4 +- src/abi/mod.rs | 6 +- src/base.rs | 37 +++++- src/concurrency_limiter.rs | 21 +--- src/config.rs | 9 +- src/constant.rs | 2 +- src/discriminant.rs | 45 ++++--- src/driver/aot.rs | 72 +++++------ src/driver/jit.rs | 23 ++-- src/driver/mod.rs | 16 ++- src/global_asm.rs | 2 +- src/inline_asm.rs | 201 +++++++++++++++++++++++++------ src/intrinsics/llvm_x86.rs | 52 ++++++++ src/lib.rs | 6 +- src/main_shim.rs | 2 +- src/value_and_place.rs | 8 -- y.cmd | 4 +- y.ps1 | 7 +- y.sh | 3 +- 31 files changed, 481 insertions(+), 166 deletions(-) mode change 100644 => 100755 y.ps1 diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index a745f2801cc4e..b7063f35a3e80 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -51,6 +51,14 @@ jobs: if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14aa850ff5cb7..1f5a6513f63b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,12 +98,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install toolchain and emulator if: matrix.apt_deps != null run: | sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare @@ -230,12 +238,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install MinGW toolchain if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: | sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml index 75ea94ee79790..70c214ce8b147 100644 --- a/.github/workflows/rustc.yml +++ b/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Prepare dependencies run: ./y.sh prepare @@ -43,7 +43,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/.gitignore b/.gitignore index 7915fa138f8fc..5a38f2acb0e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ # Build artifacts during normal use -/y.bin -/y.bin.dSYM -/y.exe -/y.pdb /download /build /dist diff --git a/build_system/Cargo.toml b/build_system/Cargo.toml index f47b9bc554041..feed2b6eafe82 100644 --- a/build_system/Cargo.toml +++ b/build_system/Cargo.toml @@ -11,3 +11,6 @@ path = "main.rs" unstable-features = [] # for rust-analyzer # Do not add any dependencies + +[profile.dev] +debug = 1 diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 10c3f9cfa2ce3..196ff8fda7544 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -267,12 +267,16 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } + rustflags.push("-Zunstable-options".to_owned()); + for (name, values) in EXTRA_CHECK_CFGS { + rustflags.push(check_cfg_arg(name, *values)); + } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { build_cmd.arg("--release"); } - build_cmd.arg("--features").arg("compiler-builtins-no-asm backtrace panic-unwind"); + build_cmd.arg("--features").arg("backtrace panic-unwind"); build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); if compiler.triple.contains("apple") { @@ -326,3 +330,34 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } + +// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 +/// Create a `--check-cfg` argument invocation for a given name +/// and it's values. +fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { + // Creating a string of the values by concatenating each value: + // ',values("tvos","watchos")' or '' (nothing) when there are no values. + let next = match values { + Some(values) => { + let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); + + tmp.insert_str(1, "values("); + tmp.push(')'); + tmp + } + None => "".to_string(), + }; + format!("--check-cfg=cfg({name}{next})") +} + +const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ + ("bootstrap", None), + ("stdarch_intel_sde", None), + ("no_fp_fmt_parse", None), + ("no_global_oom_handling", None), + ("no_rc", None), + ("no_sync", None), + ("netbsd10", None), + ("backtrace_in_libstd", None), + ("target_arch", Some(&["xtensa"])), +]; diff --git a/build_system/main.rs b/build_system/main.rs index cdd2bae03f8f1..7dbf608f991e4 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -147,9 +147,11 @@ fn main() { let rustup_toolchain_name = match (env::var("CARGO"), env::var("RUSTC"), env::var("RUSTDOC")) { (Ok(_), Ok(_), Ok(_)) => None, - (Err(_), Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), - _ => { - eprintln!("All of CARGO, RUSTC and RUSTDOC need to be set or none must be set"); + (_, Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), + vars => { + eprintln!( + "If RUSTC or RUSTDOC is set, both need to be set and in addition CARGO needs to be set: {vars:?}" + ); process::exit(1); } }; diff --git a/build_system/tests.rs b/build_system/tests.rs index 76104901474c2..278f334796a9b 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -77,7 +77,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ ), TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"), TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]), - TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""), + TestCase::jit_bin("jit.std_example", "example/std_example.rs", "arg"), TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]), TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]), TestCase::build_bin_and_run( diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index efa4be7e15ac3..aab20f672487b 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -4,6 +4,7 @@ never_type, linkage, extern_types, + naked_functions, thread_local, repr_simd, raw_ref_op @@ -340,6 +341,7 @@ fn main() { ))] unsafe { global_asm_test(); + naked_test(); } // Both statics have a reference that points to the same anonymous allocation. @@ -395,6 +397,14 @@ global_asm! { " } +#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[naked] +extern "C" fn naked_test() { + unsafe { + asm!("ret", options(noreturn)); + } +} + #[repr(C)] enum c_void { _1, diff --git a/example/std_example.rs b/example/std_example.rs index 90d4ab721daef..7347b2e77899f 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -210,6 +210,21 @@ struct I64X2(i64, i64); #[allow(improper_ctypes_definitions)] extern "C" fn foo(_a: I64X2) {} +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse4.2")] +#[cfg(not(jit))] +unsafe fn test_crc32() { + assert!(is_x86_feature_detected!("sse4.2")); + + let a = 42u32; + let b = 0xdeadbeefu64; + + assert_eq!(_mm_crc32_u8(a, b as u8), 4135334616); + assert_eq!(_mm_crc32_u16(a, b as u16), 1200687288); + assert_eq!(_mm_crc32_u32(a, b as u32), 2543798776); + assert_eq!(_mm_crc32_u64(a as u64, b as u64), 241952147); +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { @@ -244,10 +259,14 @@ unsafe fn test_simd() { test_mm256_shuffle_epi8(); test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); assert_eq!(mask1, 1); + + #[cfg(not(jit))] + test_crc32(); } #[cfg(target_arch = "x86_64")] @@ -447,6 +466,16 @@ unsafe fn test_mm256_permute2x128_si256() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm256_permutevar8x32_epi32() { + let a = _mm256_setr_epi32(100, 200, 300, 400, 500, 600, 700, 800); + let idx = _mm256_setr_epi32(7, 6, 5, 4, 3, 2, 1, 0); + let r = _mm256_setr_epi32(800, 700, 600, 500, 400, 300, 200, 100); + let e = _mm256_permutevar8x32_epi32(a, idx); + assert_eq_m256i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index a72fa2c62a96c..c8c7b45bc9a6f 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -42,9 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" diff --git a/rust-toolchain b/rust-toolchain index de340cf8c35cc..a2ba79cbe9038 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-23" +channel = "nightly-2024-05-13" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 8580f4557e883..689cda21643cb 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -44,6 +44,7 @@ rm tests/incremental/hashes/statics.rs # same rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support +rm tests/ui/delegation/fn-header.rs # unsized locals rm -r tests/run-pass-valgrind/unsized-locals @@ -87,6 +88,7 @@ rm -r tests/run-make/no-builtins-attribute # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific +rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= @@ -151,7 +153,7 @@ index 9607ff02f96..b7d97caf9a2 100644 let mut cmd = setup_common(); - let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd } + Self { cmd, stdin: None } } EOF diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6f346af25c6dd..4bcef15ad0475 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) => { + InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -597,7 +597,9 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + drop_instance.def + { // we don't actually need to drop anything } else { match ty.kind() { diff --git a/src/base.rs b/src/base.rs index 8874efadec9d9..5846689643fdd 100644 --- a/src/base.rs +++ b/src/base.rs @@ -6,6 +6,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -14,6 +15,7 @@ use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphizat use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; +use crate::inline_asm::codegen_naked_asm; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -32,7 +34,7 @@ pub(crate) fn codegen_fn<'tcx>( cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, -) -> CodegenedFunction { +) -> Option { debug_assert!(!instance.args.has_infer()); let symbol_name = tcx.symbol_name(instance).name.to_string(); @@ -48,6 +50,37 @@ pub(crate) fn codegen_fn<'tcx>( String::from_utf8_lossy(&buf).into_owned() }); + if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { + assert_eq!(mir.basic_blocks.len(), 1); + assert!(mir.basic_blocks[START_BLOCK].statements.is_empty()); + + match &mir.basic_blocks[START_BLOCK].terminator().kind { + TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans: _, + targets: _, + unwind: _, + } => { + codegen_naked_asm( + tcx, + cx, + module, + instance, + mir.basic_blocks[START_BLOCK].terminator().source_info.span, + &symbol_name, + template, + operands, + *options, + ); + } + _ => unreachable!(), + } + + return None; + } + // Declare function let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap(); @@ -128,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>( // Verify function verify_func(tcx, &clif_comments, &func); - CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx } + Some(CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }) } pub(crate) fn compile_fn( diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index 9678969134a8d..a73860cf18b2d 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -6,7 +6,7 @@ use rustc_session::Session; // FIXME don't panic when a worker thread panics pub(super) struct ConcurrencyLimiter { - helper_thread: Option, + helper_thread: Option>, state: Arc>, available_token_condvar: Arc, finished: bool, @@ -39,14 +39,14 @@ impl ConcurrencyLimiter { }) .unwrap(); ConcurrencyLimiter { - helper_thread: Some(helper_thread), + helper_thread: Some(Mutex::new(helper_thread)), state, available_token_condvar, finished: false, } } - pub(super) fn acquire(&mut self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); @@ -73,16 +73,11 @@ impl ConcurrencyLimiter { } } - self.helper_thread.as_mut().unwrap().request_token(); + self.helper_thread.as_ref().unwrap().lock().unwrap().request_token(); state = self.available_token_condvar.wait(state).unwrap(); } } - pub(super) fn job_already_done(&mut self) { - let mut state = self.state.lock().unwrap(); - state.job_already_done(); - } - pub(crate) fn finished(mut self) { self.helper_thread.take(); @@ -190,14 +185,6 @@ mod state { self.assert_invariants(); } - pub(super) fn job_already_done(&mut self) { - self.assert_invariants(); - self.pending_jobs -= 1; - self.assert_invariants(); - self.drop_excess_capacity(); - self.assert_invariants(); - } - pub(super) fn poison(&mut self, error: String) { self.poisoned = true; self.stored_error = Some(error); diff --git a/src/config.rs b/src/config.rs index 9e92d656c76ef..12bce680d9e11 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,8 +64,13 @@ impl Default for BackendConfig { BackendConfig { codegen_mode: CodegenMode::Aot, jit_args: { - let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); - args.split(' ').map(|arg| arg.to_string()).collect() + match std::env::var("CG_CLIF_JIT_ARGS") { + Ok(args) => args.split(' ').map(|arg| arg.to_string()).collect(), + Err(std::env::VarError::NotPresent) => vec![], + Err(std::env::VarError::NotUnicode(s)) => { + panic!("CG_CLIF_JIT_ARGS not unicode: {:?}", s); + } + } }, enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), diff --git a/src/constant.rs b/src/constant.rs index cdf499a22f8dd..64e83e43d3272 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -258,7 +258,7 @@ fn data_id_for_static( ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol_name = tcx.symbol_name(instance).name; if let Some(import_linkage) = attrs.import_linkage { diff --git a/src/discriminant.rs b/src/discriminant.rs index 670384663e83f..e7ac084558a5a 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -28,16 +28,20 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } => { let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; - let to = if ptr.layout().abi.is_signed() { - ty::ScalarInt::try_from_int( - ptr.layout().size.sign_extend(to) as i128, - ptr.layout().size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(to, ptr.layout().size).unwrap() + let to = match ptr.layout().ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, to as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (to >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(ptr.layout().ty).unwrap(); + let raw_val = ptr.layout().size.truncate(to); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let discr = CValue::const_val(fx, ptr.layout(), to); + let discr = CValue::by_val(to, ptr.layout()); ptr.write_cvalue(fx, discr); } Variants::Multiple { @@ -85,16 +89,21 @@ pub(crate) fn codegen_get_discriminant<'tcx>( .ty .discriminant_for_variant(fx.tcx, *index) .map_or(u128::from(index.as_u32()), |discr| discr.val); - let discr_val = if dest_layout.abi.is_signed() { - ty::ScalarInt::try_from_int( - dest_layout.size.sign_extend(discr_val) as i128, - dest_layout.size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap() + + let val = match dest_layout.ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, discr_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (discr_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(dest_layout.ty).unwrap(); + let raw_val = dest_layout.size.truncate(discr_val); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let res = CValue::const_val(fx, dest_layout, discr_val); + let res = CValue::by_val(val, dest_layout); dest.write_cvalue(fx, res); return; } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e8c96486041b1..fce4690f97dc9 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::{par_map, IntoDynSyncSend}; use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -481,15 +482,16 @@ fn module_codegen( for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - let codegened_function = crate::base::codegen_fn( + if let Some(codegened_function) = crate::base::codegen_fn( tcx, &mut cx, &mut type_dbg, Function::new(), &mut module, inst, - ); - codegened_functions.push(codegened_function); + ) { + codegened_functions.push(codegened_function); + } } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); @@ -604,39 +606,39 @@ pub(crate) fn run_aot( let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx)); - let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); + let (todo_cgus, done_cgus) = + cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + _ if backend_config.disable_incr_cache => true, + CguReuse::No => true, + CguReuse::PreLto | CguReuse::PostLto => false, + }); + + let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len())); let modules = tcx.sess.time("codegen mono items", || { - cgus.iter() - .enumerate() - .map(|(i, cgu)| { - let cgu_reuse = - if backend_config.disable_incr_cache { CguReuse::No } else { cgu_reuse[i] }; - match cgu_reuse { - CguReuse::No => { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.dcx()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - } - CguReuse::PreLto | CguReuse::PostLto => { - concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - } - } - }) - .collect::>() + let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 + }); + modules.extend( + done_cgus + .into_iter() + .map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))), + ); + modules }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); @@ -705,6 +707,6 @@ pub(crate) fn run_aot( metadata_module, metadata, crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter, + concurrency_limiter: concurrency_limiter.0, }) } diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 929fa92596dc6..4b149131b61aa 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -83,13 +83,6 @@ fn create_jit_module( ); crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); (jit_module, cx) } @@ -153,6 +146,14 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } + crate::main_shim::maybe_create_entry_wrapper( + tcx, + &mut jit_module, + &mut cx.unwind_context, + true, + true, + ); + tcx.dcx().abort_if_errors(); jit_module.finalize_definitions().unwrap(); @@ -231,16 +232,16 @@ pub(crate) fn codegen_and_compile_fn<'tcx>( crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = crate::base::codegen_fn( + if let Some(codegened_func) = crate::base::codegen_fn( tcx, cx, &mut TypeDebugContext::default(), cached_func, module, instance, - ); - - crate::base::compile_fn(cx, cached_context, module, codegened_func); + ) { + crate::base::compile_fn(cx, cached_context, module, codegened_func); + } }); } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 12e90b5841034..fb0eed07c1971 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -5,6 +5,7 @@ //! [`codegen_static`]: crate::constant::codegen_static use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{MonoItem, MonoItemData}; use crate::prelude::*; @@ -33,7 +34,20 @@ fn predefine_mono_items<'tcx>( data.visibility, is_compiler_builtins, ); - module.declare_function(name, linkage, &sig).unwrap(); + let is_naked = tcx + .codegen_fn_attrs(instance.def_id()) + .flags + .contains(CodegenFnAttrFlags::NAKED); + module + .declare_function( + name, + // Naked functions are defined in a separate object + // file from the codegen unit rustc expects them to + // be defined in. + if is_naked { Linkage::Import } else { linkage }, + &sig, + ) + .unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } diff --git a/src/global_asm.rs b/src/global_asm.rs index 5a0cd3990f2a7..0c99a5ce12f6e 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -81,7 +81,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); global_asm.push_str(symbol.name); } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 28b92f730da34..2de804f5e0423 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -127,7 +127,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( } InlineAsmOperand::SymStatic { def_id } => { assert!(fx.tcx.is_static(def_id)); - let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + let instance = Instance::mono(fx.tcx, def_id); CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() } } InlineAsmOperand::Label { .. } => { @@ -169,6 +169,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( stack_slots_input: Vec::new(), stack_slots_output: Vec::new(), stack_slot_size: Size::from_bytes(0), + is_naked: false, }; asm_gen.allocate_registers(); asm_gen.allocate_stack_slots(); @@ -209,6 +210,121 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs); } +pub(crate) fn codegen_naked_asm<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut crate::CodegenCx, + module: &mut dyn Module, + instance: Instance<'tcx>, + span: Span, + symbol_name: &str, + template: &[InlineAsmTemplatePiece], + operands: &[InlineAsmOperand<'tcx>], + options: InlineAsmOptions, +) { + // FIXME add .eh_frame unwind info directives + + let operands = operands + .iter() + .map(|operand| match *operand { + InlineAsmOperand::In { .. } + | InlineAsmOperand::Out { .. } + | InlineAsmOperand::InOut { .. } => { + span_bug!(span, "invalid operand type for naked asm") + } + InlineAsmOperand::Const { ref value } => { + let cv = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + let const_value = cv + .eval(tcx, ty::ParamEnv::reveal_all(), value.span) + .expect("erroneous constant missed by mono item collection"); + + let value = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + span, + const_value, + RevealAllLayoutCx(tcx).layout_of(cv.ty()), + ); + CInlineAsmOperand::Const { value } + } + InlineAsmOperand::SymFn { ref value } => { + if cfg!(not(feature = "inline_asm_sym")) { + tcx.dcx() + .span_err(span, "asm! and global_asm! sym operands are not yet supported"); + } + + let const_ = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + if let ty::FnDef(def_id, args) = *const_.ty().kind() { + let instance = ty::Instance::resolve_for_fn_ptr( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ) + .unwrap(); + let symbol = tcx.symbol_name(instance); + + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let inline_asm_index = cx.inline_asm_index.get(); + cx.inline_asm_index.set(inline_asm_index + 1); + let wrapper_name = format!( + "__inline_asm_{}_wrapper_n{}", + cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + inline_asm_index + ); + let sig = + get_function_sig(tcx, module.target_config().default_call_conv, instance); + create_wrapper_function( + module, + &mut cx.unwind_context, + sig, + &wrapper_name, + symbol.name, + ); + + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } else { + span_bug!(span, "invalid type for asm sym (fn)"); + } + } + InlineAsmOperand::SymStatic { def_id } => { + assert!(tcx.is_static(def_id)); + let instance = Instance::mono(tcx, def_id); + CInlineAsmOperand::Symbol { symbol: tcx.symbol_name(instance).name.to_owned() } + } + InlineAsmOperand::Label { .. } => { + span_bug!(span, "asm! label operands are not yet supported"); + } + }) + .collect::>(); + + let asm_gen = InlineAssemblyGenerator { + tcx, + arch: tcx.sess.asm_arch.unwrap(), + enclosing_def_id: instance.def_id(), + template, + operands: &operands, + options, + registers: Vec::new(), + stack_slots_clobber: Vec::new(), + stack_slots_input: Vec::new(), + stack_slots_output: Vec::new(), + stack_slot_size: Size::from_bytes(0), + is_naked: true, + }; + + let generated_asm = asm_gen.generate_asm_wrapper(symbol_name); + cx.global_asm.push_str(&generated_asm); +} + struct InlineAssemblyGenerator<'a, 'tcx> { tcx: TyCtxt<'tcx>, arch: InlineAsmArch, @@ -221,10 +337,13 @@ struct InlineAssemblyGenerator<'a, 'tcx> { stack_slots_input: Vec>, stack_slots_output: Vec>, stack_slot_size: Size, + is_naked: bool, } impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { + assert!(!self.is_naked); + let sess = self.tcx.sess; let map = allocatable_registers( self.arch, @@ -348,6 +467,8 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { } fn allocate_stack_slots(&mut self) { + assert!(!self.is_naked); + let mut slot_size = Size::from_bytes(0); let mut slots_clobber = vec![None; self.operands.len()]; let mut slots_input = vec![None; self.operands.len()]; @@ -468,30 +589,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { if is_x86 { generated_asm.push_str(".intel_syntax noprefix\n"); } - Self::prologue(&mut generated_asm, self.arch); + if !self.is_naked { + Self::prologue(&mut generated_asm, self.arch); + + // Save clobbered registers + if !self.options.contains(InlineAsmOptions::NORETURN) { + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } + } - // Save clobbered registers - if !self.options.contains(InlineAsmOptions::NORETURN) { + // Write input registers for (reg, slot) in self .registers .iter() - .zip(self.stack_slots_clobber.iter().copied()) + .zip(self.stack_slots_input.iter().copied()) .filter_map(|(r, s)| r.zip(s)) { - Self::save_register(&mut generated_asm, self.arch, reg, slot); + Self::restore_register(&mut generated_asm, self.arch, reg, slot); } } - // Write input registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_input.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } - if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) { generated_asm.push_str(".att_syntax\n"); } @@ -553,30 +676,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { generated_asm.push_str(".intel_syntax noprefix\n"); } - if !self.options.contains(InlineAsmOptions::NORETURN) { - // Read output registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_output.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::save_register(&mut generated_asm, self.arch, reg, slot); - } + if !self.is_naked { + if !self.options.contains(InlineAsmOptions::NORETURN) { + // Read output registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_output.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } - // Restore clobbered registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_clobber.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } + // Restore clobbered registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::restore_register(&mut generated_asm, self.arch, reg, slot); + } - Self::epilogue(&mut generated_asm, self.arch); - } else { - Self::epilogue_noreturn(&mut generated_asm, self.arch); + Self::epilogue(&mut generated_asm, self.arch); + } else { + Self::epilogue_noreturn(&mut generated_asm, self.arch); + } } if is_x86 { diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 8df83c706a100..27b55ecc72eef 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -374,6 +374,21 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } } + "llvm.x86.avx2.permd" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permutevar8x32_epi32 + intrinsic_args!(fx, args => (a, idx); intrinsic); + + for j in 0..=7 { + let index = idx.value_typed_lane(fx, fx.tcx.types.u32, j).load_scalar(fx); + let index = fx.bcx.ins().uextend(fx.pointer_type, index); + let value = a.value_lane_dyn(fx, index).load_scalar(fx); + ret.place_typed_lane(fx, fx.tcx.types.u32, j).to_ptr().store( + fx, + value, + MemFlags::trusted(), + ); + } + } "llvm.x86.avx2.vperm2i128" | "llvm.x86.avx.vperm2f128.ps.256" | "llvm.x86.avx.vperm2f128.pd.256" => { @@ -832,6 +847,43 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } + "llvm.x86.sse42.crc32.32.8" + | "llvm.x86.sse42.crc32.32.16" + | "llvm.x86.sse42.crc32.32.32" + | "llvm.x86.sse42.crc32.64.64" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1419&text=_mm_crc32_u32 + intrinsic_args!(fx, args => (crc, v); intrinsic); + + let crc = crc.load_scalar(fx); + let v = v.load_scalar(fx); + + let asm = match intrinsic { + "llvm.x86.sse42.crc32.32.8" => "crc32 eax, dl", + "llvm.x86.sse42.crc32.32.16" => "crc32 eax, dx", + "llvm.x86.sse42.crc32.32.32" => "crc32 eax, edx", + "llvm.x86.sse42.crc32.64.64" => "crc32 rax, rdx", + _ => unreachable!(), + }; + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(asm.to_string())], + &[ + CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + _late: true, + in_value: crc, + out_place: Some(ret), + }, + CInlineAsmOperand::In { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + value: v, + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + "llvm.x86.sse42.pcmpestri128" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestri&ig_expand=939 intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic); diff --git a/src/lib.rs b/src/lib.rs index e72951b6f3447..39bbad16b0c00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -331,9 +331,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc CValue<'tcx> { let clif_ty = fx.clif_type(layout.ty).unwrap(); - if let ty::Bool = layout.ty.kind() { - assert!( - const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE, - "Invalid bool 0x{:032X}", - const_val - ); - } - let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.assert_bits(layout.size); diff --git a/y.cmd b/y.cmd index e9b688645a4d8..42106849163b5 100644 --- a/y.cmd +++ b/y.cmd @@ -1,8 +1,6 @@ @echo off echo [BUILD] build system >&2 -mkdir build 2>nul -rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 || goto :error -build\y.exe %* || goto :error +cargo run --manifest-path build_system/Cargo.toml -- %* || goto :error goto :EOF :error diff --git a/y.ps1 b/y.ps1 old mode 100644 new mode 100755 index 02ef0fcbd50f1..821f0ec6e5777 --- a/y.ps1 +++ b/y.ps1 @@ -1,12 +1,7 @@ $ErrorActionPreference = "Stop" $host.ui.WriteErrorLine("[BUILD] build system") -New-Item -ItemType Directory -Force -Path build | Out-Null -& rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 -if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE -} -& build\y.exe $args +& cargo run --manifest-path build_system/Cargo.toml -- $args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/y.sh b/y.sh index bc925a23e2a88..b9152d2cc6de0 100755 --- a/y.sh +++ b/y.sh @@ -2,5 +2,4 @@ set -e echo "[BUILD] build system" 1>&2 -rustc build_system/main.rs -o y.bin -Cdebuginfo=1 --edition 2021 -exec ./y.bin "$@" +exec cargo run --manifest-path build_system/Cargo.toml -- "$@" From 8aa7112c82416cfaf0fb63db2467d45fdb0407bc Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 17 May 2024 14:17:48 -0300 Subject: [PATCH 008/217] Rename Unsafe to Safety --- src/value_and_place.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index b6d6d211e658c..4146137c2263a 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -872,7 +872,7 @@ pub(crate) fn assert_assignable<'tcx>( let FnSig { inputs_and_output: types_from, c_variadic: c_variadic_from, - unsafety: unsafety_from, + safety: unsafety_from, abi: abi_from, } = from_sig; let to_sig = fx @@ -881,7 +881,7 @@ pub(crate) fn assert_assignable<'tcx>( let FnSig { inputs_and_output: types_to, c_variadic: c_variadic_to, - unsafety: unsafety_to, + safety: unsafety_to, abi: abi_to, } = to_sig; let mut types_from = types_from.iter(); From 6965b4a8bd9f06aa956db21058092da9421f4ceb Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 16 May 2024 02:07:31 -0700 Subject: [PATCH 009/217] Remove `Rvalue::CheckedBinaryOp` --- src/base.rs | 13 +++++-------- src/codegen_i128.rs | 2 ++ src/num.rs | 3 +++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/base.rs b/src/base.rs index 5846689643fdd..8d778f736d671 100644 --- a/src/base.rs +++ b/src/base.rs @@ -609,14 +609,11 @@ fn codegen_stmt<'tcx>( let lhs = codegen_operand(fx, &lhs_rhs.0); let rhs = codegen_operand(fx, &lhs_rhs.1); - let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); - lval.write_cvalue(fx, res); - } - Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => { - let lhs = codegen_operand(fx, &lhs_rhs.0); - let rhs = codegen_operand(fx, &lhs_rhs.1); - - let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs); + let res = if let Some(bin_op) = bin_op.overflowing_to_wrapping() { + crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs) + } else { + crate::num::codegen_binop(fx, bin_op, lhs, rhs) + }; lval.write_cvalue(fx, res); } Rvalue::UnaryOp(un_op, ref operand) => { diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 4a5ef352151f3..e16b77648d12f 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -70,6 +70,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne | BinOp::Cmp => None, BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => None, + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(), } } @@ -132,6 +133,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>( Some(out_place.to_cvalue(fx)) } BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(), + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(), BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Div | BinOp::Rem => unreachable!(), BinOp::Cmp => unreachable!(), diff --git a/src/num.rs b/src/num.rs index 4d96a26ea4fa8..fb18f45d7dcad 100644 --- a/src/num.rs +++ b/src/num.rs @@ -179,6 +179,9 @@ pub(crate) fn codegen_int_binop<'tcx>( } } BinOp::Offset => unreachable!("Offset is not an integer operation"), + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => { + unreachable!("Overflow binops handled by `codegen_checked_int_binop`") + } // Compare binops handles by `codegen_binop`. BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Cmp => { unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty); From bff31bdcbc016c425f5027d7b15e3a1aad8a717c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 May 2024 13:22:06 +0000 Subject: [PATCH 010/217] Rustup to rustc 1.80.0-nightly (b1ec1bd65 2024-05-18) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index a2ba79cbe9038..9726708ce106d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-13" +channel = "nightly-2024-05-19" components = ["rust-src", "rustc-dev", "llvm-tools"] From 8cea8a78409ae5db5ac5d9f15bd4497d5bba0734 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 May 2024 13:37:01 +0000 Subject: [PATCH 011/217] Fix rustc test suite --- scripts/test_rustc_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 689cda21643cb..ec29efa05fb13 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,13 +60,13 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib -rm -r tests/run-make/issue-14500 rm -r tests/run-make/issue-64153 rm -r tests/run-make/codegen-options-parsing rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 rm -r tests/run-make/issue-109934-lto-debuginfo rm -r tests/run-make/no-builtins-lto +rm -r tests/run-make/reachable-extern-fn-available-lto # optimization tests # ================== From 7a53ba2e764d4e953ec654b73a6222163482db88 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 19 May 2024 18:50:42 -0700 Subject: [PATCH 012/217] cg_clif: support simd_ctpop --- src/intrinsics/simd.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 452b5988dab4c..b17f191ce267e 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -348,6 +348,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( | sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctlz + | sym::simd_ctpop | sym::simd_cttz => { intrinsic_args!(fx, args => (a); intrinsic); @@ -367,6 +368,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( (ty::Uint(_) | ty::Int(_), sym::simd_bswap) => fx.bcx.ins().bswap(lane), (ty::Uint(_) | ty::Int(_), sym::simd_bitreverse) => fx.bcx.ins().bitrev(lane), (ty::Uint(_) | ty::Int(_), sym::simd_ctlz) => fx.bcx.ins().clz(lane), + (ty::Uint(_) | ty::Int(_), sym::simd_ctpop) => fx.bcx.ins().popcnt(lane), (ty::Uint(_) | ty::Int(_), sym::simd_cttz) => fx.bcx.ins().ctz(lane), _ => unreachable!(), From 39daa5a182dfd6eabd803066cce09353116628e2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 20 May 2024 20:26:12 +0000 Subject: [PATCH 013/217] Update to Cranelift 0.108 --- Cargo.lock | 54 ++++++++++++++++++++++++++++-------------------------- Cargo.toml | 12 ++++++------ 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33fe52ddbdd64..b95ab0a7f177a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b27922a6879b5b5361d0a084cb0b1941bf109a98540addcb932da13b68bed4" +checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304c455b28bf56372729acb356afbb55d622f2b0f2f7837aa5e57c138acaac4d" +checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" dependencies = [ "bumpalo", "cranelift-bforest", @@ -70,45 +70,46 @@ dependencies = [ "hashbrown 0.14.3", "log", "regalloc2", + "rustc-hash", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1653c56b99591d07f67c5ca7f9f25888948af3f4b97186bff838d687d666f613" +checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5b6a9cf6b6eb820ee3f973a0db313c05dc12d370f37b4fe9630286e1672573f" +checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" [[package]] name = "cranelift-control" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d06e6bf30075fb6bed9e034ec046475093392eea1aff90eb5c44c4a033d19a" +checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29be04f931b73cdb9694874a295027471817f26f26d2f0ebe5454153176b6e3a" +checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" [[package]] name = "cranelift-frontend" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07fd7393041d7faa2f37426f5dc7fc04003b70988810e8c063beefeff1cd8f9" +checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" dependencies = [ "cranelift-codegen", "log", @@ -118,15 +119,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f341d7938caa6dff8149dac05bb2b53fc680323826b83b4cf175ab9f5139a3c9" +checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" [[package]] name = "cranelift-jit" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42733555e06433f1461570e09dbd756dafc228b4dac75c597cdbdc518de07522" +checksum = "2d396c6f5cde59c1e408d813426d2332031692152432e12f4de63a936c6c10c7" dependencies = [ "anyhow", "cranelift-codegen", @@ -144,9 +145,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84950af02bb85f3da764d53a953b43bb29a732e793d4fe24637a61591be9a024" +checksum = "7067c2b072829bb35f19f9e99eb42b6982faf4339adb2946797728ff0bd6a089" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +156,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82af6066e6448d26eeabb7aa26a43f7ff79f8217b06bade4ee6ef230aecc8880" +checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +167,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00af56107039ed150391df6f753298c7b08f2b6a2e0727d216b5fa599d684d8b" +checksum = "d8a09bc240fb04674e01382ca505b34e71ea0ee8499a7960cd85f70359873852" dependencies = [ "anyhow", "cranelift-codegen", @@ -410,10 +411,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "20.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9f93a3289057b26dc75eb84d6e60d7694f7d169c7c09597495de6e016a13ff" +checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" dependencies = [ + "anyhow", "cfg-if", "libc", "windows-sys", diff --git a/Cargo.toml b/Cargo.toml index 2015cdbcc2a74..6aaff55023b07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.107.0", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.107.0" } -cranelift-module = { version = "0.107.0" } -cranelift-native = { version = "0.107.0" } -cranelift-jit = { version = "0.107.0", optional = true } -cranelift-object = { version = "0.107.0" } +cranelift-codegen = { version = "0.108.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.108.0" } +cranelift-module = { version = "0.108.0" } +cranelift-native = { version = "0.108.0" } +cranelift-jit = { version = "0.108.0", optional = true } +cranelift-object = { version = "0.108.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} object = { version = "0.33", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } From 715f2264a9cfc79bab3e6c5bc4f2f7608c4a7af4 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 19 Jan 2024 14:42:43 -0500 Subject: [PATCH 014/217] rustc_codegen_llvm: add support for writing summary bitcode Typical uses of ThinLTO don't have any use for this as a standalone file, but distributed ThinLTO uses this to make the linker phase more efficient. With clang you'd do something like `clang -flto=thin -fthin-link-bitcode=foo.indexing.o -c foo.c` and then get both foo.o (full of bitcode) and foo.indexing.o (just the summary or index part of the bitcode). That's then usable by a two-stage linking process that's more friendly to distributed build systems like bazel, which is why I'm working on this area. I talked some to @teresajohnson about naming in this area, as things seem to be a little confused between various blog posts and build systems. "bitcode index" and "bitcode summary" tend to be a little too ambiguous, and she tends to use "thin link bitcode" and "minimized bitcode" (which matches the descriptions in LLVM). Since the clang option is thin-link-bitcode, I went with that to try and not add a new spelling in the world. Per @dtolnay, you can work around the lack of this by using `lld --thinlto-index-only` to do the indexing on regular .o files of bitcode, but that is a bit wasteful on actions when we already have all the information in rustc and could just write out the matching minimized bitcode. I didn't test that at all in our infrastructure, because by the time I learned that I already had this patch largely written. --- src/driver/aot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index fce4690f97dc9..394c810176ab2 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -200,7 +200,7 @@ fn produce_final_output_artifacts( // to get rid of it. for output_type in crate_output.outputs.keys() { match *output_type { - OutputType::Bitcode => { + OutputType::Bitcode | OutputType::ThinLinkBitcode => { // Cranelift doesn't have bitcode // user_wants_bitcode = true; // // Copy to .bc, but always keep the .0.bc. There is a later From 8bb463ae11586bb40a4e26cac1a2e2485cd98e58 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 May 2024 12:25:11 +0000 Subject: [PATCH 015/217] Rustup to rustc 1.80.0-nightly (9cdfe285c 2024-05-22) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9726708ce106d..a1a7214c9060c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-19" +channel = "nightly-2024-05-23" components = ["rust-src", "rustc-dev", "llvm-tools"] From ba8c695326e24498ff8794da1c5bf5c7d2c43f04 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 May 2024 12:40:09 +0000 Subject: [PATCH 016/217] Stop passing --check-cfg to rustc The standard library now has the right configs in it's Cargo.toml --- build_system/build_sysroot.rs | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 196ff8fda7544..dfbe0f51e7be2 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -267,10 +267,6 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } - rustflags.push("-Zunstable-options".to_owned()); - for (name, values) in EXTRA_CHECK_CFGS { - rustflags.push(check_cfg_arg(name, *values)); - } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { @@ -330,34 +326,3 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } - -// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 -/// Create a `--check-cfg` argument invocation for a given name -/// and it's values. -fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { - // Creating a string of the values by concatenating each value: - // ',values("tvos","watchos")' or '' (nothing) when there are no values. - let next = match values { - Some(values) => { - let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); - - tmp.insert_str(1, "values("); - tmp.push(')'); - tmp - } - None => "".to_string(), - }; - format!("--check-cfg=cfg({name}{next})") -} - -const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ - ("bootstrap", None), - ("stdarch_intel_sde", None), - ("no_fp_fmt_parse", None), - ("no_global_oom_handling", None), - ("no_rc", None), - ("no_sync", None), - ("netbsd10", None), - ("backtrace_in_libstd", None), - ("target_arch", Some(&["xtensa"])), -]; From 9ddcc594113d9d8a3b9181c4436b767251b876c5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 17 Mar 2024 17:42:37 -0400 Subject: [PATCH 017/217] Omit non-needs_drop drop_in_place in vtables This replaces the drop_in_place reference with null in vtables. On librustc_driver.so, this drops about ~17k dynamic relocations from the output, since many vtables can now be placed in read-only memory, rather than having a relocated pointer included. This makes a tradeoff by adding a null check at vtable call sites. That's hard to avoid without changing the vtable format (e.g., to use a pc-relative relocation instead of an absolute address, and avoid the dynamic relocation that way). But it seems likely that the check is cheap at runtime. --- src/abi/mod.rs | 16 ++++++++++++++++ src/base.rs | 5 +---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 4bcef15ad0475..bd5a88769059f 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -593,6 +593,7 @@ pub(crate) fn codegen_drop<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, source_info: mir::SourceInfo, drop_place: CPlace<'tcx>, + target: BasicBlock, ) { let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); @@ -620,6 +621,12 @@ pub(crate) fn codegen_drop<'tcx>( let ptr = ptr.get_addr(fx); let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable); + let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0); + let target_block = fx.get_block(target); + let continued = fx.bcx.create_block(); + fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]); + fx.bcx.switch_to_block(continued); + // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? let virtual_drop = Instance { @@ -659,6 +666,12 @@ pub(crate) fn codegen_drop<'tcx>( let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx); let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable); + let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0); + let target_block = fx.get_block(target); + let continued = fx.bcx.create_block(); + fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]); + fx.bcx.switch_to_block(continued); + let virtual_drop = Instance { def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, @@ -697,4 +710,7 @@ pub(crate) fn codegen_drop<'tcx>( } } } + + let target_block = fx.get_block(target); + fx.bcx.ins().jump(target_block, &[]); } diff --git a/src/base.rs b/src/base.rs index 8d778f736d671..c394844e62593 100644 --- a/src/base.rs +++ b/src/base.rs @@ -548,10 +548,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } TerminatorKind::Drop { place, target, unwind: _, replace: _ } => { let drop_place = codegen_place(fx, *place); - crate::abi::codegen_drop(fx, source_info, drop_place); - - let target_block = fx.get_block(*target); - fx.bcx.ins().jump(target_block, &[]); + crate::abi::codegen_drop(fx, source_info, drop_place, *target); } }; } From 676fec7c651870268d47fdab098bae900fac07e4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 21 Apr 2024 16:11:01 -0700 Subject: [PATCH 018/217] Add an intrinsic for `ptr::metadata` --- src/base.rs | 38 +++++++++++++++++++++++++------------- src/constant.rs | 2 +- src/value_and_place.rs | 8 ++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/base.rs b/src/base.rs index 8d778f736d671..de1cd9c75c16e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -619,22 +619,34 @@ fn codegen_stmt<'tcx>( Rvalue::UnaryOp(un_op, ref operand) => { let operand = codegen_operand(fx, operand); let layout = operand.layout(); - let val = operand.load_scalar(fx); let res = match un_op { - UnOp::Not => match layout.ty.kind() { - ty::Bool => { - let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0); - CValue::by_val(res, layout) + UnOp::Not => { + let val = operand.load_scalar(fx); + match layout.ty.kind() { + ty::Bool => { + let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0); + CValue::by_val(res, layout) + } + ty::Uint(_) | ty::Int(_) => { + CValue::by_val(fx.bcx.ins().bnot(val), layout) + } + _ => unreachable!("un op Not for {:?}", layout.ty), } - ty::Uint(_) | ty::Int(_) => { - CValue::by_val(fx.bcx.ins().bnot(val), layout) + } + UnOp::Neg => { + let val = operand.load_scalar(fx); + match layout.ty.kind() { + ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout), + ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout), + _ => unreachable!("un op Neg for {:?}", layout.ty), } - _ => unreachable!("un op Not for {:?}", layout.ty), - }, - UnOp::Neg => match layout.ty.kind() { - ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout), - ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout), - _ => unreachable!("un op Neg for {:?}", layout.ty), + } + UnOp::PtrMetadata => match layout.abi { + Abi::Scalar(_) => CValue::zst(dest_layout), + Abi::ScalarPair(_, _) => { + CValue::by_val(operand.load_scalar_pair(fx).1, dest_layout) + } + _ => bug!("Unexpected `PtrToMetadata` operand: {operand:?}"), }, }; lval.write_cvalue(fx, res); diff --git a/src/constant.rs b/src/constant.rs index 64e83e43d3272..ba98f2e772cbf 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -100,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>( assert!(layout.is_sized(), "unsized const value"); if layout.is_zst() { - return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout); + return CValue::zst(layout); } match const_val { diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 4146137c2263a..512a96450a4b6 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -95,6 +95,14 @@ impl<'tcx> CValue<'tcx> { CValue(CValueInner::ByValPair(value, extra), layout) } + /// Create an instance of a ZST + /// + /// The is represented by a dangling pointer of suitable alignment. + pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> { + assert!(layout.is_zst()); + CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout) + } + pub(crate) fn layout(&self) -> TyAndLayout<'tcx> { self.1 } From a25596584988c972546d60fe1b3ffe75cbcc0cf6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 May 2024 16:34:21 +0000 Subject: [PATCH 019/217] Rustup to rustc 1.80.0-nightly (debd22da6 2024-05-29) --- patches/stdlib-lock.toml | 23 +++++++++++++++++------ rust-toolchain | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index c8c7b45bc9a6f..1bac8a93240b7 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -4,12 +4,12 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.29.0", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] @@ -133,6 +133,17 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -286,9 +297,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -430,7 +441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.28.1", "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index a1a7214c9060c..44a196c18ae17 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-23" +channel = "nightly-2024-05-30" components = ["rust-src", "rustc-dev", "llvm-tools"] From ab10da27a11133add161bc6f9b2b7580ba455d58 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 May 2024 16:42:52 +0000 Subject: [PATCH 020/217] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index ec29efa05fb13..980bb2e666039 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -36,9 +36,8 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic # exotic linkages -rm tests/ui/issues/issue-33992.rs # unsupported linkages -rm tests/incremental/hashes/function_interfaces.rs # same -rm tests/incremental/hashes/statics.rs # same +rm tests/incremental/hashes/function_interfaces.rs +rm tests/incremental/hashes/statics.rs # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs @@ -93,7 +92,6 @@ rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= rm -r tests/run-make/emit-named-files -rm -r tests/run-make/issue-30063 rm -r tests/run-make/multiple-emits rm -r tests/run-make/output-type-permutations rm -r tests/run-make/emit-to-stdout From 8f1d41e2a0cf73f6ecb1737f0c70a07bc8989bfa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 2 Jun 2024 11:18:51 +0200 Subject: [PATCH 021/217] Implement _rdtsc x86 vendor intrinsic Fixes rust-lang/rustc_codegen_cranelift#1493 --- src/intrinsics/llvm_x86.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 27b55ecc72eef..03dca0656ef1e 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1416,6 +1416,36 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue(fx, res); } + "llvm.x86.rdtsc" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdtsc&ig_expand=5273 + + let res_place = CPlace::new_stack_slot( + fx, + fx.layout_of(Ty::new_tup(fx.tcx, &[fx.tcx.types.u32, fx.tcx.types.u32])), + ); + let eax_place = res_place.place_field(fx, FieldIdx::new(0)); + let edx_place = res_place.place_field(fx, FieldIdx::new(1)); + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String("rdtsc".to_string())], + &[ + CInlineAsmOperand::Out { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + late: true, + place: Some(eax_place), + }, + CInlineAsmOperand::Out { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + late: true, + place: Some(edx_place), + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::NOMEM, + ); + let res = res_place.to_cvalue(fx); + ret.write_cvalue_transmute(fx, res); + } + _ => { fx.tcx .dcx() From eb449c133903c6b274580f8e365a3f287670d667 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:02:36 +0200 Subject: [PATCH 022/217] Move error on -Cinstrument-coverage earlier and elaborate that it is LLVM specific cc rust-lang/rustc_codegen_cranelift#1494 --- src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 39bbad16b0c00..9eece684b1a6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,7 +172,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn init(&self, sess: &Session) { - use rustc_session::config::Lto; + use rustc_session::config::{InstrumentCoverage, Lto}; match sess.lto() { Lto::No | Lto::ThinLocal => {} Lto::Thin | Lto::Fat => { @@ -180,6 +180,11 @@ impl CodegenBackend for CraneliftCodegenBackend { } } + if sess.opts.cg.instrument_coverage() != InstrumentCoverage::No { + sess.dcx() + .fatal("`-Cinstrument-coverage` is LLVM specific and not supported by Cranelift"); + } + let mut config = self.config.borrow_mut(); if config.is_none() { let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args) From 97d47f7077d631c0eb8dac000638496a2c2a5ee2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:21:13 +0200 Subject: [PATCH 023/217] Fix rustc tests --- scripts/test_rustc_tests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 980bb2e666039..6c45a4ccf7962 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -67,6 +67,11 @@ rm -r tests/run-make/issue-109934-lto-debuginfo rm -r tests/run-make/no-builtins-lto rm -r tests/run-make/reachable-extern-fn-available-lto +# coverage instrumentation +rm tests/ui/consts/precise-drop-with-coverage.rs +rm tests/ui/issues/issue-85461.rs +rm -r tests/ui/instrument-coverage/ + # optimization tests # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations From 406770001e8a2379e0175cecce11016a4448835a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:26:14 +0200 Subject: [PATCH 024/217] Don't require the bench job to pass for a new release cc rust-lang/rust#125493 --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1f5a6513f63b1..a0c7ccdec0d59 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -282,7 +282,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 if: ${{ github.ref == 'refs/heads/master' }} - needs: [rustfmt, test, bench, dist] + # FIXME add the bench job back to the dependency list once rust-lang/rust#125493 gets merged + needs: [rustfmt, test, dist] permissions: contents: write # for creating the dev tag and release From 632e5df38aab0b6d0c2a5f57cb1e214910bfe2b0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:41:37 +0200 Subject: [PATCH 025/217] Remove unreachable fatal error --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 963e5de91cefe..e04501d5705b8 100644 --- a/src/base.rs +++ b/src/base.rs @@ -907,7 +907,7 @@ fn codegen_stmt<'tcx>( | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) => {} - StatementKind::Coverage { .. } => fx.tcx.dcx().fatal("-Zcoverage is unimplemented"), + StatementKind::Coverage { .. } => unreachable!(), StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic { // We ignore `assume` intrinsics, they are only useful for optimizations NonDivergingIntrinsic::Assume(_) => {} From 5d0ec8d16210412210291987d74d9ea1fa75153c Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 4 Jun 2024 07:01:58 +0100 Subject: [PATCH 026/217] Misc fixes to cranelift/clippy/miri --- src/intrinsics/simd.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index b17f191ce267e..65eeaf156d844 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( .expect_const() .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() + .1 .unwrap_branch(); assert_eq!(x.layout(), y.layout()); From 63cb28ed481e2f3096af20293a24f231d063b301 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 6 Jun 2024 22:33:43 +0200 Subject: [PATCH 027/217] add `llvm.x86.sse2.cvtps2dq` --- example/std_example.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/intrinsics/llvm_x86.rs | 11 ++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/example/std_example.rs b/example/std_example.rs index 7347b2e77899f..6cedd84adfe52 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -251,6 +251,9 @@ unsafe fn test_simd() { test_mm_add_epi8(); test_mm_add_pd(); test_mm_cvtepi8_epi16(); + #[cfg(not(jit))] + test_mm_cvtps_epi32(); + test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); test_mm_extract_epi8(); @@ -476,6 +479,41 @@ unsafe fn test_mm256_permutevar8x32_epi32() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_epi32() { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvtps_epi32(float_vec); + + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN]; + + assert_eq!(ints, expected_ints); +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm_cvttps_epi32() { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvttps_epi32(float_vec); + + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN]; + + assert_eq!(ints, expected_ints); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 03dca0656ef1e..166b260b38af7 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -459,11 +459,20 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( intrinsic_args!(fx, args => (a); intrinsic); let a = a.load_scalar(fx); + let value = fx.bcx.ins().x86_cvtt2dq(types::I32X4, a); + let cvalue = CValue::by_val(value, ret.layout()); + ret.write_cvalue(fx, cvalue); + } + "llvm.x86.sse2.cvtps2dq" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_epi32 + intrinsic_args!(fx, args => (a); intrinsic); + let a = a.load_scalar(fx); + // Using inline asm instead of fcvt_to_sint_sat as unrepresentable values are turned // into 0x80000000 for which Cranelift doesn't have a native instruction. codegen_inline_asm_inner( fx, - &[InlineAsmTemplatePiece::String(format!("cvttps2dq xmm0, xmm0"))], + &[InlineAsmTemplatePiece::String(format!("cvtps2dq xmm0, xmm0"))], &[CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), _late: true, From 6210c26a5adcf9d9d469ef8c9820d937c42dc1e4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 11:26:56 +0200 Subject: [PATCH 028/217] offset_of: allow (unstably) taking the offset of slice tail fields --- src/base.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 963e5de91cefe..6d26ca0b899b2 100644 --- a/src/base.rs +++ b/src/base.rs @@ -832,9 +832,10 @@ fn codegen_stmt<'tcx>( let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(fx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => fx + .tcx + .offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => { let val = fx.tcx.sess.ub_checks(); let val = CValue::by_val( From 0eb782ba13d34c75de2c3d72343a1c946e57d7d3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 16:13:45 +0200 Subject: [PATCH 029/217] ScalarInt: size mismatches are a bug, do not delay the panic --- src/constant.rs | 6 +++--- src/intrinsics/llvm_x86.rs | 10 +++++----- src/intrinsics/simd.rs | 11 +++-------- src/value_and_place.rs | 4 ++-- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index ba98f2e772cbf..a53598018f4a4 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -110,7 +110,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_some() { return CValue::const_val(fx, layout, int); } else { - let raw_val = int.size().truncate(int.assert_bits(int.size())); + let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), @@ -501,12 +501,12 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( Ordering::Equal => scalar_int, Ordering::Less => match ty.kind() { ty::Uint(_) => ScalarInt::try_from_uint( - scalar_int.assert_uint(scalar_int.size()), + scalar_int.to_uint(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), ty::Int(_) => ScalarInt::try_from_int( - scalar_int.assert_int(scalar_int.size()), + scalar_int.to_int(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 27b55ecc72eef..d454f3c1de7e4 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -902,7 +902,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -955,7 +955,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1003,7 +1003,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1040,7 +1040,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1195,7 +1195,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant"); }; - let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func)); + let func = func.to_u8(); codegen_inline_asm_inner( fx, diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 65eeaf156d844..ca910dccb0d06 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -147,8 +147,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = - idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::>(); + let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -282,9 +281,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant"); }; - let idx: u32 = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx: u32 = idx_const.to_u32(); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( @@ -330,9 +327,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.to_u32(); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 512a96450a4b6..1aa28daeafc7e 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -327,7 +327,7 @@ impl<'tcx> CValue<'tcx> { let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { - let const_val = const_val.assert_bits(layout.size); + let const_val = const_val.to_bits(layout.size); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) @@ -339,7 +339,7 @@ impl<'tcx> CValue<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) => { - let raw_val = const_val.size().truncate(const_val.assert_bits(layout.size)); + let raw_val = const_val.size().truncate(const_val.to_bits(layout.size)); fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F32) => { From c06cbc8dbe87e6824e8c7b2e5714756abec7f89f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:18:15 +0000 Subject: [PATCH 030/217] Rustup to rustc 1.81.0-nightly (b5b13568f 2024-06-10) --- patches/stdlib-lock.toml | 6 ++---- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index 1bac8a93240b7..aea0a779b1e11 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "compiler_builtins", "memchr", @@ -407,8 +407,6 @@ dependencies = [ "core", "getopts", "libc", - "panic_abort", - "panic_unwind", "std", ] diff --git a/rust-toolchain b/rust-toolchain index 44a196c18ae17..35d7372a196ee 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-30" +channel = "nightly-2024-06-11" components = ["rust-src", "rustc-dev", "llvm-tools"] From ee188cabc298e9aff8e81f096b9e33830a0f9afb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:47:34 +0000 Subject: [PATCH 031/217] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 6c45a4ccf7962..fce46459cac4d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -102,7 +102,7 @@ rm -r tests/run-make/output-type-permutations rm -r tests/run-make/emit-to-stdout rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name - +rm -r tests/run-make/notify-all-emit-artifacts # giving different but possibly correct results # ============================================= @@ -154,9 +154,9 @@ index 9607ff02f96..b7d97caf9a2 100644 /// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set. pub fn new() -> Self { let mut cmd = setup_common(); -- let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); +- let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd, stdin: None } + Self { cmd } } EOF From 02b20f88710e36c953cc46f08607ad9c82a11794 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 15:01:57 +1000 Subject: [PATCH 032/217] Update a cranelift patch file for formatting changes. PR #125443 will reformat all the use declarations in the repo. This would break a patch kept in `rustc_codegen_cranelift` that gets applied to `library/std/src/sys/pal/windows/rand.rs`. So this commit formats the use declarations in `library/std/src/sys/pal/windows/rand.rs` in advance of #125443 and updates the patch file accordingly. The motivation is that #125443 is a huge change and we want to get fiddly little changes like this out of the way so it can be nothing more than an `x fmt --all`. --- patches/0029-stdlib-rawdylib-processprng.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/0029-stdlib-rawdylib-processprng.patch b/patches/0029-stdlib-rawdylib-processprng.patch index 6af11e54d88af..584dbdb647f60 100644 --- a/patches/0029-stdlib-rawdylib-processprng.patch +++ b/patches/0029-stdlib-rawdylib-processprng.patch @@ -12,7 +12,7 @@ diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/wind index ad8e01bfa9b..9ca8e4c16ce 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs -@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile( +@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile( // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library. cfg_if::cfg_if! { @@ -26,8 +26,8 @@ index e427546222a..f2fe42a4d51 100644 --- a/library/std/src/sys/pal/windows/rand.rs +++ b/library/std/src/sys/pal/windows/rand.rs @@ -2,7 +2,7 @@ - use core::mem; - use core::ptr; + + use crate::sys::c; -#[cfg(not(target_vendor = "win7"))] +#[cfg(any())] From 0b7375f2a04076b64ab071ea0f538f6ca0ebb0c8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 12 Jun 2024 13:49:36 +1000 Subject: [PATCH 033/217] Use `tidy` to sort crate attributes for all compiler crates. We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`. For the ones we don't, in many cases the attributes are a mess. - There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`). - Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order. - Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`. This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions. Exceptions: - `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes. - `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`). --- src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 39bbad16b0c00..0fea3fd425391 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,16 @@ +// tidy-alphabetical-start +#![allow(rustc::diagnostic_outside_of_impl)] +#![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, feature(rustdoc_internals))] #![cfg_attr(doc, doc(rust_logo))] +#![cfg_attr(doc, feature(rustdoc_internals))] +// Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Note: please avoid adding other feature gates where possible -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] #![warn(rust_2018_idioms)] -#![warn(unused_lifetimes)] #![warn(unreachable_pub)] +#![warn(unused_lifetimes)] +// tidy-alphabetical-end extern crate jobserver; #[macro_use] From 4e0af7cc6176b7410fa95c3324381c2baa9ad769 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jun 2024 16:17:38 +0000 Subject: [PATCH 034/217] Require any function with a tait in its signature to actually constrain a hidden type --- example/issue-72793.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/example/issue-72793.rs b/example/issue-72793.rs index 166b006004385..2e08fbca8ef27 100644 --- a/example/issue-72793.rs +++ b/example/issue-72793.rs @@ -2,20 +2,23 @@ #![feature(type_alias_impl_trait)] -trait T { - type Item; -} +mod helper { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } -fn filter_positive<'a>() -> Alias<'a> { - &S + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } +use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); From c86767797182c7a4ff0e7644a42fb2a93e0ef422 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 14 Jun 2024 14:46:32 -0400 Subject: [PATCH 035/217] Use is_lang_item more aggressively --- src/inline_asm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 2de804f5e0423..c6b26dd873bdc 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -4,6 +4,7 @@ use std::fmt::Write; use cranelift_codegen::isa::CallConv; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; use target_lexicon::BinaryFormat; @@ -927,7 +928,7 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { match ty.kind() { // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 - ty::Adt(adt, args) if Some(adt.did()) == fx.tcx.lang_items().maybe_uninit() => { + ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); let ty::Adt(ty, args) = ty.kind() else { From 5ccfa787fd26da2e4fb5f4c6dca89c84342716ef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 14 Jun 2024 20:35:45 -0400 Subject: [PATCH 036/217] Only compute vtable information during codegen --- src/unsize.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/unsize.rs b/src/unsize.rs index 4acbc8a27edb9..967aa53abbda5 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -39,8 +39,7 @@ pub(crate) fn unsized_info<'tcx>( } // trait upcasting coercion - let vptr_entry_idx = - fx.tcx.vtable_trait_upcasting_coercion_new_vptr_slot((source, target)); + let vptr_entry_idx = fx.tcx.supertrait_vtable_slot((source, target)); if let Some(entry_idx) = vptr_entry_idx { let entry_idx = u32::try_from(entry_idx).unwrap(); From 54aa510c32180887632cd262782c8efc6dfc6acb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 16 Jun 2024 21:35:16 -0400 Subject: [PATCH 037/217] Rename InstanceDef -> InstanceKind --- src/abi/mod.rs | 14 +++++++------- src/constant.rs | 2 +- src/intrinsics/mod.rs | 2 +- src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index bd5a88769059f..695dbaf2804b1 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -399,7 +399,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } match instance.def { - InstanceDef::Intrinsic(_) => { + InstanceKind::Intrinsic(_) => { match crate::intrinsics::codegen_intrinsic_call( fx, instance, @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { + InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -494,7 +494,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let (func_ref, first_arg_override) = match instance { // Trait object call - Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { + Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => { if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment( @@ -598,7 +598,7 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) = drop_instance.def { // we don't actually need to drop anything @@ -630,7 +630,7 @@ pub(crate) fn codegen_drop<'tcx>( // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), + def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; let fn_abi = @@ -673,7 +673,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.switch_to_block(continued); let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), + def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; let fn_abi = @@ -684,7 +684,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().call_indirect(sig, drop_fn, &[data]); } _ => { - assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _))); + assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty()); diff --git a/src/constant.rs b/src/constant.rs index a53598018f4a4..87c5da3b7c3ed 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -50,7 +50,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceDef::ThreadLocalShim(def_id), + def: ty::InstanceKind::ThreadLocalShim(def_id), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index cafdc051db5ac..b21c559e6686c 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -1261,7 +1261,7 @@ fn codegen_regular_intrinsic_call<'tcx>( } // Unimplemented intrinsics must have a fallback body. The fallback body is obtained - // by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`. + // by converting the `InstanceKind::Intrinsic` to an `InstanceKind::Item`. _ => { let intrinsic = fx.tcx.intrinsic(instance.def_id()).unwrap(); if intrinsic.must_be_overridden { diff --git a/src/lib.rs b/src/lib.rs index 0fea3fd425391..2edb34e7c20dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,7 +98,7 @@ mod prelude { pub(crate) use rustc_middle::mir::{self, *}; pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, UintTy, + self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy, }; pub(crate) use rustc_span::Span; pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; From a4b36e5adbb50eb827053f036d335d4bd3e6829a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 17 Jun 2024 07:57:10 +0000 Subject: [PATCH 038/217] Rustup to rustc 1.81.0-nightly (d7f6ebace 2024-06-16) --- patches/stdlib-lock.toml | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index aea0a779b1e11..9ea53e8f848d9 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", diff --git a/rust-toolchain b/rust-toolchain index 35d7372a196ee..3cb1f15bb3f21 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-11" +channel = "nightly-2024-06-17" components = ["rust-src", "rustc-dev", "llvm-tools"] From e24117653571901c8e1a2212fb93dd0cc4401aaf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 17 Jun 2024 08:27:01 +0000 Subject: [PATCH 039/217] Fix rustc tests --- scripts/test_rustc_tests.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index fce46459cac4d..62a1c61c9069d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -89,6 +89,7 @@ rm -r tests/run-make/sepcomp-cci-copies # same rm -r tests/run-make/volatile-intrinsics # same rm -r tests/run-make/llvm-ident # same rm -r tests/run-make/no-builtins-attribute # same +rm -r tests/run-make/pgo-gen-no-imp-symbols # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific @@ -103,6 +104,7 @@ rm -r tests/run-make/emit-to-stdout rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name rm -r tests/run-make/notify-all-emit-artifacts +rm -r tests/run-make/reset-codegen-1 # giving different but possibly correct results # ============================================= @@ -125,6 +127,7 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue +rm -r tests/run-make/const_fn_mir # needs-unwind directive accidentally dropped rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd @@ -151,7 +154,7 @@ index 9607ff02f96..b7d97caf9a2 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -34,8 +34,6 @@ pub fn bare() -> Self { - /// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set. + #[track_caller] pub fn new() -> Self { let mut cmd = setup_common(); - let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); From afef64c1bd36a85f71f739e09c901cc6209c82bd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 18 Jun 2024 10:35:56 +0000 Subject: [PATCH 040/217] Use a dedicated type instead of a reference for the diagnostic context This paves the way for tracking more state (e.g. error tainting) in the diagnostic context handle --- src/concurrency_limiter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index a73860cf18b2d..2093b49ff31a7 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -1,6 +1,7 @@ use std::sync::{Arc, Condvar, Mutex}; use jobserver::HelperThread; +use rustc_errors::DiagCtxtHandle; use rustc_session::Session; // FIXME don't panic when a worker thread panics @@ -46,7 +47,7 @@ impl ConcurrencyLimiter { } } - pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: DiagCtxtHandle<'_>) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); From c5bd2e3b9070243409b22fd62f30408f2d1a905d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:14:35 +0000 Subject: [PATCH 041/217] Rustup to rustc 1.81.0-nightly (59e2c01c2 2024-06-17) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 3cb1f15bb3f21..36d98a869db1e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-17" +channel = "nightly-2024-06-18" components = ["rust-src", "rustc-dev", "llvm-tools"] From 729cb08d4c476410f296940e6d6487a4e81b88d2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:23:11 +0000 Subject: [PATCH 042/217] Fix rustc tests --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 62a1c61c9069d..a0d6916dc7ef9 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -78,6 +78,7 @@ rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same rm tests/ui/issues/issue-40883.rs # same rm -r tests/run-make/fmt-write-bloat/ # tests an optimization +rm tests/ui/statics/const_generics.rs # same # backend specific tests # ====================== From 1cb728280dfe7cc241eae34196f80c876aa9addc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 18 Jun 2024 18:51:53 +0200 Subject: [PATCH 043/217] Re-enable `tests/run-make/const_fn_mir` (#1497) --- scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index a0d6916dc7ef9..283889e9471c3 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -128,7 +128,6 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm -r tests/run-make/const_fn_mir # needs-unwind directive accidentally dropped rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From e79dc7656a5664a6daf1b4a1f521bf1c6c6b30a1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 14 Jun 2024 23:01:22 -0700 Subject: [PATCH 044/217] `bug!` more uses of these in runtime stuff --- src/base.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/base.rs b/src/base.rs index 6d26ca0b899b2..b117dc496c2bb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -677,21 +677,22 @@ fn codegen_stmt<'tcx>( CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer), ref operand, to_ty, - ) - | Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer), - ref operand, - to_ty, - ) - | Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer), - ref operand, - to_ty, ) => { let to_layout = fx.layout_of(fx.monomorphize(to_ty)); let operand = codegen_operand(fx, operand); lval.write_cvalue(fx, operand.cast_pointer_to(to_layout)); } + Rvalue::Cast( + CastKind::PointerCoercion( + PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + ), + .., + ) => { + bug!( + "{:?} is for borrowck, and should never appear in codegen", + to_place_and_rval.1 + ); + } Rvalue::Cast( CastKind::IntToInt | CastKind::FloatToFloat From ea29d6ad0bfb2b1544566369746aeaa85b5f9de5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:15:03 +0200 Subject: [PATCH 045/217] We can traverse bindings before `lower_match_tree` now --- .../rustc_mir_build/src/build/matches/mod.rs | 71 ++++++++--------- .../rustc_mir_build/src/build/matches/util.rs | 77 ++++++++++++++++--- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 68244136d1adf..f182e1c57f416 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -21,6 +21,7 @@ use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; use rustc_target::abi::VariantIdx; use tracing::{debug, instrument}; +use util::visit_bindings; // helper functions, broken out by category: mod simplify; @@ -725,55 +726,49 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { set_match_place: bool, ) -> BlockAnd<()> { let mut candidate = Candidate::new(initializer.clone(), irrefutable_pat, false, self); - let fake_borrow_temps = self.lower_match_tree( - block, - irrefutable_pat.span, - &initializer, - irrefutable_pat.span, - false, - &mut [&mut candidate], - ); // For matches and function arguments, the place that is being matched // can be set when creating the variables. But the place for // let PATTERN = ... might not even exist until we do the assignment. // so we set it here instead. if set_match_place { - let mut next = Some(&candidate); - while let Some(candidate_ref) = next.take() { - for binding in &candidate_ref.extra_data.bindings { + // `try_to_place` may fail if it is unable to resolve the given `PlaceBuilder` inside a + // closure. In this case, we don't want to include a scrutinee place. + // `scrutinee_place_builder` will fail for destructured assignments. This is because a + // closure only captures the precise places that it will read and as a result a closure + // may not capture the entire tuple/struct and rather have individual places that will + // be read in the final MIR. + // Example: + // ``` + // let foo = (0, 1); + // let c = || { + // let (v1, v2) = foo; + // }; + // ``` + if let Some(place) = initializer.try_to_place(self) { + visit_bindings(&[&mut candidate], |binding: &Binding<'_>| { let local = self.var_local_id(binding.var_id, OutsideGuard); - // `try_to_place` may fail if it is unable to resolve the given - // `PlaceBuilder` inside a closure. In this case, we don't want to include - // a scrutinee place. `scrutinee_place_builder` will fail for destructured - // assignments. This is because a closure only captures the precise places - // that it will read and as a result a closure may not capture the entire - // tuple/struct and rather have individual places that will be read in the - // final MIR. - // Example: - // ``` - // let foo = (0, 1); - // let c = || { - // let (v1, v2) = foo; - // }; - // ``` - if let Some(place) = initializer.try_to_place(self) { - let LocalInfo::User(BindingForm::Var(VarBindingForm { - opt_match_place: Some((ref mut match_place, _)), - .. - })) = **self.local_decls[local].local_info.as_mut().assert_crate_local() - else { - bug!("Let binding to non-user variable.") - }; + if let LocalInfo::User(BindingForm::Var(VarBindingForm { + opt_match_place: Some((ref mut match_place, _)), + .. + })) = **self.local_decls[local].local_info.as_mut().assert_crate_local() + { *match_place = Some(place); - } - } - // All of the subcandidates should bind the same locals, so we - // only visit the first one. - next = candidate_ref.subcandidates.get(0) + } else { + bug!("Let binding to non-user variable.") + }; + }); } } + let fake_borrow_temps = self.lower_match_tree( + block, + irrefutable_pat.span, + &initializer, + irrefutable_pat.span, + false, + &mut [&mut candidate], + ); self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 50f4ca2d819d3..e0ba736f1989c 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase}; use crate::build::Builder; @@ -267,18 +269,6 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } } -pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { - cx: &'a mut Builder<'b, 'tcx>, - /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from - /// bindings inside deref patterns. - scrutinee_base: PlaceBase, - /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest - /// borrow (i.e. Deep > Shallow). - /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are - /// dereferences are also borrowed with the same of stronger borrow kind. - fake_borrows: FxIndexMap, FakeBorrowKind>, -} - /// Determine the set of places that have to be stable across match guards. /// /// Returns a list of places that need a fake borrow along with a local to store it. @@ -342,6 +332,18 @@ pub(super) fn collect_fake_borrows<'tcx>( .collect() } +pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { + cx: &'a mut Builder<'b, 'tcx>, + /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from + /// bindings inside deref patterns. + scrutinee_base: PlaceBase, + /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest + /// borrow (i.e. Deep > Shallow). + /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are + /// dereferences are also borrowed with the same of stronger borrow kind. + fake_borrows: FxIndexMap, FakeBorrowKind>, +} + impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { // Fake borrow this place and its dereference prefixes. fn fake_borrow(&mut self, place: Place<'tcx>, kind: FakeBorrowKind) { @@ -455,6 +457,57 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } } +/// Visit all the bindings of these candidates. Because or-alternatives bind the same variables, we +/// only explore the first one of each or-pattern. +pub(super) fn visit_bindings<'tcx>( + candidates: &[&mut Candidate<'_, 'tcx>], + f: impl FnMut(&Binding<'tcx>), +) { + let mut visitor = BindingsVisitor { f, phantom: PhantomData }; + for candidate in candidates.iter() { + visitor.visit_candidate(candidate); + } +} + +pub(super) struct BindingsVisitor<'tcx, F> { + f: F, + phantom: PhantomData<&'tcx ()>, +} + +impl<'tcx, F> BindingsVisitor<'tcx, F> +where + F: FnMut(&Binding<'tcx>), +{ + fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) { + for binding in &candidate.extra_data.bindings { + (self.f)(binding) + } + for match_pair in &candidate.match_pairs { + self.visit_match_pair(match_pair); + } + } + + fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) { + for binding in &flat_pat.extra_data.bindings { + (self.f)(binding) + } + for match_pair in &flat_pat.match_pairs { + self.visit_match_pair(match_pair); + } + } + + fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) { + if let TestCase::Or { pats, .. } = &match_pair.test_case { + // All the or-alternatives should bind the same locals, so we only visit the first one. + self.visit_flat_pat(&pats[0]) + } else { + for subpair in &match_pair.subpairs { + self.visit_match_pair(subpair); + } + } + } +} + #[must_use] pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { match ref_mutability { From 012626b32bee88181cca63ef592cad83b19c8fda Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:29:14 +0200 Subject: [PATCH 046/217] Only one caller of `lower_match_tree` was using the fake borrows --- .../rustc_mir_build/src/build/matches/mod.rs | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f182e1c57f416..e9fc9361a719e 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -315,12 +315,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let match_start_span = span.shrink_to_lo().to(scrutinee_span); - let fake_borrow_temps = self.lower_match_tree( + // The set of places that we are creating fake borrows of. If there are no match guards then + // we don't need any fake borrows, so don't track them. + let fake_borrow_temps: Vec<(Place<'tcx>, Local, FakeBorrowKind)> = if match_has_guard { + util::collect_fake_borrows(self, &candidates, scrutinee_span, scrutinee_place.base()) + } else { + Vec::new() + }; + + self.lower_match_tree( block, scrutinee_span, &scrutinee_place, match_start_span, - match_has_guard, &mut candidates, ); @@ -377,30 +384,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// Modifies `candidates` to store the bindings and type ascriptions for /// that candidate. - /// - /// Returns the places that need fake borrows because we bind or test them. fn lower_match_tree<'pat>( &mut self, block: BasicBlock, scrutinee_span: Span, scrutinee_place_builder: &PlaceBuilder<'tcx>, match_start_span: Span, - match_has_guard: bool, candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) -> Vec<(Place<'tcx>, Local, FakeBorrowKind)> { - // The set of places that we are creating fake borrows of. If there are no match guards then - // we don't need any fake borrows, so don't track them. - let fake_borrows: Vec<(Place<'tcx>, Local, FakeBorrowKind)> = if match_has_guard { - util::collect_fake_borrows( - self, - candidates, - scrutinee_span, - scrutinee_place_builder.base(), - ) - } else { - Vec::new() - }; - + ) { // See the doc comment on `match_candidates` for why we have an // otherwise block. Match checking will ensure this is actually // unreachable. @@ -452,8 +443,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { previous_candidate = Some(leaf_candidate); }); } - - fake_borrows } /// Lower the bindings, guards and arm bodies of a `match` expression. @@ -761,18 +750,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let fake_borrow_temps = self.lower_match_tree( + self.lower_match_tree( block, irrefutable_pat.span, &initializer, irrefutable_pat.span, - false, &mut [&mut candidate], ); self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, - fake_borrow_temps.as_slice(), + &[], irrefutable_pat.span, None, false, @@ -1995,12 +1983,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); let mut otherwise_candidate = Candidate::new(expr_place_builder.clone(), &wildcard, false, self); - let fake_borrow_temps = self.lower_match_tree( + self.lower_match_tree( block, pat.span, &expr_place_builder, pat.span, - false, &mut [&mut guard_candidate, &mut otherwise_candidate], ); let expr_place = expr_place_builder.try_to_place(self); @@ -2015,7 +2002,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let post_guard_block = self.bind_pattern( self.source_info(pat.span), guard_candidate, - fake_borrow_temps.as_slice(), + &[], expr_span, None, false, @@ -2490,19 +2477,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let pat = Pat { ty: pattern.ty, span: else_block_span, kind: PatKind::Wild }; let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false, this); let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - let fake_borrow_temps = this.lower_match_tree( + this.lower_match_tree( block, initializer_span, &scrutinee, pattern.span, - false, &mut [&mut candidate, &mut wildcard], ); // This block is for the matching case let matching = this.bind_pattern( this.source_info(pattern.span), candidate, - fake_borrow_temps.as_slice(), + &[], initializer_span, None, true, @@ -2511,7 +2497,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let failure = this.bind_pattern( this.source_info(else_block_span), wildcard, - fake_borrow_temps.as_slice(), + &[], initializer_span, None, true, From cef49f73e76a5f133452b589caa179e4bea8fad2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:39:09 +0200 Subject: [PATCH 047/217] Small dedup --- .../rustc_mir_build/src/build/matches/mod.rs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index e9fc9361a719e..3826f58a6c918 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2059,14 +2059,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return self.cfg.start_new_block(); } - self.ascribe_types( - block, - parent_data - .iter() - .flat_map(|d| &d.ascriptions) - .cloned() - .chain(candidate.extra_data.ascriptions), - ); + let ascriptions = parent_data + .iter() + .flat_map(|d| &d.ascriptions) + .cloned() + .chain(candidate.extra_data.ascriptions); + let bindings = + parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings); + + self.ascribe_types(block, ascriptions); // rust-lang/rust#27282: The `autoref` business deserves some // explanation here. @@ -2153,12 +2154,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { && let Some(guard) = arm.guard { let tcx = self.tcx; - let bindings = - parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings); self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone()); - let guard_frame = - GuardFrame { locals: bindings.map(|b| GuardFrameLocal::new(b.var_id)).collect() }; + let guard_frame = GuardFrame { + locals: bindings.clone().map(|b| GuardFrameLocal::new(b.var_id)).collect(), + }; debug!("entering guard building context: {:?}", guard_frame); self.guard_context.push(guard_frame); @@ -2231,11 +2231,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``` // // and that is clearly not correct. - let by_value_bindings = parent_data - .iter() - .flat_map(|d| &d.bindings) - .chain(&candidate.extra_data.bindings) - .filter(|binding| matches!(binding.binding_mode.0, ByRef::No)); + let by_value_bindings = + bindings.filter(|binding| matches!(binding.binding_mode.0, ByRef::No)); // Read all of the by reference bindings to ensure that the // place they refer to can't be modified by the guard. for binding in by_value_bindings.clone() { @@ -2259,7 +2256,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_matched_candidate_for_arm_body( block, schedule_drops, - parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings), + bindings, storages_alive, ); block From 878ccd22fa6562afd6658f6558632ba8953ae22a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:46:07 +0200 Subject: [PATCH 048/217] There's nothing to bind for a wildcard This commit was obtained by repeatedly inlining and simplifying. --- compiler/rustc_mir_build/src/build/matches/mod.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3826f58a6c918..17b5e1b495578 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2491,14 +2491,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { true, ); // This block is for the failure case - let failure = this.bind_pattern( - this.source_info(else_block_span), - wildcard, - &[], - initializer_span, - None, - true, - ); + let failure = wildcard.pre_binding_block.unwrap(); // If branch coverage is enabled, record this branch. this.visit_coverage_conditional_let(pattern, matching, failure); From c0c6c32a45e9ef05d99459a77e39072524ed1dc4 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:08:05 +0200 Subject: [PATCH 049/217] Move `lower_match_tree` --- .../rustc_mir_build/src/build/matches/mod.rs | 129 +++++++++--------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 17b5e1b495578..8531ea891d2e3 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -380,71 +380,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect() } - /// Create the decision tree for the match expression, starting from `block`. - /// - /// Modifies `candidates` to store the bindings and type ascriptions for - /// that candidate. - fn lower_match_tree<'pat>( - &mut self, - block: BasicBlock, - scrutinee_span: Span, - scrutinee_place_builder: &PlaceBuilder<'tcx>, - match_start_span: Span, - candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) { - // See the doc comment on `match_candidates` for why we have an - // otherwise block. Match checking will ensure this is actually - // unreachable. - let otherwise_block = self.cfg.start_new_block(); - - // This will generate code to test scrutinee_place and - // branch to the appropriate arm block - self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); - - let source_info = self.source_info(scrutinee_span); - - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. - // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - - if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { - self.cfg.push_fake_read( - otherwise_block, - source_info, - cause_matched_place, - scrutinee_place, - ); - } - - self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); - - // Link each leaf candidate to the `pre_binding_block` of the next one. - let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; - - for candidate in candidates { - candidate.visit_leaves(|leaf_candidate| { - if let Some(ref mut prev) = previous_candidate { - assert!(leaf_candidate.false_edge_start_block.is_some()); - prev.next_candidate_start_block = leaf_candidate.false_edge_start_block; - } - previous_candidate = Some(leaf_candidate); - }); - } - } - /// Lower the bindings, guards and arm bodies of a `match` expression. /// /// The decision tree should have already been created @@ -1275,6 +1210,70 @@ pub(crate) struct ArmHasGuard(pub(crate) bool); // Main matching algorithm impl<'a, 'tcx> Builder<'a, 'tcx> { + /// The entrypoint of the matching algorithm. Create the decision tree for the match expression, + /// starting from `block`. + /// + /// Modifies `candidates` to store the bindings and type ascriptions for + /// that candidate. + fn lower_match_tree<'pat>( + &mut self, + block: BasicBlock, + scrutinee_span: Span, + scrutinee_place_builder: &PlaceBuilder<'tcx>, + match_start_span: Span, + candidates: &mut [&mut Candidate<'pat, 'tcx>], + ) { + // See the doc comment on `match_candidates` for why we have an + // otherwise block. Match checking will ensure this is actually + // unreachable. + let otherwise_block = self.cfg.start_new_block(); + + // This will generate code to test scrutinee_place and branch to the appropriate arm block + self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); + + let source_info = self.source_info(scrutinee_span); + + // Matching on a `scrutinee_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // + // NOTE: ReadForMatch also checks that the scrutinee is initialized. + // This is currently needed to not allow matching on an uninitialized, + // uninhabited value. If we get never patterns, those will check that + // the place is initialized, and so this read would only be used to + // check safety. + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); + + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { + self.cfg.push_fake_read( + otherwise_block, + source_info, + cause_matched_place, + scrutinee_place, + ); + } + + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + + // Link each leaf candidate to the `false_edge_start_block` of the next one. + let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; + for candidate in candidates { + candidate.visit_leaves(|leaf_candidate| { + if let Some(ref mut prev) = previous_candidate { + assert!(leaf_candidate.false_edge_start_block.is_some()); + prev.next_candidate_start_block = leaf_candidate.false_edge_start_block; + } + previous_candidate = Some(leaf_candidate); + }); + } + } + /// The main match algorithm. It begins with a set of candidates /// `candidates` and has the job of generating code to determine /// which of these candidates, if any, is the correct one. The From 8556604bc6f282fbc9442d91b2929ea3e354ef88 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Jun 2024 17:42:32 +0100 Subject: [PATCH 050/217] Fix varargs support on `aarch64-apple-darwin` --- src/abi/mod.rs | 135 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 31 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 695dbaf2804b1..0d7eee7afb41e 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -5,8 +5,9 @@ mod pass_mode; mod returning; use std::borrow::Cow; +use std::mem; -use cranelift_codegen::ir::SigRef; +use cranelift_codegen::ir::{ArgumentPurpose, SigRef}; use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; @@ -17,7 +18,7 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_session::Session; use rustc_span::source_map::Spanned; -use rustc_target::abi::call::{Conv, FnAbi}; +use rustc_target::abi::call::{Conv, FnAbi, PassMode}; use rustc_target::spec::abi::Abi; use self::pass_mode::*; @@ -487,6 +488,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let args = args; assert_eq!(fn_abi.args.len(), args.len()); + #[derive(Copy, Clone)] enum CallTarget { Direct(FuncRef), Indirect(SigRef, Value), @@ -532,7 +534,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| { - let call_args = return_ptr + let mut call_args = return_ptr .into_iter() .chain(first_arg_override.into_iter()) .chain( @@ -545,47 +547,118 @@ pub(crate) fn codegen_terminator_call<'tcx>( ) .collect::>(); - let call_inst = match func_ref { + // FIXME: Find a cleaner way to support varargs. + if fn_abi.c_variadic { + adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args); + } + + match func_ref { CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args), CallTarget::Indirect(sig, func_ptr) => { fx.bcx.ins().call_indirect(sig, func_ptr, &call_args) } + } + }); + + if let Some(dest) = target { + let ret_block = fx.get_block(dest); + fx.bcx.ins().jump(ret_block, &[]); + } else { + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); + } + + fn adjust_call_for_c_variadic<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + source_info: mir::SourceInfo, + target: CallTarget, + call_args: &mut Vec, + ) { + if fn_abi.conv != Conv::C { + fx.tcx.dcx().span_fatal( + source_info.span, + format!("Variadic call for non-C abi {:?}", fn_abi.conv), + ); + } + let sig_ref = match target { + CallTarget::Direct(func_ref) => fx.bcx.func.dfg.ext_funcs[func_ref].signature, + CallTarget::Indirect(sig_ref, _) => sig_ref, }; + // `mem::take()` the `params` so that `fx.bcx` can be used below. + let mut abi_params = mem::take(&mut fx.bcx.func.dfg.signatures[sig_ref].params); + + // Recalculate the parameters in the signature to ensure the signature contains the variadic arguments. + let has_return_arg = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); + // Drop everything except the return argument (if there is one). + abi_params.truncate(if has_return_arg { 1 } else { 0 }); + // Add the fixed arguments. + abi_params.extend( + fn_abi.args[..fn_abi.fixed_count as usize] + .iter() + .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), + ); + let fixed_arg_count = abi_params.len(); + // Add the variadic arguments. + abi_params.extend( + fn_abi.args[fn_abi.fixed_count as usize..] + .iter() + .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), + ); - // FIXME find a cleaner way to support varargs - if fn_sig.c_variadic() { - if !matches!(fn_sig.abi(), Abi::C { .. }) { + if fx.tcx.sess.target.is_like_osx && fx.tcx.sess.target.arch == "aarch64" { + // Add any padding arguments needed for Apple AArch64. + // There's no need to pad the argument list unless variadic arguments are actually being + // passed. + if abi_params.len() > fixed_arg_count { + // 128-bit integers take 2 registers, and everything else takes 1. + // FIXME: Add support for non-integer types + // This relies on the checks below to ensure all arguments are integer types and + // that the ABI is "C". + // The return argument isn't counted as it goes in its own dedicated register. + let integer_registers_used: usize = abi_params + [if has_return_arg { 1 } else { 0 }..fixed_arg_count] + .iter() + .map(|arg| if arg.value_type.bits() == 128 { 2 } else { 1 }) + .sum(); + // The ABI uses 8 registers before it starts pushing arguments to the stack. Pad out + // the registers if needed to ensure the variadic arguments are passed on the stack. + if integer_registers_used < 8 { + abi_params.splice( + fixed_arg_count..fixed_arg_count, + (integer_registers_used..8).map(|_| AbiParam::new(types::I64)), + ); + call_args.splice( + fixed_arg_count..fixed_arg_count, + (integer_registers_used..8).map(|_| fx.bcx.ins().iconst(types::I64, 0)), + ); + } + } + + // `StructArgument` is not currently used by the `aarch64` ABI, and is therefore not + // handled when calculating how many padding arguments to use. Assert that this remains + // the case. + assert!(abi_params.iter().all(|param| matches!( + param.purpose, + // The only purposes used are `Normal` and `StructReturn`. + ArgumentPurpose::Normal | ArgumentPurpose::StructReturn + ))); + } + + // Check all parameters are integers. + for param in abi_params.iter() { + if !param.value_type.is_int() { + // FIXME: Set %al to upperbound on float args once floats are supported. fx.tcx.dcx().span_fatal( source_info.span, - format!("Variadic call for non-C abi {:?}", fn_sig.abi()), + format!("Non int ty {:?} for variadic call", param.value_type), ); } - let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); - let abi_params = call_args - .into_iter() - .map(|arg| { - let ty = fx.bcx.func.dfg.value_type(arg); - if !ty.is_int() { - // FIXME set %al to upperbound on float args once floats are supported - fx.tcx.dcx().span_fatal( - source_info.span, - format!("Non int ty {:?} for variadic call", ty), - ); - } - AbiParam::new(ty) - }) - .collect::>(); - fx.bcx.func.dfg.signatures[sig_ref].params = abi_params; } - call_inst - }); + assert_eq!(abi_params.len(), call_args.len()); - if let Some(dest) = target { - let ret_block = fx.get_block(dest); - fx.bcx.ins().jump(ret_block, &[]); - } else { - fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); + // Put the `AbiParam`s back in the signature. + fx.bcx.func.dfg.signatures[sig_ref].params = abi_params; } } From b0fcf2e27aac8d5eae00b7236bbdba7f73ce03ab Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Jun 2024 17:43:18 +0100 Subject: [PATCH 051/217] Add `aarch64-apple-darwin` to CI --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0c7ccdec0d59..1fc7087170065 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,6 +66,9 @@ jobs: env: TARGET_TRIPLE: aarch64-unknown-linux-gnu apt_deps: gcc-aarch64-linux-gnu qemu-user + - os: macos-latest + env: + TARGET_TRIPLE: aarch64-apple-darwin - os: ubuntu-latest env: TARGET_TRIPLE: s390x-unknown-linux-gnu @@ -214,6 +217,9 @@ jobs: - os: macos-latest env: TARGET_TRIPLE: x86_64-apple-darwin + - os: macos-latest + env: + TARGET_TRIPLE: aarch64-apple-darwin # cross-compile from Linux to Windows using mingw - os: ubuntu-latest env: From bb00657d168e347ac04b5f90e8e77edc14a03050 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:05:45 +0300 Subject: [PATCH 052/217] Stabilize `PanicInfo::message()` and `PanicMessage` --- library/core/src/panic.rs | 2 +- library/core/src/panic/panic_info.rs | 10 +++++----- library/std/src/lib.rs | 1 - tests/run-make/wasm-exceptions-nostd/src/lib.rs | 1 - 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 56ede02673c03..37c338dd9b778 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -12,7 +12,7 @@ use crate::any::Any; pub use self::location::Location; #[stable(feature = "panic_hooks", since = "1.10.0")] pub use self::panic_info::PanicInfo; -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub use self::panic_info::PanicMessage; #[stable(feature = "catch_unwind", since = "1.9.0")] pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe}; diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 91953fd656b6a..6bbb9c3017110 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -24,7 +24,7 @@ pub struct PanicInfo<'a> { /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, } @@ -57,7 +57,7 @@ impl<'a> PanicInfo<'a> { /// } /// ``` #[must_use] - #[unstable(feature = "panic_info_message", issue = "66745")] + #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub fn message(&self) -> PanicMessage<'_> { PanicMessage { message: self.message } } @@ -164,7 +164,7 @@ impl<'a> PanicMessage<'a> { /// For most cases with placeholders, this function will return `None`. /// /// See [`fmt::Arguments::as_str`] for details. - #[unstable(feature = "panic_info_message", issue = "66745")] + #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "103900")] #[must_use] #[inline] @@ -173,7 +173,7 @@ impl<'a> PanicMessage<'a> { } } -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] impl Display for PanicMessage<'_> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,7 +181,7 @@ impl Display for PanicMessage<'_> { } } -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for PanicMessage<'_> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1c226f9f08f10..0f4064d10b56d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -341,7 +341,6 @@ #![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_write_slice)] #![feature(panic_can_unwind)] -#![feature(panic_info_message)] #![feature(panic_internals)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs index 3ea8797d3a6dd..ef2f117e01af9 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs @@ -5,7 +5,6 @@ #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(panic_info_message)] extern crate alloc; From 2a378251fba001fa3b9f5b8cb1d57159d73db8b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:00:13 +0200 Subject: [PATCH 053/217] Update to Cranelift 0.109 --- Cargo.lock | 56 +++++++++++++++++++++++------------------------ Cargo.toml | 14 ++++++------ src/common.rs | 2 ++ src/driver/jit.rs | 2 +- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b95ab0a7f177a..e4959eed37a00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" +checksum = "0b6b33d7e757a887989eb18b35712b2a67d96171ec3149d1bfb657b29b7b367c" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" +checksum = "b9acf15cb22be42d07c3b57d7856329cb228b7315d385346149df2566ad5e4aa" dependencies = [ "bumpalo", "cranelift-bforest", @@ -77,39 +77,39 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" +checksum = "e934d301392b73b3f8b0540391fb82465a0f179a3cee7c726482ac4727efcc97" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" +checksum = "8afb2a2566b3d54b854dfb288b3b187f6d3d17d6f762c92898207eba302931da" [[package]] name = "cranelift-control" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" +checksum = "0100f33b704cdacd01ad66ff41f8c5030d57cbff078e2a4e49ab1822591299fa" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" +checksum = "a8cfdc315e5d18997093e040a8d234bea1ac1e118a716d3e30f40d449e78207b" [[package]] name = "cranelift-frontend" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" +checksum = "0f74b84f16af2e982b0c0c72233503d9d55cbfe3865dbe807ca28dc6642a28b5" dependencies = [ "cranelift-codegen", "log", @@ -119,15 +119,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" +checksum = "adf306d3dde705fb94bd48082f01d38c4ededc74293a4c007805f610bf08bc6e" [[package]] name = "cranelift-jit" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d396c6f5cde59c1e408d813426d2332031692152432e12f4de63a936c6c10c7" +checksum = "f5c5cfb8bbd3339cd25cca30e7516ff8fe5cb1feeddde6980cc4d5ef34df97bb" dependencies = [ "anyhow", "cranelift-codegen", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7067c2b072829bb35f19f9e99eb42b6982faf4339adb2946797728ff0bd6a089" +checksum = "7c9b0d4269b36fd858e6d8f20cd4938941186fb831488c361888cb2d6b33a9a6" dependencies = [ "anyhow", "cranelift-codegen", @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" +checksum = "1ea0ebdef7aff4a79bcbc8b6495f31315f16b3bf311152f472eaa8d679352581" dependencies = [ "cranelift-codegen", "libc", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a09bc240fb04674e01382ca505b34e71ea0ee8499a7960cd85f70359873852" +checksum = "19e33439ec20db058bc7cc3410f9748ab1ad90a35cef713d625c736f43e3820d" dependencies = [ "anyhow", "cranelift-codegen", @@ -279,9 +279,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "object" -version = "0.33.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "crc32fast", "hashbrown 0.14.3", @@ -411,9 +411,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "21.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" +checksum = "5afe2f0499542f9a4bcfa1b55bfdda803b6ade4e7c93c6b99e0f39dba44b0a91" dependencies = [ "anyhow", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 6aaff55023b07..2969a6cf6ecaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,15 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.108.0", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.108.0" } -cranelift-module = { version = "0.108.0" } -cranelift-native = { version = "0.108.0" } -cranelift-jit = { version = "0.108.0", optional = true } -cranelift-object = { version = "0.108.0" } +cranelift-codegen = { version = "0.109.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.109.0" } +cranelift-module = { version = "0.109.0" } +cranelift-native = { version = "0.109.0" } +cranelift-jit = { version = "0.109.0", optional = true } +cranelift-object = { version = "0.109.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} -object = { version = "0.33", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.8.0", optional = true } diff --git a/src/common.rs b/src/common.rs index 21d0cd2d30f2a..817498b195690 100644 --- a/src/common.rs +++ b/src/common.rs @@ -395,6 +395,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { // FIXME Don't force the size to a multiple of bytes once Cranelift gets // a way to specify stack slot alignment. size: (size + abi_align - 1) / abi_align * abi_align, + align_shift: 4, }); Pointer::stack_slot(stack_slot) } else { @@ -405,6 +406,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { // FIXME Don't force the size to a multiple of bytes once Cranelift gets // a way to specify stack slot alignment. size: (size + align) / abi_align * abi_align, + align_shift: 4, }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().urem_imm(base_ptr, i64::from(align)); diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 4b149131b61aa..ae0e45ae5312b 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -310,7 +310,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> fn dep_symbol_lookup_fn( sess: &Session, crate_info: CrateInfo, -) -> Box Option<*const u8>> { +) -> Box Option<*const u8> + Send> { use rustc_middle::middle::dependency_format::Linkage; let mut dylib_paths = Vec::new(); From 1031d4da55e9e4f96ace279281530bc8914472c4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Jun 2024 13:52:17 -0400 Subject: [PATCH 054/217] Add nightly style guide section for precise_capturing --- src/doc/style-guide/src/nightly.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md index 66e7fa3c9f89c..d870edf18882e 100644 --- a/src/doc/style-guide/src/nightly.md +++ b/src/doc/style-guide/src/nightly.md @@ -5,3 +5,15 @@ This chapter documents style and formatting for nightly-only syntax. The rest of Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization. There is no guarantee of the stability of this chapter in contrast to the rest of the style guide. Refer to the style team policy for nightly formatting procedure regarding breaking changes to this chapter. + +### `feature(precise_capturing)` + +A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`. + +``` +fn foo() -> impl Sized + use<'a> {} + +// is formatted analogously to: + +fn foo() -> impl Sized + Use<'a> {} +``` From aa5d7a0d8ae4654c8739db1d7ac75dc0e6e24434 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:31:16 +0000 Subject: [PATCH 055/217] Update platform support table for the new arm64 macOS support Closes rust-lang/rustc_codegen_cranelift#1248 --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 00ea15cb38cc2..eb21e027dd0e0 100644 --- a/Readme.md +++ b/Readme.md @@ -70,7 +70,7 @@ For more docs on how to build and test see [build_system/usage.txt](build_system |FreeBSD|✅[^no-rustup]|❓|❓|❓| |AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]| |Other unixes|❓|❓|❓|❓| -|macOS|✅|❌[^apple-silicon]|N/A|N/A| +|macOS|✅|✅[^no-rustup]|N/A|N/A| |Windows|✅[^no-rustup]|❌|N/A|N/A| ✅: Fully supported and tested @@ -80,7 +80,6 @@ For more docs on how to build and test see [build_system/usage.txt](build_system Not all targets are available as rustup component for nightly. See notes in the platform support matrix. [^xcoff]: XCOFF object file format is not supported. -[^apple-silicon]: Tracked in [#1248](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1248). [^no-rustup]: Not available as rustup component for nightly. You can build it yourself. ## Usage From e9ea57814768cdae0b36065a731009afa7e36f31 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:01:57 +0000 Subject: [PATCH 056/217] Move vcall_visibility_metadata optimization hint out of a debuginfo generation method --- compiler/rustc_codegen_llvm/src/context.rs | 10 ++++++++++ .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 14 +++++++------- compiler/rustc_codegen_ssa/src/meth.rs | 1 + compiler/rustc_codegen_ssa/src/traits/misc.rs | 7 +++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 7d92888feeed4..57682d1cc8c4c 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -3,6 +3,7 @@ use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; +use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm; use crate::llvm_util; use crate::type_::Type; @@ -522,6 +523,15 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self.vtables } + fn apply_vcall_visibility_metadata( + &self, + ty: Ty<'tcx>, + poly_trait_ref: Option>, + vtable: &'ll Value, + ) { + apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable); + } + fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value { get_fn(self, instance) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8de4e0effad28..742bfd76590a4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1449,12 +1449,18 @@ fn build_vtable_type_di_node<'ll, 'tcx>( .di_node } -fn vcall_visibility_metadata<'ll, 'tcx>( +pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, trait_ref: Option>, vtable: &'ll Value, ) { + // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in + // LLVM at the moment. + if !cx.sess().opts.unstable_opts.virtual_function_elimination || cx.sess().lto() != Lto::Fat { + return; + } + enum VCallVisibility { Public = 0, LinkageUnit = 1, @@ -1531,12 +1537,6 @@ pub fn create_vtable_di_node<'ll, 'tcx>( poly_trait_ref: Option>, vtable: &'ll Value, ) { - // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in - // LLVM at the moment. - if cx.sess().opts.unstable_opts.virtual_function_elimination && cx.sess().lto() == Lto::Fat { - vcall_visibility_metadata(cx, ty, poly_trait_ref, vtable); - } - if cx.dbg_cx.is_none() { return; } diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index ddc6797388e77..febc8ee2be248 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -133,6 +133,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let align = cx.data_layout().pointer_align.abi; let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); + cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable); cx.create_vtable_debuginfo(ty, trait_ref, vtable); cx.vtables().borrow_mut().insert((ty, trait_ref), vtable); vtable diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 04e2b8796c46a..af3a998960491 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -9,6 +9,13 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn vtables( &self, ) -> &RefCell, Option>), Self::Value>>; + fn apply_vcall_visibility_metadata( + &self, + _ty: Ty<'tcx>, + _poly_trait_ref: Option>, + _vtable: Self::Value, + ) { + } fn check_overflow(&self) -> bool; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; From 7f445329ec3330f4334431b68b26325922391e5c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:19:58 +0000 Subject: [PATCH 057/217] Remove PrintBackendInfo trait It is only implemented for a single type. Directly passing this type is simpler and avoids overhead from indirect calls. --- compiler/rustc_codegen_llvm/src/lib.rs | 24 ++++++++------- compiler/rustc_codegen_llvm/src/llvm_util.rs | 30 ++++++++++--------- .../rustc_codegen_ssa/src/traits/backend.rs | 20 +------------ compiler/rustc_codegen_ssa/src/traits/mod.rs | 4 +-- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4b7a264300711..ed0989a0ba413 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -274,10 +274,11 @@ impl CodegenBackend for LlvmCodegenBackend { |tcx, ()| llvm_util::global_llvm_features(tcx.sess, true) } - fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) { + fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) { + use std::fmt::Write; match req.kind { PrintKind::RelocationModels => { - writeln!(out, "Available relocation models:"); + writeln!(out, "Available relocation models:").unwrap(); for name in &[ "static", "pic", @@ -288,25 +289,25 @@ impl CodegenBackend for LlvmCodegenBackend { "ropi-rwpi", "default", ] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::CodeModels => { - writeln!(out, "Available code models:"); + writeln!(out, "Available code models:").unwrap(); for name in &["tiny", "small", "kernel", "medium", "large"] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::TlsModels => { - writeln!(out, "Available TLS models:"); + writeln!(out, "Available TLS models:").unwrap(); for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::StackProtectorStrategies => { writeln!( @@ -332,7 +333,8 @@ impl CodegenBackend for LlvmCodegenBackend { none Do not generate stack canaries. "# - ); + ) + .unwrap(); } _other => llvm_util::print(req, out, sess), } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 7e0f264a4aedf..0e89e66be49a0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -6,7 +6,6 @@ use crate::errors::{ use crate::llvm; use libc::c_int; use rustc_codegen_ssa::base::wants_wasm_eh; -use rustc_codegen_ssa::traits::PrintBackendInfo; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_fs_util::path_to_c_string; @@ -18,6 +17,7 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy}; use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use std::ffi::{c_char, c_void, CStr, CString}; +use std::fmt::Write; use std::path::Path; use std::ptr; use std::slice; @@ -372,7 +372,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> { ret } -fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) { +fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMachine) { let mut llvm_target_features = llvm_target_features(tm); let mut known_llvm_target_features = FxHashSet::<&'static str>::default(); let mut rustc_target_features = sess @@ -412,24 +412,26 @@ fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &ll .max() .unwrap_or(0); - writeln!(out, "Features supported by rustc for this target:"); + writeln!(out, "Features supported by rustc for this target:").unwrap(); for (feature, desc) in &rustc_target_features { - writeln!(out, " {feature:max_feature_len$} - {desc}."); + writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap(); } - writeln!(out, "\nCode-generation features supported by LLVM for this target:"); + writeln!(out, "\nCode-generation features supported by LLVM for this target:").unwrap(); for (feature, desc) in &llvm_target_features { - writeln!(out, " {feature:max_feature_len$} - {desc}."); + writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap(); } if llvm_target_features.is_empty() { - writeln!(out, " Target features listing is not supported by this LLVM version."); + writeln!(out, " Target features listing is not supported by this LLVM version.") + .unwrap(); } - writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it."); - writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n"); - writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],"); - writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n"); + writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.").unwrap(); + writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n") + .unwrap(); + writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],").unwrap(); + writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n").unwrap(); } -pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) { +pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) { require_inited(); let tm = create_informational_target_machine(sess); match req.kind { @@ -440,9 +442,9 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref())) .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e)); unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) { - let out = &mut *(out as *mut &mut dyn PrintBackendInfo); + let out = &mut *(out as *mut &mut String); let bytes = slice::from_raw_parts(string as *const u8, len); - write!(out, "{}", String::from_utf8_lossy(bytes)); + write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap(); } unsafe { llvm::LLVMRustPrintTargetCPUs( diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index e8b9490d4010a..3770bd11cf9b2 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -22,8 +22,6 @@ use rustc_session::{ use rustc_span::symbol::Symbol; use rustc_target::abi::call::FnAbi; -use std::fmt; - pub trait BackendTypes { type Value: CodegenObject; type Function: CodegenObject; @@ -62,7 +60,7 @@ pub trait CodegenBackend { fn locale_resource(&self) -> &'static str; fn init(&self, _sess: &Session) {} - fn print(&self, _req: &PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {} + fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {} fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { vec![] } @@ -150,19 +148,3 @@ pub trait ExtraBackendMethods: std::thread::Builder::new().name(name).spawn(f) } } - -pub trait PrintBackendInfo { - fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>); -} - -impl PrintBackendInfo for String { - fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) { - fmt::Write::write_fmt(self, args).unwrap(); - } -} - -impl dyn PrintBackendInfo + '_ { - pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) { - self.infallible_write_fmt(args); - } -} diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index 728c2bc8c49bc..8cb58bd4c704d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -30,9 +30,7 @@ mod write; pub use self::abi::AbiBuilderMethods; pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef}; -pub use self::backend::{ - Backend, BackendTypes, CodegenBackend, ExtraBackendMethods, PrintBackendInfo, -}; +pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; pub use self::consts::ConstMethods; pub use self::coverageinfo::CoverageInfoBuilderMethods; From 98e8601ac3426c395c017f110e2ff8b05733a163 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:32:05 +0000 Subject: [PATCH 058/217] Remove const_bitcast from ConstMethods --- compiler/rustc_codegen_gcc/src/common.rs | 26 +++++++++---------- compiler/rustc_codegen_llvm/src/common.rs | 4 --- .../rustc_codegen_ssa/src/traits/consts.rs | 1 - 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 548c23cc7948a..230fe4f5871e8 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -28,6 +28,19 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global // TODO(antoyo): set linkage. } + + pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { + if value.get_type() == self.bool_type.make_pointer() { + if let Some(pointee) = typ.get_pointee() { + if pointee.dyncast_vector().is_some() { + panic!() + } + } + } + // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some + // SIMD builtins require a constant value. + self.bitcast_if_needed(value, typ) + } } pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> { @@ -239,19 +252,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { const_alloc_to_gcc(self, alloc) } - fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { - if value.get_type() == self.bool_type.make_pointer() { - if let Some(pointee) = typ.get_pointee() { - if pointee.dyncast_vector().is_some() { - panic!() - } - } - } - // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some - // SIMD builtins require a constant value. - self.bitcast_if_needed(value, typ) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { self.context .new_array_access(None, base_addr, self.const_usize(offset.bytes())) diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 4ffc92eb63356..d42c6ed827aec 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -329,10 +329,6 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { const_alloc_to_llvm(self, alloc, /*static*/ false) } - fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { - self.const_bitcast(val, ty) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { unsafe { llvm::LLVMConstInBoundsGEP2( diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 8cb17a5b37a89..3da732602c520 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -37,6 +37,5 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value; - fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value; } From e32eb4c9e933d98455205348706620c51f25b69d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:53:52 +0000 Subject: [PATCH 059/217] Dedup some intrinsic handling code for caller_location --- compiler/rustc_codegen_ssa/src/mir/block.rs | 37 +++++++-------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57138d3b9dbdb..57a5393da251e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -902,31 +902,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; - if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) { - return if let Some(target) = target { - let location = - self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); - - let mut llargs = Vec::with_capacity(arg_count); - let ret_dest = self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - intrinsic, - Some(target), - ); - assert_eq!(llargs, []); - if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { - location.val.store(bx, tmp); - } - self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); - helper.funclet_br(self, bx, target, mergeable_succ) - } else { - MergingSucc::False - }; - } - let instance = match intrinsic { None => instance, Some(intrinsic) => { @@ -971,6 +946,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) .collect(); + if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) { + let location = self + .get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); + + assert_eq!(llargs, []); + if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { + location.val.store(bx, tmp); + } + self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); + return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); + } + let instance = *instance.as_ref().unwrap(); match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) { Ok(()) => { From 22b32432ca3e8296a7649ef8c3711c0310f8f426 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:58:06 +0000 Subject: [PATCH 060/217] Move all intrinsic handling code in codegen_call_terminators together --- compiler/rustc_codegen_ssa/src/mir/block.rs | 44 +++++++++------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57a5393da251e..1eec1841a3753 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -751,7 +751,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, helper: &TerminatorCodegenHelper<'tcx>, bx: &mut Bx, - intrinsic: Option, + intrinsic: ty::IntrinsicDef, instance: Option>, source_info: mir::SourceInfo, target: Option, @@ -761,8 +761,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Emit a panic or a no-op for `assert_*` intrinsics. // These are intrinsics that compile to panics so that we can get a message // which mentions the offending type, even from a const context. - let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name)); - if let Some(requirement) = panic_intrinsic { + if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) { let ty = instance.unwrap().args.type_at(0); let do_panic = !bx @@ -869,12 +868,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let sig = callee.layout.ty.fn_sig(bx.tcx()); let abi = sig.abi(); - // Handle intrinsics old codegen wants Expr's for, ourselves. - let intrinsic = match def { - Some(ty::InstanceKind::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()), - _ => None, - }; - let extra_args = &args[sig.inputs().skip_binder().len()..]; let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| { let op_ty = op_arg.node.ty(self.mir, bx.tcx()); @@ -886,25 +879,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => bx.fn_abi_of_fn_ptr(sig, extra_args), }; - if let Some(merging_succ) = self.codegen_panic_intrinsic( - &helper, - bx, - intrinsic, - instance, - source_info, - target, - unwind, - mergeable_succ, - ) { - return merging_succ; - } - // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; - let instance = match intrinsic { - None => instance, - Some(intrinsic) => { + let instance = match def { + Some(ty::InstanceKind::Intrinsic(def_id)) => { + let intrinsic = bx.tcx().intrinsic(def_id).unwrap(); + if let Some(merging_succ) = self.codegen_panic_intrinsic( + &helper, + bx, + intrinsic, + instance, + source_info, + target, + unwind, + mergeable_succ, + ) { + return merging_succ; + } + let mut llargs = Vec::with_capacity(1); let ret_dest = self.make_return_dest( bx, @@ -984,6 +977,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } + _ => instance, }; let mut llargs = Vec::with_capacity(arg_count); From aacdce38f7f2298c5779446ffe17cae0068ccd37 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:25:13 +0000 Subject: [PATCH 061/217] Remove check_overflow method from MiscMethods It can be retrieved from the Session too. --- compiler/rustc_codegen_gcc/src/context.rs | 8 -------- compiler/rustc_codegen_llvm/src/context.rs | 8 -------- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/misc.rs | 1 - 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 4a1f5188a8013..6231b09552cea 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -27,7 +27,6 @@ use crate::callee::get_fn; use crate::common::SignType; pub struct CodegenCx<'gcc, 'tcx> { - pub check_overflow: bool, pub codegen_unit: &'tcx CodegenUnit<'tcx>, pub context: &'gcc Context<'gcc>, @@ -134,8 +133,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { tcx: TyCtxt<'tcx>, supports_128bit_integers: bool, ) -> Self { - let check_overflow = tcx.sess.overflow_checks(); - let create_type = |ctype, rust_type| { let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap(); let align = layout.align.abi.bytes(); @@ -271,7 +268,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } let mut cx = Self { - check_overflow, codegen_unit, context, current_func: RefCell::new(None), @@ -511,10 +507,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self.tcx.sess } - fn check_overflow(&self) -> bool { - self.check_overflow - } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { self.codegen_unit } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 57682d1cc8c4c..1a8e8efdae507 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -44,7 +44,6 @@ use std::str; /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. pub struct CodegenCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, - pub check_overflow: bool, pub use_dll_storage_attrs: bool, pub tls_model: llvm::ThreadLocalMode, @@ -442,8 +441,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // start) and then strongly recommending static linkage on Windows! let use_dll_storage_attrs = tcx.sess.target.is_like_windows; - let check_overflow = tcx.sess.overflow_checks(); - let tls_model = to_llvm_tls_model(tcx.sess.tls_model()); let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod()); @@ -467,7 +464,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { CodegenCx { tcx, - check_overflow, use_dll_storage_attrs, tls_model, llmod, @@ -606,10 +602,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.tcx.sess } - fn check_overflow(&self) -> bool { - self.check_overflow - } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { self.codegen_unit } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1eec1841a3753..b1c22faf1ae9d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -658,7 +658,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // with #[rustc_inherit_overflow_checks] and inlined from // another crate (mostly core::num generic/#[inline] fns), // while the current crate doesn't use overflow checks. - if !bx.cx().check_overflow() && msg.is_optional_overflow_check() { + if !bx.sess().overflow_checks() && msg.is_optional_overflow_check() { const_cond = Some(expected); } diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index af3a998960491..0ace28ed3ba5e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -16,7 +16,6 @@ pub trait MiscMethods<'tcx>: BackendTypes { _vtable: Self::Value, ) { } - fn check_overflow(&self) -> bool; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; From 887f57ff0bd0664bfb901321048302f0879e1be2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:36:14 +0000 Subject: [PATCH 062/217] Remove type_i1 and type_struct from cg_ssa They are not representable by Cranelift --- compiler/rustc_codegen_gcc/src/type_.rs | 50 +++++++++---------- compiler/rustc_codegen_llvm/src/type_.rs | 28 +++++------ .../rustc_codegen_ssa/src/traits/type_.rs | 2 - 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index 68471b028beb8..4caff2e63106a 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -89,13 +89,34 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { ty::FloatTy::F128 => self.type_f128(), } } -} -impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn type_i1(&self) -> Type<'gcc> { + pub fn type_i1(&self) -> Type<'gcc> { self.bool_type } + pub fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { + let types = fields.to_vec(); + if let Some(typ) = self.struct_types.borrow().get(fields) { + return *typ; + } + let fields: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, field)| { + self.context.new_field(None, *field, format!("field{}_TODO", index)) + }) + .collect(); + let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); + if packed { + #[cfg(feature = "master")] + typ.set_packed(); + } + self.struct_types.borrow_mut().insert(types, typ); + typ + } +} + +impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_i8(&self) -> Type<'gcc> { self.i8_type } @@ -131,7 +152,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_f64(&self) -> Type<'gcc> { self.double_type } - + fn type_f128(&self) -> Type<'gcc> { unimplemented!("f16_f128") } @@ -140,27 +161,6 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.context.new_function_pointer_type(None, return_type, params, false) } - fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { - let types = fields.to_vec(); - if let Some(typ) = self.struct_types.borrow().get(fields) { - return *typ; - } - let fields: Vec<_> = fields - .iter() - .enumerate() - .map(|(index, field)| { - self.context.new_field(None, *field, format!("field{}_TODO", index)) - }) - .collect(); - let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); - if packed { - #[cfg(feature = "master")] - typ.set_packed(); - } - self.struct_types.borrow_mut().insert(types, typ); - typ - } - fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index a00f09dc40da6..f1141c57cedd7 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -127,13 +127,24 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } -} -impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn type_i1(&self) -> &'ll Type { + pub(crate) fn type_i1(&self) -> &'ll Type { unsafe { llvm::LLVMInt1TypeInContext(self.llcx) } } + pub(crate) fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { + unsafe { + llvm::LLVMStructTypeInContext( + self.llcx, + els.as_ptr(), + els.len() as c_uint, + packed as Bool, + ) + } + } +} + +impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn type_i8(&self) -> &'ll Type { unsafe { llvm::LLVMInt8TypeInContext(self.llcx) } } @@ -178,17 +189,6 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) } } - fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { - unsafe { - llvm::LLVMStructTypeInContext( - self.llcx, - els.as_ptr(), - els.len() as c_uint, - packed as Bool, - ) - } - } - fn type_kind(&self, ty: &'ll Type) -> TypeKind { unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() } } diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 403f6a7327715..e492bba969e1a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -12,7 +12,6 @@ use rustc_target::abi::{AddressSpace, Float, Integer}; // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { - fn type_i1(&self) -> Self::Type; fn type_i8(&self) -> Self::Type; fn type_i16(&self) -> Self::Type; fn type_i32(&self) -> Self::Type; @@ -27,7 +26,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; - fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; fn type_kind(&self, ty: Self::Type) -> TypeKind; fn type_ptr(&self) -> Self::Type; fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type; From 84f45bb0930a0696f8d0bcb8b480bc194da80db1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:29:32 +0000 Subject: [PATCH 063/217] Fix doc comment --- compiler/rustc_codegen_ssa/src/traits/type_.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index e492bba969e1a..b1bad6cfa6f58 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -113,8 +113,8 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { /// The backend type used for a rust type when it's in an SSA register. /// /// For nearly all types this is the same as the [`Self::backend_type`], however - /// `bool` (and other `0`-or-`1` values) are kept as [`BaseTypeMethods::type_i1`] - /// in registers but as [`BaseTypeMethods::type_i8`] in memory. + /// `bool` (and other `0`-or-`1` values) are kept as `i1` in registers but as + /// [`BaseTypeMethods::type_i8`] in memory. /// /// Converting values between the two different backend types is done using /// [`from_immediate`](super::BuilderMethods::from_immediate) and From 790c238ef431639997730eb9e5f21fe043d4adf2 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:30:51 -0400 Subject: [PATCH 064/217] rewrite pdb-alt-path to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pdb-alt-path/Makefile | 20 ---------- tests/run-make/pdb-alt-path/rmake.rs | 37 +++++++++++++++++++ 3 files changed, 37 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/pdb-alt-path/Makefile create mode 100644 tests/run-make/pdb-alt-path/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f32413540498d..3c6bb33813162 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -131,7 +131,6 @@ run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile run-make/pass-linker-flags/Makefile run-make/pass-non-c-like-enum-to-c/Makefile -run-make/pdb-alt-path/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile diff --git a/tests/run-make/pdb-alt-path/Makefile b/tests/run-make/pdb-alt-path/Makefile deleted file mode 100644 index 7a0ae3bf2ef0d..0000000000000 --- a/tests/run-make/pdb-alt-path/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ../tools.mk - -# only-windows-msvc - -all: - # Test that we don't have the full path to the PDB file in the binary - $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Cforce-frame-pointers - $(CGREP) "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe - $(CGREP) -v "\\my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe - - # Test that backtraces still can find debuginfo by checking that they contain symbol names and - # source locations. - $(TMPDIR)/my_crate_name.exe &> $(TMPDIR)/backtrace.txt - $(CGREP) "my_crate_name::fn_in_backtrace" < $(TMPDIR)/backtrace.txt - $(CGREP) "main.rs:15" < $(TMPDIR)/backtrace.txt - - # Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected - $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Clink-arg=/PDBALTPATH:abcdefg.pdb -Cforce-frame-pointers - $(CGREP) "abcdefg.pdb" < $(TMPDIR)/my_crate_name.exe - $(CGREP) -v "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs new file mode 100644 index 0000000000000..197768d82c114 --- /dev/null +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -0,0 +1,37 @@ +// The information inside a .exe file contains a string of the PDB file name. +// This could be a security concern if the full path was exposed, as it could +// reveal information about the filesystem where the bin was first compiled. +// This should only be overridden by `-Clink-arg=/PDBALTPATH:...` - this test +// checks that no full file paths are exposed and that the override flag is respected. +// See https://github.com/rust-lang/rust/pull/121297 + +//@ only-windows-msvc + +fn main() { + // Test that we don't have the full path to the PDB file in the binary + rustc() + .input("main.rs") + .arg("-g") + .crate_name("my_crate_name") + .crate_type("bin") + .arg("-Cforce-frame-pointers") + .run(); + invalid_utf8_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_not_contains(bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); + // Test that backtraces still can find debuginfo by checking that they contain symbol names and + // source locations. + let out = run(bin_name(my_crate_name)); + out.assert_stdout_contains("my_crate_name::fn_in_backtrace"); + out.assert_stdout_contains("main.rs:15"); + // Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected + rustc() + .input("main.rs") + .arg("-g") + .crate_name("my_crate_name") + .crate_type("bin") + .link_arg("/PDBALTPATH:abcdefg.pdb") + .arg("-Cforce-frame-pointers") + .run(); + invalid_utf8_contains(bin_name("my_crate_name"), "abcdefg.pdb"); + invalid_utf8_not_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); +} From 9dff8a33e1abcf8f0455acf7befd5366cc3d800f Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:46:34 -0400 Subject: [PATCH 065/217] rewrite mismatching-target-triples to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/mismatching-target-triples/Makefile | 11 ----------- .../run-make/mismatching-target-triples/rmake.rs | 15 +++++++++++++++ tests/run-make/pdb-alt-path/rmake.rs | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/mismatching-target-triples/Makefile create mode 100644 tests/run-make/mismatching-target-triples/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 3c6bb33813162..f8b0742a55c87 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -111,7 +111,6 @@ run-make/many-crates-but-no-match/Makefile run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile run-make/mingw-export-call-convention/Makefile -run-make/mismatching-target-triples/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile diff --git a/tests/run-make/mismatching-target-triples/Makefile b/tests/run-make/mismatching-target-triples/Makefile deleted file mode 100644 index 409388e041478..0000000000000 --- a/tests/run-make/mismatching-target-triples/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -# Issue #10814 -# -# these are no_std to avoid having to have the standard library or any -# linkers/assemblers for the relevant platform - -all: - $(RUSTC) foo.rs --target=i686-unknown-linux-gnu - $(RUSTC) bar.rs --target=x86_64-unknown-linux-gnu 2>&1 \ - | $(CGREP) 'couldn'"'"'t find crate `foo` with expected target triple x86_64-unknown-linux-gnu' diff --git a/tests/run-make/mismatching-target-triples/rmake.rs b/tests/run-make/mismatching-target-triples/rmake.rs new file mode 100644 index 0000000000000..6f41eac8cdaf4 --- /dev/null +++ b/tests/run-make/mismatching-target-triples/rmake.rs @@ -0,0 +1,15 @@ +// In this test, foo links against 32-bit architecture, and then, bar, which depends +// on foo, links against 64-bit architecture, causing a metadata mismatch due to the +// differences in target architectures. This used to cause an internal compiler error, +// now replaced by a clearer normal error message. This test checks that this aforementioned +// error message is used. +// See https://github.com/rust-lang/rust/issues/10814 + +use run_make_support::rustc; + +fn main() { + rustc().input("foo.rs").target("i686-unknown-linux-gnu").run(); + rustc().input("bar.rs").target("x86_64-unknown-linux-gnu").run_fail().assert_stderr_contains( + r#"couldn't find crate `foo` with expected target triple x86_64-unknown-linux-gnu"#, + ); +} diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs index 197768d82c114..15497be4ecfe2 100644 --- a/tests/run-make/pdb-alt-path/rmake.rs +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -5,7 +5,7 @@ // checks that no full file paths are exposed and that the override flag is respected. // See https://github.com/rust-lang/rust/pull/121297 -//@ only-windows-msvc +//@ only-windows fn main() { // Test that we don't have the full path to the PDB file in the binary From 7b150a161e7c90cc067c1a709a63785b5dc2a5e9 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:16:53 +0200 Subject: [PATCH 066/217] Don't use fake wildcards when we can get the failure block directly This commit too was obtained by repeatedly inlining and simplifying. --- .../rustc_mir_build/src/build/matches/mod.rs | 109 +++++++------- .../issue_101867.main.built.after.mir | 21 +-- ...n_conditional.test_complex.built.after.mir | 138 ++++++++---------- 3 files changed, 125 insertions(+), 143 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 8531ea891d2e3..3eacd598f66c2 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -329,6 +329,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &scrutinee_place, match_start_span, &mut candidates, + false, ); self.lower_match_arms( @@ -691,6 +692,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &initializer, irrefutable_pat.span, &mut [&mut candidate], + false, ); self.bind_pattern( self.source_info(irrefutable_pat.span), @@ -1215,6 +1217,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// Modifies `candidates` to store the bindings and type ascriptions for /// that candidate. + /// + /// `refutable` indicates whether the candidate list is refutable (for `if let` and `let else`) + /// or not (for `let` and `match`). In the refutable case we return the block to which we branch + /// on failure. fn lower_match_tree<'pat>( &mut self, block: BasicBlock, @@ -1222,45 +1228,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_place_builder: &PlaceBuilder<'tcx>, match_start_span: Span, candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) { - // See the doc comment on `match_candidates` for why we have an - // otherwise block. Match checking will ensure this is actually - // unreachable. + refutable: bool, + ) -> BasicBlock { + // See the doc comment on `match_candidates` for why we have an otherwise block. let otherwise_block = self.cfg.start_new_block(); // This will generate code to test scrutinee_place and branch to the appropriate arm block self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); - let source_info = self.source_info(scrutinee_span); - - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. - // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - - if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { - self.cfg.push_fake_read( - otherwise_block, - source_info, - cause_matched_place, - scrutinee_place, - ); - } - - self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); - // Link each leaf candidate to the `false_edge_start_block` of the next one. let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; for candidate in candidates { @@ -1272,6 +1247,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { previous_candidate = Some(leaf_candidate); }); } + + if refutable { + // In refutable cases there's always at least one candidate, and we want a false edge to + // the failure block. + previous_candidate.as_mut().unwrap().next_candidate_start_block = Some(otherwise_block) + } else { + // Match checking ensures `otherwise_block` is actually unreachable in irrefutable + // cases. + let source_info = self.source_info(scrutinee_span); + + // Matching on a `scrutinee_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // + // NOTE: ReadForMatch also checks that the scrutinee is initialized. + // This is currently needed to not allow matching on an uninitialized, + // uninhabited value. If we get never patterns, those will check that + // the place is initialized, and so this read would only be used to + // check safety. + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); + + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { + self.cfg.push_fake_read( + otherwise_block, + source_info, + cause_matched_place, + scrutinee_place, + ); + } + + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + } + + otherwise_block } /// The main match algorithm. It begins with a set of candidates @@ -1978,21 +1993,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); - let wildcard = Pat::wildcard_from_ty(pat.ty); let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); - let mut otherwise_candidate = - Candidate::new(expr_place_builder.clone(), &wildcard, false, self); - self.lower_match_tree( + let otherwise_block = self.lower_match_tree( block, pat.span, &expr_place_builder, pat.span, - &mut [&mut guard_candidate, &mut otherwise_candidate], + &mut [&mut guard_candidate], + true, ); let expr_place = expr_place_builder.try_to_place(self); let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); - let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); - self.break_for_else(otherwise_post_guard_block, self.source_info(expr_span)); + self.break_for_else(otherwise_block, self.source_info(expr_span)); if declare_bindings { self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); @@ -2008,7 +2020,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); // If branch coverage is enabled, record this branch. - self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_post_guard_block); + self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block); post_guard_block.unit() } @@ -2470,15 +2482,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let else_block_span = self.thir[else_block].span; let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| { let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span)); - let pat = Pat { ty: pattern.ty, span: else_block_span, kind: PatKind::Wild }; - let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false, this); let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - this.lower_match_tree( + let failure_block = this.lower_match_tree( block, initializer_span, &scrutinee, pattern.span, - &mut [&mut candidate, &mut wildcard], + &mut [&mut candidate], + true, ); // This block is for the matching case let matching = this.bind_pattern( @@ -2489,13 +2500,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, true, ); - // This block is for the failure case - let failure = wildcard.pre_binding_block.unwrap(); // If branch coverage is enabled, record this branch. - this.visit_coverage_conditional_let(pattern, matching, failure); + this.visit_coverage_conditional_let(pattern, matching, failure_block); - this.break_for_else(failure, this.source_info(initializer_span)); + this.break_for_else(failure_block, this.source_info(initializer_span)); matching.unit() }); matching.and(failure) diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 0f7917dbb5cbf..5c50b3db5cad6 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -27,13 +27,13 @@ fn main() -> () { StorageLive(_5); PlaceMention(_1); _6 = discriminant(_1); - switchInt(move _6) -> [1: bb6, otherwise: bb4]; + switchInt(move _6) -> [1: bb4, otherwise: bb3]; } bb1: { StorageLive(_3); StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb10; + _4 = begin_panic::<&str>(const "explicit panic") -> bb8; } bb2: { @@ -43,12 +43,11 @@ fn main() -> () { } bb3: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; + goto -> bb7; } bb4: { - goto -> bb9; + falseEdge -> [real: bb6, imaginary: bb3]; } bb5: { @@ -56,14 +55,6 @@ fn main() -> () { } bb6: { - falseEdge -> [real: bb8, imaginary: bb4]; - } - - bb7: { - goto -> bb4; - } - - bb8: { _5 = ((_1 as Some).0: u8); _0 = const (); StorageDead(_5); @@ -71,12 +62,12 @@ fn main() -> () { return; } - bb9: { + bb7: { StorageDead(_5); goto -> bb1; } - bb10 (cleanup): { + bb8 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index fd8eb370ca958..3e16efe6980d9 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,22 +19,21 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb38]; + _2 = E::f() -> [return: bb1, unwind: bb34]; } bb1: { PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb5, otherwise: bb3]; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; } bb2: { - FakeRead(ForMatchedPlace(None), _2); - unreachable; + goto -> bb21; } bb3: { - goto -> bb23; + falseEdge -> [real: bb5, imaginary: bb2]; } bb4: { @@ -42,175 +41,158 @@ fn test_complex() -> () { } bb5: { - falseEdge -> [real: bb7, imaginary: bb3]; + StorageLive(_4); + _4 = always_true() -> [return: bb6, unwind: bb34]; } bb6: { - goto -> bb3; + switchInt(move _4) -> [0: bb8, otherwise: bb7]; } bb7: { - StorageLive(_4); - _4 = always_true() -> [return: bb8, unwind: bb38]; - } - - bb8: { - switchInt(move _4) -> [0: bb10, otherwise: bb9]; - } - - bb9: { StorageLive(_5); StorageLive(_6); StorageLive(_7); _7 = Droppy(const 0_u8); _6 = (_7.0: u8); _5 = Gt(move _6, const 0_u8); - switchInt(move _5) -> [0: bb12, otherwise: bb11]; + switchInt(move _5) -> [0: bb10, otherwise: bb9]; } - bb10: { - goto -> bb16; + bb8: { + goto -> bb14; } - bb11: { - drop(_7) -> [return: bb13, unwind: bb38]; + bb9: { + drop(_7) -> [return: bb11, unwind: bb34]; } - bb12: { - goto -> bb14; + bb10: { + goto -> bb12; } - bb13: { + bb11: { StorageDead(_7); StorageDead(_6); - goto -> bb20; + goto -> bb18; } - bb14: { - drop(_7) -> [return: bb15, unwind: bb38]; + bb12: { + drop(_7) -> [return: bb13, unwind: bb34]; } - bb15: { + bb13: { StorageDead(_7); StorageDead(_6); - goto -> bb16; + goto -> bb14; } - bb16: { + bb14: { StorageLive(_8); StorageLive(_9); StorageLive(_10); _10 = Droppy(const 1_u8); _9 = (_10.0: u8); _8 = Gt(move _9, const 1_u8); - switchInt(move _8) -> [0: bb18, otherwise: bb17]; + switchInt(move _8) -> [0: bb16, otherwise: bb15]; } - bb17: { - drop(_10) -> [return: bb19, unwind: bb38]; + bb15: { + drop(_10) -> [return: bb17, unwind: bb34]; } - bb18: { - goto -> bb21; + bb16: { + goto -> bb19; } - bb19: { + bb17: { StorageDead(_10); StorageDead(_9); - goto -> bb20; + goto -> bb18; } - bb20: { + bb18: { _1 = const (); - goto -> bb24; + goto -> bb22; } - bb21: { - drop(_10) -> [return: bb22, unwind: bb38]; + bb19: { + drop(_10) -> [return: bb20, unwind: bb34]; } - bb22: { + bb20: { StorageDead(_10); StorageDead(_9); - goto -> bb23; + goto -> bb21; } - bb23: { + bb21: { _1 = const (); - goto -> bb24; + goto -> bb22; } - bb24: { + bb22: { StorageDead(_8); StorageDead(_5); StorageDead(_4); StorageDead(_2); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb25, unwind: bb38]; + _11 = always_true() -> [return: bb23, unwind: bb34]; } - bb25: { - switchInt(move _11) -> [0: bb27, otherwise: bb26]; + bb23: { + switchInt(move _11) -> [0: bb25, otherwise: bb24]; } - bb26: { - goto -> bb36; + bb24: { + goto -> bb32; } - bb27: { - goto -> bb28; + bb25: { + goto -> bb26; } - bb28: { + bb26: { StorageLive(_12); - _12 = E::f() -> [return: bb29, unwind: bb38]; + _12 = E::f() -> [return: bb27, unwind: bb34]; } - bb29: { + bb27: { PlaceMention(_12); _13 = discriminant(_12); - switchInt(move _13) -> [1: bb33, otherwise: bb31]; - } - - bb30: { - FakeRead(ForMatchedPlace(None), _12); - unreachable; + switchInt(move _13) -> [1: bb29, otherwise: bb28]; } - bb31: { - goto -> bb36; - } - - bb32: { - goto -> bb30; + bb28: { + goto -> bb32; } - bb33: { - falseEdge -> [real: bb35, imaginary: bb31]; + bb29: { + falseEdge -> [real: bb31, imaginary: bb28]; } - bb34: { - goto -> bb31; + bb30: { + goto -> bb28; } - bb35: { + bb31: { _0 = const (); - goto -> bb37; + goto -> bb33; } - bb36: { + bb32: { _0 = const (); - goto -> bb37; + goto -> bb33; } - bb37: { + bb33: { StorageDead(_11); StorageDead(_12); return; } - bb38 (cleanup): { + bb34 (cleanup): { resume; } } From ff49c3769b0ec5b1abc628e55c7547e765086e6a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:51:35 +0200 Subject: [PATCH 067/217] Reuse `lower_let_expr` for `let .. else` lowering --- compiler/rustc_mir_build/src/build/block.rs | 63 ++++++++-------- .../rustc_mir_build/src/build/matches/mod.rs | 73 +++++-------------- 2 files changed, 49 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index c1d645aa42cb8..476969a1bd7ad 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -189,38 +189,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let initializer_span = this.thir[*initializer].span; let scope = (*init_scope, source_info); - let failure = unpack!( - block = this.in_scope(scope, *lint_level, |this| { - this.declare_bindings( - visibility_scope, - remainder_span, - pattern, - None, - Some((Some(&destination), initializer_span)), - ); - this.visit_primary_bindings( - pattern, - UserTypeProjections::none(), - &mut |this, _, _, node, span, _, _| { - this.storage_live_binding( - block, - node, - span, - OutsideGuard, - true, - ); - }, - ); - this.ast_let_else( - block, - *initializer, - initializer_span, - *else_block, - &last_remainder_scope, - pattern, - ) - }) - ); + let failure_and_block = this.in_scope(scope, *lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + pattern, + None, + Some((Some(&destination), initializer_span)), + ); + this.visit_primary_bindings( + pattern, + UserTypeProjections::none(), + &mut |this, _, _, node, span, _, _| { + this.storage_live_binding(block, node, span, OutsideGuard, true); + }, + ); + let else_block_span = this.thir[*else_block].span; + let (matching, failure) = + this.in_if_then_scope(last_remainder_scope, else_block_span, |this| { + this.lower_let_expr( + block, + *initializer, + pattern, + None, + initializer_span, + false, + true, + ) + }); + matching.and(failure) + }); + let failure = unpack!(block = failure_and_block); this.cfg.goto(failure, source_info, failure_entry); if let Some(source_scope) = visibility_scope { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3eacd598f66c2..f9333a165cef1 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -147,6 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(args.variable_source_info.scope), args.variable_source_info.span, args.declare_let_bindings, + false, ), _ => { let mut block = block; @@ -1981,48 +1982,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> { /// If the bindings have already been declared, set `declare_bindings` to - /// `false` to avoid duplicated bindings declaration. Used for if-let guards. + /// `false` to avoid duplicated bindings declaration; used for if-let guards. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, expr_id: ExprId, pat: &Pat<'tcx>, source_scope: Option, - span: Span, + scope_span: Span, declare_bindings: bool, + storages_alive: bool, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; - let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); - let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); + let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); + let mut candidate = Candidate::new(scrutinee.clone(), pat, false, self); let otherwise_block = self.lower_match_tree( block, + expr_span, + &scrutinee, pat.span, - &expr_place_builder, - pat.span, - &mut [&mut guard_candidate], + &mut [&mut candidate], true, ); - let expr_place = expr_place_builder.try_to_place(self); - let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.break_for_else(otherwise_block, self.source_info(expr_span)); if declare_bindings { - self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); + let expr_place = scrutinee.try_to_place(self); + let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place); } - let post_guard_block = self.bind_pattern( + let success = self.bind_pattern( self.source_info(pat.span), - guard_candidate, + candidate, &[], expr_span, None, - false, + storages_alive, ); // If branch coverage is enabled, record this branch. - self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block); + self.visit_coverage_conditional_let(pat, success, otherwise_block); - post_guard_block.unit() + success.unit() } /// Initializes each of the bindings from the candidate by @@ -2469,44 +2472,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!(?locals); self.var_indices.insert(var_id, locals); } - - pub(crate) fn ast_let_else( - &mut self, - mut block: BasicBlock, - init_id: ExprId, - initializer_span: Span, - else_block: BlockId, - let_else_scope: ®ion::Scope, - pattern: &Pat<'tcx>, - ) -> BlockAnd { - let else_block_span = self.thir[else_block].span; - let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| { - let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span)); - let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - let failure_block = this.lower_match_tree( - block, - initializer_span, - &scrutinee, - pattern.span, - &mut [&mut candidate], - true, - ); - // This block is for the matching case - let matching = this.bind_pattern( - this.source_info(pattern.span), - candidate, - &[], - initializer_span, - None, - true, - ); - - // If branch coverage is enabled, record this branch. - this.visit_coverage_conditional_let(pattern, matching, failure_block); - - this.break_for_else(failure_block, this.source_info(initializer_span)); - matching.unit() - }); - matching.and(failure) - } } From beb1d35d7d63d331089620c60d591bab7e6495a5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 22 Jun 2024 18:21:03 +0200 Subject: [PATCH 068/217] Change comment to reflect switch to THIR unsafeck --- .../rustc_mir_build/src/build/matches/mod.rs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f9333a165cef1..a92272c9809a2 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1258,21 +1258,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // cases. let source_info = self.source_info(scrutinee_span); - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // Matching on a scrutinee place of an uninhabited type doesn't generate any memory + // reads by itself, and so if the place is uninitialized we wouldn't know. In order to + // disallow the following: + // ```rust + // let x: !; + // match x {} + // ``` + // we add a dummy read on the place. // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. + // NOTE: If we require never patterns for empty matches, those will check that the place + // is initialized, and so this read would no longer be needed. let cause_matched_place = FakeReadCause::ForMatchedPlace(None); if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { From f1052eb253580ce2adbcc7a24b15e291e4f0c760 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 4 May 2024 16:47:18 -0700 Subject: [PATCH 069/217] cg_clif: Define build opts from FramePointer --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2edb34e7c20dc..06ca52b390320 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,9 +271,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc Date: Sun, 23 Jun 2024 21:55:41 +0200 Subject: [PATCH 070/217] Add `.ignore` file to make `config.toml` searchable in vscode --- .ignore | 2 ++ .reuse/dep5 | 1 + 2 files changed, 3 insertions(+) create mode 100644 .ignore diff --git a/.ignore b/.ignore new file mode 100644 index 0000000000000..40d1513978fc6 --- /dev/null +++ b/.ignore @@ -0,0 +1,2 @@ +# Make vscode *not* count `config.toml` as ignored, so it is included in search +!/config.toml diff --git a/.reuse/dep5 b/.reuse/dep5 index 06afec2b3faec..7b9365a5e48f7 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -35,6 +35,7 @@ Files: compiler/* .gitignore .gitmodules .mailmap + .ignore Copyright: The Rust Project Developers (see https://thanks.rust-lang.org) License: MIT or Apache-2.0 From dbf701838758bd70d51fa36dcb79e7d02e0e4352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petteri=20R=C3=A4ty?= Date: Mon, 24 Jun 2024 11:12:10 +0300 Subject: [PATCH 071/217] Fix simd_gather documentation There is no idx in the function signature. --- library/core/src/intrinsics/simd.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 4be5e62ea5bc6..b892e11158822 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -263,9 +263,6 @@ extern "rust-intrinsic" { /// /// `V` must be a vector of integers with the same length as `T` (but any element size). /// - /// `idx` must be a constant: either naming a constant item, or an inline - /// `const {}` expression. - /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, read the pointer. /// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from /// `val`. From 39bf1dcce5b0e80fbdbcde30e618821f5c9b0bf0 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 24 Jun 2024 17:57:58 +0300 Subject: [PATCH 072/217] Small fixme in core now that split_first has no codegen issues --- library/core/src/num/dec2flt/common.rs | 4 +--- library/core/src/num/dec2flt/parse.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs index 11a626485191c..c85727b493816 100644 --- a/library/core/src/num/dec2flt/common.rs +++ b/library/core/src/num/dec2flt/common.rs @@ -39,9 +39,7 @@ impl ByteSlice for [u8] { fn parse_digits(&self, mut func: impl FnMut(u8)) -> &Self { let mut s = self; - // FIXME: Can't use s.split_first() here yet, - // see https://github.com/rust-lang/rust/issues/109328 - while let [c, s_next @ ..] = s { + while let Some((c, s_next)) = s.split_first() { let c = c.wrapping_sub(b'0'); if c < 10 { func(c); diff --git a/library/core/src/num/dec2flt/parse.rs b/library/core/src/num/dec2flt/parse.rs index b0a23835c5bd4..975bb8ad6bc1f 100644 --- a/library/core/src/num/dec2flt/parse.rs +++ b/library/core/src/num/dec2flt/parse.rs @@ -51,9 +51,7 @@ fn try_parse_19digits(s_ref: &mut &[u8], x: &mut u64) { let mut s = *s_ref; while *x < MIN_19DIGIT_INT { - // FIXME: Can't use s.split_first() here yet, - // see https://github.com/rust-lang/rust/issues/109328 - if let [c, s_next @ ..] = s { + if let Some((c, s_next)) = s.split_first() { let digit = c.wrapping_sub(b'0'); if digit < 10 { From ac670721c90985af11ddfe7d00b6ffcb8b5d226d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 24 Jun 2024 16:22:47 -0700 Subject: [PATCH 073/217] test: dont optimize to invalid bitcasts --- tests/ui/simd/dont-invalid-bitcast-masks.rs | 17 ++++++++++++ tests/ui/simd/dont-invalid-bitcast-x86_64.rs | 27 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/simd/dont-invalid-bitcast-masks.rs create mode 100644 tests/ui/simd/dont-invalid-bitcast-x86_64.rs diff --git a/tests/ui/simd/dont-invalid-bitcast-masks.rs b/tests/ui/simd/dont-invalid-bitcast-masks.rs new file mode 100644 index 0000000000000..3d8376207cd07 --- /dev/null +++ b/tests/ui/simd/dont-invalid-bitcast-masks.rs @@ -0,0 +1,17 @@ +//@ build-pass +//@ compile-flags: -Copt-level=3 + +// regression test for https://github.com/rust-lang/rust/issues/110722 +// in --release we were optimizing to invalid bitcasts, due to a combination of MIR inlining and +// mostly bad repr(simd) lowering which prevented even basic splats from working +#![crate_type = "rlib"] +#![feature(portable_simd)] +use std::simd::*; +use std::simd::num::*; + +pub unsafe fn mask_to_array(mask: u8) -> [i32; 8] { + let mut output = [0; 8]; + let m = masksizex8::from_bitmask(mask as _); + output.copy_from_slice(&m.to_int().cast::().to_array()); + output +} diff --git a/tests/ui/simd/dont-invalid-bitcast-x86_64.rs b/tests/ui/simd/dont-invalid-bitcast-x86_64.rs new file mode 100644 index 0000000000000..e6e435bcfc902 --- /dev/null +++ b/tests/ui/simd/dont-invalid-bitcast-x86_64.rs @@ -0,0 +1,27 @@ +//@ build-pass +//@ compile-flags: -Copt-level=3 +//@ only-x86_64 +// ignore-tidy-linelength + +// regression test for https://github.com/rust-lang/rust/issues/110707 +// in --release we were optimizing to invalid bitcasts, due to a combination of MIR inlining and +// mostly bad repr(simd) lowering which prevented even basic splats from working + +#![crate_type = "rlib"] +#![feature(portable_simd)] +use std::simd::*; +use std::arch::x86_64::*; + +#[target_feature(enable = "sse4.1")] +pub unsafe fn fast_round_sse(i: f32x8) -> f32x8 { + let a = i.to_array(); + let [low, high]: [[f32; 4]; 2] = + unsafe { std::mem::transmute::<[f32; 8], [[f32; 4]; 2]>(a) }; + + let low = f32x4::from(_mm_round_ps::<{_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC}>(f32x4::from_array(low).into())); + let high = f32x4::from(_mm_round_ps::<{_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC}>(f32x4::from_array(high).into())); + + let a: [f32; 8] = + unsafe { std::mem::transmute::<[[f32; 4]; 2], [f32; 8]>([low.to_array(), high.to_array()]) }; + f32x8::from_array(a) +} From e8516f8b52d8ae49c2e0b2ff2cb5faf28b1a6526 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 25 Jun 2024 18:30:49 +0200 Subject: [PATCH 074/217] std: separate TLS key creation from TLS access Currently, `std` performs an atomic load to get the OS key on every access to `StaticKey` even when the key is already known. This PR thus replaces `StaticKey` with the platform-specific `get` and `set` function and a new `LazyKey` type that acts as a `LazyLock`, allowing the reuse of the retreived key for multiple accesses. --- library/std/src/sys/thread_local/guard/key.rs | 6 +- library/std/src/sys/thread_local/key/racy.rs | 56 +++---------------- library/std/src/sys/thread_local/key/tests.rs | 39 ++++++++----- library/std/src/sys/thread_local/key/unix.rs | 1 + .../std/src/sys/thread_local/key/windows.rs | 56 +++++++++---------- library/std/src/sys/thread_local/key/xous.rs | 2 +- library/std/src/sys/thread_local/mod.rs | 21 ++++--- library/std/src/sys/thread_local/os.rs | 44 +++++++-------- 8 files changed, 100 insertions(+), 125 deletions(-) diff --git a/library/std/src/sys/thread_local/guard/key.rs b/library/std/src/sys/thread_local/guard/key.rs index ee9d55ddd5e8e..67c3ca8862767 100644 --- a/library/std/src/sys/thread_local/guard/key.rs +++ b/library/std/src/sys/thread_local/guard/key.rs @@ -4,15 +4,15 @@ use crate::ptr; use crate::sys::thread_local::destructors; -use crate::sys::thread_local::key::StaticKey; +use crate::sys::thread_local::key::{set, LazyKey}; pub fn enable() { - static DTORS: StaticKey = StaticKey::new(Some(run)); + static DTORS: LazyKey = LazyKey::new(Some(run)); // Setting the key value to something other than NULL will result in the // destructor being run at thread exit. unsafe { - DTORS.set(ptr::without_provenance_mut(1)); + set(DTORS.force(), ptr::without_provenance_mut(1)); } unsafe extern "C" fn run(_: *mut u8) { diff --git a/library/std/src/sys/thread_local/key/racy.rs b/library/std/src/sys/thread_local/key/racy.rs index eda8b83bc7f03..69f11458c3289 100644 --- a/library/std/src/sys/thread_local/key/racy.rs +++ b/library/std/src/sys/thread_local/key/racy.rs @@ -1,4 +1,4 @@ -//! A `StaticKey` implementation using racy initialization. +//! A `LazyKey` implementation using racy initialization. //! //! Unfortunately, none of the platforms currently supported by `std` allows //! creating TLS keys at compile-time. Thus we need a way to lazily create keys. @@ -10,34 +10,12 @@ use crate::sync::atomic::{self, AtomicUsize, Ordering}; /// A type for TLS keys that are statically allocated. /// -/// This type is entirely `unsafe` to use as it does not protect against -/// use-after-deallocation or use-during-deallocation. -/// -/// The actual OS-TLS key is lazily allocated when this is used for the first -/// time. The key is also deallocated when the Rust runtime exits or `destroy` -/// is called, whichever comes first. -/// -/// # Examples -/// -/// ```ignore (cannot-doctest-private-modules) -/// use tls::os::{StaticKey, INIT}; -/// -/// // Use a regular global static to store the key. -/// static KEY: StaticKey = INIT; -/// -/// // The state provided via `get` and `set` is thread-local. -/// unsafe { -/// assert!(KEY.get().is_null()); -/// KEY.set(1 as *mut u8); -/// } -/// ``` -pub struct StaticKey { +/// This is basically a `LazyLock`, but avoids blocking and circular +/// dependencies with the rest of `std`. +pub struct LazyKey { /// Inner static TLS key (internals). key: AtomicUsize, /// Destructor for the TLS value. - /// - /// See `Key::new` for information about when the destructor runs and how - /// it runs. dtor: Option, } @@ -51,32 +29,14 @@ const KEY_SENTVAL: usize = 0; #[cfg(target_os = "nto")] const KEY_SENTVAL: usize = libc::PTHREAD_KEYS_MAX + 1; -impl StaticKey { +impl LazyKey { #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] - pub const fn new(dtor: Option) -> StaticKey { - StaticKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } - } - - /// Gets the value associated with this TLS key - /// - /// This will lazily allocate a TLS key from the OS if one has not already - /// been allocated. - #[inline] - pub unsafe fn get(&self) -> *mut u8 { - unsafe { super::get(self.key()) } - } - - /// Sets this TLS key to a new value. - /// - /// This will lazily allocate a TLS key from the OS if one has not already - /// been allocated. - #[inline] - pub unsafe fn set(&self, val: *mut u8) { - unsafe { super::set(self.key(), val) } + pub const fn new(dtor: Option) -> LazyKey { + LazyKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } } #[inline] - fn key(&self) -> super::Key { + pub fn force(&self) -> super::Key { match self.key.load(Ordering::Acquire) { KEY_SENTVAL => self.lazy_init() as super::Key, n => n as super::Key, diff --git a/library/std/src/sys/thread_local/key/tests.rs b/library/std/src/sys/thread_local/key/tests.rs index 24cad396da269..d82b34e71f0e4 100644 --- a/library/std/src/sys/thread_local/key/tests.rs +++ b/library/std/src/sys/thread_local/key/tests.rs @@ -1,18 +1,25 @@ -use super::StaticKey; +use super::{get, set, LazyKey}; use crate::ptr; #[test] fn smoke() { - static K1: StaticKey = StaticKey::new(None); - static K2: StaticKey = StaticKey::new(None); + static K1: LazyKey = LazyKey::new(None); + static K2: LazyKey = LazyKey::new(None); + + let k1 = K1.force(); + let k2 = K2.force(); + assert_ne!(k1, k2); + + assert_eq!(K1.force(), k1); + assert_eq!(K2.force(), k2); unsafe { - assert!(K1.get().is_null()); - assert!(K2.get().is_null()); - K1.set(ptr::without_provenance_mut(1)); - K2.set(ptr::without_provenance_mut(2)); - assert_eq!(K1.get() as usize, 1); - assert_eq!(K2.get() as usize, 2); + assert!(get(k1).is_null()); + assert!(get(k2).is_null()); + set(k1, ptr::without_provenance_mut(1)); + set(k2, ptr::without_provenance_mut(2)); + assert_eq!(get(k1) as usize, 1); + assert_eq!(get(k2) as usize, 2); } } @@ -26,25 +33,27 @@ fn destructors() { drop(unsafe { Arc::from_raw(ptr as *const ()) }); } - static KEY: StaticKey = StaticKey::new(Some(destruct)); + static KEY: LazyKey = LazyKey::new(Some(destruct)); let shared1 = Arc::new(()); let shared2 = Arc::clone(&shared1); + let key = KEY.force(); unsafe { - assert!(KEY.get().is_null()); - KEY.set(Arc::into_raw(shared1) as *mut u8); + assert!(get(key).is_null()); + set(key, Arc::into_raw(shared1) as *mut u8); } thread::spawn(move || unsafe { - assert!(KEY.get().is_null()); - KEY.set(Arc::into_raw(shared2) as *mut u8); + let key = KEY.force(); + assert!(get(key).is_null()); + set(key, Arc::into_raw(shared2) as *mut u8); }) .join() .unwrap(); // Leak the Arc, let the TLS destructor clean it up. - let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(KEY.get() as *const ())) }; + let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(get(key) as *const ())) }; assert_eq!( Arc::strong_count(&shared1), 1, diff --git a/library/std/src/sys/thread_local/key/unix.rs b/library/std/src/sys/thread_local/key/unix.rs index 13522d44b35dc..28e48a750b9bf 100644 --- a/library/std/src/sys/thread_local/key/unix.rs +++ b/library/std/src/sys/thread_local/key/unix.rs @@ -16,6 +16,7 @@ pub unsafe fn set(key: Key, value: *mut u8) { } #[inline] +#[cfg(any(not(target_thread_local), test))] pub unsafe fn get(key: Key) -> *mut u8 { unsafe { libc::pthread_getspecific(key) as *mut u8 } } diff --git a/library/std/src/sys/thread_local/key/windows.rs b/library/std/src/sys/thread_local/key/windows.rs index ad0e72c29edaf..baf23979c7c61 100644 --- a/library/std/src/sys/thread_local/key/windows.rs +++ b/library/std/src/sys/thread_local/key/windows.rs @@ -1,4 +1,4 @@ -//! Implementation of `StaticKey` for Windows. +//! Implementation of `LazyKey` for Windows. //! //! Windows has no native support for running destructors so we manage our own //! list of destructors to keep track of how to destroy keys. We then install a @@ -13,9 +13,9 @@ //! don't reach a fixed point after a short while then we just inevitably leak //! something. //! -//! The list is implemented as an atomic single-linked list of `StaticKey`s and +//! The list is implemented as an atomic single-linked list of `LazyKey`s and //! does not support unregistration. Unfortunately, this means that we cannot -//! use racy initialization for creating the keys in `StaticKey`, as that could +//! use racy initialization for creating the keys in `LazyKey`, as that could //! result in destructors being missed. Hence, we synchronize the creation of //! keys with destructors through [`INIT_ONCE`](c::INIT_ONCE) (`std`'s //! [`Once`](crate::sync::Once) cannot be used since it might use TLS itself). @@ -33,26 +33,26 @@ use crate::sync::atomic::{ use crate::sys::c; use crate::sys::thread_local::guard; -type Key = c::DWORD; +pub type Key = c::DWORD; type Dtor = unsafe extern "C" fn(*mut u8); -pub struct StaticKey { +pub struct LazyKey { /// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == DWORD::MAX /// is not a valid key value, this allows us to use zero as sentinel value /// without risking overflow. key: AtomicU32, dtor: Option, - next: AtomicPtr, + next: AtomicPtr, /// Currently, destructors cannot be unregistered, so we cannot use racy /// initialization for keys. Instead, we need synchronize initialization. /// Use the Windows-provided `Once` since it does not require TLS. once: UnsafeCell, } -impl StaticKey { +impl LazyKey { #[inline] - pub const fn new(dtor: Option) -> StaticKey { - StaticKey { + pub const fn new(dtor: Option) -> LazyKey { + LazyKey { key: AtomicU32::new(0), dtor, next: AtomicPtr::new(ptr::null_mut()), @@ -61,18 +61,7 @@ impl StaticKey { } #[inline] - pub unsafe fn set(&'static self, val: *mut u8) { - let r = unsafe { c::TlsSetValue(self.key(), val.cast()) }; - debug_assert_eq!(r, c::TRUE); - } - - #[inline] - pub unsafe fn get(&'static self) -> *mut u8 { - unsafe { c::TlsGetValue(self.key()).cast() } - } - - #[inline] - fn key(&'static self) -> Key { + pub fn force(&'static self) -> Key { match self.key.load(Acquire) { 0 => unsafe { self.init() }, key => key - 1, @@ -141,17 +130,28 @@ impl StaticKey { } } -unsafe impl Send for StaticKey {} -unsafe impl Sync for StaticKey {} +unsafe impl Send for LazyKey {} +unsafe impl Sync for LazyKey {} + +#[inline] +pub unsafe fn set(key: Key, val: *mut u8) { + let r = unsafe { c::TlsSetValue(key, val.cast()) }; + debug_assert_eq!(r, c::TRUE); +} + +#[inline] +pub unsafe fn get(key: Key) -> *mut u8 { + unsafe { c::TlsGetValue(key).cast() } +} -static DTORS: AtomicPtr = AtomicPtr::new(ptr::null_mut()); +static DTORS: AtomicPtr = AtomicPtr::new(ptr::null_mut()); /// Should only be called once per key, otherwise loops or breaks may occur in /// the linked list. -unsafe fn register_dtor(key: &'static StaticKey) { +unsafe fn register_dtor(key: &'static LazyKey) { guard::enable(); - let this = <*const StaticKey>::cast_mut(key); + let this = <*const LazyKey>::cast_mut(key); // Use acquire ordering to pass along the changes done by the previously // registered keys when we store the new head with release ordering. let mut head = DTORS.load(Acquire); @@ -176,9 +176,9 @@ pub unsafe fn run_dtors() { let dtor = unsafe { (*cur).dtor.unwrap() }; cur = unsafe { (*cur).next.load(Relaxed) }; - // In StaticKey::init, we register the dtor before setting `key`. + // In LazyKey::init, we register the dtor before setting `key`. // So if one thread's `run_dtors` races with another thread executing `init` on the same - // `StaticKey`, we can encounter a key of 0 here. That means this key was never + // `LazyKey`, we can encounter a key of 0 here. That means this key was never // initialized in this thread so we can safely skip it. if pre_key == 0 { continue; diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs index a23f6de95f7b5..5a837a33e190e 100644 --- a/library/std/src/sys/thread_local/key/xous.rs +++ b/library/std/src/sys/thread_local/key/xous.rs @@ -30,7 +30,7 @@ //! really. //! //! Perhaps one day we can fold the `Box` here into a static allocation, -//! expanding the `StaticKey` structure to contain not only a slot for the TLS +//! expanding the `LazyKey` structure to contain not only a slot for the TLS //! key but also a slot for the destructor queue on windows. An optimization for //! another day! diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index f74fd828cbe50..3d1b91a7ea095 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -36,7 +36,7 @@ cfg_if::cfg_if! { pub use native::{EagerStorage, LazyStorage, thread_local_inner}; } else { mod os; - pub use os::{Key, thread_local_inner}; + pub use os::{Storage, thread_local_inner}; } } @@ -126,28 +126,33 @@ pub(crate) mod key { mod unix; #[cfg(test)] mod tests; - pub(super) use racy::StaticKey; - use unix::{Key, create, destroy, get, set}; + pub(super) use racy::LazyKey; + pub(super) use unix::{Key, set}; + #[cfg(any(not(target_thread_local), test))] + pub(super) use unix::get; + use unix::{create, destroy}; } else if #[cfg(all(not(target_thread_local), target_os = "windows"))] { #[cfg(test)] mod tests; mod windows; - pub(super) use windows::{StaticKey, run_dtors}; + pub(super) use windows::{Key, LazyKey, get, run_dtors, set}; } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod racy; mod sgx; #[cfg(test)] mod tests; - pub(super) use racy::StaticKey; - use sgx::{Key, create, destroy, get, set}; + pub(super) use racy::LazyKey; + pub(super) use sgx::{Key, get, set}; + use sgx::{create, destroy}; } else if #[cfg(target_os = "xous")] { mod racy; #[cfg(test)] mod tests; mod xous; - pub(super) use racy::StaticKey; + pub(super) use racy::LazyKey; pub(crate) use xous::destroy_tls; - use xous::{Key, create, destroy, get, set}; + pub(super) use xous::{Key, get, set}; + use xous::{create, destroy}; } } } diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 6980c897fdb53..625943bb25512 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -2,7 +2,7 @@ use super::abort_on_dtor_unwind; use crate::cell::Cell; use crate::marker::PhantomData; use crate::ptr; -use crate::sys::thread_local::key::StaticKey as OsKey; +use crate::sys::thread_local::key::{get, set, Key, LazyKey}; #[doc(hidden)] #[allow_internal_unstable(thread_local_internals)] @@ -22,12 +22,12 @@ pub macro thread_local_inner { unsafe { use $crate::thread::LocalKey; - use $crate::thread::local_impl::Key; + use $crate::thread::local_impl::Storage; // Inlining does not work on windows-gnu due to linking errors around // dllimports. See https://github.com/rust-lang/rust/issues/109797. LocalKey::new(#[cfg_attr(windows, inline(never))] |init| { - static VAL: Key<$t> = Key::new(); + static VAL: Storage<$t> = Storage::new(); VAL.get(init, __init) }) } @@ -41,22 +41,22 @@ pub macro thread_local_inner { /// Use a regular global static to store this key; the state provided will then be /// thread-local. #[allow(missing_debug_implementations)] -pub struct Key { - os: OsKey, +pub struct Storage { + key: LazyKey, marker: PhantomData>, } -unsafe impl Sync for Key {} +unsafe impl Sync for Storage {} struct Value { value: T, - key: &'static Key, + key: Key, } -impl Key { +impl Storage { #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] - pub const fn new() -> Key { - Key { os: OsKey::new(Some(destroy_value::)), marker: PhantomData } + pub const fn new() -> Storage { + Storage { key: LazyKey::new(Some(destroy_value::)), marker: PhantomData } } /// Get a pointer to the TLS value, potentially initializing it with the @@ -66,19 +66,19 @@ impl Key { /// The resulting pointer may not be used after reentrant inialialization /// or thread destruction has occurred. pub fn get(&'static self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { - // SAFETY: (FIXME: get should actually be safe) - let ptr = unsafe { self.os.get() as *mut Value }; + let key = self.key.force(); + let ptr = unsafe { get(key) as *mut Value }; if ptr.addr() > 1 { // SAFETY: the check ensured the pointer is safe (its destructor // is not running) + it is coming from a trusted source (self). unsafe { &(*ptr).value } } else { - self.try_initialize(ptr, i, f) + unsafe { Self::try_initialize(key, ptr, i, f) } } } - fn try_initialize( - &'static self, + unsafe fn try_initialize( + key: Key, ptr: *mut Value, i: Option<&mut Option>, f: impl FnOnce() -> T, @@ -88,13 +88,13 @@ impl Key { return ptr::null(); } - let value = i.and_then(Option::take).unwrap_or_else(f); - let ptr = Box::into_raw(Box::new(Value { value, key: self })); - // SAFETY: (FIXME: get should actually be safe) - let old = unsafe { self.os.get() as *mut Value }; + let value = Box::new(Value { value: i.and_then(Option::take).unwrap_or_else(f), key }); + let ptr = Box::into_raw(value); + + let old = unsafe { get(key) as *mut Value }; // SAFETY: `ptr` is a correct pointer that can be destroyed by the key destructor. unsafe { - self.os.set(ptr as *mut u8); + set(key, ptr as *mut u8); } if !old.is_null() { // If the variable was recursively initialized, drop the old value. @@ -123,8 +123,8 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) { abort_on_dtor_unwind(|| { let ptr = unsafe { Box::from_raw(ptr as *mut Value) }; let key = ptr.key; - unsafe { key.os.set(ptr::without_provenance_mut(1)) }; + unsafe { set(key, ptr::without_provenance_mut(1)) }; drop(ptr); - unsafe { key.os.set(ptr::null_mut()) }; + unsafe { set(key, ptr::null_mut()) }; }); } From a2ed16cc061f4b25c673d0f53264e5c7c389eb9b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 16:00:53 -0400 Subject: [PATCH 075/217] rewrite mingw-export-call-convention to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/mingw-export-call-convention/Makefile | 9 --------- .../run-make/mingw-export-call-convention/rmake.rs | 13 +++++++++++++ tests/run-make/pdb-alt-path/rmake.rs | 14 ++++++++------ 4 files changed, 21 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/mingw-export-call-convention/Makefile create mode 100644 tests/run-make/mingw-export-call-convention/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f8b0742a55c87..a029c20dec30f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -110,7 +110,6 @@ run-make/manual-link/Makefile run-make/many-crates-but-no-match/Makefile run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile -run-make/mingw-export-call-convention/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile diff --git a/tests/run-make/mingw-export-call-convention/Makefile b/tests/run-make/mingw-export-call-convention/Makefile deleted file mode 100644 index 4a60059cc5441..0000000000000 --- a/tests/run-make/mingw-export-call-convention/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# only-windows-gnu - -all: - $(RUSTC) foo.rs - # FIXME: we should make sure __stdcall calling convention is used here - # but that only works with LLD right now - nm -g "$(call IMPLIB,foo)" | $(CGREP) bar diff --git a/tests/run-make/mingw-export-call-convention/rmake.rs b/tests/run-make/mingw-export-call-convention/rmake.rs new file mode 100644 index 0000000000000..d1fb745a64de9 --- /dev/null +++ b/tests/run-make/mingw-export-call-convention/rmake.rs @@ -0,0 +1,13 @@ +// On windows-gnu, symbol exporting used to fail to export names +// with no_mangle. #72049 brought this feature up to par with msvc, +// and this test checks that the symbol "bar" is successfully exported. +// See https://github.com/rust-lang/rust/issues/50176 + +//@ only-x86_64-pc-windows-gnu + +use run_make_support::{llvm_readobj, rustc}; + +fn main() { + rustc().input("foo.rs").run(); + llvm_readobj().arg("--all").input("libfoo.dll.a").run().assert_stdout_contains("bar"); +} diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs index 15497be4ecfe2..6311d6d9ed7d0 100644 --- a/tests/run-make/pdb-alt-path/rmake.rs +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -5,7 +5,9 @@ // checks that no full file paths are exposed and that the override flag is respected. // See https://github.com/rust-lang/rust/pull/121297 -//@ only-windows +//@ only-x86_64-pc-windows-msvc + +use run_make_support::{bin_name, invalid_utf8_contains, invalid_utf8_not_contains, run, rustc}; fn main() { // Test that we don't have the full path to the PDB file in the binary @@ -16,11 +18,11 @@ fn main() { .crate_type("bin") .arg("-Cforce-frame-pointers") .run(); - invalid_utf8_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); - invalid_utf8_not_contains(bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); + invalid_utf8_contains(&bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_not_contains(&bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); // Test that backtraces still can find debuginfo by checking that they contain symbol names and // source locations. - let out = run(bin_name(my_crate_name)); + let out = run(&bin_name("my_crate_name")); out.assert_stdout_contains("my_crate_name::fn_in_backtrace"); out.assert_stdout_contains("main.rs:15"); // Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected @@ -32,6 +34,6 @@ fn main() { .link_arg("/PDBALTPATH:abcdefg.pdb") .arg("-Cforce-frame-pointers") .run(); - invalid_utf8_contains(bin_name("my_crate_name"), "abcdefg.pdb"); - invalid_utf8_not_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_contains(&bin_name("my_crate_name"), "abcdefg.pdb"); + invalid_utf8_not_contains(&bin_name("my_crate_name"), "my_crate_name.pdb"); } From 8a87f02138ad4dae9a57d71635f9be2bf5696202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 25 Jun 2024 20:46:13 +0200 Subject: [PATCH 076/217] Improve error message in tidy --- src/tools/tidy/src/ext_tool_checks.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 995ad58cb6219..26af51bd2d744 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -267,11 +267,10 @@ fn create_venv_at_path(path: &Path) -> Result<(), Error> { let stderr = String::from_utf8_lossy(&out.stderr); let err = if stderr.contains("No module named virtualenv") { - Error::Generic( + Error::Generic(format!( "virtualenv not found: you may need to install it \ - (`python3 -m pip install venv`)" - .to_owned(), - ) + (`{sys_py} -m pip install virtualenv`)" + )) } else { Error::Generic(format!( "failed to create venv at '{}' using {sys_py}: {stderr}", From 476b7bdbe5fec58075b38b783bb463e6e4dd257f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:13:12 +0000 Subject: [PATCH 077/217] Rustup to rustc 1.81.0-nightly (fda509e81 2024-06-25) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 36d98a869db1e..85d73cb414f17 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-18" +channel = "nightly-2024-06-26" components = ["rust-src", "rustc-dev", "llvm-tools"] From 94c2e7aad3ae5c8ac690ab9c173d68a1fe79d82c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:33:35 +0000 Subject: [PATCH 078/217] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 283889e9471c3..c1b7e4b0e0768 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -59,7 +59,6 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib -rm -r tests/run-make/issue-64153 rm -r tests/run-make/codegen-options-parsing rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 @@ -72,6 +71,9 @@ rm tests/ui/consts/precise-drop-with-coverage.rs rm tests/ui/issues/issue-85461.rs rm -r tests/ui/instrument-coverage/ +# missing f16/f128 support +rm tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs + # optimization tests # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations @@ -106,6 +108,7 @@ rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name rm -r tests/run-make/notify-all-emit-artifacts rm -r tests/run-make/reset-codegen-1 +rm -r tests/run-make/inline-always-many-cgu # giving different but possibly correct results # ============================================= @@ -124,6 +127,7 @@ rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contain # ============ rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort +rm tests/ui/deprecation/deprecated_inline_threshold.rs # missing deprecation warning for -Cinline-threshold # bugs in the test suite # ====================== From 2ffff791ce0d5d29a0e47d9c5519fcccdb696e9f Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 10:39:45 -0400 Subject: [PATCH 079/217] rewrite pretty-print-with-dep-file to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../pretty-print-with-dep-file/Makefile | 9 --------- .../pretty-print-with-dep-file/rmake.rs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/pretty-print-with-dep-file/Makefile create mode 100644 tests/run-make/pretty-print-with-dep-file/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index cb68589d8a4c2..2f64b6004fd52 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -134,7 +134,6 @@ run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/pretty-print-to-file/Makefile -run-make/pretty-print-with-dep-file/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile diff --git a/tests/run-make/pretty-print-with-dep-file/Makefile b/tests/run-make/pretty-print-with-dep-file/Makefile deleted file mode 100644 index fa8089eb6a552..0000000000000 --- a/tests/run-make/pretty-print-with-dep-file/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --emit=dep-info -Zunpretty=expanded with-dep.rs - $(CGREP) "with-dep.rs" < $(TMPDIR)/with-dep.d - -rm $(TMPDIR)/with-dep.d - - $(RUSTC) --emit=dep-info -Zunpretty=normal with-dep.rs - ! test -f $(TMPDIR)/with-dep.d diff --git a/tests/run-make/pretty-print-with-dep-file/rmake.rs b/tests/run-make/pretty-print-with-dep-file/rmake.rs new file mode 100644 index 0000000000000..859a9781bb6e6 --- /dev/null +++ b/tests/run-make/pretty-print-with-dep-file/rmake.rs @@ -0,0 +1,17 @@ +// Passing --emit=dep-info to the Rust compiler should create a .d file... +// but it failed to do so in Rust 1.69.0 when combined with -Z unpretty=expanded +// due to a bug. This test checks that -Z unpretty=expanded does not prevent the +// generation of the dep-info file, and that its -Z unpretty=normal counterpart +// does not get an unexpected dep-info file. +// See https://github.com/rust-lang/rust/issues/112898 + +use run_make_support::{fs_wrapper, invalid_utf8_contains, rustc}; +use std::path::Path; + +fn main() { + rustc().emit("dep-info").arg("-Zunpretty=expanded").input("with-dep.rs").run(); + invalid_utf8_contains("with-dep.d", "with-dep.rs"); + fs_wrapper::remove_file("with-dep.d"); + rustc().emit("dep-info").arg("-Zunpretty=normal").input("with-dep.rs").run(); + assert!(!Path::new("with-dep.d").exists()); +} From 722ae2243ece024797c006d1812c6abd3158f720 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 11:44:11 -0400 Subject: [PATCH 080/217] rewrite pretty-print-to-file to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 2 -- tests/run-make/pretty-print-to-file/Makefile | 5 ----- tests/run-make/pretty-print-to-file/rmake.rs | 12 ++++++++++++ 3 files changed, 12 insertions(+), 7 deletions(-) delete mode 100644 tests/run-make/pretty-print-to-file/Makefile create mode 100644 tests/run-make/pretty-print-to-file/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2f64b6004fd52..fa754d2e6d543 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -84,7 +84,6 @@ run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile run-make/libtest-json/Makefile run-make/libtest-junit/Makefile -run-make/libtest-padding/Makefile run-make/libtest-thread-limit/Makefile run-make/link-cfg/Makefile run-make/link-framework/Makefile @@ -133,7 +132,6 @@ run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile -run-make/pretty-print-to-file/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile diff --git a/tests/run-make/pretty-print-to-file/Makefile b/tests/run-make/pretty-print-to-file/Makefile deleted file mode 100644 index ca11b8c47f06f..0000000000000 --- a/tests/run-make/pretty-print-to-file/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) -o $(TMPDIR)/input.out -Zunpretty=normal input.rs - diff -u $(TMPDIR)/input.out input.pp diff --git a/tests/run-make/pretty-print-to-file/rmake.rs b/tests/run-make/pretty-print-to-file/rmake.rs new file mode 100644 index 0000000000000..c23514ae84960 --- /dev/null +++ b/tests/run-make/pretty-print-to-file/rmake.rs @@ -0,0 +1,12 @@ +// The "pretty-printer" of rustc translates source code into other formats, +// which is useful for debugging. This test checks the "normal" version of +// -Zunpretty, which should format the poorly formatted input.rs into a one-line +// function identical to the one in input.pp. +// See https://github.com/rust-lang/rust/commit/da25539c1ab295ec40261109557dd4526923928c + +use run_make_support::{diff, rustc}; + +fn main() { + rustc().output("input.out").arg("-Zunpretty=normal").input("input.rs").run(); + diff().expected_file("input.out").actual_file("input.pp").run(); +} From 53109d5d6e284da313617be95e31ff4152d317f0 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 11:44:23 -0400 Subject: [PATCH 081/217] rewrite libtest-padding to rmake --- tests/run-make/libtest-padding/Makefile | 14 -------- tests/run-make/libtest-padding/rmake.rs | 46 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/libtest-padding/Makefile create mode 100644 tests/run-make/libtest-padding/rmake.rs diff --git a/tests/run-make/libtest-padding/Makefile b/tests/run-make/libtest-padding/Makefile deleted file mode 100644 index c8e2fc01f677d..0000000000000 --- a/tests/run-make/libtest-padding/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# ignore-cross-compile because we run the compiled code -# needs-unwind because #[bench] and -Cpanic=abort requires -Zpanic-abort-tests -include ../tools.mk - -NORMALIZE=sed 's%[0-9,\.]\{1,\} ns/iter (+/- [0-9,\.]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%' - -all: - $(RUSTC) --test tests.rs - - $(call RUN,tests) --test-threads=1 | $(NORMALIZE) > "$(TMPDIR)"/test.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/test.stdout test.stdout - - $(call RUN,tests) --test-threads=1 --bench | $(NORMALIZE) > "$(TMPDIR)"/bench.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/bench.stdout bench.stdout diff --git a/tests/run-make/libtest-padding/rmake.rs b/tests/run-make/libtest-padding/rmake.rs new file mode 100644 index 0000000000000..4b17ba19bf7da --- /dev/null +++ b/tests/run-make/libtest-padding/rmake.rs @@ -0,0 +1,46 @@ +// Benchmarks, when ran as tests, would cause strange indentations +// to appear in the output. This was because padding formatting was +// applied before the conversion from bench to test, and not afterwards. +// Now that this bug has been fixed in #118548, this test checks that it +// does not make a resurgence by comparing the output of --bench with an +// example stdout file. +// See https://github.com/rust-lang/rust/issues/104092 + +//@ ignore-cross-compile +// Reason: the compiled code is ran +//@ needs-unwind +// Reason: #[bench] requires -Z panic-abort-tests + +use run_make_support::{diff, run_with_args, rustc}; + +fn main() { + rustc().arg("--test").input("tests.rs").run(); + let out = run_with_args("tests", &["--test-threads=1"]).stdout_utf8(); + diff() + .expected_file("test.stdout") + .actual_text("actual-test-stdout", out) + .normalize( + // Replace all instances of (arbitrary numbers) + // [1.2345 ns/iter (+/- 0.1234)] + // with + // [?? ns/iter (+/- ??)] + r#"(\d+(?:[.,]\d+)*)\s*ns/iter\s*\(\+/-\s*(\d+(?:[.,]\d+)*)\)"#, + "?? ns/iter (+/- ??)", + ) + // Replace all instances of (arbitrary numbers) + // finished in 8.0000 s + // with + // finished in ?? + .normalize(r#"finished\s+in\s+(\d+(?:\.\d+)*)"#, "finished in ??") + .run(); + let out = run_with_args("tests", &["--test-threads=1", "--bench"]).stdout_utf8(); + diff() + .expected_file("bench.stdout") + .actual_text("actual-bench-stdout", out) + .normalize( + r#"(\d+(?:[.,]\d+)*)\s*ns/iter\s*\(\+/-\s*(\d+(?:[.,]\d+)*)\)"#, + "?? ns/iter (+/- ??)", + ) + .normalize(r#"finished\s+in\s+(\d+(?:\.\d+)*)"#, "finished in ??") + .run(); +} From 81695a147aa1f88c34ec4ae1f0bffe429981c442 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:05:58 +0000 Subject: [PATCH 082/217] Split lifetimes on mir borrowck dataflow --- compiler/rustc_borrowck/src/dataflow.rs | 40 +++++++------- compiler/rustc_borrowck/src/lib.rs | 38 ++++++------- compiler/rustc_borrowck/src/nll.rs | 2 +- .../src/type_check/liveness/mod.rs | 2 +- .../src/type_check/liveness/trace.rs | 16 +++--- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- .../src/impls/initialized.rs | 54 +++++++++++-------- .../src/elaborate_drops.rs | 26 ++++----- 8 files changed, 94 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index f2b5ddcd7827c..00a30dc2240a6 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -15,24 +15,24 @@ use std::fmt; use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; /// The results of the dataflow analyses used by the borrow checker. -pub struct BorrowckResults<'mir, 'tcx> { - pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>, - pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, - pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>, +pub struct BorrowckResults<'a, 'mir, 'tcx> { + pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>, + pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, + pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>, } /// The transient state of the dataflow analyses used by the borrow checker. #[derive(Debug)] -pub struct BorrowckFlowState<'mir, 'tcx> { - pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, - pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, - pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, +pub struct BorrowckFlowState<'a, 'mir, 'tcx> { + pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, + pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, + pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, } -impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> { +impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> { // All three analyses are forward, but we have to use just one here. - type Direction = as AnalysisDomain<'tcx>>::Direction; - type FlowState = BorrowckFlowState<'mir, 'tcx>; + type Direction = as AnalysisDomain<'tcx>>::Direction; + type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>; fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState { BorrowckFlowState { @@ -106,11 +106,11 @@ rustc_index::newtype_index! { /// `BorrowIndex`, and maps each such index to a `BorrowData` /// describing the borrow. These indexes are used for representing the /// borrows in compact bitvectors. -pub struct Borrows<'mir, 'tcx> { +pub struct Borrows<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - borrow_set: &'mir BorrowSet<'tcx>, + borrow_set: &'a BorrowSet<'tcx>, borrows_out_of_scope_at_location: FxIndexMap>, } @@ -389,12 +389,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> { } } -impl<'mir, 'tcx> Borrows<'mir, 'tcx> { +impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - regioncx: &'mir RegionInferenceContext<'tcx>, - borrow_set: &'mir BorrowSet<'tcx>, + regioncx: &RegionInferenceContext<'tcx>, + borrow_set: &'a BorrowSet<'tcx>, ) -> Self { let mut borrows_out_of_scope_at_location = calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set); @@ -494,7 +494,7 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> { } } -impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { +impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> { type Domain = BitSet; const NAME: &'static str = "borrows"; @@ -517,7 +517,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { /// region stops containing the CFG points reachable from the issuing location. /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// `a.b.c` when `a` is overwritten. -impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { +impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> { type Idx = BorrowIndex; fn domain_size(&self, _: &mir::Body<'tcx>) -> usize { @@ -617,8 +617,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { } } -impl DebugWithContext> for BorrowIndex { - fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl DebugWithContext> for BorrowIndex { + fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", ctxt.location(*self)) } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 69efee2fbdc14..0bdae081b94f1 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -605,15 +605,15 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { // 2. loans made in overlapping scopes do not conflict // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> - for MirBorrowckCtxt<'_, 'mir, '_, 'tcx> +impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> + for MirBorrowckCtxt<'a, 'mir, '_, 'tcx> { - type FlowState = Flows<'mir, 'tcx>; + type FlowState = Flows<'a, 'mir, 'tcx>; fn visit_statement_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, stmt: &'mir Statement<'tcx>, location: Location, ) { @@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> fn visit_terminator_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, term: &'mir Terminator<'tcx>, loc: Location, ) { @@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> fn visit_terminator_after_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, term: &'mir Terminator<'tcx>, loc: Location, ) { @@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let (sd, rw) = kind; @@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) -> bool { let mut error_reported = false; let borrow_set = Rc::clone(&self.borrow_set); @@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, place_span: (Place<'tcx>, Span), kind: AccessDepth, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // Write of P[i] or *P requires P init'd. self.check_if_assigned_path_is_moved(location, place_span, flow_state); @@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (rvalue, span): (&'mir Rvalue<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { match rvalue { &Rvalue::Ref(_ /*rgn*/, bk, place) => { @@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (operand, span): (&'mir Operand<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { match *operand { Operand::Copy(place) => { @@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, span: Span, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // Two-phase borrow support: For each activation that is newly // generated at this statement, check if it interferes with @@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (place, span): (Place<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); @@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, base: PlaceRef<'tcx>, span: Span, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // rust-lang/rust#21232: Until Rust allows reads from the // initialized parts of partially initialized structs, we @@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, location: Location, ) -> bool { debug!( @@ -2220,7 +2220,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { fn is_local_ever_initialized( &self, local: Local, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) -> Option { let mpi = self.move_data.rev_lookup.find_local(local)?; let ii = &self.move_data.init_path_map[mpi]; @@ -2228,7 +2228,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { } /// Adds the place into the used mutable variables set - fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) { + fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) { match root_place { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 923cf7e940573..4ab06d9c4d09e 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -81,7 +81,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( promoted: &IndexSlice>, location_table: &LocationTable, param_env: ty::ParamEnv<'tcx>, - flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>, + flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'_, 'cx, 'tcx>>, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, upvars: &[&ty::CapturedPlace<'tcx>], diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index b777e01f7a6c2..6d6425b5f19f0 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -34,7 +34,7 @@ pub(super) fn generate<'mir, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &Rc, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, ) { debug!("liveness::generate"); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 359c4ea0eb1e2..eb86c8d06f113 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &Rc, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, relevant_live_locals: Vec, boring_locals: Vec, @@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>( } /// Contextual state for the type-liveness coroutine. -struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { +struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> { /// Current type-checker, giving us our inference context etc. typeck: &'me mut TypeChecker<'typeck, 'tcx>, @@ -119,7 +119,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { /// Results of dataflow tracking which variables (and paths) have been /// initialized. - flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>, + flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>, /// Index indicating where each variable is assigned, used, or /// dropped. @@ -131,8 +131,8 @@ struct DropData<'tcx> { region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>, } -struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { - cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>, +struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { + cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>, /// Set of points that define the current local. defs: BitSet, @@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { stack: Vec, } -impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { - fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self { +impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { + fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self { let num_points = cx.elements.num_points(); LivenessResults { cx, @@ -507,7 +507,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { } } -impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { +impl<'tcx> LivenessContext<'_, '_, '_, '_, 'tcx> { /// Returns `true` if the local variable (or some part of it) is initialized at the current /// cursor position. Callers should call one of the `seek` methods immediately before to point /// the cursor to the desired location. diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 81bde14a82f4e..aa25e3adf28af 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>( location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, all_facts: &mut Option, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, elements: &Rc, upvars: &[&ty::CapturedPlace<'tcx>], diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index f0b79dab0c974..ffcf630b653cd 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -50,15 +50,19 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable}; /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeUninitializedPlaces` yields the set of /// places that would require a dynamic drop-flag at that statement. -pub struct MaybeInitializedPlaces<'a, 'tcx> { +pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, skip_unreachable_unwind: bool, } -impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + body: &'mir Body<'tcx>, + mdpe: &'a MoveDataParamEnv<'tcx>, + ) -> Self { MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false } } @@ -84,7 +88,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { +impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } @@ -125,17 +129,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeInitializedPlaces` yields the set of /// places that would require a dynamic drop-flag at that statement. -pub struct MaybeUninitializedPlaces<'a, 'tcx> { +pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, mark_inactive_variants_as_uninit: bool, skip_unreachable_unwind: BitSet, } -impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + body: &'mir Body<'tcx>, + mdpe: &'a MoveDataParamEnv<'tcx>, + ) -> Self { MaybeUninitializedPlaces { tcx, body, @@ -164,7 +172,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } @@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { /// c = S; // {a, b, c, d } /// } /// ``` -pub struct EverInitializedPlaces<'a, 'tcx> { - body: &'a Body<'tcx>, +pub struct EverInitializedPlaces<'a, 'mir, 'tcx> { + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, } -impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> { + pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { EverInitializedPlaces { body, mdpe } } } -impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } } -impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { +impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { fn update_bits( trans: &mut impl GenKill, path: MovePathIndex, @@ -280,7 +288,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> { fn update_bits( trans: &mut impl GenKill, path: MovePathIndex, @@ -306,7 +314,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = MaybeReachable>; @@ -328,7 +336,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { type Idx = MovePathIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { @@ -441,7 +449,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -465,7 +473,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { type Idx = MovePathIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { @@ -642,7 +650,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { /// There can be many more `InitIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -661,7 +669,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { type Idx = InitIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 665b2260294a3..fbbb8c5e47245 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -97,7 +97,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { #[instrument(level = "trace", skip(body, flow_inits), ret)] fn compute_dead_unwinds<'mir, 'tcx>( body: &'mir Body<'tcx>, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, ) -> BitSet { // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. @@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>( dead_unwinds } -struct InitializationData<'mir, 'tcx> { - inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, - uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, +struct InitializationData<'a, 'mir, 'tcx> { + inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>, + uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, } -impl InitializationData<'_, '_> { +impl InitializationData<'_, '_, '_> { fn seek_before(&mut self, loc: Location) { self.inits.seek_before_primary_effect(loc); self.uninits.seek_before_primary_effect(loc); @@ -134,17 +134,17 @@ impl InitializationData<'_, '_> { } } -struct Elaborator<'a, 'b, 'tcx> { - ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>, +struct Elaborator<'a, 'b, 'mir, 'tcx> { + ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>, } -impl fmt::Debug for Elaborator<'_, '_, '_> { +impl fmt::Debug for Elaborator<'_, '_, '_, '_> { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } -impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { +impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> { type Path = MovePathIndex; fn patch(&mut self) -> &mut MirPatch<'tcx> { @@ -238,16 +238,16 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { } } -struct ElaborateDropsCtxt<'a, 'tcx> { +struct ElaborateDropsCtxt<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, env: &'a MoveDataParamEnv<'tcx>, - init_data: InitializationData<'a, 'tcx>, + init_data: InitializationData<'a, 'mir, 'tcx>, drop_flags: IndexVec>, patch: MirPatch<'tcx>, } -impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { +impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> { fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data } From ef559199efc3f9d411353140f46fdcec4f0bab04 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:06:34 +0000 Subject: [PATCH 083/217] Restrict diagnostic context lifetime of mir borrowck to InferCtxt instead of TyCtxt --- .../rustc_borrowck/src/borrowck_errors.rs | 50 +++++++++---------- .../src/diagnostics/conflict_errors.rs | 24 ++++----- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 6 +-- .../src/diagnostics/mutability_errors.rs | 10 ++-- .../src/diagnostics/region_errors.rs | 8 +-- compiler/rustc_borrowck/src/lib.rs | 38 +++++++------- compiler/rustc_borrowck/src/nll.rs | 10 ++-- 8 files changed, 75 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index f26f8711dd40b..604feeb47feaf 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,8 +6,8 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { +impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'cx> { self.infcx.dcx() } @@ -18,7 +18,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { place: &str, borrow_place: &str, value_place: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { self.dcx().create_err(crate::session_diagnostics::MoveBorrow { place, span, @@ -34,7 +34,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -54,7 +54,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -101,7 +101,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -134,7 +134,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -166,7 +166,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -198,7 +198,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -239,7 +239,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -256,12 +256,12 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } - pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'tcx> { + pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } @@ -269,7 +269,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -287,7 +287,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let type_name = match (&ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -308,7 +308,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -325,7 +325,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); struct_span_code_err!( @@ -344,7 +344,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, path: &str, reason: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -362,7 +362,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), mutate_span, @@ -380,7 +380,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, span: Span, yield_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; struct_span_code_err!( self.dcx(), @@ -391,7 +391,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { .with_span_label(yield_span, "possible yield occurs here") } - pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'tcx> { + pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'cx> { struct_span_code_err!( self.dcx(), borrow_span, @@ -400,7 +400,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { ) } - pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'tcx> { + pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) } @@ -410,7 +410,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -433,7 +433,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { borrowed_path: &str, capture_span: Span, scope: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), closure_span, @@ -445,7 +445,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } - pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'tcx> { + pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -454,7 +454,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { ) } - pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'tcx> { + pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1cc7fee718e87..74ebfc54182b6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -341,7 +341,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn suggest_ref_or_clone( &self, mpi: MovePathIndex, - err: &mut Diag<'tcx>, + err: &mut Diag<'cx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, ) { @@ -517,7 +517,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { // We need all statements in the body where the binding was assigned to later find all // the branching code paths where the binding *wasn't* assigned to. let inits = &self.move_data.init_path_map[mpi]; @@ -1441,7 +1441,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -1491,7 +1491,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -1782,7 +1782,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { err } - fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'tcx>, place: Place<'tcx>) { + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'cx>, place: Place<'tcx>) { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; @@ -2841,7 +2841,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -3016,7 +3016,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, drop_span: Span, borrow_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -3041,7 +3041,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { @@ -3206,7 +3206,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'cx>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -3299,7 +3299,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { constraint_span: Span, captured_var: &str, scope: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -3411,7 +3411,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { upvar_span: Span, upvar_name: Symbol, escape_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 842ed38f1e294..3bc7083976e44 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -86,7 +86,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, location: Location, place: PlaceRef<'tcx>, - diag: &mut Diag<'_>, + diag: &mut Diag<'cx>, ) -> bool { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); let mut target = place.local_or_deref_local(); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 12fa4c4f5ee05..40a6a65649a35 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { @@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { self.buffer_error(err); } - fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'tcx> { + fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'cx> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -428,7 +428,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 93fac3181ba4b..6d92f0cdd988a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, @@ -541,7 +541,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { } /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. - fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'tcx>, span: Span) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'cx>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) @@ -550,13 +550,13 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Walks through the HIR, looking for the corresponding span for this error. /// When it finds it, see if it corresponds to assignment operator whose LHS /// is an index expr. - struct SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { + struct SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { assign_span: Span, - err: &'a mut Diag<'tcx>, + err: &'a mut Diag<'cx>, ty: Ty<'tcx>, suggested: bool, } - impl<'a, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { + impl<'a, 'cx, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { hir::intravisit::walk_stmt(self, stmt); let expr = match stmt.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index db78edc45b9de..bb3542287d5e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is @@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -658,7 +658,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` #[instrument(level = "debug", skip(self))] - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -767,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// | is returning data with lifetime `'b` /// ``` #[allow(rustc::diagnostic_outside_of_impl)] // FIXME - fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { let ErrorConstraintInfo { fr, fr_is_local, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0bdae081b94f1..8aea8ae188898 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: diags::BorrowckDiags<'tcx>, + diags: diags::BorrowckDiags<'cx, 'tcx>, move_errors: Vec>, } @@ -2428,12 +2428,12 @@ mod diags { use super::*; - enum BufferedDiag<'tcx> { - Error(Diag<'tcx>), - NonError(Diag<'tcx, ()>), + enum BufferedDiag<'cx> { + Error(Diag<'cx>), + NonError(Diag<'cx, ()>), } - impl<'tcx> BufferedDiag<'tcx> { + impl<'cx> BufferedDiag<'cx> { fn sort_span(&self) -> Span { match self { BufferedDiag::Error(diag) => diag.sort_span, @@ -2442,7 +2442,7 @@ mod diags { } } - pub struct BorrowckDiags<'tcx> { + pub struct BorrowckDiags<'cx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -2457,15 +2457,15 @@ mod diags { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'tcx>)>, + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'cx>)>, - buffered_mut_errors: FxIndexMap, usize)>, + buffered_mut_errors: FxIndexMap, usize)>, /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, + buffered_diags: Vec>, } - impl<'tcx> BorrowckDiags<'tcx> { + impl<'cx, 'tcx> BorrowckDiags<'cx, 'tcx> { pub fn new() -> Self { BorrowckDiags { buffered_move_errors: BTreeMap::new(), @@ -2474,28 +2474,28 @@ mod diags { } } - pub fn buffer_error(&mut self, diag: Diag<'tcx>) { + pub fn buffer_error(&mut self, diag: Diag<'cx>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } } - impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { - pub fn buffer_error(&mut self, diag: Diag<'tcx>) { + impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { + pub fn buffer_error(&mut self, diag: Diag<'cx>) { self.diags.buffer_error(diag); } - pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { self.diags.buffer_non_error(diag); } pub fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'tcx>), + place_and_err: (PlaceRef<'tcx>, Diag<'cx>), ) -> bool { if let Some((_, diag)) = self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -2508,12 +2508,12 @@ mod diags { } } - pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'tcx>, usize)> { + pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'cx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags.buffered_mut_errors.swap_remove(&span) } - pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'tcx>, count: usize) { + pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'cx>, count: usize) { self.diags.buffered_mut_errors.insert(span, (diag, count)); } @@ -2554,7 +2554,7 @@ mod diags { pub fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'tcx>)> { + ) -> Option<&(PlaceRef<'tcx>, Diag<'cx>)> { self.diags.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 4ab06d9c4d09e..2ffa9ba5b4d32 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -262,13 +262,13 @@ pub(super) fn dump_mir_results<'tcx>( #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] -pub(super) fn dump_annotation<'tcx>( - infcx: &BorrowckInferCtxt<'tcx>, +pub(super) fn dump_annotation<'tcx, 'cx>( + infcx: &'cx BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut crate::diags::BorrowckDiags<'tcx>, + diags: &mut crate::diags::BorrowckDiags<'cx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); @@ -285,7 +285,7 @@ pub(super) fn dump_annotation<'tcx>( let def_span = tcx.def_span(body.source.def_id()); let mut err = if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx.dcx().struct_span_note(def_span, "external requirements"); + let mut err = infcx.dcx().struct_span_note(def_span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -304,7 +304,7 @@ pub(super) fn dump_annotation<'tcx>( err } else { - let mut err = tcx.dcx().struct_span_note(def_span, "no external requirements"); + let mut err = infcx.dcx().struct_span_note(def_span, "no external requirements"); regioncx.annotate(tcx, &mut err); err From f3d9523a2e0d9c2a60e713decd32a59c347e113f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:10:04 +0000 Subject: [PATCH 084/217] Restrict diagnostic context lifetime of FnCtxt to InferCtxt instead of TyCtxt --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 4 ++-- compiler/rustc_infer/src/infer/mod.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c0d604779677b..ad8eb7c30826c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> { self.infcx.dcx() } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index aaf3d3ec34d01..208930208ed83 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1881,7 +1881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &Pat<'_>, fields: &'tcx [hir::PatField<'tcx>], - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = self .dcx() .struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields"); @@ -1973,7 +1973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unmentioned_fields: &[(&ty::FieldDef, Ident)], have_inaccessible_fields: bool, fields: &'tcx [hir::PatField<'tcx>], - ) -> Diag<'tcx> { + ) -> Diag<'a> { let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; let field_names = if let [(_, field)] = unmentioned_fields { format!("field `{field}`{inaccessible}") diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index a3cf588da1c02..78d42942de47c 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1607,7 +1607,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // [Note-Type-error-reporting] // An invariant is that anytime the expected or actual type is Error (the special // error type, meaning that an error occurred when typechecking this expression), @@ -1623,9 +1623,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { sp: Span, mk_diag: M, actual_ty: Ty<'tcx>, - ) -> Diag<'tcx> + ) -> Diag<'a> where - M: FnOnce(String) -> Diag<'tcx>, + M: FnOnce(String) -> Diag<'a>, { let actual_ty = self.resolve_vars_if_possible(actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); From 79ac8982ca24e25b592b06ef636050f5a5a81bde Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:14:35 +0000 Subject: [PATCH 085/217] Restrict diagnostic context lifetime of TypeErrCtxt to InferCtxt instead of TyCtxt --- .../src/infer/error_reporting/mod.rs | 2 +- .../infer/error_reporting/need_type_info.rs | 4 ++-- .../src/infer/error_reporting/note.rs | 6 +++--- .../src/traits/error_reporting/suggestions.rs | 10 +++++----- .../error_reporting/type_err_ctxt_ext.rs | 18 +++++++++--------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 227691d099434..503d3424e7481 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -139,7 +139,7 @@ pub struct TypeErrCtxt<'a, 'tcx> { } impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'a> { self.infcx.dcx() } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index d7349abc44c24..ba5e3ae8a930c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self, error_code))] pub fn emit_inference_failure_err( &self, @@ -445,7 +445,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let arg = self.resolve_vars_if_possible(arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 8fd19563c3057..e37b0b83f4d00 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -14,7 +14,7 @@ use rustc_span::symbol::kw; use super::ObligationCauseAsDiagArg; -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { match *origin { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { @@ -79,7 +79,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); @@ -378,7 +378,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { // I can't think how to do better than this right now. -nikomatsakis debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); match placeholder_origin { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f4a026c0367f4..5753ac91709a4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -241,8 +241,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( } } -#[extension(pub trait TypeErrCtxtExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn suggest_restricting_param_bound( &self, err: &mut Diag<'_>, @@ -1845,7 +1845,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, obligation: &PredicateObligation<'tcx>, ) { match obligation.cause.code().peel_derives() { @@ -1884,7 +1884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCauseCode<'tcx>, found_node: Option>, param_env: ty::ParamEnv<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { pub(crate) fn build_fn_sig_ty<'tcx>( infcx: &InferCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, @@ -2104,7 +2104,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn note_conflicting_closure_bounds( &self, cause: &ObligationCauseCode<'tcx>, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, ) { // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index d3096cf4b52ce..cccb78bec9d39 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -82,8 +82,8 @@ pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>( )); } -#[extension(pub trait TypeErrCtxtExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn report_fulfillment_errors( &self, mut errors: Vec>, @@ -228,7 +228,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: OverflowCause<'tcx>, span: Span, suggest_increasing_limit: bool, - ) -> Diag<'tcx> { + ) -> Diag<'a> { fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String where T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, @@ -1351,7 +1351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let span = obligation.cause.span; let mut diag = match ty.kind() { @@ -1445,8 +1445,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } -#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub(super) trait InferCtxtPrivExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn can_match_trait( &self, goal: ty::TraitPredicate<'tcx>, @@ -3379,7 +3379,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found_kind: ty::ClosureKind, kind: ty::ClosureKind, trait_prefix: &'static str, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let closure_span = self.tcx.def_span(closure_def_id); let mut err = ClosureKindMismatch { @@ -3473,7 +3473,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span: Span, found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, ErrorGuaranteed> { let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); @@ -3569,7 +3569,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, span: Span, - ) -> Result, ErrorGuaranteed> { + ) -> Result, ErrorGuaranteed> { if !self.tcx.features().generic_const_exprs { let guar = self .dcx() From 5988078aa20bf642bc1bbab15a45ac5cb74e77e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 26 Jun 2024 10:52:57 +0000 Subject: [PATCH 086/217] Restrict diagnostic context lifetime of InferCtxt to itself instead of TyCtxt --- .../src/diagnostics/bound_region_errors.rs | 69 ++++++++++++------- compiler/rustc_errors/src/diagnostic.rs | 5 ++ compiler/rustc_hir_typeck/src/coercion.rs | 6 +- compiler/rustc_hir_typeck/src/demand.rs | 20 +++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +- .../src/infer/error_reporting/mod.rs | 4 +- .../infer/error_reporting/need_type_info.rs | 6 +- compiler/rustc_infer/src/infer/mod.rs | 6 +- .../traits/error_reporting/infer_ctxt_ext.rs | 2 +- .../error_reporting/type_err_ctxt_ext.rs | 4 +- 12 files changed, 79 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index d46febffba862..c4275e1393509 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; #[instrument(level = "debug", skip(self, mbcx))] fn report_error( @@ -231,18 +231,25 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_prove_predicate_with_cause(&ocx, key, cause); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -268,13 +275,13 @@ where self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -288,7 +295,14 @@ where let (param_env, value) = key.into_parts(); let _ = ocx.normalize(&cause, param_env, value.value); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -308,18 +322,25 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -334,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), @@ -358,12 +379,12 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { } #[instrument(skip(ocx), level = "debug")] -fn try_extract_error_from_fulfill_cx<'tcx>( - ocx: &ObligationCtxt<'_, 'tcx>, +fn try_extract_error_from_fulfill_cx<'a, 'tcx>( + ocx: &ObligationCtxt<'a, 'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, -) -> Option> { +) -> Option> { // We generally shouldn't have errors here because the query was // already run, but there's no point using `span_delayed_bug` // when we're going to emit an error here anyway. @@ -381,15 +402,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>( } #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] -fn try_extract_error_from_region_constraints<'tcx>( - infcx: &InferCtxt<'tcx>, +fn try_extract_error_from_region_constraints<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, -) -> Option> { +) -> Option> { let placeholder_universe = match placeholder_region.kind() { ty::RePlaceholder(p) => p.universe, ty::ReVar(vid) => universe_of_region(vid), diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index e580910af7799..0231665b64cf5 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -582,6 +582,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { Self::new_diagnostic(dcx, DiagInner::new(level, message)) } + /// Allow moving diagnostics between different error tainting contexts + pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> { + Diag { dcx, diag: self.diag.take(), _marker: PhantomData } + } + /// Creates a new `Diag` with an already constructed diagnostic. #[track_caller] pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 0551b9bc1f0b4..f055a77696180 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); } - fn report_return_mismatched_types<'a>( + fn report_return_mismatched_types<'cx>( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, ty_err: TypeError<'tcx>, - fcx: &FnCtxt<'a, 'tcx>, + fcx: &'cx FnCtxt<'_, 'tcx>, block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, - ) -> Diag<'a> { + ) -> Diag<'cx> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index f9720c9c30795..ad9c1e2821172 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -172,21 +172,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_suptype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_suptype_with_origin(&self.misc(sp), expected, actual) } #[instrument(skip(self), level = "debug")] pub fn demand_suptype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .sup(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -200,20 +200,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_eqtype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } pub fn demand_eqtype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .eq(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -247,13 +247,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// will be permitted if the diverges flag is currently "always". #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))] pub fn demand_coerce_diag( - &self, + &'a self, mut expr: &'tcx hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, - ) -> Result, Diag<'tcx>> { + ) -> Result, Diag<'a>> { let expected = self.resolve_vars_with_obligations(expected); let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 1138642c56d61..75664824477e3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1424,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, provided_ty: Ty<'tcx>, arg: &hir::Expr<'tcx>, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, ) { if let ty::RawPtr(_, hir::Mutability::Mut) = expected_ty.kind() && let ty::RawPtr(_, hir::Mutability::Not) = provided_ty.kind() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index ad8eb7c30826c..f0131b3225cc9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> { - self.infcx.dcx() + self.root_ctxt.infcx.dcx() } pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 208930208ed83..8dde3032ca471 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -89,7 +89,7 @@ struct PatInfo<'tcx, 'a> { current_depth: u32, } -impl<'tcx> FnCtxt<'_, 'tcx> { +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { let code = ObligationCauseCode::Pattern { span: ti.span, @@ -100,12 +100,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } fn demand_eqtype_pat_diag( - &self, + &'a self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, ti: &TopInfo<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) .map_err(|mut diag| { if let Some(expr) = ti.origin_expr { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 503d3424e7481..d321bc265bc93 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn report_region_errors( &self, generic_param_scope: LocalDefId, @@ -2206,7 +2206,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, trace: TypeTrace<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); let span = trace.cause.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index ba5e3ae8a930c..084aebc296f86 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> { span: Span, arg_data: InferenceDiagnosticsData, error_code: TypeAnnotationNeeded, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let source_kind = "other"; let source_name = ""; let failure_span = None; @@ -453,7 +453,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // If we don't have any typeck results we're outside // of a body, so we won't be able to get better info // here. - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); @@ -465,7 +465,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let (source_kind, name, path) = kind.ty_localized_msg(self); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 78d42942de47c..10471e8bbdd71 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -684,7 +684,7 @@ impl<'tcx> InferOk<'tcx, ()> { } impl<'tcx> InferCtxt<'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'_> { self.tcx.dcx() } @@ -1646,7 +1646,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) } @@ -1656,7 +1656,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: ty::Const<'tcx>, actual: ty::Const<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 4b5b1d77b30da..34da8e576ce86 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> { found_args: Vec, is_closure: bool, closure_arg_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let kind = if is_closure { "closure" } else { "function" }; let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cccb78bec9d39..3ef3efc6252e9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3422,7 +3422,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let self_ty = found_trait_ref.self_ty(); let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { ( @@ -3553,7 +3553,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .unwrap_or((found_span, None, found)); - self.report_arg_count_mismatch( + self.infcx.report_arg_count_mismatch( span, closure_span, expected, From 86c8eae7745b47ada8305dcdac16b7f2dbdd68c9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 26 Jun 2024 16:01:38 +0000 Subject: [PATCH 087/217] Automatically taint InferCtxt when errors are emitted --- .../src/diagnostics/region_errors.rs | 2 +- .../src/region_infer/opaque_types.rs | 13 +- compiler/rustc_errors/src/diagnostic.rs | 2 +- compiler/rustc_errors/src/lib.rs | 61 ++++++--- compiler/rustc_hir_typeck/src/cast.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 14 +- compiler/rustc_hir_typeck/src/intrinsicck.rs | 6 +- .../rustc_hir_typeck/src/method/suggest.rs | 8 +- compiler/rustc_hir_typeck/src/pat.rs | 17 +-- .../src/infer/error_reporting/mod.rs | 21 +-- .../src/infer/error_reporting/note.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 19 +-- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 +- .../src/traits/error_reporting/mod.rs | 8 +- .../error_reporting/type_err_ctxt_ext.rs | 4 +- tests/ui/asm/x86_64/type-check-2.rs | 3 + tests/ui/asm/x86_64/type-check-2.stderr | 68 ++++++++-- .../associated-types-eq-expr-path.rs | 1 + .../associated-types-eq-expr-path.stderr | 20 ++- .../assoc_const_as_type_argument.rs | 1 + .../assoc_const_as_type_argument.stderr | 18 ++- .../const-arg-in-const-arg.min.stderr | 120 ++++++++++++------ .../const-generics/const-arg-in-const-arg.rs | 4 + .../generic_const_exprs/opaque_type.rs | 1 + .../generic_const_exprs/opaque_type.stderr | 14 +- .../issues/issue-62878.min.stderr | 30 ++++- tests/ui/const-generics/issues/issue-62878.rs | 2 + ...const-expression-suggest-missing-braces.rs | 1 + ...t-expression-suggest-missing-braces.stderr | 38 ++++-- .../min_const_generics/macro-fail.rs | 5 +- .../min_const_generics/macro-fail.stderr | 61 +++++++-- .../const-generics/suggest_const_for_array.rs | 10 +- .../suggest_const_for_array.stderr | 41 ++++-- .../generic-function-item-where-type.rs | 1 + .../generic-function-item-where-type.stderr | 11 +- .../impl-fn-predefined-lifetimes.rs | 1 + .../impl-fn-predefined-lifetimes.stderr | 14 +- .../impl-trait/transmute/in-defining-scope.rs | 1 + .../transmute/in-defining-scope.stderr | 14 +- tests/ui/infinite/infinite-struct.rs | 1 + tests/ui/infinite/infinite-struct.stderr | 17 ++- .../reference-of-mut-static-unsafe-fn.rs | 26 ---- .../reference-of-mut-static-unsafe-fn.stderr | 75 ----------- .../reference-of-mut-static.e2021.stderr | 91 ------------- .../reference-of-mut-static.e2024.stderr | 75 ----------- tests/ui/static/reference-of-mut-static.rs | 50 -------- .../reference-to-mut-static-safe.e2024.stderr | 13 +- .../ui/static/reference-to-mut-static-safe.rs | 2 +- .../reference-to-mut-static-unsafe-fn.rs | 28 ++-- .../reference-to-mut-static-unsafe-fn.stderr | 60 ++++----- .../hkl_forbidden4.stderr | 24 ++-- .../ui/type-alias-impl-trait/issue-53092-2.rs | 2 + .../issue-53092-2.stderr | 32 ++++- 56 files changed, 601 insertions(+), 570 deletions(-) delete mode 100644 tests/ui/static/reference-of-mut-static-unsafe-fn.rs delete mode 100644 tests/ui/static/reference-of-mut-static-unsafe-fn.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.e2021.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.e2024.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.rs diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index bb3542287d5e0..dd22f8d8440ee 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -360,7 +360,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { let named_key = self.regioncx.name_regions(self.infcx.tcx, key); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let diag = unexpected_hidden_region_diagnostic( - self.infcx.tcx, + self.infcx, self.mir_def_id(), span, named_ty, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 67e5c8352df0f..e195ceded1bf3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -285,7 +285,7 @@ impl<'tcx> InferCtxt<'tcx> { } if let Err(guar) = - check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span) + check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span) { return Ty::new_error(self.tcx, guar); } @@ -294,6 +294,10 @@ impl<'tcx> InferCtxt<'tcx> { .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; + if let Err(e) = definition_ty.error_reported() { + return Ty::new_error(self.tcx, e); + } + // `definition_ty` does not live in of the current inference context, // so lets make sure that we don't accidentally misuse our current `infcx`. match check_opaque_type_well_formed( @@ -387,10 +391,11 @@ fn check_opaque_type_well_formed<'tcx>( /// [rustc-dev-guide chapter]: /// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html fn check_opaque_type_parameter_valid<'tcx>( - tcx: TyCtxt<'tcx>, + infcx: &InferCtxt<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, ) -> Result<(), ErrorGuaranteed> { + let tcx = infcx.tcx; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); @@ -420,7 +425,7 @@ fn check_opaque_type_parameter_valid<'tcx>( opaque_env.param_is_error(i)?; - return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam { + return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { ty: arg, kind, span, @@ -438,7 +443,7 @@ fn check_opaque_type_parameter_valid<'tcx>( .collect(); #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] - return Err(tcx + return Err(infcx .dcx() .struct_span_err(span, "non-defining opaque type use in defining scope") .with_span_note(spans, format!("{descr} used multiple times")) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 0231665b64cf5..d500f6d88a01b 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -510,7 +510,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> { // would be bad. impl !Clone for Diag<'_, G> {} -rustc_data_structures::static_assert_size!(Diag<'_, ()>, 2 * std::mem::size_of::()); +rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * std::mem::size_of::()); impl Deref for Diag<'_, G> { type Target = DiagInner; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 91112a572770e..242684e63a082 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -63,6 +63,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::{Loc, Span, DUMMY_SP}; use std::backtrace::{Backtrace, BacktraceStatus}; use std::borrow::Cow; +use std::cell::Cell; use std::error::Report; use std::fmt; use std::hash::Hash; @@ -98,9 +99,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16); +rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24); #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16); +rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24); #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] pub enum SuggestionStyle { @@ -417,6 +418,7 @@ pub struct DiagCtxt { #[derive(Copy, Clone)] pub struct DiagCtxtHandle<'a> { dcx: &'a DiagCtxt, + tainted_with_errors: Option<&'a Cell>>, } impl<'a> std::ops::Deref for DiagCtxtHandle<'a> { @@ -752,7 +754,14 @@ impl DiagCtxt { } pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> { - DiagCtxtHandle { dcx: self } + DiagCtxtHandle { dcx: self, tainted_with_errors: None } + } + + pub fn taintable_handle<'a>( + &'a self, + tainted_with_errors: &'a Cell>, + ) -> DiagCtxtHandle<'a> { + DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) } } } @@ -795,7 +804,9 @@ impl<'a> DiagCtxtHandle<'a> { // can be used to create a backtrace at the stashing site insted of whenever the // diagnostic context is dropped and thus delayed bugs are emitted. Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))), - DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), + DelayedBug => { + return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors); + } ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow | Expect(_) => None, }; @@ -947,16 +958,19 @@ impl<'a> DiagCtxtHandle<'a> { (0, _) => { // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a // configuration like `--cap-lints allow --force-warn bare_trait_objects`. - inner.emit_diagnostic(DiagInner::new( - ForceWarning(None), - DiagMessage::Str(warnings), - )); + inner.emit_diagnostic( + DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)), + None, + ); } (_, 0) => { - inner.emit_diagnostic(DiagInner::new(Error, errors)); + inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors); } (_, _) => { - inner.emit_diagnostic(DiagInner::new(Error, format!("{errors}; {warnings}"))); + inner.emit_diagnostic( + DiagInner::new(Error, format!("{errors}; {warnings}")), + self.tainted_with_errors, + ); } } @@ -987,14 +1001,14 @@ impl<'a> DiagCtxtHandle<'a> { "For more information about an error, try `rustc --explain {}`.", &error_codes[0] ); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg1)); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg2)); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None); } else { let msg = format!( "For more information about this error, try `rustc --explain {}`.", &error_codes[0] ); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg)); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None); } } } @@ -1020,7 +1034,7 @@ impl<'a> DiagCtxtHandle<'a> { } pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option { - self.inner.borrow_mut().emit_diagnostic(diagnostic) + self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { @@ -1080,7 +1094,7 @@ impl<'a> DiagCtxtHandle<'a> { // Here the diagnostic is given back to `emit_diagnostic` where it was first // intercepted. Now it should be processed as usual, since the unstable expectation // id is now stable. - inner.emit_diagnostic(diag); + inner.emit_diagnostic(diag, self.tainted_with_errors); } } @@ -1430,13 +1444,17 @@ impl DiagCtxtInner { continue; } } - guar = guar.or(self.emit_diagnostic(diag)); + guar = guar.or(self.emit_diagnostic(diag, None)); } guar } // Return value is only `Some` if the level is `Error` or `DelayedBug`. - fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option { + fn emit_diagnostic( + &mut self, + mut diagnostic: DiagInner, + taint: Option<&Cell>>, + ) -> Option { match diagnostic.level { Expect(expect_id) | ForceWarning(Some(expect_id)) => { // The `LintExpectationId` can be stable or unstable depending on when it was @@ -1609,6 +1627,9 @@ impl DiagCtxtInner { if is_lint { self.lint_err_guars.push(guar); } else { + if let Some(taint) = taint { + taint.set(Some(guar)); + } self.err_guars.push(guar); } self.panic_if_treat_err_as_bug(); @@ -1718,8 +1739,8 @@ impl DiagCtxtInner { // `-Ztreat-err-as-bug`, which we don't want. let note1 = "no errors encountered even though delayed bugs were created"; let note2 = "those delayed bugs will now be shown as internal compiler errors"; - self.emit_diagnostic(DiagInner::new(Note, note1)); - self.emit_diagnostic(DiagInner::new(Note, note2)); + self.emit_diagnostic(DiagInner::new(Note, note1), None); + self.emit_diagnostic(DiagInner::new(Note, note2), None); for bug in bugs { if let Some(out) = &mut out { @@ -1752,7 +1773,7 @@ impl DiagCtxtInner { } bug.level = Bug; - self.emit_diagnostic(bug); + self.emit_diagnostic(bug, None); } // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f2d3254bb22..cb1a412d17eef 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else { errors::CannotCastToBoolHelp::Unsupported(self.span) }; - fcx.tcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help }); + fcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help }); } CastError::CastToChar => { let mut err = type_error_struct!( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f4e1e46195345..2fbc8a3f146a1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -638,7 +638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Set expectation to error in that case and set tainted // by error (#114529) let coerce_to = opt_coerce_to.unwrap_or_else(|| { - let guar = tcx.dcx().span_delayed_bug( + let guar = self.dcx().span_delayed_bug( expr.span, "illegal break with value found but no error reported", ); @@ -1716,7 +1716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { error_happened = true; let guar = if let Some(prev_span) = seen_fields.get(&ident) { - tcx.dcx().emit_err(FieldMultiplySpecifiedInInitializer { + self.dcx().emit_err(FieldMultiplySpecifiedInInitializer { span: field.ident.span, prev_span: *prev_span, ident, @@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if adt_kind == AdtKind::Union { if hir_fields.len() != 1 { struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0784, "union expressions should have exactly one field", diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 0ba4bd090f5e2..9a353bfe49d0e 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -170,7 +170,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { } fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error { - self.tcx.dcx().span_delayed_bug(span, msg.to_string()) + self.dcx().span_delayed_bug(span, msg.to_string()) } fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 061afd0306230..21269d9c0982b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1182,7 +1182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { name: self.tcx.item_name(def.did()).to_ident_string(), }); if ty.raw.has_param() { - let guar = self.tcx.dcx().emit_err(errors::SelfCtorFromOuterItem { + let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem { span: path_span, impl_span: tcx.def_span(impl_def_id), sugg, @@ -1207,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check the visibility of the ctor. let vis = tcx.visibility(ctor_def_id); if !vis.is_accessible_from(tcx.parent_module(hir_id).to_def_id(), tcx) { - tcx.dcx() + self.dcx() .emit_err(CtorIsPrivate { span, def: tcx.def_path_str(adt_def.did()) }); } let new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); @@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (new_res, Some(user_args.args)) } _ => { - let mut err = tcx.dcx().struct_span_err( + let mut err = self.dcx().struct_span_err( span, "the `Self` constructor can only be used with tuple or unit structs", ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 75664824477e3..430e12ff7b87b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages let guar = struct_span_code_err!( - tcx.dcx(), + self.dcx(), call_span, E0059, "cannot use call notation; the first type parameter \ @@ -453,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|vars| self.resolve_vars_if_possible(vars)), ); - self.set_tainted_by_errors(self.report_arg_errors( + self.report_arg_errors( compatibility_diagonal, formal_and_expected_inputs, provided_args, @@ -462,7 +462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_def_id, call_span, call_expr, - )); + ); } } @@ -788,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("arguments to this {call_name} are incorrect"), ); } else { - err = tcx.dcx().struct_span_err( + err = self.dcx().struct_span_err( full_call_span, format!( "{call_name} takes {}{} but {} {} supplied", @@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span_bug!(error_span, "expected errors from argument matrix"); } else { let mut err = - tcx.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span }); + self.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span }); suggest_confusable(&mut err); return err.emit(); } @@ -953,14 +953,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = if formal_and_expected_inputs.len() == provided_args.len() { struct_span_code_err!( - tcx.dcx(), + self.dcx(), full_call_span, E0308, "arguments to this {} are incorrect", call_name, ) } else { - tcx.dcx() + self.dcx() .struct_span_err( full_call_span, format!( diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 5eafc60a04eb8..0389c06c3123f 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Note: this path is currently not reached in any test, so any // example that triggers this would be worth minimizing and // converting into a test. - tcx.dcx().span_bug(span, "argument to transmute has inference variables"); + self.dcx().span_bug(span, "argument to transmute has inference variables"); } // Transmutes that are only changing lifetimes are always ok. if from == to { @@ -76,7 +76,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { - struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") + struct_span_code_err!(self.dcx(), span, E0591, "can't transmute zero-sized type") .with_note(format!("source type: {from}")) .with_note(format!("target type: {to}")) .with_help("cast with `as` to a pointer instead") @@ -116,7 +116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0512, "cannot transmute between types of different sizes, \ diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a385bc70e359b..e310730bf9e91 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -705,7 +705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_missing_writer(rcvr_ty, rcvr_expr) } else { - let mut err = tcx.dcx().create_err(NoAssociatedItem { + let mut err = self.dcx().create_err(NoAssociatedItem { span, item_kind, item_name, @@ -1194,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: item_span, .. })) => { - tcx.dcx().span_delayed_bug( + self.dcx().span_delayed_bug( *item_span, "auto trait is invoked with no method error, but no error reported?", ); @@ -2361,7 +2361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange { + return Err(self.dcx().emit_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2420,7 +2420,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let SelfSource::MethodCall(expr) = source { let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0689, "can't call {} `{}` on ambiguous numeric type `{}`", diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 8dde3032ca471..f932a27e9a287 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -698,7 +698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl { let mut err = struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), ident.span, E0596, "cannot borrow as mutable inside an `&` pattern" @@ -1010,7 +1010,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { - let e = tcx.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); + let e = + self.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); return Ty::new_error(tcx, e); } @@ -1191,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span); if res == Res::Err { - let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); + let e = self.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); return Ty::new_error(tcx, e); @@ -1207,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match res { Res::Err => { - tcx.dcx().span_bug(pat.span, "`Res::Err` but no error emitted"); + self.dcx().span_bug(pat.span, "`Res::Err` but no error emitted"); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { let e = report_unexpected_res(res); @@ -1549,10 +1550,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Report an error if an incorrect number of fields was specified. if adt.is_union() { if fields.len() != 1 { - tcx.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span }); + self.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span }); } if has_rest_pat { - tcx.dcx().emit_err(errors::UnionPatDotDot { span: pat.span }); + self.dcx().emit_err(errors::UnionPatDotDot { span: pat.span }); } } else if !unmentioned_fields.is_empty() { let accessible_unmentioned_fields: Vec<_> = unmentioned_fields @@ -1690,7 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx Pat<'tcx>, variant: &ty::VariantDef, args: ty::GenericArgsRef<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let tcx = self.tcx; let (field_names, t, plural) = if let [field] = inexistent_fields { (format!("a field named `{}`", field.ident), "this", "") @@ -1710,7 +1711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::>(); let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), spans, E0026, "{} `{}` does not have {}", diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index d321bc265bc93..a8fd3ca8c59bd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -305,16 +305,17 @@ fn label_msg_span( } } -#[instrument(level = "trace", skip(tcx))] -pub fn unexpected_hidden_region_diagnostic<'tcx>( - tcx: TyCtxt<'tcx>, +#[instrument(level = "trace", skip(infcx))] +pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, generic_param_scope: LocalDefId, span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, opaque_ty_key: ty::OpaqueTypeKey<'tcx>, -) -> Diag<'tcx> { - let mut err = tcx.dcx().create_err(errors::OpaqueCapturesLifetime { +) -> Diag<'a> { + let tcx = infcx.tcx; + let mut err = infcx.dcx().create_err(errors::OpaqueCapturesLifetime { span, opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), @@ -2215,7 +2216,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, self.type_error_additional_suggestions(&trace, terr), ); - let mut diag = self.tcx.dcx().create_err(failure_code); + let mut diag = self.dcx().create_err(failure_code); self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false); diag } @@ -2357,14 +2358,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { origin: Option>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { if let Some(SubregionOrigin::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id, }) = origin { - return self.report_extra_impl_obligation( + return self.infcx.report_extra_impl_obligation( span, impl_item_def_id, trait_item_def_id, @@ -2790,7 +2791,7 @@ impl<'tcx> TypeRelation> for SameTypeModuloInfer<'_, 'tcx> { } impl<'tcx> InferCtxt<'tcx> { - fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'tcx> { + fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> { let br_string = |br: ty::BoundRegionKind| { let mut s = match br { ty::BrNamed(_, name) => name.to_string(), @@ -2829,7 +2830,7 @@ impl<'tcx> InferCtxt<'tcx> { }; struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), var_origin.span(), E0495, "cannot infer an appropriate lifetime{} due to conflicting requirements", diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e37b0b83f4d00..d1fc9c9f140b1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { - let mut err = self.report_extra_impl_obligation( + let mut err = self.infcx.report_extra_impl_obligation( span, impl_item_def_id, trait_item_def_id, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 10471e8bbdd71..ff593d7ffb7df 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -685,7 +685,7 @@ impl<'tcx> InferOk<'tcx, ()> { impl<'tcx> InferCtxt<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'_> { - self.tcx.dcx() + self.tcx.dcx().taintable_handle(&self.tainted_by_errors) } pub fn defining_opaque_types(&self) -> &'tcx ty::List { @@ -1089,19 +1089,7 @@ impl<'tcx> InferCtxt<'tcx> { /// inference variables, regionck errors). #[must_use = "this method does not have any side effects"] pub fn tainted_by_errors(&self) -> Option { - if let Some(guar) = self.tainted_by_errors.get() { - Some(guar) - } else if self.dcx().err_count_excluding_lint_errs() > self.err_count_on_creation { - // Errors reported since this infcx was made. Lint errors are - // excluded to avoid some being swallowed in the presence of - // non-lint errors. (It's arguable whether or not this exclusion is - // important.) - let guar = self.dcx().has_errors().unwrap(); - self.set_tainted_by_errors(guar); - Some(guar) - } else { - None - } + self.tainted_by_errors.get() } /// Set the "tainted by errors" flag to true. We call this when we @@ -1328,8 +1316,7 @@ impl<'tcx> InferCtxt<'tcx> { bug!("`{value:?}` is not fully resolved"); } if value.has_infer_regions() { - let guar = - self.tcx.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); + let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); Ok(self.tcx.fold_regions(value, |re, _| { if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } })) diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index b8dd501a721b5..7c764cccc4772 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -156,7 +156,7 @@ impl<'tcx> InferCtxt<'tcx> { if self.can_define_opaque_ty(b_def_id) && self.tcx.is_type_alias_impl_trait(b_def_id) { - self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag { + self.dcx().emit_err(OpaqueHiddenTypeDiag { span, hidden_type: self.tcx.def_span(b_def_id), opaque_type: self.tcx.def_span(def_id), diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 890e25368bc75..7730fe29e0933 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -12,15 +12,15 @@ use std::fmt; use std::iter; impl<'tcx> InferCtxt<'tcx> { - pub fn report_extra_impl_obligation( - &self, + pub fn report_extra_impl_obligation<'a>( + &'a self, error_span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId, requirement: &dyn fmt::Display, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), error_span, E0276, "impl has stricter requirements than trait" diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3ef3efc6252e9..adf1076a7c90e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1101,7 +1101,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let ty::FnPtr(sig) = by_ref_captures.kind() && !sig.skip_binder().output().is_unit() { - let mut err = self.tcx.dcx().create_err(AsyncClosureNotFn { + let mut err = self.dcx().create_err(AsyncClosureNotFn { span: self.tcx.def_span(closure_def_id), kind: expected_kind.as_str(), }); @@ -2884,7 +2884,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.suggest_unsized_bound_if_applicable(err, obligation); if let Some(span) = err.span.primary_span() && let Some(mut diag) = - self.tcx.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion) + self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion) && let Ok(ref mut s1) = err.suggestions && let Ok(ref mut s2) = diag.suggestions { diff --git a/tests/ui/asm/x86_64/type-check-2.rs b/tests/ui/asm/x86_64/type-check-2.rs index c866f9fd8cc4d..4b5d59fdbc785 100644 --- a/tests/ui/asm/x86_64/type-check-2.rs +++ b/tests/ui/asm/x86_64/type-check-2.rs @@ -13,13 +13,16 @@ fn main() { let x: u64; asm!("{}", in(reg) x); + //~^ ERROR isn't initialized let mut y: u64; asm!("{}", inout(reg) y); + //~^ ERROR isn't initialized let _ = y; // Outputs require mutable places let v: Vec = vec![0, 1, 2]; + //~^ ERROR is not declared as mutable asm!("{}", in(reg) v[0]); asm!("{}", out(reg) v[0]); asm!("{}", inout(reg) v[0]); diff --git a/tests/ui/asm/x86_64/type-check-2.stderr b/tests/ui/asm/x86_64/type-check-2.stderr index 4f3d5100af056..6ae118b16e766 100644 --- a/tests/ui/asm/x86_64/type-check-2.stderr +++ b/tests/ui/asm/x86_64/type-check-2.stderr @@ -1,5 +1,5 @@ error: invalid `sym` operand - --> $DIR/type-check-2.rs:35:24 + --> $DIR/type-check-2.rs:38:24 | LL | asm!("{}", sym x); | ^ is a local variable @@ -7,7 +7,7 @@ LL | asm!("{}", sym x); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/type-check-2.rs:86:19 + --> $DIR/type-check-2.rs:89:19 | LL | global_asm!("{}", sym C); | ^^^^^ is an `i32` @@ -15,7 +15,7 @@ LL | global_asm!("{}", sym C); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/type-check-2.rs:33:20 + --> $DIR/type-check-2.rs:36:20 | LL | asm!("{}", sym C); | ^^^^^ is an `i32` @@ -23,15 +23,15 @@ LL | asm!("{}", sym C); = help: `sym` operands must refer to either a function or a static error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:40:32 + --> $DIR/type-check-2.rs:43:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `{closure@$DIR/type-check-2.rs:52:28: 52:36}` for inline assembly - --> $DIR/type-check-2.rs:52:28 +error: cannot use value of type `{closure@$DIR/type-check-2.rs:55:28: 55:36}` for inline assembly + --> $DIR/type-check-2.rs:55:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:54:28 + --> $DIR/type-check-2.rs:57:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -48,7 +48,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:56:28 + --> $DIR/type-check-2.rs:59:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:58:28 + --> $DIR/type-check-2.rs:61:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -64,7 +64,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:66:31 + --> $DIR/type-check-2.rs:69:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -72,12 +72,56 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:69:31 + --> $DIR/type-check-2.rs:72:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: aborting due to 10 previous errors +error[E0381]: used binding `x` isn't initialized + --> $DIR/type-check-2.rs:15:28 + | +LL | let x: u64; + | - binding declared here but left uninitialized +LL | asm!("{}", in(reg) x); + | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x: u64 = 42; + | ++++ + +error[E0381]: used binding `y` isn't initialized + --> $DIR/type-check-2.rs:18:9 + | +LL | let mut y: u64; + | ----- binding declared here but left uninitialized +LL | asm!("{}", inout(reg) y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let mut y: u64 = 42; + | ++++ + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-2.rs:24:13 + | +LL | let v: Vec = vec![0, 1, 2]; + | ^ not mutable +... +LL | asm!("{}", out(reg) v[0]); + | - cannot borrow as mutable +LL | asm!("{}", inout(reg) v[0]); + | - cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut v: Vec = vec![0, 1, 2]; + | +++ + +error: aborting due to 13 previous errors +Some errors have detailed explanations: E0381, E0596. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.rs b/tests/ui/associated-types/associated-types-eq-expr-path.rs index 4561e596c6658..67831f913039a 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.rs +++ b/tests/ui/associated-types/associated-types-eq-expr-path.rs @@ -13,4 +13,5 @@ impl Foo for isize { pub fn main() { let x: isize = Foo::::bar(); //~^ ERROR associated item constraints are not allowed here + //~| ERROR cannot call } diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.stderr b/tests/ui/associated-types/associated-types-eq-expr-path.stderr index 3d0e3e61eca90..4f28b3cb2de33 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.stderr +++ b/tests/ui/associated-types/associated-types-eq-expr-path.stderr @@ -4,6 +4,22 @@ error[E0229]: associated item constraints are not allowed here LL | let x: isize = Foo::::bar(); | ^^^^^^^^^ associated item constraint not allowed here -error: aborting due to 1 previous error +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/associated-types-eq-expr-path.rs:14:20 + | +LL | fn bar() -> isize; + | ------------------ `Foo::bar` defined here +... +LL | let x: isize = Foo::::bar(); + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL - let x: isize = Foo::::bar(); +LL + let x: isize = >::bar(); + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0229`. +Some errors have detailed explanations: E0229, E0790. +For more information about an error, try `rustc --explain E0229`. diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs index ffc7f116a94ef..bec6102417c5f 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.rs +++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs @@ -8,6 +8,7 @@ fn foo() { bar::<::ASSOC>(); //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC` //~| ERROR: unresolved item provided when a constant was expected + //~| ERROR type annotations needed } fn main() {} diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr index ac00954613506..53edc19b28ca2 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.stderr +++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr @@ -15,7 +15,19 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | bar::<{ ::ASSOC }>(); | + + -error: aborting due to 2 previous errors +error[E0284]: type annotations needed + --> $DIR/assoc_const_as_type_argument.rs:8:5 + | +LL | bar::<::ASSOC>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/assoc_const_as_type_argument.rs:5:8 + | +LL | fn bar() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0575, E0747. -For more information about an error, try `rustc --explain E0575`. +Some errors have detailed explanations: E0284, E0575, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index ce7fce2599360..2ea9d6b35b451 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -17,7 +17,7 @@ LL | let _: [u8; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -26,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:20:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -35,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:22:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -44,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:23:23 + --> $DIR/const-arg-in-const-arg.rs:24:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ cannot perform const operation using `N` @@ -62,7 +62,7 @@ LL | let _ = [0; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:32:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:35:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:34:24 + --> $DIR/const-arg-in-const-arg.rs:36:24 | LL | let _: Foo<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:39:24 + --> $DIR/const-arg-in-const-arg.rs:42:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:43:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:42:24 + --> $DIR/const-arg-in-const-arg.rs:45:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:43:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:48:27 + --> $DIR/const-arg-in-const-arg.rs:52:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:53:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:51:27 + --> $DIR/const-arg-in-const-arg.rs:55:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -216,8 +216,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: [u8; bar::<{ N }>()]; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:16:17 + | +LL | let _: [u8; bar::()]; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -229,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:22:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -241,7 +253,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ bar::() }>; | ^ @@ -251,8 +263,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: Foo<{ bar::<{ N }>() }>; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:37:18 + | +LL | let _: Foo<{ bar::() }>; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -264,7 +288,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:43:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -276,7 +300,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:25:17 + --> $DIR/const-arg-in-const-arg.rs:26:17 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^ @@ -284,7 +308,7 @@ LL | let _ = [0; foo::()]; = note: this may fail depending on what value the parameter takes error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ @@ -294,8 +318,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = [0; bar::<{ N }>()]; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:27:17 + | +LL | let _ = [0; bar::()]; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -307,7 +343,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -319,7 +355,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ bar::() }>; | ^ @@ -329,8 +365,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = Foo::<{ bar::<{ N }>() }>; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:47:21 + | +LL | let _ = Foo::<{ bar::() }>; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -342,7 +390,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:53:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -353,7 +401,7 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: aborting due to 36 previous errors +error: aborting due to 40 previous errors -Some errors have detailed explanations: E0747, E0794. -For more information about an error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747, E0794. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index 27b74489fe8e0..b95c63309f782 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -15,6 +15,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::()]; //[min]~ ERROR generic parameters may not let _: [u8; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -25,6 +26,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = [0; foo::()]; //[min]~ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -34,6 +36,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: Foo<{ foo::() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not @@ -43,6 +46,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = Foo::<{ foo::() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs index 56b8acbf88cde..7209290a36e0a 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs @@ -2,6 +2,7 @@ #![allow(incomplete_features)] type Foo = impl Sized; +//~^ ERROR: unconstrained opaque type fn with_bound() -> Foo where diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr index e9fb8c0f403ae..c7a266205b4b5 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | type Foo = impl Sized; | ---------- the found opaque type @@ -11,12 +11,20 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; found opaque type `Foo` error[E0605]: non-primitive cast: `usize` as `Foo` - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object -error: aborting due to 2 previous errors +error: unconstrained opaque type + --> $DIR/opaque_type.rs:4:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0605. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 5205726d73845..3fd50bbe29803 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -30,7 +30,31 @@ help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable LL + #![feature(generic_arg_infer)] | -error: aborting due to 3 previous errors +error[E0284]: type annotations needed + --> $DIR/issue-62878.rs:10:5 + | +LL | foo::<_, { [1] }>(); + | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/issue-62878.rs:5:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error[E0284]: type annotations needed + --> $DIR/issue-62878.rs:10:5 + | +LL | foo::<_, { [1] }>(); + | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `A` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/issue-62878.rs:5:24 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0747, E0770. -For more information about an error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747, E0770. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs index 0b5269df85ee1..c784e95edd824 100644 --- a/tests/ui/const-generics/issues/issue-62878.rs +++ b/tests/ui/const-generics/issues/issue-62878.rs @@ -9,4 +9,6 @@ fn foo() {} fn main() { foo::<_, { [1] }>(); //[min]~^ ERROR: type provided when a constant was expected + //[min]~| ERROR type annotations needed + //[min]~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs index e12e07a28e763..497c020bde43e 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -12,6 +12,7 @@ fn b() { //~^ ERROR expected trait, found constant `BAR` //~| ERROR expected trait, found constant `BAR` //~| ERROR type provided when a constant was expected + //~| ERROR type annotations needed } fn c() { foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr index d9bcc523b1fc4..c2ba517f60960 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr @@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:17:11 + --> $DIR/const-expression-suggest-missing-braces.rs:18:11 | LL | foo::<3 + 3>(); | ^^^^^ @@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:20:15 + --> $DIR/const-expression-suggest-missing-braces.rs:21:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:23:15 + --> $DIR/const-expression-suggest-missing-braces.rs:24:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:26:11 + --> $DIR/const-expression-suggest-missing-braces.rs:27:11 | LL | foo::<100 - BAR>(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:29:19 + --> $DIR/const-expression-suggest-missing-braces.rs:30:19 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -65,7 +65,7 @@ LL | foo::<{ bar() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:32:21 + --> $DIR/const-expression-suggest-missing-braces.rs:33:21 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -76,7 +76,7 @@ LL | foo::<{ bar::() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:35:21 + --> $DIR/const-expression-suggest-missing-braces.rs:36:21 | LL | foo::() + BAR>(); | ^ expected one of `,` or `>` @@ -87,7 +87,7 @@ LL | foo::<{ bar::() + BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:38:21 + --> $DIR/const-expression-suggest-missing-braces.rs:39:21 | LL | foo::() - BAR>(); | ^ expected one of `,` or `>` @@ -98,7 +98,7 @@ LL | foo::<{ bar::() - BAR }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:41:15 + --> $DIR/const-expression-suggest-missing-braces.rs:42:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::() }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:44:15 + --> $DIR/const-expression-suggest-missing-braces.rs:45:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -137,7 +137,19 @@ error[E0747]: type provided when a constant was expected LL | foo::(); | ^^^^^^^^^ -error: aborting due to 14 previous errors +error[E0284]: type annotations needed + --> $DIR/const-expression-suggest-missing-braces.rs:11:5 + | +LL | foo::(); + | ^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/const-expression-suggest-missing-braces.rs:1:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 15 previous errors -Some errors have detailed explanations: E0404, E0747. -For more information about an error, try `rustc --explain E0404`. +Some errors have detailed explanations: E0284, E0404, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.rs b/tests/ui/const-generics/min_const_generics/macro-fail.rs index 2f101ecfb1f7a..25726490c2cca 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.rs +++ b/tests/ui/const-generics/min_const_generics/macro-fail.rs @@ -16,6 +16,7 @@ fn make_marker() -> impl Marker { //~| ERROR: type provided when a constant was expected Example:: //~^ ERROR: type provided when a constant was expected + //~| ERROR type annotations needed } fn from_marker(_: impl Marker<{ @@ -35,9 +36,11 @@ fn main() { }>; let _fail = Example::; - //~^ ERROR: type provided when a constant was expected + //~^ ERROR: type provided when a constant + //~| ERROR type annotations needed let _fail = Example::; //~^ ERROR unexpected end of macro invocation //~| ERROR: type provided when a constant was expected + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.stderr b/tests/ui/const-generics/min_const_generics/macro-fail.stderr index 34764982bb046..4e183fe5b1c55 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/tests/ui/const-generics/min_const_generics/macro-fail.stderr @@ -1,5 +1,5 @@ error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:31:27 | LL | fn make_marker() -> impl Marker { | ---------------------- @@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:31:27 | LL | Example:: | ---------------------- @@ -41,7 +41,7 @@ LL | let _fail = Example::; = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation - --> $DIR/macro-fail.rs:40:25 + --> $DIR/macro-fail.rs:42:25 | LL | macro_rules! gimme_a_const { | -------------------------- when calling this macro @@ -50,7 +50,7 @@ LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | note: while trying to match meta-variable `$rusty:ident` - --> $DIR/macro-fail.rs:30:8 + --> $DIR/macro-fail.rs:31:8 | LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} | ^^^^^^^^^^^^^ @@ -75,18 +75,63 @@ error[E0747]: type provided when a constant was expected LL | Example:: | ^^^^^^^^^^^^^^^^^^^^^^ +error[E0284]: type annotations needed + --> $DIR/macro-fail.rs:17:3 + | +LL | Example:: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the struct `Example` + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` + error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:37:25 + --> $DIR/macro-fail.rs:38:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^^ error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:40:25 + --> $DIR/macro-fail.rs:42:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error[E0284]: type annotations needed for `Example<_>` + --> $DIR/macro-fail.rs:38:7 + | +LL | let _fail = Example::; + | ^^^^^ ---------------------------- type must be known at this point + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` +help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified + | +LL | let _fail: Example = Example::; + | ++++++++++++ + +error[E0284]: type annotations needed for `Example<_>` + --> $DIR/macro-fail.rs:42:7 + | +LL | let _fail = Example::; + | ^^^^^ --------------------------- type must be known at this point + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` +help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified + | +LL | let _fail: Example = Example::; + | ++++++++++++ + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/suggest_const_for_array.rs b/tests/ui/const-generics/suggest_const_for_array.rs index f3e5a3186cdd6..4d29d0693759f 100644 --- a/tests/ui/const-generics/suggest_const_for_array.rs +++ b/tests/ui/const-generics/suggest_const_for_array.rs @@ -3,8 +3,10 @@ fn example() {} fn other() { - example::<[usize; 3]>(); - //~^ ERROR type provided when a const - example::<[usize; 4+5]>(); - //~^ ERROR type provided when a const + example::<[usize; 3]>(); + //~^ ERROR type provided when a const + //~| ERROR type annotations needed + example::<[usize; 4 + 5]>(); + //~^ ERROR type provided when a const + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/suggest_const_for_array.stderr b/tests/ui/const-generics/suggest_const_for_array.stderr index a617bf2bb0d96..c867914070bb7 100644 --- a/tests/ui/const-generics/suggest_const_for_array.stderr +++ b/tests/ui/const-generics/suggest_const_for_array.stderr @@ -1,15 +1,40 @@ error[E0747]: type provided when a constant was expected - --> $DIR/suggest_const_for_array.rs:6:13 + --> $DIR/suggest_const_for_array.rs:6:15 | -LL | example::<[usize; 3]>(); - | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` +LL | example::<[usize; 3]>(); + | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` error[E0747]: type provided when a constant was expected - --> $DIR/suggest_const_for_array.rs:8:13 + --> $DIR/suggest_const_for_array.rs:9:15 | -LL | example::<[usize; 4+5]>(); - | ^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4+5 }` +LL | example::<[usize; 4 + 5]>(); + | ^^^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4 + 5 }` -error: aborting due to 2 previous errors +error[E0284]: type annotations needed + --> $DIR/suggest_const_for_array.rs:6:5 + | +LL | example::<[usize; 3]>(); + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` + | +note: required by a const generic parameter in `example` + --> $DIR/suggest_const_for_array.rs:3:12 + | +LL | fn example() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` + +error[E0284]: type annotations needed + --> $DIR/suggest_const_for_array.rs:9:5 + | +LL | example::<[usize; 4 + 5]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` + | +note: required by a const generic parameter in `example` + --> $DIR/suggest_const_for_array.rs:3:12 + | +LL | fn example() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/generics/generic-function-item-where-type.rs b/tests/ui/generics/generic-function-item-where-type.rs index e1b0578cadbe9..0e36018389e96 100644 --- a/tests/ui/generics/generic-function-item-where-type.rs +++ b/tests/ui/generics/generic-function-item-where-type.rs @@ -3,4 +3,5 @@ fn foo() {} fn main() { foo::
() //~^ ERROR constant provided when a type was expected + //~| ERROR type annotations needed } diff --git a/tests/ui/generics/generic-function-item-where-type.stderr b/tests/ui/generics/generic-function-item-where-type.stderr index 00e62843cb4b6..5b0c9a8ee6df5 100644 --- a/tests/ui/generics/generic-function-item-where-type.stderr +++ b/tests/ui/generics/generic-function-item-where-type.stderr @@ -7,6 +7,13 @@ LL | foo::
() = help: `main` is a function item, not a type = help: function item types cannot be named directly -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/generic-function-item-where-type.rs:4:5 + | +LL | foo::
() + | ^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `foo` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0282, E0747. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 199cbbf4fcc9b..8aba3de530b8e 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { + //~^ ERROR cannot resolve opaque type |x| x //~^ ERROR expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 6064b09ef0927..c2386e8c88be0 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -1,11 +1,19 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/impl-fn-predefined-lifetimes.rs:5:9 + --> $DIR/impl-fn-predefined-lifetimes.rs:6:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- this generic parameter must be used with a generic lifetime parameter +LL | LL | |x| x | ^ -error: aborting due to 1 previous error +error[E0720]: cannot resolve opaque type + --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 + | +LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { + | ^^^^^^^^^^^^^^^ cannot resolve opaque type + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0792`. +Some errors have detailed explanations: E0720, E0792. +For more information about an error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.rs b/tests/ui/impl-trait/transmute/in-defining-scope.rs index b0b77d60b245e..b9a9dbc10a5b4 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.rs +++ b/tests/ui/impl-trait/transmute/in-defining-scope.rs @@ -5,6 +5,7 @@ use std::mem::transmute; fn foo() -> impl Sized { //~^ ERROR cycle detected when computing type of + //~| WARN function cannot return without recursing unsafe { transmute::<_, u8>(foo()); } diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.stderr b/tests/ui/impl-trait/transmute/in-defining-scope.stderr index 69812f43072b0..7172bfdf0d7e2 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.stderr +++ b/tests/ui/impl-trait/transmute/in-defining-scope.stderr @@ -24,6 +24,18 @@ LL | fn foo() -> impl Sized { | ^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error +warning: function cannot return without recursing + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +... +LL | transmute::<_, u8>(foo()); + | ----- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/infinite/infinite-struct.rs b/tests/ui/infinite/infinite-struct.rs index f08e10f6bdbc0..62f9702b9f411 100644 --- a/tests/ui/infinite/infinite-struct.rs +++ b/tests/ui/infinite/infinite-struct.rs @@ -1,5 +1,6 @@ struct Take(Take); //~^ ERROR has infinite size +//~| ERROR cycle // check that we don't hang trying to find the tail of a recursive struct (#79437) fn foo() -> Take { diff --git a/tests/ui/infinite/infinite-struct.stderr b/tests/ui/infinite/infinite-struct.stderr index 82d147b63cda0..5896aec399dc4 100644 --- a/tests/ui/infinite/infinite-struct.stderr +++ b/tests/ui/infinite/infinite-struct.stderr @@ -10,7 +10,7 @@ LL | struct Take(Box); | ++++ + error[E0072]: recursive type `Foo` has infinite size - --> $DIR/infinite-struct.rs:10:1 + --> $DIR/infinite-struct.rs:11:1 | LL | struct Foo { | ^^^^^^^^^^ @@ -26,6 +26,17 @@ error: reached the recursion limit finding the struct tail for `Take` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` -error: aborting due to 3 previous errors +error[E0391]: cycle detected when computing when `Take` needs drop + --> $DIR/infinite-struct.rs:1:1 + | +LL | struct Take(Take); + | ^^^^^^^^^^^ + | + = note: ...which immediately requires computing when `Take` needs drop again + = note: cycle used when computing whether `Take` needs drop + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0072`. +Some errors have detailed explanations: E0072, E0391. +For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.rs b/tests/ui/static/reference-of-mut-static-unsafe-fn.rs deleted file mode 100644 index 5652703a27186..0000000000000 --- a/tests/ui/static/reference-of-mut-static-unsafe-fn.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ compile-flags: --edition 2024 -Z unstable-options - -fn main() {} - -unsafe fn _foo() { - static mut X: i32 = 1; - static mut Y: i32 = 1; - - let _y = &X; - //~^ ERROR creating a shared reference to a mutable static [E0796] - - let ref _a = X; - //~^ ERROR creating a shared reference to a mutable static [E0796] - - let ref mut _a = X; - //~^ ERROR creating a mutable reference to a mutable static [E0796] - - let (_b, _c) = (&X, &mut Y); - //~^ ERROR creating a shared reference to a mutable static [E0796] - //~^^ ERROR creating a mutable reference to a mutable static [E0796] - - foo(&X); - //~^ ERROR creating a shared reference to a mutable static [E0796] -} - -fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr deleted file mode 100644 index 5675d313e0763..0000000000000 --- a/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:9:14 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:12:18 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:15:22 - | -LL | let ref mut _a = X; - | ^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let ref mut _a = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:18:21 - | -LL | let (_b, _c) = (&X, &mut Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &mut Y); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:18:25 - | -LL | let (_b, _c) = (&X, &mut Y); - | ^^^^^^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of_mut!(Y)); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:22:9 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.e2021.stderr b/tests/ui/static/reference-of-mut-static.e2021.stderr deleted file mode 100644 index f7ad51b615711..0000000000000 --- a/tests/ui/static/reference-of-mut-static.e2021.stderr +++ /dev/null @@ -1,91 +0,0 @@ -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:16:18 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -note: the lint level is defined here - --> $DIR/reference-of-mut-static.rs:6:9 - | -LL | #![deny(static_mut_refs)] - | ^^^^^^^^^^^^^^^ -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error: creating a mutable reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:20:18 - | -LL | let _y = &mut X; - | ^^^^^^ mutable reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let _y = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:28:22 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:32:25 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &Y); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:32:29 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of!(Y)); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:38:13 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - diff --git a/tests/ui/static/reference-of-mut-static.e2024.stderr b/tests/ui/static/reference-of-mut-static.e2024.stderr deleted file mode 100644 index 6205c10ac416f..0000000000000 --- a/tests/ui/static/reference-of-mut-static.e2024.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:16:18 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static.rs:20:18 - | -LL | let _y = &mut X; - | ^^^^^^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let _y = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:28:22 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:32:25 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &Y); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:32:29 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of!(Y)); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:38:13 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.rs b/tests/ui/static/reference-of-mut-static.rs deleted file mode 100644 index af2cab7dd8723..0000000000000 --- a/tests/ui/static/reference-of-mut-static.rs +++ /dev/null @@ -1,50 +0,0 @@ -//@ revisions: e2021 e2024 - -//@ [e2021] edition:2021 -//@ [e2024] compile-flags: --edition 2024 -Z unstable-options - -#![deny(static_mut_refs)] - -use std::ptr::{addr_of, addr_of_mut}; - -fn main() { - static mut X: i32 = 1; - - static mut Y: i32 = 1; - - unsafe { - let _y = &X; - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - let _y = &mut X; - //[e2024]~^ ERROR creating a mutable reference to a mutable static [E0796] - //[e2021]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs] - - let _z = addr_of_mut!(X); - - let _p = addr_of!(X); - - let ref _a = X; - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - let (_b, _c) = (&X, &Y); - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - foo(&X); - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - static mut Z: &[i32; 3] = &[0, 1, 2]; - - let _ = Z.len(); - let _ = Z[0]; - let _ = format!("{:?}", Z); - } -} - -fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr index 607c1bba1352a..c57b418d7b2e2 100644 --- a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr +++ b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr @@ -10,6 +10,15 @@ help: use `addr_of!` instead to create a raw pointer LL | let _x = addr_of!(X); | ~~~~~~~~~~~ -error: aborting due to 1 previous error +error[E0133]: use of mutable static is unsafe and requires unsafe block + --> $DIR/reference-to-mut-static-safe.rs:9:15 + | +LL | let _x = &X; + | ^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0796`. +Some errors have detailed explanations: E0133, E0796. +For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/static/reference-to-mut-static-safe.rs b/tests/ui/static/reference-to-mut-static-safe.rs index de4f4be8f7621..98afdadf4d255 100644 --- a/tests/ui/static/reference-to-mut-static-safe.rs +++ b/tests/ui/static/reference-to-mut-static-safe.rs @@ -8,6 +8,6 @@ fn main() { let _x = &X; //[e2024]~^ creating a shared reference to a mutable static [E0796] - //[e2021]~^^ use of mutable static is unsafe and requires unsafe function or block [E0133] + //~^^ use of mutable static is unsafe and requires unsafe //[e2021]~^^^ shared reference to mutable static is discouraged [static_mut_refs] } diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs b/tests/ui/static/reference-to-mut-static-unsafe-fn.rs index 5652703a27186..d63fd5460d840 100644 --- a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs +++ b/tests/ui/static/reference-to-mut-static-unsafe-fn.rs @@ -3,24 +3,26 @@ fn main() {} unsafe fn _foo() { - static mut X: i32 = 1; - static mut Y: i32 = 1; + unsafe { + static mut X: i32 = 1; + static mut Y: i32 = 1; - let _y = &X; - //~^ ERROR creating a shared reference to a mutable static [E0796] + let _y = &X; + //~^ ERROR creating a shared reference to a mutable static [E0796] - let ref _a = X; - //~^ ERROR creating a shared reference to a mutable static [E0796] + let ref _a = X; + //~^ ERROR creating a shared reference to a mutable static [E0796] - let ref mut _a = X; - //~^ ERROR creating a mutable reference to a mutable static [E0796] + let ref mut _a = X; + //~^ ERROR creating a mutable reference to a mutable static [E0796] - let (_b, _c) = (&X, &mut Y); - //~^ ERROR creating a shared reference to a mutable static [E0796] - //~^^ ERROR creating a mutable reference to a mutable static [E0796] + let (_b, _c) = (&X, &mut Y); + //~^ ERROR creating a shared reference to a mutable static [E0796] + //~^^ ERROR creating a mutable reference to a mutable static [E0796] - foo(&X); - //~^ ERROR creating a shared reference to a mutable static [E0796] + foo(&X); + //~^ ERROR creating a shared reference to a mutable static [E0796] + } } fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr index 77d2aa5d1aec6..b24943cf59363 100644 --- a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr +++ b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr @@ -1,74 +1,74 @@ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:9:14 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18 | -LL | let _y = &X; - | ^^ shared reference to mutable static +LL | let _y = &X; + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ +LL | let _y = addr_of!(X); + | ~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:12:18 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22 | -LL | let ref _a = X; - | ^ shared reference to mutable static +LL | let ref _a = X; + | ^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ +LL | let ref _a = addr_of!(X); + | ~~~~~~~~~~~ error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:15:22 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26 | -LL | let ref mut _a = X; - | ^ mutable reference to mutable static +LL | let ref mut _a = X; + | ^ mutable reference to mutable static | = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior help: use `addr_of_mut!` instead to create a raw pointer | -LL | let ref mut _a = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ +LL | let ref mut _a = addr_of_mut!(X); + | ~~~~~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:18:21 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25 | -LL | let (_b, _c) = (&X, &mut Y); - | ^^ shared reference to mutable static +LL | let (_b, _c) = (&X, &mut Y); + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let (_b, _c) = (addr_of!(X), &mut Y); - | ~~~~~~~~~~~ +LL | let (_b, _c) = (addr_of!(X), &mut Y); + | ~~~~~~~~~~~ error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:18:25 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29 | -LL | let (_b, _c) = (&X, &mut Y); - | ^^^^^^ mutable reference to mutable static +LL | let (_b, _c) = (&X, &mut Y); + | ^^^^^^ mutable reference to mutable static | = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior help: use `addr_of_mut!` instead to create a raw pointer | -LL | let (_b, _c) = (&X, addr_of_mut!(Y)); - | ~~~~~~~~~~~~~~~ +LL | let (_b, _c) = (&X, addr_of_mut!(Y)); + | ~~~~~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:22:9 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13 | -LL | foo(&X); - | ^^ shared reference to mutable static +LL | foo(&X); + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ +LL | foo(addr_of!(X)); + | ~~~~~~~~~~~ error: aborting due to 6 previous errors diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 7df1a08bc883d..0c2772683a918 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -44,18 +44,6 @@ LL | LL | call(operation).await | ^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:23:1 - | -LL | type FutNothing<'a> = impl 'a + Future; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | / { -LL | | -LL | | -LL | | } - | |_^ - error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:13:1 | @@ -68,6 +56,18 @@ note: previous use here LL | call(operation).await | ^^^^^^^^^^^^^^^ +error[E0792]: expected generic lifetime parameter, found `'any` + --> $DIR/hkl_forbidden4.rs:23:1 + | +LL | type FutNothing<'a> = impl 'a + Future; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | / { +LL | | +LL | | +LL | | } + | |_^ + error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs index 61b23a3a93322..2adfad4fc5b80 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs @@ -5,6 +5,8 @@ type Bug = impl Fn(T) -> U + Copy; //~ ERROR cycle detected const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; //~^ ERROR: non-defining opaque type use +//~| ERROR: item does not constrain +//~| ERROR: item does not constrain fn make_bug>() -> Bug { |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index c2da5fc265cc2..121f765e66726 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -36,14 +36,40 @@ LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +error: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:6:7 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:6:61 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `U: From` is not satisfied - --> $DIR/issue-53092-2.rs:10:5 + --> $DIR/issue-53092-2.rs:12:5 | LL | |x| x.into() | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | note: required by a bound in `make_bug` - --> $DIR/issue-53092-2.rs:9:19 + --> $DIR/issue-53092-2.rs:11:19 | LL | fn make_bug>() -> Bug { | ^^^^^^^ required by this bound in `make_bug` @@ -52,7 +78,7 @@ help: consider restricting type parameter `U` LL | type Bug> = impl Fn(T) -> U + Copy; | +++++++++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0277, E0391, E0792. For more information about an error, try `rustc --explain E0277`. From c053e8939bae9c052ff53f58e692408a8099df5d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Jun 2024 18:06:09 +1000 Subject: [PATCH 088/217] Remove the `box_pointers` lint. As the comment says, this lint "is mostly historical, and not particularly useful". It's not worth keeping it around. --- compiler/rustc_lint/messages.ftl | 2 - compiler/rustc_lint/src/builtin.rs | 82 +------------------ compiler/rustc_lint/src/lib.rs | 5 +- compiler/rustc_lint/src/lints.rs | 6 -- .../crates/ide-db/src/generated/lints.rs | 1 - tests/ui/lint/lint-owned-heap-memory.rs | 12 --- tests/ui/lint/lint-owned-heap-memory.stderr | 20 ----- tests/ui/lint/reasons-erroneous.rs | 2 +- tests/ui/lint/reasons-erroneous.stderr | 6 +- 9 files changed, 11 insertions(+), 125 deletions(-) delete mode 100644 tests/ui/lint/lint-owned-heap-memory.rs delete mode 100644 tests/ui/lint/lint-owned-heap-memory.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 46cf87d1e3c17..3e952558d29d3 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -56,8 +56,6 @@ lint_builtin_asm_labels = avoid using named labels in inline assembly .help = only local labels of the form `:` should be used in inline asm .note = see the asm section of Rust By Example for more information -lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty} - lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature .previous_decl_label = `{$orig}` previously declared here .mismatch_label = this signature doesn't match the previous declaration diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 98318cd14d9dc..79c8046f9b741 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -24,9 +24,9 @@ use crate::fluent_generated as fluent; use crate::{ errors::BuiltinEllipsisInclusiveRangePatterns, lints::{ - BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle, - BuiltinDeprecatedAttrLink, BuiltinDeprecatedAttrLinkSuggestion, BuiltinDeprecatedAttrUsed, - BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, + BuiltinAnonymousParams, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink, + BuiltinDeprecatedAttrLinkSuggestion, BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, + BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures, BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, @@ -56,7 +56,6 @@ use rustc_middle::bug; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::Upcast; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; @@ -134,80 +133,6 @@ impl EarlyLintPass for WhileTrue { } } -declare_lint! { - /// The `box_pointers` lints use of the Box type. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(box_pointers)] - /// struct Foo { - /// x: Box, - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// This lint is mostly historical, and not particularly useful. `Box` - /// used to be built into the language, and the only way to do heap - /// allocation. Today's Rust can call into other allocators, etc. - BOX_POINTERS, - Allow, - "use of owned (Box type) heap memory" -} - -declare_lint_pass!(BoxPointers => [BOX_POINTERS]); - -impl BoxPointers { - fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { - for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() - && leaf_ty.is_box() - { - cx.emit_span_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); - } - } - } -} - -impl<'tcx> LateLintPass<'tcx> for BoxPointers { - fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - match it.kind { - hir::ItemKind::Fn(..) - | hir::ItemKind::TyAlias(..) - | hir::ItemKind::Enum(..) - | hir::ItemKind::Struct(..) - | hir::ItemKind::Union(..) => self.check_heap_type( - cx, - it.span, - cx.tcx.type_of(it.owner_id).instantiate_identity(), - ), - _ => (), - } - - // If it's a struct, we also have to check the fields' types - match it.kind { - hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { - for field in struct_def.fields() { - self.check_heap_type( - cx, - field.span, - cx.tcx.type_of(field.def_id).instantiate_identity(), - ); - } - } - _ => (), - } - } - - fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) { - let ty = cx.typeck_results().node_type(e.hir_id); - self.check_heap_type(cx, e.span, ty); - } -} - declare_lint! { /// The `non_shorthand_field_patterns` lint detects using `Struct { x: x }` /// instead of `Struct { x }` in a pattern. @@ -1640,7 +1565,6 @@ declare_lint_pass!( /// which are used by other parts of the compiler. SoftLints => [ WHILE_TRUE, - BOX_POINTERS, NON_SHORTHAND_FIELD_PATTERNS, UNSAFE_CODE, MISSING_DOCS, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7dae2de7bfb58..17f9d4421aef2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -187,7 +187,6 @@ late_lint_methods!( ImproperCTypesDefinitions: ImproperCTypesDefinitions, InvalidFromUtf8: InvalidFromUtf8, VariantSizeDifferences: VariantSizeDifferences, - BoxPointers: BoxPointers, PathStatements: PathStatements, LetUnderscore: LetUnderscore, InvalidReferenceCasting: InvalidReferenceCasting, @@ -551,6 +550,10 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ for more information", ); + store.register_removed( + "box_pointers", + "it does not detect other kinds of allocations, and existed only for historical reasons", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 14084405d0ee1..7c5640f5959a0 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -66,12 +66,6 @@ pub struct BuiltinWhileTrue { pub replace: String, } -#[derive(LintDiagnostic)] -#[diag(lint_builtin_box_pointers)] -pub struct BuiltinBoxPointers<'a> { - pub ty: Ty<'a>, -} - #[derive(LintDiagnostic)] #[diag(lint_builtin_non_shorthand_field_patterns)] pub struct BuiltinNonShorthandFieldPatterns { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index c92d4e78ffa71..7755a9b9748be 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -49,7 +49,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "bindings_with_variant_name", description: r##"detects pattern bindings with the same name as one of the matched variants"##, }, - Lint { label: "box_pointers", description: r##"use of owned (Box type) heap memory"## }, Lint { label: "break_with_label_and_loop", description: r##"`break` expression with label and unlabeled loop as value expression"##, diff --git a/tests/ui/lint/lint-owned-heap-memory.rs b/tests/ui/lint/lint-owned-heap-memory.rs deleted file mode 100644 index af47d5c072005..0000000000000 --- a/tests/ui/lint/lint-owned-heap-memory.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow(dead_code)] -#![forbid(box_pointers)] - - -struct Foo { - x: Box //~ ERROR type uses owned -} - -fn main() { - let _x: Foo = Foo { x : Box::new(10) }; - //~^ ERROR type uses owned -} diff --git a/tests/ui/lint/lint-owned-heap-memory.stderr b/tests/ui/lint/lint-owned-heap-memory.stderr deleted file mode 100644 index 5ba3969707571..0000000000000 --- a/tests/ui/lint/lint-owned-heap-memory.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: type uses owned (Box type) pointers: Box - --> $DIR/lint-owned-heap-memory.rs:6:5 - | -LL | x: Box - | ^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/lint-owned-heap-memory.rs:2:11 - | -LL | #![forbid(box_pointers)] - | ^^^^^^^^^^^^ - -error: type uses owned (Box type) pointers: Box - --> $DIR/lint-owned-heap-memory.rs:10:29 - | -LL | let _x: Foo = Foo { x : Box::new(10) }; - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/lint/reasons-erroneous.rs b/tests/ui/lint/reasons-erroneous.rs index 244b376b60d88..0aa46953bf1ac 100644 --- a/tests/ui/lint/reasons-erroneous.rs +++ b/tests/ui/lint/reasons-erroneous.rs @@ -9,7 +9,7 @@ #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] //~^ ERROR malformed lint attribute //~| NOTE bad attribute argument -#![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] +#![warn(unsafe_code, blerp = "or in league with robbers have reversed the signposts")] //~^ ERROR malformed lint attribute //~| NOTE bad attribute argument #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] diff --git a/tests/ui/lint/reasons-erroneous.stderr b/tests/ui/lint/reasons-erroneous.stderr index adc97174b99cd..fcff88d8e0fa7 100644 --- a/tests/ui/lint/reasons-erroneous.stderr +++ b/tests/ui/lint/reasons-erroneous.stderr @@ -17,10 +17,10 @@ LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides thei | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:12:23 + --> $DIR/reasons-erroneous.rs:12:22 | -LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument +LL | #![warn(unsafe_code, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input --> $DIR/reasons-erroneous.rs:15:36 From 0c0dfb88eeefbbaa4c10cfa4a7f0e16541e086eb Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 27 Jun 2024 08:05:07 +0200 Subject: [PATCH 089/217] Switch back `non_local_definitions` lint to allow-by-default as request T-lang is requesting some major changes in the lint inner workings in #126768#issuecomment-2192634762 --- compiler/rustc_lint/src/non_local_def.rs | 2 +- tests/rustdoc-ui/doctest/non_local_defs.rs | 2 + .../rustdoc-ui/doctest/non_local_defs.stderr | 8 ++- .../rustdoc-ui/doctest/non_local_defs.stdout | 2 +- tests/ui/lint/non-local-defs/cargo-update.rs | 2 + .../lint/non-local-defs/cargo-update.stderr | 8 ++- tests/ui/lint/non-local-defs/consts.rs | 2 + tests/ui/lint/non-local-defs/consts.stderr | 22 ++++--- .../lint/non-local-defs/exhaustive-trait.rs | 2 + .../non-local-defs/exhaustive-trait.stderr | 18 +++--- tests/ui/lint/non-local-defs/exhaustive.rs | 2 + .../ui/lint/non-local-defs/exhaustive.stderr | 58 ++++++++++--------- .../non-local-defs/from-local-for-global.rs | 2 + .../from-local-for-global.stderr | 24 ++++---- tests/ui/lint/non-local-defs/generics.rs | 2 + tests/ui/lint/non-local-defs/generics.stderr | 36 +++++++----- .../lint/non-local-defs/inside-macro_rules.rs | 2 + .../non-local-defs/inside-macro_rules.stderr | 8 ++- tests/ui/lint/non-local-defs/local.rs | 2 + tests/ui/lint/non-local-defs/macro_rules.rs | 2 + .../ui/lint/non-local-defs/macro_rules.stderr | 14 +++-- .../non-local-defs/suggest-moving-inner.rs | 2 + .../suggest-moving-inner.stderr | 10 +++- .../trait-solver-overflow-123573.rs | 2 + .../trait-solver-overflow-123573.stderr | 10 +++- tests/ui/lint/non-local-defs/weird-exprs.rs | 2 + .../ui/lint/non-local-defs/weird-exprs.stderr | 18 +++--- 27 files changed, 169 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 300dac442d564..17429ed061f25 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -50,7 +50,7 @@ declare_lint! { /// All nested bodies (functions, enum discriminant, array length, consts) (expect for /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked. pub NON_LOCAL_DEFINITIONS, - Warn, + Allow, "checks for non-local definitions", report_in_external_macro } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index aa166c343b2b0..d8cfe5637ae02 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -4,6 +4,8 @@ //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +#![doc(test(attr(warn(non_local_definitions))))] + //! ``` //! #[macro_export] //! macro_rules! a_macro { () => {} } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr index 2b47e6b5bc4d5..13cd2558793f8 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stderr +++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/non_local_defs.rs:9:1 + --> $DIR/non_local_defs.rs:11:1 | LL | macro_rules! a_macro { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,11 @@ LL | macro_rules! a_macro { () => {} } = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/non_local_defs.rs:8:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout index bee195fcdd772..61b4074886e4b 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stdout +++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout @@ -1,6 +1,6 @@ running 1 test -test $DIR/non_local_defs.rs - (line 7) ... ok +test $DIR/non_local_defs.rs - (line 9) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/ui/lint/non-local-defs/cargo-update.rs b/tests/ui/lint/non-local-defs/cargo-update.rs index 8b8c15795d376..3c62a655a9f61 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.rs +++ b/tests/ui/lint/non-local-defs/cargo-update.rs @@ -10,6 +10,8 @@ // of the `cargo update` suggestion we assert it here. //@ error-pattern: `cargo update -p non_local_macro` +#![warn(non_local_definitions)] + extern crate non_local_macro; struct LocalStruct; diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index bccf8622bac66..4dd41519455c6 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/cargo-update.rs:17:1 + --> $DIR/cargo-update.rs:19:1 | LL | non_local_macro::non_local_impl!(LocalStruct); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,11 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/cargo-update.rs:13:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/consts.rs b/tests/ui/lint/non-local-defs/consts.rs index d8a497e43e502..e7ee611529b96 100644 --- a/tests/ui/lint/non-local-defs/consts.rs +++ b/tests/ui/lint/non-local-defs/consts.rs @@ -2,6 +2,8 @@ //@ edition:2021 //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + struct Test; trait Uto {} diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 9f70119e0f8c9..ed7bd56fe4a54 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:13:5 + --> $DIR/consts.rs:15:5 | LL | const Z: () = { | ----------- @@ -17,10 +17,14 @@ LL | impl Uto for &Test {} = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/consts.rs:5:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:24:5 + --> $DIR/consts.rs:26:5 | LL | static A: u32 = { | ------------- move the `impl` block outside of this static `A` @@ -36,7 +40,7 @@ LL | impl Uto2 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:32:5 + --> $DIR/consts.rs:34:5 | LL | const B: u32 = { | ------------ move the `impl` block outside of this constant `B` @@ -52,7 +56,7 @@ LL | impl Uto3 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:43:5 + --> $DIR/consts.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -65,7 +69,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:50:9 + --> $DIR/consts.rs:52:9 | LL | const { | ___________- @@ -84,7 +88,7 @@ LL | | }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:59:9 + --> $DIR/consts.rs:61:9 | LL | const _: u32 = { | ------------ move the `impl` block outside of this constant `_` and up 2 bodies @@ -98,7 +102,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:72:9 + --> $DIR/consts.rs:74:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -113,7 +117,7 @@ LL | impl Uto9 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:79:9 + --> $DIR/consts.rs:81:9 | LL | type A = [u32; { | ____________________- diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.rs b/tests/ui/lint/non-local-defs/exhaustive-trait.rs index 40d2314460f86..79f8cc4620b97 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.rs +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Dog; fn main() { diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr index 67df0e31d5bdf..24c9a6b4f01e2 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:7:5 + --> $DIR/exhaustive-trait.rs:9:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl PartialEq<()> for Dog { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive-trait.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:14:5 + --> $DIR/exhaustive-trait.rs:16:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -31,7 +35,7 @@ LL | impl PartialEq<()> for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:21:5 + --> $DIR/exhaustive-trait.rs:23:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -47,7 +51,7 @@ LL | impl PartialEq for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:28:5 + --> $DIR/exhaustive-trait.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -63,7 +67,7 @@ LL | impl PartialEq<&Dog> for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:35:5 + --> $DIR/exhaustive-trait.rs:37:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -79,7 +83,7 @@ LL | impl PartialEq for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:42:5 + --> $DIR/exhaustive-trait.rs:44:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` diff --git a/tests/ui/lint/non-local-defs/exhaustive.rs b/tests/ui/lint/non-local-defs/exhaustive.rs index 2fb30f4344abb..f59a85c7ed94f 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.rs +++ b/tests/ui/lint/non-local-defs/exhaustive.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Display; trait Trait {} diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr index 1e0d5caec3830..6d8c2ec0bc7cf 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:10:5 + --> $DIR/exhaustive.rs:12:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -10,10 +10,14 @@ LL | impl Test { | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:15:5 + --> $DIR/exhaustive.rs:17:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -29,7 +33,7 @@ LL | impl Display for Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:22:5 + --> $DIR/exhaustive.rs:24:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -43,7 +47,7 @@ LL | impl dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:25:5 + --> $DIR/exhaustive.rs:27:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -59,7 +63,7 @@ LL | impl Trait for Vec { } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:28:5 + --> $DIR/exhaustive.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -75,7 +79,7 @@ LL | impl Trait for &dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:31:5 + --> $DIR/exhaustive.rs:33:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -91,7 +95,7 @@ LL | impl Trait for *mut Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:34:5 + --> $DIR/exhaustive.rs:36:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -107,7 +111,7 @@ LL | impl Trait for *mut [Test] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:37:5 + --> $DIR/exhaustive.rs:39:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -123,7 +127,7 @@ LL | impl Trait for [Test; 8] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:40:5 + --> $DIR/exhaustive.rs:42:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -139,7 +143,7 @@ LL | impl Trait for (Test,) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:43:5 + --> $DIR/exhaustive.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -155,7 +159,7 @@ LL | impl Trait for fn(Test) -> () {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:46:5 + --> $DIR/exhaustive.rs:48:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -171,7 +175,7 @@ LL | impl Trait for fn() -> Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:50:9 + --> $DIR/exhaustive.rs:52:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -186,7 +190,7 @@ LL | impl Trait for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:58:5 + --> $DIR/exhaustive.rs:60:5 | LL | impl Trait for *mut InsideMain {} | ^^^^^-----^^^^^--------------- @@ -198,7 +202,7 @@ LL | impl Trait for *mut InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -208,7 +212,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:60:5 + --> $DIR/exhaustive.rs:62:5 | LL | impl Trait for *mut [InsideMain] {} | ^^^^^-----^^^^^----------------- @@ -219,7 +223,7 @@ LL | impl Trait for *mut [InsideMain] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -229,7 +233,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:62:5 + --> $DIR/exhaustive.rs:64:5 | LL | impl Trait for [InsideMain; 8] {} | ^^^^^-----^^^^^--------------- @@ -240,7 +244,7 @@ LL | impl Trait for [InsideMain; 8] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -250,7 +254,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:64:5 + --> $DIR/exhaustive.rs:66:5 | LL | impl Trait for (InsideMain,) {} | ^^^^^-----^^^^^------------- @@ -261,7 +265,7 @@ LL | impl Trait for (InsideMain,) {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -271,7 +275,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:66:5 + --> $DIR/exhaustive.rs:68:5 | LL | impl Trait for fn(InsideMain) -> () {} | ^^^^^-----^^^^^-------------------- @@ -282,7 +286,7 @@ LL | impl Trait for fn(InsideMain) -> () {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -292,7 +296,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:68:5 + --> $DIR/exhaustive.rs:70:5 | LL | impl Trait for fn() -> InsideMain {} | ^^^^^-----^^^^^------------------ @@ -303,7 +307,7 @@ LL | impl Trait for fn() -> InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -313,7 +317,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:72:9 + --> $DIR/exhaustive.rs:74:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies @@ -328,7 +332,7 @@ LL | impl Display for InsideMain { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:79:9 + --> $DIR/exhaustive.rs:81:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.rs b/tests/ui/lint/non-local-defs/from-local-for-global.rs index fea9679d7375d..1d8f4845c2860 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.rs +++ b/tests/ui/lint/non-local-defs/from-local-for-global.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Cat; struct Wrap(T); diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr index 67fd937d134cc..04eba8435fc04 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr +++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:8:5 + --> $DIR/from-local-for-global.rs:10:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl From for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/from-local-for-global.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:18:5 + --> $DIR/from-local-for-global.rs:20:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^-- @@ -25,7 +29,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/from-local-for-global.rs:7:1 + --> $DIR/from-local-for-global.rs:9:1 | LL | fn main() { | ^^^^^^^^^ @@ -35,7 +39,7 @@ LL | struct Elephant; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:32:5 + --> $DIR/from-local-for-global.rs:34:5 | LL | impl StillNonLocal for &Foo {} | ^^^^^-------------^^^^^---- @@ -47,7 +51,7 @@ LL | impl StillNonLocal for &Foo {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `only_global` - --> $DIR/from-local-for-global.rs:30:1 + --> $DIR/from-local-for-global.rs:32:1 | LL | fn only_global() { | ^^^^^^^^^^^^^^^^ @@ -56,7 +60,7 @@ LL | struct Foo; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:40:5 + --> $DIR/from-local-for-global.rs:42:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -67,7 +71,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ @@ -76,7 +80,7 @@ LL | struct Local1(GlobalSameFunction); = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:48:5 + --> $DIR/from-local-for-global.rs:50:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -87,7 +91,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/generics.rs b/tests/ui/lint/non-local-defs/generics.rs index 0f526526dba21..13e392c510c64 100644 --- a/tests/ui/lint/non-local-defs/generics.rs +++ b/tests/ui/lint/non-local-defs/generics.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Global {} fn main() { diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr index ed2f87a4ed2d2..35366ed8ecf94 100644 --- a/tests/ui/lint/non-local-defs/generics.stderr +++ b/tests/ui/lint/non-local-defs/generics.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:9:5 + --> $DIR/generics.rs:11:5 | LL | impl Global for Vec { } | ^^^^^^^^^^^^^^^------^^^^^---^^^ @@ -10,17 +10,21 @@ LL | impl Global for Vec { } = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/generics.rs:6:1 + --> $DIR/generics.rs:8:1 | LL | fn main() { | ^^^^^^^^^ LL | trait Local {}; | ----------- may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/generics.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:20:5 + --> $DIR/generics.rs:22:5 | LL | impl Uto7 for Test where Local: std::any::Any {} | ^^^^^----^^^^^---- @@ -31,7 +35,7 @@ LL | impl Uto7 for Test where Local: std::any::Any {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `bad` - --> $DIR/generics.rs:18:1 + --> $DIR/generics.rs:20:1 | LL | fn bad() { | ^^^^^^^^ @@ -40,7 +44,7 @@ LL | struct Local; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:23:5 + --> $DIR/generics.rs:25:5 | LL | fn bad() { | -------- move the `impl` block outside of this function `bad` @@ -56,7 +60,7 @@ LL | impl Uto8 for T {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:32:5 + --> $DIR/generics.rs:34:5 | LL | impl Default for UwU { | ^^^^^-------^^^^^---^^^^^ @@ -67,7 +71,7 @@ LL | impl Default for UwU { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun` - --> $DIR/generics.rs:29:1 + --> $DIR/generics.rs:31:1 | LL | fn fun() { | ^^^^^^^^ @@ -77,7 +81,7 @@ LL | struct OwO; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:43:5 + --> $DIR/generics.rs:45:5 | LL | impl AsRef for () { | ^^^^^-----^^^^^^^^^^-- @@ -88,7 +92,7 @@ LL | impl AsRef for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `meow` - --> $DIR/generics.rs:40:1 + --> $DIR/generics.rs:42:1 | LL | fn meow() { | ^^^^^^^^^ @@ -98,7 +102,7 @@ LL | struct Cat; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:54:5 + --> $DIR/generics.rs:56:5 | LL | impl PartialEq for G { | ^^^^^---------^^^^^^^^- @@ -109,7 +113,7 @@ LL | impl PartialEq for G { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun2` - --> $DIR/generics.rs:51:1 + --> $DIR/generics.rs:53:1 | LL | fn fun2() { | ^^^^^^^^^ @@ -119,7 +123,7 @@ LL | struct B; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:69:5 + --> $DIR/generics.rs:71:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^-- @@ -129,7 +133,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ @@ -138,7 +142,7 @@ LL | struct Lion; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:76:5 + --> $DIR/generics.rs:78:5 | LL | impl From<()> for Wrap { | ^^^^^----^^^^^^^^^----^^^^^^ @@ -149,7 +153,7 @@ LL | impl From<()> for Wrap { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.rs b/tests/ui/lint/non-local-defs/inside-macro_rules.rs index 9f21cc89852e2..744a1f7a6f1ab 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.rs +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + macro_rules! m { () => { trait MacroTrait {} diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr index fa9ba2cb785d9..89835372c8a53 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/inside-macro_rules.rs:9:13 + --> $DIR/inside-macro_rules.rs:11:13 | LL | fn my_func() { | ------------ move the `impl` block outside of this function `my_func` @@ -16,7 +16,11 @@ LL | m!(); = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/inside-macro_rules.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/local.rs b/tests/ui/lint/non-local-defs/local.rs index 166ee88c0210c..e9dbff1300f28 100644 --- a/tests/ui/lint/non-local-defs/local.rs +++ b/tests/ui/lint/non-local-defs/local.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Debug; trait GlobalTrait {} diff --git a/tests/ui/lint/non-local-defs/macro_rules.rs b/tests/ui/lint/non-local-defs/macro_rules.rs index ed30a24903d01..20672cf0a3225 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.rs +++ b/tests/ui/lint/non-local-defs/macro_rules.rs @@ -3,6 +3,8 @@ //@ aux-build:non_local_macro.rs //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + extern crate non_local_macro; const B: u32 = { diff --git a/tests/ui/lint/non-local-defs/macro_rules.stderr b/tests/ui/lint/non-local-defs/macro_rules.stderr index 4e86fc7b987e6..f9995bf82183c 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:10:5 + --> $DIR/macro_rules.rs:12:5 | LL | macro_rules! m0 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,10 +7,14 @@ LL | macro_rules! m0 { () => { } }; = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current constant `B` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/macro_rules.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:16:1 + --> $DIR/macro_rules.rs:18:1 | LL | non_local_macro::non_local_macro_rules!(my_macro); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +26,7 @@ LL | non_local_macro::non_local_macro_rules!(my_macro); = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:21:5 + --> $DIR/macro_rules.rs:23:5 | LL | macro_rules! m { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +36,7 @@ LL | macro_rules! m { () => { } }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:29:13 + --> $DIR/macro_rules.rs:31:13 | LL | macro_rules! m2 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs index 61b32e5bad9fe..9360ace4d805b 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs @@ -1,5 +1,7 @@ //@ check-pass +#![warn(non_local_definitions)] + trait Trait {} fn main() { diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr index f0de0f72e74f6..a214415316f84 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/suggest-moving-inner.rs:12:5 + --> $DIR/suggest-moving-inner.rs:14:5 | LL | impl Trait for &Vec> | ^^^^^^^^-----^^^^^^^^^^^^^^^^^---------------------------------- @@ -10,7 +10,7 @@ LL | impl Trait for &Vec> = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/suggest-moving-inner.rs:5:1 + --> $DIR/suggest-moving-inner.rs:7:1 | LL | fn main() { | ^^^^^^^^^ @@ -23,7 +23,11 @@ LL | struct InsideMain; LL | trait HasFoo {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/suggest-moving-inner.rs:3:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs index 4291426e046a8..b726398bf9c9a 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs @@ -3,6 +3,8 @@ // https://github.com/rust-lang/rust/issues/123573#issue-2229428739 +#![warn(non_local_definitions)] + pub trait Test {} impl<'a, T: 'a> Test for &[T] where &'a T: Test {} diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr index 80930ce1bcdf3..2eb71cecacaaf 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/trait-solver-overflow-123573.rs:12:5 + --> $DIR/trait-solver-overflow-123573.rs:14:5 | LL | impl Test for &Local {} | ^^^^^----^^^^^------ @@ -11,14 +11,18 @@ LL | impl Test for &Local {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/trait-solver-overflow-123573.rs:10:1 + --> $DIR/trait-solver-overflow-123573.rs:12:1 | LL | fn main() { | ^^^^^^^^^ LL | struct Local {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/trait-solver-overflow-123573.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/weird-exprs.rs b/tests/ui/lint/non-local-defs/weird-exprs.rs index 1d9cecea0c971..fbf1fd941eecb 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.rs +++ b/tests/ui/lint/non-local-defs/weird-exprs.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Uto {} struct Test; diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr index cd414d636d34b..49aba904ebb0e 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.stderr +++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:8:5 + --> $DIR/weird-exprs.rs:10:5 | LL | type A = [u32; { | ________________- @@ -16,10 +16,14 @@ LL | | }]; = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/weird-exprs.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:16:9 + --> $DIR/weird-exprs.rs:18:9 | LL | Discr = { | _____________- @@ -38,7 +42,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:25:9 + --> $DIR/weird-exprs.rs:27:9 | LL | let _array = [0i32; { | _________________________- @@ -57,7 +61,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:34:9 + --> $DIR/weird-exprs.rs:36:9 | LL | type A = [u32; { | ____________________- @@ -76,7 +80,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:41:9 + --> $DIR/weird-exprs.rs:43:9 | LL | fn a(_: [u32; { | ___________________- @@ -95,7 +99,7 @@ LL | | }]) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:48:9 + --> $DIR/weird-exprs.rs:50:9 | LL | fn b() -> [u32; { | _____________________- From 151986f493bce146db808db2bbb2b29fa6e0049c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Jun 2024 10:22:03 +0200 Subject: [PATCH 090/217] Implement `x perf` as a separate tool --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/bootstrap/src/core/build_steps/perf.rs | 32 ++--- src/bootstrap/src/core/build_steps/tool.rs | 1 + src/bootstrap/src/core/config/flags.rs | 4 +- src/etc/completions/x.py.fish | 2 +- src/etc/completions/x.py.ps1 | 2 +- src/etc/completions/x.py.zsh | 2 +- src/tools/rustc-perf-wrapper/Cargo.toml | 7 ++ src/tools/rustc-perf-wrapper/README.md | 3 + src/tools/rustc-perf-wrapper/src/config.rs | 45 +++++++ src/tools/rustc-perf-wrapper/src/main.rs | 130 +++++++++++++++++++++ 12 files changed, 211 insertions(+), 25 deletions(-) create mode 100644 src/tools/rustc-perf-wrapper/Cargo.toml create mode 100644 src/tools/rustc-perf-wrapper/README.md create mode 100644 src/tools/rustc-perf-wrapper/src/config.rs create mode 100644 src/tools/rustc-perf-wrapper/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 241a37588b409..b1b7020f29000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3453,6 +3453,13 @@ dependencies = [ "stable_mir", ] +[[package]] +name = "rustc-perf-wrapper" +version = "0.1.0" +dependencies = [ + "clap", +] + [[package]] name = "rustc-rayon" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index c17ea99d03767..93c520b0d689d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ members = [ "src/tools/rustdoc-gui-test", "src/tools/opt-dist", "src/tools/coverage-dump", + "src/tools/rustc-perf-wrapper", ] exclude = [ diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 9d70ca6bd71fd..f8170580722bf 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -1,7 +1,5 @@ -use std::process::Command; - use crate::core::build_steps::compile::{Std, Sysroot}; -use crate::core::build_steps::tool::RustcPerf; +use crate::core::build_steps::tool::{RustcPerf, Tool}; use crate::core::builder::Builder; use crate::core::config::DebuginfoLevel; @@ -22,24 +20,16 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let sysroot = builder.ensure(Sysroot::new(compiler)); let rustc = sysroot.join("bin/rustc"); - let results_dir = builder.build.tempdir().join("rustc-perf"); - - let mut cmd = Command::new(collector); - let cmd = cmd - .arg("profile_local") - .arg("eprintln") - .arg("--out-dir") - .arg(&results_dir) - .arg("--include") - .arg("helloworld") - .arg(&rustc); - - builder.info(&format!("Running `rustc-perf` using `{}`", rustc.display())); + let rustc_perf_dir = builder.build.tempdir().join("rustc-perf"); + let profile_results_dir = rustc_perf_dir.join("results"); - // We need to set the working directory to `src/tools/perf`, so that it can find the directory - // with compile-time benchmarks. - let cmd = cmd.current_dir(builder.src.join("src/tools/rustc-perf")); - builder.build.run(cmd); + // We need to take args passed after `--` and pass them to `rustc-perf-wrapper` + let args = std::env::args().skip_while(|a| a != "--").skip(1); - builder.info(&format!("You can find the results at `{}`", results_dir.display())); + let mut cmd = builder.tool_cmd(Tool::RustcPerfWrapper); + cmd.env("PERF_RUSTC", rustc) + .env("PERF_COLLECTOR", collector) + .env("PERF_RESULT_DIR", profile_results_dir) + .args(args); + builder.run(&mut cmd); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 7411d0ba2befe..2ceca7305a621 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -336,6 +336,7 @@ bootstrap_tool!( GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys"; RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test"; CoverageDump, "src/tools/coverage-dump", "coverage-dump"; + RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper"; ); #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index eb5152a38312b..aeb608a9ea26b 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -470,7 +470,9 @@ Arguments: versioned_dirs: bool, }, /// Perform profiling and benchmarking of the compiler using the - /// `rustc-perf` benchmark suite. + /// `rustc-perf-wrapper` tool. + /// + /// You need to pass arguments after `--`, e.g.`x perf -- cachegrind`. Perf {}, } diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 2072f76a48181..805fc8aa8ccd0 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -48,7 +48,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files' complete -c x.py -n "__fish_use_subcommand" -f -a "vendor" -d 'Vendor dependencies' -complete -c x.py -n "__fish_use_subcommand" -f -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite' +complete -c x.py -n "__fish_use_subcommand" -f -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool' complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 919382d441ffc..ce590d2fa4897 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -75,7 +75,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files') [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies') - [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite') + [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool') break } 'x.py;build' { diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index bbebf8b892d1f..fc8be4f788127 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -856,7 +856,7 @@ _x.py_commands() { 'setup:Set up the environment for development' \ 'suggest:Suggest a subset of tests to run, based on modified files' \ 'vendor:Vendor dependencies' \ -'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf\` benchmark suite' \ +'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf-wrapper\` tool' \ ) _describe -t commands 'x.py commands' commands "$@" } diff --git a/src/tools/rustc-perf-wrapper/Cargo.toml b/src/tools/rustc-perf-wrapper/Cargo.toml new file mode 100644 index 0000000000000..416bfef41d7fd --- /dev/null +++ b/src/tools/rustc-perf-wrapper/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rustc-perf-wrapper" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.5.7", features = ["derive", "env"] } diff --git a/src/tools/rustc-perf-wrapper/README.md b/src/tools/rustc-perf-wrapper/README.md new file mode 100644 index 0000000000000..7c096e3081416 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/README.md @@ -0,0 +1,3 @@ +# rustc-perf wrapper +Utility tool for invoking [`rustc-perf`](https://github.com/rust-lang/rustc-perf) for benchmarking/profiling +a stage1/2 compiler built by bootstrap using `x run perf`. diff --git a/src/tools/rustc-perf-wrapper/src/config.rs b/src/tools/rustc-perf-wrapper/src/config.rs new file mode 100644 index 0000000000000..a88abfe472377 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/src/config.rs @@ -0,0 +1,45 @@ +use std::fmt::{Display, Formatter}; + +#[derive(Clone, Copy, Debug, clap::ValueEnum)] +#[value(rename_all = "PascalCase")] +pub enum Profile { + Check, + Debug, + Doc, + Opt, + Clippy, +} + +impl Display for Profile { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let name = match self { + Profile::Check => "Check", + Profile::Debug => "Debug", + Profile::Doc => "Doc", + Profile::Opt => "Opt", + Profile::Clippy => "Clippy", + }; + f.write_str(name) + } +} + +#[derive(Clone, Copy, Debug, clap::ValueEnum)] +#[value(rename_all = "PascalCase")] +pub enum Scenario { + Full, + IncrFull, + IncrUnchanged, + IncrPatched, +} + +impl Display for Scenario { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let name = match self { + Scenario::Full => "Full", + Scenario::IncrFull => "IncrFull", + Scenario::IncrUnchanged => "IncrUnchanged", + Scenario::IncrPatched => "IncrPatched", + }; + f.write_str(name) + } +} diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs new file mode 100644 index 0000000000000..0974661f99787 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -0,0 +1,130 @@ +use crate::config::{Profile, Scenario}; +use clap::Parser; +use std::path::PathBuf; +use std::process::Command; + +mod config; + +/// Performs profiling or benchmarking with [`rustc-perf`](https://github.com/rust-lang/rustc-perf) +/// using a locally built compiler. +#[derive(Debug, clap::Parser)] +// Hide arguments from BuildContext in the default usage string. +// Clap does not seem to have a way of disabling the usage of these arguments. +#[clap(override_usage = "rustc-perf-wrapper [OPTIONS] ")] +pub struct Args { + #[clap(subcommand)] + cmd: PerfCommand, + + #[clap(flatten)] + opts: SharedOpts, + + #[clap(flatten)] + ctx: BuildContext, +} + +#[derive(Debug, clap::Parser)] +enum PerfCommand { + /// Run `profile_local eprintln`. + /// This executes the compiler on the given benchmarks and stores its stderr output. + Eprintln, + /// Run `profile_local samply` + /// This executes the compiler on the given benchmarks and profiles it with `samply`. + /// You need to install `samply`, e.g. using `cargo install samply`. + Samply, + /// Run `profile_local cachegrind`. + /// This executes the compiler on the given benchmarks under `Cachegrind`. + Cachegrind, +} + +impl PerfCommand { + fn is_profiling(&self) -> bool { + match self { + PerfCommand::Eprintln | PerfCommand::Samply | PerfCommand::Cachegrind => true, + } + } +} + +#[derive(Debug, clap::Parser)] +struct SharedOpts { + /// Select the benchmarks that you want to run (separated by commas). + /// If unspecified, all benchmarks will be executed. + #[clap(long, global = true, value_delimiter = ',')] + include: Vec, + /// Select the scenarios that should be benchmarked. + #[clap( + long, + global = true, + value_delimiter = ',', + default_value = "Full,IncrFull,IncrUnchanged,IncrPatched" + )] + scenarios: Vec, + /// Select the profiles that should be benchmarked. + #[clap(long, global = true, value_delimiter = ',', default_value = "Check,Debug,Opt")] + profiles: Vec, +} + +/// These arguments are mostly designed to be passed from bootstrap, not by users +/// directly. +#[derive(Debug, clap::Parser)] +struct BuildContext { + /// Compiler binary that will be benchmarked/profiled. + #[clap(long, hide = true, env = "PERF_RUSTC")] + compiler: PathBuf, + /// rustc-perf collector binary that will be used for running benchmarks/profilers. + #[clap(long, hide = true, env = "PERF_COLLECTOR")] + collector: PathBuf, + /// Directory where to store results. + #[clap(long, hide = true, env = "PERF_RESULT_DIR")] + results_dir: PathBuf, +} + +fn main() { + let args = Args::parse(); + run(args); +} + +fn run(args: Args) { + let mut cmd = Command::new(args.ctx.collector); + match &args.cmd { + PerfCommand::Eprintln => { + cmd.arg("profile_local").arg("eprintln"); + } + PerfCommand::Samply => { + cmd.arg("profile_local").arg("samply"); + } + PerfCommand::Cachegrind => { + cmd.arg("profile_local").arg("cachegrind"); + } + } + if args.cmd.is_profiling() { + cmd.arg("--out-dir").arg(&args.ctx.results_dir); + } + + if !args.opts.include.is_empty() { + cmd.arg("--include").arg(args.opts.include.join(",")); + } + if !args.opts.profiles.is_empty() { + cmd.arg("--profiles") + .arg(args.opts.profiles.iter().map(|p| p.to_string()).collect::>().join(",")); + } + if !args.opts.scenarios.is_empty() { + cmd.arg("--scenarios") + .arg(args.opts.scenarios.iter().map(|p| p.to_string()).collect::>().join(",")); + } + cmd.arg(&args.ctx.compiler); + + println!("Running `rustc-perf` using `{}`", args.ctx.compiler.display()); + + const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); + + let rustc_perf_dir = PathBuf::from(MANIFEST_DIR).join("../rustc-perf"); + + // We need to set the working directory to `src/tools/perf`, so that it can find the directory + // with compile-time benchmarks. + let cmd = cmd.current_dir(rustc_perf_dir); + cmd.status().expect("error while running rustc-perf collector"); + + if args.cmd.is_profiling() { + println!("You can find the results at `{}`", args.ctx.results_dir.display()); + } +} From ba198af81f75ef01b7d603a7b1c001fafe8ad4a4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 09:07:57 +0000 Subject: [PATCH 091/217] Rename `'cx` to `'infcx` --- .../rustc_borrowck/src/borrowck_errors.rs | 50 +++++++++---------- .../src/diagnostics/bound_region_errors.rs | 30 +++++------ .../src/diagnostics/conflict_errors.rs | 24 ++++----- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 6 +-- .../src/diagnostics/mutability_errors.rs | 8 +-- .../src/diagnostics/region_errors.rs | 8 +-- compiler/rustc_borrowck/src/lib.rs | 46 ++++++++--------- compiler/rustc_borrowck/src/used_muts.rs | 4 +- compiler/rustc_hir_typeck/src/coercion.rs | 6 +-- 10 files changed, 93 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 604feeb47feaf..8eb44458137ff 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,8 +6,8 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'cx> { +impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'infcx> { self.infcx.dcx() } @@ -18,7 +18,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { place: &str, borrow_place: &str, value_place: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { self.dcx().create_err(crate::session_diagnostics::MoveBorrow { place, span, @@ -34,7 +34,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -54,7 +54,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -101,7 +101,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -134,7 +134,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -166,7 +166,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -198,7 +198,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -239,7 +239,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -256,12 +256,12 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } - pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'cx> { + pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } @@ -269,7 +269,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -287,7 +287,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let type_name = match (&ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -308,7 +308,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -325,7 +325,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); struct_span_code_err!( @@ -344,7 +344,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, path: &str, reason: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -362,7 +362,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), mutate_span, @@ -380,7 +380,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, span: Span, yield_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; struct_span_code_err!( self.dcx(), @@ -391,7 +391,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { .with_span_label(yield_span, "possible yield occurs here") } - pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'cx> { + pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), borrow_span, @@ -400,7 +400,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { ) } - pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'cx> { + pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) } @@ -410,7 +410,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -433,7 +433,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { borrowed_path: &str, capture_span: Span, scope: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), closure_span, @@ -445,7 +445,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } - pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'cx> { + pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -454,7 +454,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { ) } - pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'cx> { + pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index c4275e1393509..8bf3e670ff228 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; #[instrument(level = "debug", skip(self, mbcx))] fn report_error( @@ -231,13 +231,13 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -275,13 +275,13 @@ where self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -322,13 +322,13 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -355,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 74ebfc54182b6..d72c5962929fc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -341,7 +341,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { fn suggest_ref_or_clone( &self, mpi: MovePathIndex, - err: &mut Diag<'cx>, + err: &mut Diag<'infcx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, ) { @@ -517,7 +517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { // We need all statements in the body where the binding was assigned to later find all // the branching code paths where the binding *wasn't* assigned to. let inits = &self.move_data.init_path_map[mpi]; @@ -1441,7 +1441,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -1491,7 +1491,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -1782,7 +1782,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { err } - fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'cx>, place: Place<'tcx>) { + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'infcx>, place: Place<'tcx>) { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; @@ -2841,7 +2841,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -3016,7 +3016,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, drop_span: Span, borrow_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -3041,7 +3041,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { @@ -3206,7 +3206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Result<(), Diag<'cx>> { + ) -> Result<(), Diag<'infcx>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -3299,7 +3299,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { constraint_span: Span, captured_var: &str, scope: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -3411,7 +3411,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { upvar_span: Span, upvar_name: Symbol, escape_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 3bc7083976e44..4567a014fe83d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -86,7 +86,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, location: Location, place: PlaceRef<'tcx>, - diag: &mut Diag<'cx>, + diag: &mut Diag<'infcx>, ) -> bool { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); let mut target = place.local_or_deref_local(); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 40a6a65649a35..b82ffe63266e4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { @@ -291,7 +291,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { self.buffer_error(err); } - fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'cx> { + fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -428,7 +428,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6d92f0cdd988a..19a4df0cd7b43 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, @@ -541,7 +541,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { } /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. - fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'cx>, span: Span) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'infcx>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) @@ -550,9 +550,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Walks through the HIR, looking for the corresponding span for this error. /// When it finds it, see if it corresponds to assignment operator whose LHS /// is an index expr. - struct SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { + struct SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> { assign_span: Span, - err: &'a mut Diag<'cx>, + err: &'a mut Diag<'infcx>, ty: Ty<'tcx>, suggested: bool, } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index dd22f8d8440ee..fba18c381466b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is @@ -589,7 +589,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -658,7 +658,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` #[instrument(level = "debug", skip(self))] - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -767,7 +767,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// | is returning data with lifetime `'b` /// ``` #[allow(rustc::diagnostic_outside_of_impl)] // FIXME - fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { let ErrorConstraintInfo { fr, fr_is_local, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8aea8ae188898..e6f8ffd428d06 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -310,8 +310,8 @@ fn do_mir_borrowck<'tcx>( promoted_mbcx.report_move_errors(); diags = promoted_mbcx.diags; - struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>, + struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>, } impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { @@ -528,8 +528,8 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { - infcx: &'cx BorrowckInferCtxt<'tcx>, +struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> { + infcx: &'infcx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>, @@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: diags::BorrowckDiags<'cx, 'tcx>, + diags: diags::BorrowckDiags<'infcx, 'tcx>, move_errors: Vec>, } @@ -2428,12 +2428,12 @@ mod diags { use super::*; - enum BufferedDiag<'cx> { - Error(Diag<'cx>), - NonError(Diag<'cx, ()>), + enum BufferedDiag<'infcx> { + Error(Diag<'infcx>), + NonError(Diag<'infcx, ()>), } - impl<'cx> BufferedDiag<'cx> { + impl<'infcx> BufferedDiag<'infcx> { fn sort_span(&self) -> Span { match self { BufferedDiag::Error(diag) => diag.sort_span, @@ -2442,7 +2442,7 @@ mod diags { } } - pub struct BorrowckDiags<'cx, 'tcx> { + pub struct BorrowckDiags<'infcx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -2457,15 +2457,15 @@ mod diags { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'cx>)>, + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, - buffered_mut_errors: FxIndexMap, usize)>, + buffered_mut_errors: FxIndexMap, usize)>, /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, + buffered_diags: Vec>, } - impl<'cx, 'tcx> BorrowckDiags<'cx, 'tcx> { + impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { pub fn new() -> Self { BorrowckDiags { buffered_move_errors: BTreeMap::new(), @@ -2474,28 +2474,28 @@ mod diags { } } - pub fn buffer_error(&mut self, diag: Diag<'cx>) { + pub fn buffer_error(&mut self, diag: Diag<'infcx>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } } - impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { - pub fn buffer_error(&mut self, diag: Diag<'cx>) { + impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { + pub fn buffer_error(&mut self, diag: Diag<'infcx>) { self.diags.buffer_error(diag); } - pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.diags.buffer_non_error(diag); } pub fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'cx>), + place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), ) -> bool { if let Some((_, diag)) = self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -2508,12 +2508,12 @@ mod diags { } } - pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'cx>, usize)> { + pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags.buffered_mut_errors.swap_remove(&span) } - pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'cx>, count: usize) { + pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { self.diags.buffered_mut_errors.insert(span, (diag, count)); } @@ -2554,7 +2554,7 @@ mod diags { pub fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'cx>)> { + ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { self.diags.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 25e1f6268e062..e2de6b8b4a929 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -45,10 +45,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> { +struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'infcx, 'tcx> { temporary_used_locals: FxIndexSet, never_initialized_mut_locals: &'visit mut FxIndexSet, - mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>, + mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>, } impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f055a77696180..f72e8a4afdef6 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); } - fn report_return_mismatched_types<'cx>( + fn report_return_mismatched_types<'infcx>( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, ty_err: TypeError<'tcx>, - fcx: &'cx FnCtxt<'_, 'tcx>, + fcx: &'infcx FnCtxt<'_, 'tcx>, block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); From f026e0bfc16633d225dbc49e5b4da048bd419831 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 27 Jun 2024 11:04:16 +0200 Subject: [PATCH 092/217] Cleanup bootstrap check-cfg --- library/alloc/Cargo.toml | 2 -- library/core/Cargo.toml | 2 -- library/std/Cargo.toml | 2 -- src/bootstrap/src/lib.rs | 37 ++++--------------------------------- 4 files changed, 4 insertions(+), 39 deletions(-) diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 024b92790e970..612452a960a37 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -47,8 +47,6 @@ optimize_for_size = ["core/optimize_for_size"] [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_global_oom_handling)', diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index cf9fddd269aa4..cace4582b489a 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -39,8 +39,6 @@ debug_refcell = [] [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 32479cd2836fa..358510b8f77d8 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -100,8 +100,6 @@ test = true [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(target_arch, values("xtensa"))', diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfc30298c28d2..fac72e27f6293 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -74,7 +74,7 @@ const LLVM_TOOLS: &[&str] = &[ /// LLD file names for all flavors. const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; -/// Extra --check-cfg to add when building +/// Extra `--check-cfg` to add when building the compiler or tools /// (Mode restriction, config name, config values (if any)) #[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above. const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ @@ -84,38 +84,9 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ (Some(Mode::ToolRustc), "rust_analyzer", None), (Some(Mode::ToolStd), "rust_analyzer", None), (Some(Mode::Codegen), "parallel_compiler", None), - // NOTE: consider updating `check-cfg` entries in `std/Cargo.toml` too. - // cfg(bootstrap) remove these once the bootstrap compiler supports - // `lints.rust.unexpected_cfgs.check-cfg` - (Some(Mode::Std), "stdarch_intel_sde", None), - (Some(Mode::Std), "no_fp_fmt_parse", None), - (Some(Mode::Std), "no_global_oom_handling", None), - (Some(Mode::Std), "no_rc", None), - (Some(Mode::Std), "no_sync", None), - /* Extra values not defined in the built-in targets yet, but used in std */ - (Some(Mode::Std), "target_env", Some(&["libnx", "p2"])), - (Some(Mode::Std), "target_os", Some(&["visionos"])), - (Some(Mode::Std), "target_arch", Some(&["arm64ec", "spirv", "nvptx", "xtensa"])), - (Some(Mode::ToolStd), "target_os", Some(&["visionos"])), - /* Extra names used by dependencies */ - // FIXME: Used by serde_json, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "no_btreemap_remove_entry", None), - (Some(Mode::ToolRustc), "no_btreemap_remove_entry", None), - // FIXME: Used by crossbeam-utils, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "crossbeam_loom", None), - (Some(Mode::ToolRustc), "crossbeam_loom", None), - // FIXME: Used by proc-macro2, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "span_locations", None), - (Some(Mode::ToolRustc), "span_locations", None), - // FIXME: Used by rustix, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "rustix_use_libc", None), - (Some(Mode::ToolRustc), "rustix_use_libc", None), - // FIXME: Used by filetime, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "emulate_second_only_system", None), - (Some(Mode::ToolRustc), "emulate_second_only_system", None), - // Needed to avoid the need to copy windows.lib into the sysroot. - (Some(Mode::Rustc), "windows_raw_dylib", None), - (Some(Mode::ToolRustc), "windows_raw_dylib", None), + // Any library specific cfgs like `target_os`, `target_arch` should be put in + // priority the `[lints.rust.unexpected_cfgs.check-cfg]` table + // in the appropriate `library/{std,alloc,core}/Cargo.toml` ]; /// A structure representing a Rust compiler. From 648cb1692050ecbcb5dfbb21623debbf5244ff15 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Jun 2024 08:11:16 -0500 Subject: [PATCH 093/217] Enable const casting for `f16` and `f128` --- .../rustc_const_eval/src/interpret/cast.rs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index a13630ce084d5..83b61ab17492c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,6 +1,6 @@ use std::assert_matches::assert_matches; -use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; @@ -187,10 +187,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty) }; let val = match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty), FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty), }; Ok(ImmTy::from_scalar(val, cast_to)) } @@ -296,18 +296,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Float(fty) if signed => { let v = v as i128; match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value), } } // unsigned int -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value), }, // u8 -> char @@ -321,7 +321,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Low-level cast helper function. Converts an apfloat `f` into int or float types. fn cast_from_float(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar where - F: Float + Into> + FloatConvert + FloatConvert, + F: Float + + Into> + + FloatConvert + + FloatConvert + + FloatConvert + + FloatConvert, { use rustc_type_ir::TyKind::*; @@ -358,10 +363,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // float -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => { + Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value)) + } }, // That's it. _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty), From 4a11ab0b343239c38d7760c973f5be65dddeadc2 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Thu, 27 Jun 2024 16:45:56 +0800 Subject: [PATCH 094/217] Fix Markdown tables in platform-support.md These table entries have wrong number of columns so the "notes" field is missing from the rendered page. Fix by removing excess empty columns. --- src/doc/rustc/src/platform-support.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 71dc8c4ca0f92..f5cd4bd217a32 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -168,12 +168,12 @@ target | std | notes `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI -[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) -[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) +[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) +[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) -[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IM ISA) +[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) @@ -193,7 +193,7 @@ target | std | notes `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI -[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX `x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia` From bd111f5c4bbf3726ef0c9daf78c16c453bf5cb3d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 09:45:26 +0000 Subject: [PATCH 095/217] Document new field and function --- compiler/rustc_errors/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 242684e63a082..2086d4030f905 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -418,6 +418,8 @@ pub struct DiagCtxt { #[derive(Copy, Clone)] pub struct DiagCtxtHandle<'a> { dcx: &'a DiagCtxt, + /// Some contexts create `DiagCtxtHandle` with this field set, and thus all + /// errors emitted with it will automatically taint when emitting errors. tainted_with_errors: Option<&'a Cell>>, } @@ -757,6 +759,9 @@ impl DiagCtxt { DiagCtxtHandle { dcx: self, tainted_with_errors: None } } + /// Link this to a taintable context so that emitting errors will automatically set + /// the `Option` instead of having to do that manually at every error + /// emission site. pub fn taintable_handle<'a>( &'a self, tainted_with_errors: &'a Cell>, From 81c2c575192d8d6cc79e67187cd17cc2ed831b12 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:01:49 -0400 Subject: [PATCH 096/217] Make queries more explicit --- compiler/rustc_hir_analysis/src/collect.rs | 14 ++++---- .../src/collect/predicates_of.rs | 12 +++---- .../src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 8 ++--- .../src/multiple_supertrait_upcastable.rs | 2 +- .../src/rmeta/decoder/cstore_impl.rs | 4 +-- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++--- compiler/rustc_metadata/src/rmeta/mod.rs | 6 ++-- compiler/rustc_middle/src/query/mod.rs | 32 +++++++++++-------- compiler/rustc_middle/src/traits/util.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 9 ++++-- compiler/rustc_middle/src/ty/vtable.rs | 2 +- .../src/solve/assembly/structural_traits.rs | 5 +-- .../src/traits/object_safety.rs | 4 +-- .../src/traits/select/confirmation.rs | 2 +- .../rustc_trait_selection/src/traits/util.rs | 2 +- .../src/traits/vtable.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 3 +- src/librustdoc/clean/simplify.rs | 2 +- .../src/implied_bounds_in_impls.rs | 2 +- .../src/methods/type_id_on_box.rs | 2 +- .../clippy_lints/src/needless_maybe_sized.rs | 2 +- 22 files changed, 68 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e7892f1766067..18aff6a4d5a16 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -70,10 +70,10 @@ pub fn provide(providers: &mut Providers) { predicates_of: predicates_of::predicates_of, predicates_defined_on, explicit_predicates_of: predicates_of::explicit_predicates_of, - super_predicates_of: predicates_of::super_predicates_of, - implied_predicates_of: predicates_of::implied_predicates_of, - super_predicates_that_define_assoc_item: - predicates_of::super_predicates_that_define_assoc_item, + explicit_super_predicates_of: predicates_of::explicit_super_predicates_of, + explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of, + explicit_supertraits_containing_assoc_item: + predicates_of::explicit_supertraits_containing_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, @@ -691,14 +691,14 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::Trait(..) => { tcx.ensure().generics_of(def_id); tcx.ensure().trait_def(def_id); - tcx.at(it.span).super_predicates_of(def_id); + tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.ensure().predicates_of(def_id); tcx.ensure().associated_items(def_id); } hir::ItemKind::TraitAlias(..) => { tcx.ensure().generics_of(def_id); - tcx.at(it.span).implied_predicates_of(def_id); - tcx.at(it.span).super_predicates_of(def_id); + tcx.at(it.span).explicit_implied_predicates_of(def_id); + tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.ensure().predicates_of(def_id); } hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 3421c8da4e9f3..8ba524e72eb3d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -519,21 +519,21 @@ pub(super) fn explicit_predicates_of<'tcx>( /// Ensures that the super-predicates of the trait with a `DefId` /// of `trait_def_id` are lowered and stored. This also ensures that /// the transitive super-predicates are lowered. -pub(super) fn super_predicates_of( +pub(super) fn explicit_super_predicates_of( tcx: TyCtxt<'_>, trait_def_id: LocalDefId, ) -> ty::GenericPredicates<'_> { implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly) } -pub(super) fn super_predicates_that_define_assoc_item( +pub(super) fn explicit_supertraits_containing_assoc_item( tcx: TyCtxt<'_>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::GenericPredicates<'_> { implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name)) } -pub(super) fn implied_predicates_of( +pub(super) fn explicit_implied_predicates_of( tcx: TyCtxt<'_>, trait_def_id: LocalDefId, ) -> ty::GenericPredicates<'_> { @@ -560,7 +560,7 @@ pub(super) fn implied_predicates_with_filter( // if `assoc_name` is None, then the query should've been redirected to an // external provider assert!(matches!(filter, PredicateFilter::SelfThatDefines(_))); - return tcx.super_predicates_of(trait_def_id); + return tcx.explicit_super_predicates_of(trait_def_id); }; let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else { @@ -601,7 +601,7 @@ pub(super) fn implied_predicates_with_filter( if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder() && bound.polarity == ty::PredicatePolarity::Positive { - tcx.at(span).super_predicates_of(bound.def_id()); + tcx.at(span).explicit_super_predicates_of(bound.def_id()); } } } @@ -611,7 +611,7 @@ pub(super) fn implied_predicates_with_filter( if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder() && bound.polarity == ty::PredicatePolarity::Positive { - tcx.at(span).implied_predicates_of(bound.def_id()); + tcx.at(span).explicit_implied_predicates_of(bound.def_id()); } } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index abc3bb838db3e..f953e32416298 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1760,7 +1760,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if let Some(assoc_item) = trait_defines_associated_item_named(def_id) { break Some((bound_vars.into_iter().collect(), assoc_item)); } - let predicates = tcx.super_predicates_that_define_assoc_item((def_id, assoc_name)); + let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_name)); let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index ab4148faaab63..24cf9f03fcdb3 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -275,10 +275,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { } // Get predicates implied by the trait, or only super predicates if we only care about self predicates. let predicates = match self.mode { - Filter::All => tcx.implied_predicates_of(data.def_id()), - Filter::OnlySelf => tcx.super_predicates_of(data.def_id()), + Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), + Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), Filter::OnlySelfThatDefines(ident) => { - tcx.super_predicates_that_define_assoc_item((data.def_id(), ident)) + tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident)) } }; @@ -420,7 +420,7 @@ pub fn transitive_bounds<'tcx>( /// A specialized variant of `elaborate` that only elaborates trait references that may /// define the given associated item with the name `assoc_name`. It uses the -/// `super_predicates_that_define_assoc_item` query to avoid enumerating super-predicates that +/// `explicit_supertraits_containing_assoc_item` query to avoid enumerating super-predicates that /// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or /// `T::Item` and helps to avoid cycle errors (see e.g. #35237). pub fn transitive_bounds_that_define_assoc_item<'tcx>( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index aa1d94228ea22..445dcd41e5d52 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { { let direct_super_traits_iter = cx .tcx - .super_predicates_of(def_id) + .explicit_super_predicates_of(def_id) .predicates .into_iter() .filter_map(|(pred, _)| pred.as_trait_clause()); diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c9450142cd3be..743ceb1ee6cdf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -211,8 +211,8 @@ provide! { tcx, def_id, other, cdata, explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } - super_predicates_of => { table } - implied_predicates_of => { table } + explicit_super_predicates_of => { table } + explicit_implied_predicates_of => { table } type_of => { table } type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) } variances_of => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4bd2ec09a6e6f..957e578a08e9d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1431,8 +1431,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::Trait = def_kind { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); - record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); - record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id)); + record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id)); + record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id)); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- @@ -1440,8 +1440,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::TraitAlias = def_kind { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); - record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); - record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id)); + record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id)); + record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id)); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 87900c23d8daf..5f729fa8e3466 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -416,10 +416,10 @@ define_tables! { lookup_deprecation_entry: Table>, explicit_predicates_of: Table>>, generics_of: Table>, - super_predicates_of: Table>>, + explicit_super_predicates_of: Table>>, // As an optimization, we only store this for trait aliases, - // since it's identical to super_predicates_of for traits. - implied_predicates_of: Table>>, + // since it's identical to explicit_super_predicates_of for traits. + explicit_implied_predicates_of: Table>>, type_of: Table>>>, variances_of: Table>, fn_sig: Table>>>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 230a44bcf2452..86a415772de8a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -646,6 +646,9 @@ rustc_queries! { } /// Returns the predicates written explicitly by the user. + /// + /// You should probably use `predicates_of` unless you're looking for + /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -662,29 +665,32 @@ rustc_queries! { feedable } - /// Maps from the `DefId` of a trait to the list of - /// super-predicates. This is a subset of the full list of - /// predicates. We store these in a separate map because we must - /// evaluate them even during type conversion, often before the - /// full predicates are available (note that supertraits have - /// additional acyclicity requirements). - query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + /// Maps from the `DefId` of a trait to the list of super-predicates of the trait, + /// *before* elaboration (so it doesn't contain transitive super-predicates). This + /// is a subset of the full list of predicates. We store these in a separate map + /// because we must evaluate them even during type conversion, often before the full + /// predicates are available (note that super-predicates must not be cyclic). + query explicit_super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - query implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + /// The predicates of the trait that are implied during elaboration. This is a + /// superset of the super-predicates of the trait, but a subset of the predicates + /// of the trait. For regular traits, this includes all super-predicates and their + /// associated type bounds. For trait aliases, currently, this includes all of the + /// predicates of the trait alias. + query explicit_implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - /// The `Option` is the name of an associated type. If it is `None`, then this query - /// returns the full set of predicates. If `Some`, then the query returns only the - /// subset of super-predicates that reference traits that define the given associated type. - /// This is used to avoid cycles in resolving types like `T::Item`. - query super_predicates_that_define_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { + /// The Ident is the name of an associated type.The query returns only the subset + /// of supertraits that define the given associated type. This is used to avoid + /// cycles in resolving type-dependent associated item paths like `T::Item`. + query explicit_supertraits_containing_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", tcx.def_path_str(key.0), key.1 diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs index adbb6cf2ddc94..7437be7a74c14 100644 --- a/compiler/rustc_middle/src/traits/util.rs +++ b/compiler/rustc_middle/src/traits/util.rs @@ -35,7 +35,7 @@ struct Elaborator<'tcx> { impl<'tcx> Elaborator<'tcx> { fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) { let super_predicates = - self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( + self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( |&(pred, _)| { let clause = pred.instantiate_supertrait(self.tcx, trait_ref); self.visited.insert(clause).then_some(clause) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4bac9396e59a9..4391e2516759b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -342,12 +342,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) } - fn super_predicates_of( + fn explicit_super_predicates_of( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { ty::EarlyBinder::bind( - self.super_predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), + self.explicit_super_predicates_of(def_id) + .instantiate_identity(self) + .predicates + .into_iter(), ) } @@ -2473,7 +2476,7 @@ impl<'tcx> TyCtxt<'tcx> { iter::from_fn(move || -> Option { let trait_did = stack.pop()?; - let generic_predicates = self.super_predicates_of(trait_did); + let generic_predicates = self.explicit_super_predicates_of(trait_did); for (predicate, _) in generic_predicates.predicates { if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() { diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index dc3c84f9e439a..38da279ec58a3 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -67,7 +67,7 @@ impl Iterator for SupertraitDefIds<'_> { fn next(&mut self) -> Option { let def_id = self.stack.pop()?; - let predicates = self.tcx.super_predicates_of(def_id); + let predicates = self.tcx.explicit_super_predicates_of(def_id); let visited = &mut self.visited; self.stack.extend( predicates diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 0cef8d9f4bc34..3447b39fa5b40 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -668,8 +668,9 @@ where { let cx = ecx.cx(); let mut requirements = vec![]; - requirements - .extend(cx.super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args)); + requirements.extend( + cx.explicit_super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args), + ); // FIXME(associated_const_equality): Also add associated consts to // the requirements here. diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4d10d33fa6ef5..f1611bd049de9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -187,7 +187,7 @@ fn predicates_reference_self( ) -> SmallVec<[Span; 1]> { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { - tcx.super_predicates_of(trait_def_id) + tcx.explicit_super_predicates_of(trait_def_id) } else { tcx.predicates_of(trait_def_id) }; @@ -256,7 +256,7 @@ fn super_predicates_have_non_lifetime_binders( if !tcx.features().non_lifetime_binders { return SmallVec::new(); } - tcx.super_predicates_of(trait_def_id) + tcx.explicit_super_predicates_of(trait_def_id) .predicates .iter() .filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(*span)) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8c5dc88184cda..9508a3e8e1509 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -574,7 +574,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check supertraits hold. This is so that their associated type bounds // will be checked in the code below. for super_trait in tcx - .super_predicates_of(trait_predicate.def_id()) + .explicit_super_predicates_of(trait_predicate.def_id()) .instantiate(tcx, trait_predicate.trait_ref.args) .predicates .into_iter() diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index f132e36468ac2..951af4b0920cb 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -128,7 +128,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { } // Get components of trait alias. - let predicates = tcx.super_predicates_of(trait_ref.def_id()); + let predicates = tcx.explicit_super_predicates_of(trait_ref.def_id()); debug!(?predicates); let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 017b0a45d1f41..e54ced85deeb7 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -117,7 +117,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( let &(inner_most_trait_ref, _, _) = stack.last().unwrap(); let mut direct_super_traits_iter = tcx - .super_predicates_of(inner_most_trait_ref.def_id()) + .explicit_super_predicates_of(inner_most_trait_ref.def_id()) .predicates .into_iter() .filter_map(move |(pred, _)| { diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index b89ea30fc3435..6665158c7cd34 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -209,8 +209,7 @@ pub trait Interner: def_id: Self::DefId, ) -> ty::EarlyBinder>; - // FIXME: Rename this so it's obvious it's only *immediate* super predicates. - fn super_predicates_of( + fn explicit_super_predicates_of( self, def_id: Self::DefId, ) -> ty::EarlyBinder>; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index af61eb6ae8de8..58eef36677b23 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -113,7 +113,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) if child == trait_ { return true; } - let predicates = cx.tcx.super_predicates_of(child); + let predicates = cx.tcx.explicit_super_predicates_of(child); debug_assert!(cx.tcx.generics_of(child).has_self); let self_ty = cx.tcx.types.self_param; predicates diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 170ecf896b4e1..67b48878ca513 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -246,7 +246,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds && let [.., path] = poly_trait.trait_ref.path.segments && poly_trait.bound_generic_params.is_empty() && let Some(trait_def_id) = path.res.opt_def_id() - && let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates + && let predicates = cx.tcx.explicit_super_predicates_of(trait_def_id).predicates // If the trait has no supertrait, there is no need to collect anything from that bound && !predicates.is_empty() { diff --git a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs index 6f9b38fcf83cc..b62ecef0069af 100644 --- a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs +++ b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs @@ -24,7 +24,7 @@ fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { cx.tcx.is_diagnostic_item(sym::Any, tr.def_id) || cx .tcx - .super_predicates_of(tr.def_id) + .explicit_super_predicates_of(tr.def_id) .predicates .iter() .any(|(clause, _)| { diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index 4922c87b206c0..a1d8ec3b32ec9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -91,7 +91,7 @@ fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) -> return true; } - for &(predicate, _) in cx.tcx.super_predicates_of(trait_def_id).predicates { + for &(predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).predicates { if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && trait_predicate.polarity == PredicatePolarity::Positive && !path.contains(&trait_predicate.def_id()) From c9870cfa4bed1163be4e9fde814d79860f3caa57 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:06:47 -0400 Subject: [PATCH 097/217] supertrait_def_ids --- compiler/rustc_middle/src/ty/context.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4391e2516759b..d9fb10df103e1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2443,7 +2443,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name` /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`. pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool { - self.super_traits_of(trait_def_id).any(|trait_did| { + self.supertrait_def_ids(trait_def_id).any(|trait_did| { self.associated_items(trait_did) .filter_by_name_unhygienic(assoc_name.name) .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did)) @@ -2467,8 +2467,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. - /// Returns a `DefId` iterator. - fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator + 'tcx { + fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { let mut set = FxHashSet::default(); let mut stack = vec![trait_def_id]; From 1160eecba5883ba2bf96bf2b774bca189b3829a1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:29:34 -0400 Subject: [PATCH 098/217] supertrait_def_ids was already implemented in middle --- compiler/rustc_middle/src/ty/context.rs | 5 ++-- compiler/rustc_middle/src/ty/vtable.rs | 35 ------------------------- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d9fb10df103e1..ed1ec55bc8ed1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2466,8 +2466,9 @@ impl<'tcx> TyCtxt<'tcx> { /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used - /// to identify which traits may define a given associated type to help avoid cycle errors. - fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { + /// to identify which traits may define a given associated type to help avoid cycle errors, + /// and to make size estimates for vtable layout computation. + pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { let mut set = FxHashSet::default(); let mut stack = vec![trait_def_id]; diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 38da279ec58a3..466c3b93f8e5d 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -3,8 +3,6 @@ use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar}; use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use rustc_ast::Mutability; -use rustc_data_structures::fx::FxHashSet; -use rustc_hir::def_id::DefId; use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, HashStable)] @@ -42,45 +40,12 @@ impl<'tcx> fmt::Debug for VtblEntry<'tcx> { impl<'tcx> TyCtxt<'tcx> { pub const COMMON_VTABLE_ENTRIES: &'tcx [VtblEntry<'tcx>] = &[VtblEntry::MetadataDropInPlace, VtblEntry::MetadataSize, VtblEntry::MetadataAlign]; - - pub fn supertrait_def_ids(self, trait_def_id: DefId) -> SupertraitDefIds<'tcx> { - SupertraitDefIds { - tcx: self, - stack: vec![trait_def_id], - visited: Some(trait_def_id).into_iter().collect(), - } - } } pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0; pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1; pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2; -pub struct SupertraitDefIds<'tcx> { - tcx: TyCtxt<'tcx>, - stack: Vec, - visited: FxHashSet, -} - -impl Iterator for SupertraitDefIds<'_> { - type Item = DefId; - - fn next(&mut self) -> Option { - let def_id = self.stack.pop()?; - let predicates = self.tcx.explicit_super_predicates_of(def_id); - let visited = &mut self.visited; - self.stack.extend( - predicates - .predicates - .iter() - .filter_map(|(pred, _)| pred.as_trait_clause()) - .map(|trait_ref| trait_ref.def_id()) - .filter(|&super_def_id| visited.insert(super_def_id)), - ); - Some(def_id) - } -} - // Note that we don't have access to a self type here, this has to be purely based on the trait (and // supertrait) definitions. That means we can't call into the same vtable_entries code since that // returns a specific instantiation (e.g., with Vacant slots when bounds aren't satisfied). The goal From 64be3a3ea756cea1397476e93968673d88770db0 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Fri, 28 Jun 2024 01:52:59 +0800 Subject: [PATCH 099/217] Update the LoongArch target documentation The docs for the LoongArch targets are a bit dated since their introduction, and the prose has some room for improvement as well. Streamline a bit, referring to the neighboring targets' docs, and provide up-to-date information as much as I can come up with. --- .../src/platform-support/loongarch-linux.md | 139 ++++++++++++------ .../src/platform-support/loongarch-none.md | 56 ++++--- 2 files changed, 125 insertions(+), 70 deletions(-) diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index e8f55b8bfce10..45eb0a81216d8 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -1,30 +1,24 @@ -# loongarch\*-unknown-linux-\* +# `loongarch*-unknown-linux-*` -**Tier: 2** +**Tier: 2 (with Host Tools)** -[LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited. +[LoongArch][la-docs] Linux targets. +LoongArch is a RISC ISA developed by Loongson Technology Corporation Limited. -[LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html +| Target | Description | +|--------|-------------| +| `loongarch64-unknown-linux-gnu` | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) | +| `loongarch64-unknown-linux-musl` | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) | -The target name follow this format: `--`, where `` specifies the CPU family/model, `` specifies the vendor and `` the operating system name. -While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix ``. +These support both native and cross builds, and have full support for `std`. -| `` | `Description` | -|------------------------|--------------------------------------------------------------------| -| f64 | The base ABI use 64-bits FPRs for parameter passing. (lp64d)| -| f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| -| sf | The base ABI uses no FPR for parameter passing. (lp64s) | +Reference material: -
+* [LoongArch ISA manuals][la-docs] +* [Application Binary Interface for the LoongArch™ Architecture][la-abi-specs] -|`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | -|----------------------------------|-------------|----------|----------------------------------| -| lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | -| lp64f/base | glibc | linux | loongarch64-unknown-linux-gnuf32 | -| lp64s/base | glibc | linux | loongarch64-unknown-linux-gnusf | -| lp64d/base | musl libc | linux | loongarch64-unknown-linux-musl| -| lp64f/base | musl libc | linux | loongarch64-unknown-linux-muslf32| -| lp64s/base | musl libc | linux | loongarch64-unknown-linux-muslsf | +[la-abi-specs]: https://github.com/loongson/la-abi-specs +[la-docs]: https://loongson.github.io/LoongArch-Documentation/README-EN.html ## Target maintainers @@ -35,23 +29,57 @@ While the integer base ABI is implied by the machine field, the floating po ## Requirements -This target is cross-compiled. -A GNU toolchain for LoongArch target is required. It can be downloaded from https://github.com/loongson/build-tools/releases, or built from the source code of GCC (12.1.0 or later) and Binutils (2.40 or later). +### OS Version -## Building the target +The minimum supported Linux version is 5.19. -The target can be built by enabling it for a `rustc` build. +Some Linux distributions, mostly commercial ones, may provide forked Linux +kernels that has a version number less than 5.19 for their LoongArch ports. +Such kernels may still get patched to be compatible with the upstream Linux +5.19 UAPI, therefore supporting the targets described in this document, but +this is not always the case. The `rustup` installer contains a check for this, +and will abort if incompatibility is detected. + +### Host toolchain + +The targets require a reasonably up-to-date LoongArch toolchain on the host. +Currently the following components are used by the Rust CI to build the target, +and the versions can be seen as the minimum requirement: + +* GNU Binutils 2.40 +* GCC 13.x +* glibc 2.36 +* linux-headers 5.19 + +Of these, glibc and linux-headers are at their respective earliest versions with +mainline LoongArch support, so it is impossible to use older versions of these. +Older versions of Binutils and GCC will not work either, due to lack of support +for newer LoongArch ELF relocation types, among other features. + +Recent LLVM/Clang toolchains may be able to build the targets, but are not +currently being actively tested. + +## Building + +These targets are distributed through `rustup`, and otherwise require no +special configuration. + +If you need to build your own Rust for some reason though, the targets can be +simply enabled in `config.toml`. For example: ```toml [build] target = ["loongarch64-unknown-linux-gnu"] ``` -Make sure `loongarch64-unknown-linux-gnu-gcc` can be searched from the directories specified in`$PATH`. Alternatively, you can use GNU LoongArch Toolchain by adding the following to `config.toml`: +Make sure the LoongArch toolchain binaries are reachable from `$PATH`. +Alternatively, you can explicitly configure the paths in `config.toml`: ```toml [target.loongarch64-unknown-linux-gnu] -# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN +# Adjust the paths to point at your toolchain +# Suppose the toolchain is placed at /TOOLCHAIN_PATH, and the cross prefix is +# "loongarch64-unknown-linux-gnu-": cc = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" cxx = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++" ar = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ar" @@ -59,36 +87,51 @@ ranlib = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ranlib" linker = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" ``` -## Cross-compilation +### Cross-compilation -This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. Cross-compilation on other hosts may work but is not tested. +This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. +Other hosts are also likely to work, but not actively tested. + +You can test the cross build directly on the host, thanks to QEMU linux-user emulation. +An example is given below: + +```sh +# Suppose the cross toolchain is placed at $TOOLCHAIN_PATH, with a cross prefix +# of "loongarch64-unknown-linux-gnu-". +export CC_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc +export CXX_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-g++ +export AR_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc-ar +export CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc + +# Point qemu-loongarch64 to the LoongArch sysroot. +# Suppose the sysroot is located at "sysroot" below the toolchain root: +export CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER="qemu-loongarch64 -L $TOOLCHAIN_PATH/sysroot" +# Or alternatively, if binfmt_misc is set up for running LoongArch binaries +# transparently: +export QEMU_LD_PREFIX="$TOOLCHAIN_PATH"/sysroot -## Testing -To test a cross-compiled binary on your build system, install the qemu binary that supports the LoongArch architecture and execute the following commands. -```text -CC_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ -CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++ \ -AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \ -CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ -# SET TARGET SYSTEM LIBRARY PATH -CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRARY_PATH" \ cargo run --target loongarch64-unknown-linux-gnu --release ``` -Tested on x86 architecture, other architectures not tested. -## Building Rust programs +## Testing + +There are no special requirements for testing and running the targets. +For testing cross builds on the host, please refer to the "Cross-compilation" +section above. -Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you will either need to build Rust with the target enabled (see "Building the target" above), or build your own copy of `std` by using `build-std` or similar. +## Building Rust programs -If `rustc` has support for that target and the library artifacts are available, then Rust static libraries can be built for that target: +As the targets are available through `rustup`, it is very easy to build Rust +programs for these targets: same as with other architectures. +Note that you will need a LoongArch C/C++ toolchain for linking, or if you want +to compile C code along with Rust (such as for Rust crates with C dependencies). -```shell -$ rustc --target loongarch64-unknown-linux-gnu your-code.rs --crate-type staticlib -$ ls libyour_code.a +```sh +rustup target add loongarch64-unknown-linux-gnu +cargo build --target loongarch64-unknown-linux-gnu ``` -On Rust Nightly it's possible to build without the target artifacts available: +Availability of pre-built artifacts through `rustup` are as follows: -```text -cargo build -Z build-std --target loongarch64-unknown-linux-gnu -``` +* `loongarch64-unknown-linux-gnu`: since Rust 1.71; +* `loongarch64-unknown-linux-musl`: since Rust 1.81. diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index 68d7c9d85e444..110a7cc3424d4 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -4,10 +4,10 @@ Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. -| Target | Descriptions | -|------------------------------------|-------------------------------------------------------| -| loongarch64-unknown-none | LoongArch 64-bit, LP64D ABI (freestanding, hardfloat) | -| loongarch64-unknown-none-softfloat | LoongArch 64-bit, LP64S ABI (freestanding, softfloat) | +| Target | Description | +|--------|-------------| +| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | +| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | ## Target maintainers @@ -19,6 +19,8 @@ Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, e This target is cross-compiled. There is no support for `std`. There is no default allocator, but it's possible to use `alloc` by supplying an allocator. +The `*-softfloat` target does not assume existence of FPU or any other LoongArch +ISA extension, and does not make use of any non-GPR register. This allows the generated code to run in environments, such as kernels, which may need to avoid the use of such registers or which may have special considerations about the use of such registers (e.g. saving and restoring them to avoid breaking @@ -26,54 +28,64 @@ userspace code using the same registers). You can change code generation to use additional CPU features via the `-C target-feature=` codegen options to rustc, or via the `#[target_feature]` mechanism within Rust code. -By default, code generated with this target should run on any `loongarch` -hardware; enabling additional target features may raise this baseline. +By default, code generated with the soft-float target should run on any +LoongArch64 hardware, with the hard-float target additionally requiring an FPU; +enabling additional target features may raise this baseline. -Code generated with this target will use the `small` code model by default. +Code generated with the targets will use the `small` code model by default. You can change this using the `-C code-model=` option to rustc. -On `loongarch64-unknown-none*`, `extern "C"` uses the [standard calling -convention](https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html). +On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. -This target generates binaries in the ELF format. Any alternate formats or +[lapcs]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc + +The targets generate binaries in the ELF format. Any alternate formats or special considerations for binary layout will require linker options or linker scripts. ## Building the target -You can build Rust with support for the target by adding it to the `target` +You can build Rust with support for the targets by adding them to the `target` list in `config.toml`: ```toml [build] build-stage = 1 -target = ["loongarch64-unknown-none"] +target = [ + "loongarch64-unknown-none", + "loongarch64-unknown-none-softfloat", +] ``` +## Testing + +As the targets support a variety of different environments and do not support +`std`, they do not support running the Rust test suite. + ## Building Rust programs -```text +Starting with Rust 1.74, precompiled artifacts are provided via `rustup`: + +```sh +# install cross-compile toolchain +rustup target add loongarch64-unknown-none # target flag may be used with any cargo or rustc command cargo build --target loongarch64-unknown-none ``` -## Testing - -As `loongarch64-unknown-none*` supports a variety of different environments and does -not support `std`, this target does not support running the Rust test suite. - ## Cross-compilation toolchains and C code -If you want to compile C code along with Rust (such as for Rust crates with C -dependencies), you will need an appropriate `loongarch` toolchain. +For cross builds, you will need an appropriate LoongArch C/C++ toolchain for +linking, or if you want to compile C code along with Rust (such as for Rust +crates with C dependencies). Rust *may* be able to use an `loongarch64-unknown-linux-gnu-` toolchain with appropriate standalone flags to build for this toolchain (depending on the assumptions of that toolchain, see below), or you may wish to use a separate `loongarch64-unknown-none` toolchain. -On some `loongarch` hosts that use ELF binaries, you *may* be able to use the host +On some LoongArch hosts that use ELF binaries, you *may* be able to use the host C toolchain, if it does not introduce assumptions about the host environment that don't match the expectations of a standalone environment. Otherwise, you may need a separate toolchain for standalone/freestanding development, just as -when cross-compiling from a non-`loongarch` platform. +when cross-compiling from a non-LoongArch platform. From 448dd30ed4e28249895db1a231b336f3df573f68 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 27 Jun 2024 14:16:27 -0400 Subject: [PATCH 100/217] Mark `Hasher::finish` as #[must_use] --- library/core/src/hash/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 1c93a7b28fd35..da734466263ab 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -334,6 +334,7 @@ pub trait Hasher { /// /// [`write`]: Hasher::write #[stable(feature = "rust1", since = "1.0.0")] + #[must_use] fn finish(&self) -> u64; /// Writes some data into this `Hasher`. From 8d27980325988d71b49b9e1c6dd995d26ce9b4ef Mon Sep 17 00:00:00 2001 From: bohan Date: Thu, 27 Jun 2024 14:05:48 +0800 Subject: [PATCH 101/217] docs: check if the disambiguator matches its suffix --- .../passes/collect_intra_doc_links.rs | 32 +- .../disambiguator-endswith-named-suffix.rs | 110 +++++ ...disambiguator-endswith-named-suffix.stderr | 395 ++++++++++++++++++ 3 files changed, 529 insertions(+), 8 deletions(-) create mode 100644 tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs create mode 100644 tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 440b02a1fa75b..37f7e7ed38518 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1507,6 +1507,15 @@ impl Disambiguator { fn from_str(link: &str) -> Result, (String, Range)> { use Disambiguator::{Kind, Namespace as NS, Primitive}; + let suffixes = [ + // If you update this list, please also update the relevant rustdoc book section! + ("!()", DefKind::Macro(MacroKind::Bang)), + ("!{}", DefKind::Macro(MacroKind::Bang)), + ("![]", DefKind::Macro(MacroKind::Bang)), + ("()", DefKind::Fn), + ("!", DefKind::Macro(MacroKind::Bang)), + ]; + if let Some(idx) = link.find('@') { let (prefix, rest) = link.split_at(idx); let d = match prefix { @@ -1530,16 +1539,23 @@ impl Disambiguator { "prim" | "primitive" => Primitive, _ => return Err((format!("unknown disambiguator `{prefix}`"), 0..idx)), }; + + for (suffix, kind) in suffixes { + if let Some(path_str) = rest.strip_suffix(suffix) { + if d.ns() != Kind(kind).ns() { + return Err(( + format!("unmatched disambiguator `{prefix}` and suffix `{suffix}`"), + 0..idx, + )); + } else if path_str.len() > 1 { + // path_str != "@" + return Ok(Some((d, &path_str[1..], &rest[1..]))); + } + } + } + Ok(Some((d, &rest[1..], &rest[1..]))) } else { - let suffixes = [ - // If you update this list, please also update the relevant rustdoc book section! - ("!()", DefKind::Macro(MacroKind::Bang)), - ("!{}", DefKind::Macro(MacroKind::Bang)), - ("![]", DefKind::Macro(MacroKind::Bang)), - ("()", DefKind::Fn), - ("!", DefKind::Macro(MacroKind::Bang)), - ]; for (suffix, kind) in suffixes { if let Some(path_str) = link.strip_suffix(suffix) { // Avoid turning `!` or `()` into an empty string diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs new file mode 100644 index 0000000000000..3a59cc2247b98 --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -0,0 +1,110 @@ +//@ check-pass + +//! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` +//! [struct@m!{}] +//! [struct@m![]] +//! [struct@f()] //~ WARN: unmatched disambiguator `struct` and suffix `()` +//! [struct@m!] //~ WARN: unmatched disambiguator `struct` and suffix `!` +//! +//! [enum@m!()] //~ WARN: unmatched disambiguator `enum` and suffix `!()` +//! [enum@m!{}] +//! [enum@m![]] +//! [enum@f()] //~ WARN: unmatched disambiguator `enum` and suffix `()` +//! [enum@m!] //~ WARN: unmatched disambiguator `enum` and suffix `!` +//! +//! [trait@m!()] //~ WARN: unmatched disambiguator `trait` and suffix `!()` +//! [trait@m!{}] +//! [trait@m![]] +//! [trait@f()] //~ WARN: unmatched disambiguator `trait` and suffix `()` +//! [trait@m!] //~ WARN: unmatched disambiguator `trait` and suffix `!` +//! +//! [module@m!()] //~ WARN: unmatched disambiguator `module` and suffix `!()` +//! [module@m!{}] +//! [module@m![]] +//! [module@f()] //~ WARN: unmatched disambiguator `module` and suffix `()` +//! [module@m!] //~ WARN: unmatched disambiguator `module` and suffix `!` +//! +//! [mod@m!()] //~ WARN: unmatched disambiguator `mod` and suffix `!()` +//! [mod@m!{}] +//! [mod@m![]] +//! [mod@f()] //~ WARN: unmatched disambiguator `mod` and suffix `()` +//! [mod@m!] //~ WARN: unmatched disambiguator `mod` and suffix `!` +//! +//! [const@m!()] //~ WARN: unmatched disambiguator `const` and suffix `!()` +//! [const@m!{}] +//! [const@m![]] +//! [const@f()] //~ WARN: incompatible link kind for `f` +//! [const@m!] //~ WARN: unmatched disambiguator `const` and suffix `!` +//! +//! [constant@m!()] //~ WARN: unmatched disambiguator `constant` and suffix `!()` +//! [constant@m!{}] +//! [constant@m![]] +//! [constant@f()] //~ WARN: incompatible link kind for `f` +//! [constant@m!] //~ WARN: unmatched disambiguator `constant` and suffix `!` +//! +//! [static@m!()] //~ WARN: unmatched disambiguator `static` and suffix `!()` +//! [static@m!{}] +//! [static@m![]] +//! [static@f()] //~ WARN: incompatible link kind for `f` +//! [static@m!] //~ WARN: unmatched disambiguator `static` and suffix `!` +//! +//! [function@m!()] //~ WARN: unmatched disambiguator `function` and suffix `!()` +//! [function@m!{}] +//! [function@m![]] +//! [function@f()] +//! [function@m!] //~ WARN: unmatched disambiguator `function` and suffix `!` +//! +//! [fn@m!()] //~ WARN: unmatched disambiguator `fn` and suffix `!()` +//! [fn@m!{}] +//! [fn@m![]] +//! [fn@f()] +//! [fn@m!] //~ WARN: unmatched disambiguator `fn` and suffix `!` +//! +//! [method@m!()] //~ WARN: unmatched disambiguator `method` and suffix `!()` +//! [method@m!{}] +//! [method@m![]] +//! [method@f()] +//! [method@m!] //~ WARN: unmatched disambiguator `method` and suffix `!` +//! +//! [derive@m!()] //~ WARN: incompatible link kind for `m` +//! [derive@m!{}] //~ WARN: incompatible link kind for `m` +//! [derive@m![]] +//! [derive@f()] //~ WARN: unmatched disambiguator `derive` and suffix `()` +//! [derive@m!] //~ WARN: incompatible link kind for `m` +//! +//! [type@m!()] //~ WARN: unmatched disambiguator `type` and suffix `!()` +//! [type@m!{}] +//! [type@m![]] +//! [type@f()] //~ WARN: unmatched disambiguator `type` and suffix `()` +//! [type@m!] //~ WARN: unmatched disambiguator `type` and suffix `!` +//! +//! [value@m!()] //~ WARN: unmatched disambiguator `value` and suffix `!()` +//! [value@m!{}] +//! [value@m![]] +//! [value@f()] +//! [value@m!] //~ WARN: unmatched disambiguator `value` and suffix `!` +//! +//! [macro@m!()] +//! [macro@m!{}] +//! [macro@m![]] +//! [macro@f()] //~ WARN: unmatched disambiguator `macro` and suffix `()` +//! [macro@m!] +//! +//! [prim@m!()] //~ WARN: unmatched disambiguator `prim` and suffix `!()` +//! [prim@m!{}] +//! [prim@m![]] +//! [prim@f()] //~ WARN: unmatched disambiguator `prim` and suffix `()` +//! [prim@m!] //~ WARN: unmatched disambiguator `prim` and suffix `!` +//! +//! [primitive@m!()] //~ WARN: unmatched disambiguator `primitive` and suffix `!()` +//! [primitive@m!{}] +//! [primitive@m![]] +//! [primitive@f()] //~ WARN: unmatched disambiguator `primitive` and suffix `()` +//! [primitive@m!] //~ WARN: unmatched disambiguator `primitive` and suffix `!` + +#[macro_export] +macro_rules! m { + () => {}; +} + +pub fn f() {} diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr new file mode 100644 index 0000000000000..8d430152a83f4 --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr @@ -0,0 +1,395 @@ +warning: unmatched disambiguator `struct` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:3:6 + | +LL | //! [struct@m!()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unmatched disambiguator `struct` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:6:6 + | +LL | //! [struct@f()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `struct` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:7:6 + | +LL | //! [struct@m!] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `enum` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:9:6 + | +LL | //! [enum@m!()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `enum` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:12:6 + | +LL | //! [enum@f()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `enum` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:13:6 + | +LL | //! [enum@m!] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `trait` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:15:6 + | +LL | //! [trait@m!()] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `trait` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:18:6 + | +LL | //! [trait@f()] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `trait` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:19:6 + | +LL | //! [trait@m!] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `module` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:21:6 + | +LL | //! [module@m!()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `module` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:24:6 + | +LL | //! [module@f()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `module` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:25:6 + | +LL | //! [module@m!] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `mod` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:27:6 + | +LL | //! [mod@m!()] + | ^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `mod` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:30:6 + | +LL | //! [mod@f()] + | ^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `mod` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:31:6 + | +LL | //! [mod@m!] + | ^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `const` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:33:6 + | +LL | //! [const@m!()] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:36:6 + | +LL | //! [const@f()] + | ^^^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - //! [const@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `const` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:37:6 + | +LL | //! [const@m!] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `constant` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:39:6 + | +LL | //! [constant@m!()] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:42:6 + | +LL | //! [constant@f()] + | ^^^^^^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - //! [constant@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `constant` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:43:6 + | +LL | //! [constant@m!] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `static` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:45:6 + | +LL | //! [static@m!()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:48:6 + | +LL | //! [static@f()] + | ^^^^^^^^^^ this link resolved to a function, which is not a static + | +help: to link to the function, add parentheses + | +LL - //! [static@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `static` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:49:6 + | +LL | //! [static@m!] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `function` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:51:6 + | +LL | //! [function@m!()] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `function` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:55:6 + | +LL | //! [function@m!] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `fn` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:57:6 + | +LL | //! [fn@m!()] + | ^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `fn` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:61:6 + | +LL | //! [fn@m!] + | ^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `method` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:63:6 + | +LL | //! [method@m!()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `method` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:67:6 + | +LL | //! [method@m!] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:69:6 + | +LL | //! [derive@m!()] + | ^^^^^^^^^^^ this link resolved to a macro, which is not a derive macro + | +help: to link to the macro, add an exclamation mark + | +LL - //! [derive@m!()] +LL + //! [m!!()] + | + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:70:6 + | +LL | //! [derive@m!{}] + | ^^^^^^^^^^^ this link resolved to a macro, which is not a derive macro + | +help: to link to the macro, add an exclamation mark + | +LL - //! [derive@m!{}] +LL + //! [m!!{}] + | + +warning: unmatched disambiguator `derive` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:72:6 + | +LL | //! [derive@f()] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:73:6 + | +LL | //! [derive@m!] + | ^^^^^^^^^ this link resolved to a macro, which is not a derive macro + | +help: to link to the macro, add an exclamation mark + | +LL - //! [derive@m!] +LL + //! [m!!] + | + +warning: unmatched disambiguator `type` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:75:6 + | +LL | //! [type@m!()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `type` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:78:6 + | +LL | //! [type@f()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `type` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:79:6 + | +LL | //! [type@m!] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `value` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:81:6 + | +LL | //! [value@m!()] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `value` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:85:6 + | +LL | //! [value@m!] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `macro` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:90:6 + | +LL | //! [macro@f()] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `prim` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:93:6 + | +LL | //! [prim@m!()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `prim` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:96:6 + | +LL | //! [prim@f()] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `prim` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:97:6 + | +LL | //! [prim@m!] + | ^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `primitive` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:99:6 + | +LL | //! [primitive@m!()] + | ^^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `primitive` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:102:6 + | +LL | //! [primitive@f()] + | ^^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: unmatched disambiguator `primitive` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:103:6 + | +LL | //! [primitive@m!] + | ^^^^^^^^^ + | + = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +warning: 46 warnings emitted + From 91d3ac74501be922f08887f825bab9e069bc6a3a Mon Sep 17 00:00:00 2001 From: bohan Date: Thu, 27 Jun 2024 21:37:36 +0800 Subject: [PATCH 102/217] add test for #126986 --- .../disambiguator-endswith-named-suffix.rs | 1 + ...disambiguator-endswith-named-suffix.stderr | 172 +++++++++--------- ...isambiguator-macro-endswith-exclamatory.rs | 11 ++ ...biguator-macro-endswith-exclamatory.stderr | 11 ++ 4 files changed, 109 insertions(+), 86 deletions(-) create mode 100644 tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs create mode 100644 tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs index 3a59cc2247b98..c3da1fdd7cc6d 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` //! [struct@m!{}] diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr index 8d430152a83f4..f4e40a4887383 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr @@ -1,134 +1,134 @@ warning: unmatched disambiguator `struct` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:3:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:4:6 | LL | //! [struct@m!()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default warning: unmatched disambiguator `struct` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:6:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:7:6 | LL | //! [struct@f()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `struct` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:7:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:8:6 | LL | //! [struct@m!] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `enum` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:9:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:10:6 | LL | //! [enum@m!()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `enum` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:12:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:13:6 | LL | //! [enum@f()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `enum` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:13:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:14:6 | LL | //! [enum@m!] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `trait` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:15:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:16:6 | LL | //! [trait@m!()] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `trait` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:18:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:19:6 | LL | //! [trait@f()] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `trait` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:19:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:20:6 | LL | //! [trait@m!] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `module` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:21:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:22:6 | LL | //! [module@m!()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `module` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:24:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:25:6 | LL | //! [module@f()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `module` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:25:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:26:6 | LL | //! [module@m!] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `mod` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:27:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:28:6 | LL | //! [mod@m!()] | ^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `mod` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:30:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:31:6 | LL | //! [mod@f()] | ^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `mod` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:31:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:32:6 | LL | //! [mod@m!] | ^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `const` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:33:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:34:6 | LL | //! [const@m!()] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: incompatible link kind for `f` - --> $DIR/disambiguator-endswith-named-suffix.rs:36:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:37:6 | LL | //! [const@f()] | ^^^^^^^^^ this link resolved to a function, which is not a constant @@ -140,23 +140,23 @@ LL + //! [f()] | warning: unmatched disambiguator `const` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:37:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:38:6 | LL | //! [const@m!] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `constant` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:39:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:40:6 | LL | //! [constant@m!()] | ^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: incompatible link kind for `f` - --> $DIR/disambiguator-endswith-named-suffix.rs:42:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:43:6 | LL | //! [constant@f()] | ^^^^^^^^^^^^ this link resolved to a function, which is not a constant @@ -168,23 +168,23 @@ LL + //! [f()] | warning: unmatched disambiguator `constant` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:43:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:44:6 | LL | //! [constant@m!] | ^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `static` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:45:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:46:6 | LL | //! [static@m!()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: incompatible link kind for `f` - --> $DIR/disambiguator-endswith-named-suffix.rs:48:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:49:6 | LL | //! [static@f()] | ^^^^^^^^^^ this link resolved to a function, which is not a static @@ -196,63 +196,63 @@ LL + //! [f()] | warning: unmatched disambiguator `static` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:49:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:50:6 | LL | //! [static@m!] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `function` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:51:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:52:6 | LL | //! [function@m!()] | ^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `function` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:55:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:56:6 | LL | //! [function@m!] | ^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `fn` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:57:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:58:6 | LL | //! [fn@m!()] | ^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `fn` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:61:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:62:6 | LL | //! [fn@m!] | ^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `method` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:63:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:64:6 | LL | //! [method@m!()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `method` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:67:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:68:6 | LL | //! [method@m!] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: incompatible link kind for `m` - --> $DIR/disambiguator-endswith-named-suffix.rs:69:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:70:6 | LL | //! [derive@m!()] | ^^^^^^^^^^^ this link resolved to a macro, which is not a derive macro @@ -264,7 +264,7 @@ LL + //! [m!!()] | warning: incompatible link kind for `m` - --> $DIR/disambiguator-endswith-named-suffix.rs:70:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:71:6 | LL | //! [derive@m!{}] | ^^^^^^^^^^^ this link resolved to a macro, which is not a derive macro @@ -276,15 +276,15 @@ LL + //! [m!!{}] | warning: unmatched disambiguator `derive` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:72:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:73:6 | LL | //! [derive@f()] | ^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: incompatible link kind for `m` - --> $DIR/disambiguator-endswith-named-suffix.rs:73:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:74:6 | LL | //! [derive@m!] | ^^^^^^^^^ this link resolved to a macro, which is not a derive macro @@ -296,100 +296,100 @@ LL + //! [m!!] | warning: unmatched disambiguator `type` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:75:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:76:6 | LL | //! [type@m!()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `type` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:78:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:79:6 | LL | //! [type@f()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `type` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:79:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:80:6 | LL | //! [type@m!] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `value` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:81:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:82:6 | LL | //! [value@m!()] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `value` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:85:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:86:6 | LL | //! [value@m!] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `macro` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:90:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:91:6 | LL | //! [macro@f()] | ^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `prim` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:93:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:94:6 | LL | //! [prim@m!()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `prim` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:96:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:97:6 | LL | //! [prim@f()] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `prim` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:97:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:98:6 | LL | //! [prim@m!] | ^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `primitive` and suffix `!()` - --> $DIR/disambiguator-endswith-named-suffix.rs:99:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:100:6 | LL | //! [primitive@m!()] | ^^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `primitive` and suffix `()` - --> $DIR/disambiguator-endswith-named-suffix.rs:102:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:103:6 | LL | //! [primitive@f()] | ^^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: unmatched disambiguator `primitive` and suffix `!` - --> $DIR/disambiguator-endswith-named-suffix.rs:103:6 + --> $DIR/disambiguator-endswith-named-suffix.rs:104:6 | LL | //! [primitive@m!] | ^^^^^^^^^ | - = note: see https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators warning: 46 warnings emitted diff --git a/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs new file mode 100644 index 0000000000000..b955090e8944c --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs @@ -0,0 +1,11 @@ +//@ check-pass + +//! [macro@m!] //~ WARN: unresolved link to `m` + +//issue#126986 + +macro_rules! m { + () => {}; +} + +fn main() {} diff --git a/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr new file mode 100644 index 0000000000000..2ada7f1a4be5d --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr @@ -0,0 +1,11 @@ +warning: unresolved link to `m` + --> $DIR/disambiguator-macro-endswith-exclamatory.rs:3:6 + | +LL | //! [macro@m!] + | ^^^^^^^^ no item named `m` in scope + | + = note: `macro_rules` named `m` exists in this crate, but it is not in scope at this link's location + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + From 8bcd1dede6d5d9d1ad3f0d4e5332a3de607b37db Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 27 Jun 2024 22:37:29 -0400 Subject: [PATCH 103/217] add () to the marker_impls macro for ConstParamTy seems to have escaped bootstrap --- library/core/src/marker.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 0fedb8835d1ae..2db5a9ff3e3a8 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -996,15 +996,12 @@ marker_impls! { bool, char, str /* Technically requires `[u8]: ConstParamTy` */, + (), {T: ConstParamTy, const N: usize} [T; N], {T: ConstParamTy} [T], {T: ?Sized + ConstParamTy} &T, } -// FIXME(adt_const_params): Add to marker_impls call above once not in bootstrap -#[unstable(feature = "adt_const_params", issue = "95174")] -impl ConstParamTy for () {} - /// A common trait implemented by all function pointers. #[unstable( feature = "fn_ptr_trait", From 264e8093aa579e04074e9791d8a9391e01e00c5f Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 27 Jun 2024 23:32:20 -0400 Subject: [PATCH 104/217] Remove (deprecated & unstable) {to,from}_bits pointer methods --- library/core/src/ptr/const_ptr.rs | 65 ------------------------------ library/core/src/ptr/mut_ptr.rs | 66 ------------------------------- 2 files changed, 131 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index b1f94caed3513..5537d26669a23 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -112,71 +112,6 @@ impl *const T { self as _ } - /// Casts a pointer to its raw bits. - /// - /// This is equivalent to `as usize`, but is more specific to enhance readability. - /// The inverse method is [`from_bits`](#method.from_bits). - /// - /// In particular, `*p as usize` and `p as usize` will both compile for - /// pointers to numeric types but do very different things, so using this - /// helps emphasize that reading the bits was intentional. - /// - /// # Examples - /// - /// ``` - /// #![feature(ptr_to_from_bits)] - /// # #[cfg(not(miri))] { // doctest does not work with strict provenance - /// let array = [13, 42]; - /// let p0: *const i32 = &array[0]; - /// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0); - /// let p1: *const i32 = &array[1]; - /// assert_eq!(p1.to_bits() - p0.to_bits(), 4); - /// # } - /// ``` - #[unstable(feature = "ptr_to_from_bits", issue = "91126")] - #[deprecated( - since = "1.67.0", - note = "replaced by the `expose_provenance` method, or update your code \ - to follow the strict provenance rules using its APIs" - )] - #[inline(always)] - pub fn to_bits(self) -> usize - where - T: Sized, - { - self as usize - } - - /// Creates a pointer from its raw bits. - /// - /// This is equivalent to `as *const T`, but is more specific to enhance readability. - /// The inverse method is [`to_bits`](#method.to_bits). - /// - /// # Examples - /// - /// ``` - /// #![feature(ptr_to_from_bits)] - /// # #[cfg(not(miri))] { // doctest does not work with strict provenance - /// use std::ptr::NonNull; - /// let dangling: *const u8 = NonNull::dangling().as_ptr(); - /// assert_eq!(<*const u8>::from_bits(1), dangling); - /// # } - /// ``` - #[unstable(feature = "ptr_to_from_bits", issue = "91126")] - #[deprecated( - since = "1.67.0", - note = "replaced by the `ptr::with_exposed_provenance` function, or update \ - your code to follow the strict provenance rules using its APIs" - )] - #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function - #[inline(always)] - pub fn from_bits(bits: usize) -> Self - where - T: Sized, - { - bits as Self - } - /// Gets the "address" portion of the pointer. /// /// This is similar to `self as usize`, which semantically discards *provenance* and diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 7c685156cbb07..30d5b2cfc5a8b 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -117,72 +117,6 @@ impl *mut T { self as _ } - /// Casts a pointer to its raw bits. - /// - /// This is equivalent to `as usize`, but is more specific to enhance readability. - /// The inverse method is [`from_bits`](pointer#method.from_bits-1). - /// - /// In particular, `*p as usize` and `p as usize` will both compile for - /// pointers to numeric types but do very different things, so using this - /// helps emphasize that reading the bits was intentional. - /// - /// # Examples - /// - /// ``` - /// #![feature(ptr_to_from_bits)] - /// # #[cfg(not(miri))] { // doctest does not work with strict provenance - /// let mut array = [13, 42]; - /// let mut it = array.iter_mut(); - /// let p0: *mut i32 = it.next().unwrap(); - /// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0); - /// let p1: *mut i32 = it.next().unwrap(); - /// assert_eq!(p1.to_bits() - p0.to_bits(), 4); - /// } - /// ``` - #[unstable(feature = "ptr_to_from_bits", issue = "91126")] - #[deprecated( - since = "1.67.0", - note = "replaced by the `expose_provenance` method, or update your code \ - to follow the strict provenance rules using its APIs" - )] - #[inline(always)] - pub fn to_bits(self) -> usize - where - T: Sized, - { - self as usize - } - - /// Creates a pointer from its raw bits. - /// - /// This is equivalent to `as *mut T`, but is more specific to enhance readability. - /// The inverse method is [`to_bits`](pointer#method.to_bits-1). - /// - /// # Examples - /// - /// ``` - /// #![feature(ptr_to_from_bits)] - /// # #[cfg(not(miri))] { // doctest does not work with strict provenance - /// use std::ptr::NonNull; - /// let dangling: *mut u8 = NonNull::dangling().as_ptr(); - /// assert_eq!(<*mut u8>::from_bits(1), dangling); - /// } - /// ``` - #[unstable(feature = "ptr_to_from_bits", issue = "91126")] - #[deprecated( - since = "1.67.0", - note = "replaced by the `ptr::with_exposed_provenance_mut` function, or \ - update your code to follow the strict provenance rules using its APIs" - )] - #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function - #[inline(always)] - pub fn from_bits(bits: usize) -> Self - where - T: Sized, - { - bits as Self - } - /// Gets the "address" portion of the pointer. /// /// This is similar to `self as usize`, which semantically discards *provenance* and From 9bbf3d98054bc036f3f5e8954706610e5bae7751 Mon Sep 17 00:00:00 2001 From: Sky Date: Fri, 28 Jun 2024 00:01:32 -0400 Subject: [PATCH 105/217] docs: say "includes" instead of "does include" --- library/core/src/time.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index bc0fa3f0968d8..73c556249bedf 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -842,7 +842,7 @@ impl Duration { /// Returns the number of seconds contained by this `Duration` as `f64`. /// - /// The returned value does include the fractional (nanosecond) part of the duration. + /// The returned value includes the fractional (nanosecond) part of the duration. /// /// # Examples /// ``` @@ -861,7 +861,7 @@ impl Duration { /// Returns the number of seconds contained by this `Duration` as `f32`. /// - /// The returned value does include the fractional (nanosecond) part of the duration. + /// The returned value includes the fractional (nanosecond) part of the duration. /// /// # Examples /// ``` @@ -880,7 +880,7 @@ impl Duration { /// Returns the number of milliseconds contained by this `Duration` as `f64`. /// - /// The returned value does include the fractional (nanosecond) part of the duration. + /// The returned value includes the fractional (nanosecond) part of the duration. /// /// # Examples /// ``` @@ -901,7 +901,7 @@ impl Duration { /// Returns the number of milliseconds contained by this `Duration` as `f32`. /// - /// The returned value does include the fractional (nanosecond) part of the duration. + /// The returned value includes the fractional (nanosecond) part of the duration. /// /// # Examples /// ``` From df7331fcd2d2f059f98fbbf19eb2e493188e82da Mon Sep 17 00:00:00 2001 From: Sky Date: Fri, 28 Jun 2024 00:20:03 -0400 Subject: [PATCH 106/217] Remove unnecessary SeqCst in `impl fmt::Pointer for AtomicPtr` --- 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 1d19c985f232b..df108f5e0e4e5 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3766,7 +3766,7 @@ impl fmt::Debug for AtomicPtr { #[stable(feature = "atomic_pointer", since = "1.24.0")] impl fmt::Pointer for AtomicPtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f) + fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f) } } From ab1b48ef2ae06fe9cb0d11632255ac0ab9fff528 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 28 Jun 2024 08:06:36 +0200 Subject: [PATCH 107/217] rustc_data_structures: Explicitly check for 64-bit atomics support Instead of keeping a list of architectures which have native support for 64-bit atomics, just use #[cfg(target_has_atomic = "64")] and its inverted counterpart to determine whether we need to use portable AtomicU64 on the target architecture. --- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_data_structures/src/marker.rs | 7 +++---- compiler/rustc_data_structures/src/sync.rs | 7 +++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index f525510030b4a..c4b2e067bbeb4 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -50,7 +50,7 @@ libc = "0.2" memmap2 = "0.2.1" # tidy-alphabetical-end -[target.'cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))'.dependencies] +[target.'cfg(not(target_has_atomic = "64"))'.dependencies] portable-atomic = "1.5.1" [features] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 32fad0de1aa3e..83fdaff515b03 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -147,14 +147,13 @@ cfg_match! { [crate::owned_slice::OwnedSlice] ); - // MIPS, PowerPC and SPARC platforms with 32-bit pointers do not - // have AtomicU64 type. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc", target_arch = "sparc")))] + // Use portable AtomicU64 for targets without native 64-bit atomics + #[cfg(target_has_atomic = "64")] already_sync!( [std::sync::atomic::AtomicU64] ); - #[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))] + #[cfg(not(target_has_atomic = "64"))] already_sync!( [portable_atomic::AtomicU64] ); diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 5ae79ca988f14..79ceb28abb518 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -270,12 +270,11 @@ cfg_match! { pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; - // MIPS, PowerPC and SPARC platforms with 32-bit pointers do not - // have AtomicU64 type. - #[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc")))] + // Use portable AtomicU64 for targets without native 64-bit atomics + #[cfg(target_has_atomic = "64")] pub use std::sync::atomic::AtomicU64; - #[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))] + #[cfg(not(target_has_atomic = "64"))] pub use portable_atomic::AtomicU64; pub use std::sync::Arc as Lrc; From 65aea99dafd3d31fd2b962280049f69414190679 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 28 Jun 2024 10:44:26 +0200 Subject: [PATCH 108/217] std: add safety comments --- library/std/src/sys/thread_local/os.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 625943bb25512..e06185f00690b 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -50,6 +50,7 @@ unsafe impl Sync for Storage {} struct Value { value: T, + // INVARIANT: if this value is stored under a TLS key, `key` must be that `key`. key: Key, } @@ -73,10 +74,14 @@ impl Storage { // is not running) + it is coming from a trusted source (self). unsafe { &(*ptr).value } } else { + // SAFETY: trivially correct. unsafe { Self::try_initialize(key, ptr, i, f) } } } + /// # Safety + /// * `key` must be the result of calling `self.key.force()` + /// * `ptr` must be the current value associated with `key`. unsafe fn try_initialize( key: Key, ptr: *mut Value, @@ -91,11 +96,16 @@ impl Storage { let value = Box::new(Value { value: i.and_then(Option::take).unwrap_or_else(f), key }); let ptr = Box::into_raw(value); - let old = unsafe { get(key) as *mut Value }; - // SAFETY: `ptr` is a correct pointer that can be destroyed by the key destructor. - unsafe { + // SAFETY: + // * key came from a `LazyKey` and is thus correct. + // * `ptr` is a correct pointer that can be destroyed by the key destructor. + // * the value is stored under the key that it contains. + let old = unsafe { + let old = get(key) as *mut Value; set(key, ptr as *mut u8); - } + old + }; + if !old.is_null() { // If the variable was recursively initialized, drop the old value. // SAFETY: We cannot be inside a `LocalKey::with` scope, as the @@ -123,8 +133,10 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) { abort_on_dtor_unwind(|| { let ptr = unsafe { Box::from_raw(ptr as *mut Value) }; let key = ptr.key; + // SAFETY: `key` is the TLS key `ptr` was stored under. unsafe { set(key, ptr::without_provenance_mut(1)) }; drop(ptr); + // SAFETY: `key` is the TLS key `ptr` was stored under. unsafe { set(key, ptr::null_mut()) }; }); } From 903d6a9d89c5feb936fa29f89246385c82d2db54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 09:42:07 +0200 Subject: [PATCH 109/217] Remove `run_cmd` --- src/bootstrap/src/core/build_steps/test.rs | 6 ++--- src/bootstrap/src/core/build_steps/tool.rs | 3 ++- src/bootstrap/src/lib.rs | 27 ++++++---------------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1ef5af7cc2daf..d268149da70d2 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -766,7 +766,7 @@ impl Step for Clippy { let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs - if builder.run_cmd(BootstrapCommand::from(&mut cargo).allow_failure()) { + if builder.run_tracked(BootstrapCommand::from(&mut cargo).allow_failure()).is_success() { // The tests succeeded; nothing to do. return; } @@ -3352,7 +3352,7 @@ impl Step for CodegenCranelift { cargo.args(builder.config.test_args()); let mut cmd: Command = cargo.into(); - builder.run_cmd(BootstrapCommand::from(&mut cmd).fail_fast()); + builder.run_tracked(BootstrapCommand::from(&mut cmd)); } } @@ -3478,6 +3478,6 @@ impl Step for CodegenGCC { cargo.args(builder.config.test_args()); let mut cmd: Command = cargo.into(); - builder.run_cmd(BootstrapCommand::from(&mut cmd).fail_fast()); + builder.run_tracked(BootstrapCommand::from(&mut cmd)); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a95a7f5491f37..6716caab69a1c 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -9,6 +9,7 @@ use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::channel::GitInfo; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::output; use crate::utils::helpers::{add_dylib_path, exe, t}; use crate::Compiler; @@ -917,7 +918,7 @@ impl Step for LibcxxVersionTool { .arg(&executable) .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - builder.run_cmd(&mut cmd); + builder.run_tracked(BootstrapCommand::from(&mut cmd)); if !executable.exists() { panic!("Something went wrong. {} is not present", executable.display()); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index afba907ee92b4..ed15088bc709c 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -580,14 +580,12 @@ impl Build { // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). // diff-index reports the modifications through the exit status - let has_local_modifications = !self.run_cmd( - BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"])) - .allow_failure() - .output_mode(match self.is_verbose() { - true => OutputMode::All, - false => OutputMode::OnlyOutput, - }), - ); + let has_local_modifications = self + .run_tracked( + BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"])) + .allow_failure(), + ) + .is_failure(); if has_local_modifications { self.run(submodule_git().args(["stash", "push"])); } @@ -1026,18 +1024,7 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. fn run(&self, cmd: &mut Command) { - self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode( - match self.is_verbose() { - true => OutputMode::All, - false => OutputMode::OnlyOutput, - }, - )); - } - - /// A centralized function for running commands that do not return output. - pub(crate) fn run_cmd<'a, C: Into>>(&self, cmd: C) -> bool { - let command = cmd.into(); - self.run_tracked(command).is_success() + self.run_tracked(BootstrapCommand::from(cmd)); } /// Check if verbosity is greater than the `level` From cf5bbb3a0859c5e1854a1110b95fe25994fb091a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 09:44:04 +0200 Subject: [PATCH 110/217] Remove `run` and rename `run_tracked` to `run` --- src/bootstrap/src/core/build_steps/test.rs | 41 +++++++++------------- src/bootstrap/src/core/build_steps/tool.rs | 2 +- src/bootstrap/src/lib.rs | 12 +++---- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index d268149da70d2..eefeee8fb0db9 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -156,7 +156,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" let _guard = builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host); let _time = helpers::timeit(builder); - builder.run_tracked( + builder.run( BootstrapCommand::from(linkchecker.arg(builder.out.join(host.triple).join("doc"))) .delay_failure(), ); @@ -216,7 +216,7 @@ impl Step for HtmlCheck { builder, )); - builder.run_tracked( + builder.run( BootstrapCommand::from( builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)), ) @@ -267,7 +267,7 @@ impl Step for Cargotest { .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); add_rustdoc_cargo_linker_args(cmd, builder, compiler.host, LldThreads::No); - builder.run_tracked(BootstrapCommand::from(cmd).delay_failure()); + builder.run(BootstrapCommand::from(cmd).delay_failure()); } } @@ -766,7 +766,7 @@ impl Step for Clippy { let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs - if builder.run_tracked(BootstrapCommand::from(&mut cargo).allow_failure()).is_success() { + if builder.run(BootstrapCommand::from(&mut cargo).allow_failure()).is_success() { // The tests succeeded; nothing to do. return; } @@ -819,7 +819,7 @@ impl Step for RustdocTheme { .env("RUSTC_BOOTSTRAP", "1"); cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); - builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); } } @@ -1097,7 +1097,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to } builder.info("tidy check"); - builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); builder.info("x.py completions check"); let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"] @@ -2184,11 +2184,8 @@ impl BookTest { ); let _time = helpers::timeit(builder); let cmd = BootstrapCommand::from(&mut rustbook_cmd).delay_failure(); - let toolstate = if builder.run_tracked(cmd).is_success() { - ToolState::TestPass - } else { - ToolState::TestFail - }; + let toolstate = + if builder.run(cmd).is_success() { ToolState::TestPass } else { ToolState::TestFail }; builder.save_toolstate(self.name, toolstate); } @@ -2317,8 +2314,7 @@ impl Step for ErrorIndex { let guard = builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = helpers::timeit(builder); - builder - .run_tracked(BootstrapCommand::from(&mut tool).output_mode(OutputMode::OnlyOnFailure)); + builder.run(BootstrapCommand::from(&mut tool).output_mode(OutputMode::OnlyOnFailure)); drop(guard); // The tests themselves need to link to std, so make sure it is // available. @@ -2351,7 +2347,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> if !builder.config.verbose_tests { cmd = cmd.quiet(); } - builder.run_tracked(cmd).is_success() + builder.run(cmd).is_success() } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -2377,11 +2373,8 @@ impl Step for RustcGuide { let src = builder.src.join(relative_path); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); let cmd = BootstrapCommand::from(rustbook_cmd.arg("linkcheck").arg(&src)).delay_failure(); - let toolstate = if builder.run_tracked(cmd).is_success() { - ToolState::TestPass - } else { - ToolState::TestFail - }; + let toolstate = + if builder.run(cmd).is_success() { ToolState::TestPass } else { ToolState::TestFail }; builder.save_toolstate("rustc-dev-guide", toolstate); } } @@ -2994,7 +2987,7 @@ impl Step for Bootstrap { .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. - builder.run_tracked(BootstrapCommand::from(&mut check_bootstrap).delay_failure()); + builder.run(BootstrapCommand::from(&mut check_bootstrap).delay_failure()); let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("test") @@ -3071,7 +3064,7 @@ impl Step for TierCheck { self.compiler.host, self.compiler.host, ); - builder.run_tracked(BootstrapCommand::from(&mut cargo.into()).delay_failure()); + builder.run(BootstrapCommand::from(&mut cargo.into()).delay_failure()); } } @@ -3157,7 +3150,7 @@ impl Step for RustInstaller { cmd.env("CARGO", &builder.initial_cargo); cmd.env("RUSTC", &builder.initial_rustc); cmd.env("TMP_DIR", &tmpdir); - builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3352,7 +3345,7 @@ impl Step for CodegenCranelift { cargo.args(builder.config.test_args()); let mut cmd: Command = cargo.into(); - builder.run_tracked(BootstrapCommand::from(&mut cmd)); + builder.run(BootstrapCommand::from(&mut cmd)); } } @@ -3478,6 +3471,6 @@ impl Step for CodegenGCC { cargo.args(builder.config.test_args()); let mut cmd: Command = cargo.into(); - builder.run_tracked(BootstrapCommand::from(&mut cmd)); + builder.run(BootstrapCommand::from(&mut cmd)); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 6716caab69a1c..bf4ffc2096ada 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -918,7 +918,7 @@ impl Step for LibcxxVersionTool { .arg(&executable) .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - builder.run_tracked(BootstrapCommand::from(&mut cmd)); + builder.run(BootstrapCommand::from(&mut cmd)); if !executable.exists() { panic!("Something went wrong. {} is not present", executable.display()); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ed15088bc709c..fdf5f48771a97 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -581,7 +581,7 @@ impl Build { // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). // diff-index reports the modifications through the exit status let has_local_modifications = self - .run_tracked( + .run( BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"])) .allow_failure(), ) @@ -959,11 +959,14 @@ impl Build { } /// Execute a command and return its output. - fn run_tracked(&self, command: BootstrapCommand<'_>) -> CommandOutput { + /// This method should be used for all command executions in bootstrap. + fn run<'a, C: Into>>(&self, command: C) -> CommandOutput { if self.config.dry_run() { return CommandOutput::default(); } + let command = command.into(); + self.verbose(|| println!("running: {command:?}")); let output_mode = command.output_mode.unwrap_or_else(|| match self.is_verbose() { @@ -1022,11 +1025,6 @@ impl Build { output } - /// Runs a command, printing out nice contextual information if it fails. - fn run(&self, cmd: &mut Command) { - self.run_tracked(BootstrapCommand::from(cmd)); - } - /// Check if verbosity is greater than the `level` pub fn is_verbose_than(&self, level: usize) -> bool { self.verbosity > level From 31911e5ccf0bc364c267cb1d99f1fe06efc04009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 09:48:56 +0200 Subject: [PATCH 111/217] Improve documentation of `BootstrapCommand` --- src/bootstrap/src/utils/exec.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index e8c588b75b381..246595116147b 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -24,6 +24,18 @@ pub enum OutputMode { } /// Wrapper around `std::process::Command`. +/// +/// By default, the command will exit bootstrap if it fails. +/// If you want to allow failures, use [allow_failure]. +/// If you want to delay failures until the end of bootstrap, use [delay_failure]. +/// +/// By default, the command will print its stdout/stderr to stdout/stderr of bootstrap +/// ([OutputMode::OnlyOutput]). If bootstrap uses verbose mode, then it will also print the +/// command itself in case of failure ([OutputMode::All]). +/// If you want to handle the output programmatically, use `output_mode(OutputMode::OnlyOnFailure)`. +/// +/// [allow_failure]: BootstrapCommand::allow_failure +/// [delay_failure]: BootstrapCommand::delay_failure #[derive(Debug)] pub struct BootstrapCommand<'a> { pub command: &'a mut Command, From 3722fb5d9f32ffaabf01b05b9af3500702edfb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 10:53:35 +0200 Subject: [PATCH 112/217] Store `Command` directly inside `BootstrapCommand` This will make it easier to migrate existing commands to bootstrap command. --- src/bootstrap/src/lib.rs | 4 ++-- src/bootstrap/src/utils/exec.rs | 33 +++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index fdf5f48771a97..cee6b34490292 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -960,12 +960,12 @@ impl Build { /// Execute a command and return its output. /// This method should be used for all command executions in bootstrap. - fn run<'a, C: Into>>(&self, command: C) -> CommandOutput { + fn run>(&self, command: C) -> CommandOutput { if self.config.dry_run() { return CommandOutput::default(); } - let command = command.into(); + let mut command = command.into(); self.verbose(|| println!("running: {command:?}")); diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 246595116147b..024a80e604008 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -37,13 +37,13 @@ pub enum OutputMode { /// [allow_failure]: BootstrapCommand::allow_failure /// [delay_failure]: BootstrapCommand::delay_failure #[derive(Debug)] -pub struct BootstrapCommand<'a> { - pub command: &'a mut Command, +pub struct BootstrapCommand { + pub command: Command, pub failure_behavior: BehaviorOnFailure, pub output_mode: Option, } -impl<'a> BootstrapCommand<'a> { +impl BootstrapCommand { pub fn delay_failure(self) -> Self { Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self } } @@ -66,8 +66,33 @@ impl<'a> BootstrapCommand<'a> { } } -impl<'a> From<&'a mut Command> for BootstrapCommand<'a> { +/// This implementation is temporary, until all `Command` invocations are migrated to +/// `BootstrapCommand`. +impl<'a> From<&'a mut Command> for BootstrapCommand { fn from(command: &'a mut Command) -> Self { + // This is essentially a manual `Command::clone` + let mut cmd = Command::new(command.get_program()); + if let Some(dir) = command.get_current_dir() { + cmd.current_dir(dir); + } + cmd.args(command.get_args()); + for (key, value) in command.get_envs() { + match value { + Some(value) => { + cmd.env(key, value); + } + None => { + cmd.env_remove(key); + } + } + } + + cmd.into() + } +} + +impl From for BootstrapCommand { + fn from(command: Command) -> Self { Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None } } } From 2a9d5ab849c315918029d681d8d9a8320a0f74d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:08:46 +0200 Subject: [PATCH 113/217] Make it easier to migrate `Command` to `BootstrapCmd` By allowing `run` to receive all of `BootstrapCmd`, `&mut BootstrapCmd`, `Command` and `&mut Command`. --- src/bootstrap/src/core/build_steps/doc.rs | 6 +++--- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/core/build_steps/tool.rs | 4 ++-- src/bootstrap/src/core/builder.rs | 7 +++++++ src/bootstrap/src/utils/exec.rs | 10 ++++++++++ 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 87c700dad063d..53deef7f4626b 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -737,7 +737,7 @@ fn doc_std( format!("library{} in {} format", crate_description(requested_crates), format.as_str()); let _guard = builder.msg_doc(compiler, description, target); - builder.run(&mut cargo.into()); + builder.run(cargo); builder.cp_link_r(&out_dir, out); } @@ -862,7 +862,7 @@ impl Step for Rustc { let proc_macro_out_dir = builder.stage_out(compiler, Mode::Rustc).join("doc"); symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); - builder.run(&mut cargo.into()); + builder.run(cargo); if !builder.config.dry_run() { // Sanity check on linked compiler crates @@ -995,7 +995,7 @@ macro_rules! tool_doc { symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); let _guard = builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); - builder.run(&mut cargo.into()); + builder.run(cargo); if !builder.config.dry_run() { // Sanity check on linked doc directories diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index eefeee8fb0db9..ce9dec413948d 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3064,7 +3064,7 @@ impl Step for TierCheck { self.compiler.host, self.compiler.host, ); - builder.run(BootstrapCommand::from(&mut cargo.into()).delay_failure()); + builder.run(BootstrapCommand::from(cargo).delay_failure()); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index bf4ffc2096ada..351af7697bc45 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -602,7 +602,7 @@ impl Step for Rustdoc { &self.compiler.host, &target, ); - builder.run(&mut cargo.into()); + builder.run(cargo); // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" @@ -857,7 +857,7 @@ impl Step for LlvmBitcodeLinker { &self.extra_features, ); - builder.run(&mut cargo.into()); + builder.run(cargo); let tool_out = builder .cargo_out(self.compiler, Mode::ToolRustc, self.target) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 14ccbfe0267e8..a6d6326077048 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -25,6 +25,7 @@ use crate::EXTRA_CHECK_CFGS; use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode}; pub use crate::Compiler; +use crate::utils::exec::BootstrapCommand; use clap::ValueEnum; // FIXME: replace with std::lazy after it gets stabilized and reaches beta @@ -2622,3 +2623,9 @@ impl From for Command { cargo.command } } + +impl From for BootstrapCommand { + fn from(cargo: Cargo) -> BootstrapCommand { + Command::from(cargo).into() + } +} diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 024a80e604008..81ab204210c8b 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,3 +1,5 @@ +use std::ffi::OsStr; +use std::path::Path; use std::process::{Command, ExitStatus, Output}; /// What should be done when the command fails. @@ -91,6 +93,14 @@ impl<'a> From<&'a mut Command> for BootstrapCommand { } } +/// This implementation is temporary, until all `Command` invocations are migrated to +/// `BootstrapCommand`. +impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { + fn from(command: &'a mut BootstrapCommand) -> Self { + BootstrapCommand::from(&mut command.command) + } +} + impl From for BootstrapCommand { fn from(command: Command) -> Self { Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None } From 86b21914602637917b41657b8f05c5846ece2a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:16:09 +0200 Subject: [PATCH 114/217] Migrate some usage of `Command` to `BootstrapCmd` --- src/bootstrap/src/core/build_steps/compile.rs | 3 +- src/bootstrap/src/core/build_steps/dist.rs | 19 +++---- src/bootstrap/src/core/build_steps/doc.rs | 7 +-- src/bootstrap/src/core/build_steps/test.rs | 6 +-- src/bootstrap/src/core/builder.rs | 6 +-- src/bootstrap/src/utils/exec.rs | 51 +++++++++++++++++++ 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 5b18cb3f7e1e6..a7cb8424a4b3f 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -27,6 +27,7 @@ use crate::core::builder::crate_description; use crate::core::builder::Cargo; use crate::core::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath}; use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection}; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date, }; @@ -771,7 +772,7 @@ impl Step for StartupObjects { let src_file = &src_dir.join(file.to_string() + ".rs"); let dst_file = &dst_dir.join(file.to_string() + ".o"); if !up_to_date(src_file, dst_file) { - let mut cmd = Command::new(&builder.initial_rustc); + let mut cmd = BootstrapCommand::new(&builder.initial_rustc); cmd.env("RUSTC_BOOTSTRAP", "1"); if !builder.local_rebuild { // a local_rebuild compiler already has stage1 features diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 2dc7cd7de6a05..a46a9373d9cae 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -26,6 +26,7 @@ use crate::core::build_steps::tool::{self, Tool}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::channel::{self, Info}; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ exe, is_dylib, move_file, output, t, target_supports_cranelift_backend, timeit, }; @@ -1599,14 +1600,14 @@ impl Step for Extended { let _ = fs::remove_dir_all(&pkg); let pkgbuild = |component: &str| { - let mut cmd = Command::new("pkgbuild"); + let mut cmd = BootstrapCommand::new("pkgbuild"); cmd.arg("--identifier") .arg(format!("org.rust-lang.{}", component)) .arg("--scripts") .arg(pkg.join(component)) .arg("--nopayload") .arg(pkg.join(component).with_extension("pkg")); - builder.run(&mut cmd); + builder.run(cmd); }; let prepare = |name: &str| { @@ -1636,7 +1637,7 @@ impl Step for Extended { builder.create_dir(&pkg.join("res")); builder.create(&pkg.join("res/LICENSE.txt"), &license); builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644); - let mut cmd = Command::new("productbuild"); + let mut cmd = BootstrapCommand::new("productbuild"); cmd.arg("--distribution") .arg(xform(&etc.join("pkg/Distribution.xml"))) .arg("--resources") @@ -1649,7 +1650,7 @@ impl Step for Extended { .arg("--package-path") .arg(&pkg); let _time = timeit(builder); - builder.run(&mut cmd); + builder.run(cmd); } if target.is_windows() { @@ -1864,7 +1865,7 @@ impl Step for Extended { let candle = |input: &Path| { let output = exe.join(input.file_stem().unwrap()).with_extension("wixobj"); let arch = if target.contains("x86_64") { "x64" } else { "x86" }; - let mut cmd = Command::new(&candle); + let mut cmd = BootstrapCommand::new(&candle); cmd.current_dir(&exe) .arg("-nologo") .arg("-dRustcDir=rustc") @@ -1893,7 +1894,7 @@ impl Step for Extended { if target.ends_with("windows-gnu") { cmd.arg("-dGccDir=rust-mingw"); } - builder.run(&mut cmd); + builder.run(cmd); }; candle(&xform(&etc.join("msi/rust.wxs"))); candle(&etc.join("msi/ui.wxs")); @@ -1925,7 +1926,7 @@ impl Step for Extended { builder.info(&format!("building `msi` installer with {light:?}")); let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target.triple); - let mut cmd = Command::new(&light); + let mut cmd = BootstrapCommand::new(&light); cmd.arg("-nologo") .arg("-ext") .arg("WixUIExtension") @@ -1962,7 +1963,7 @@ impl Step for Extended { cmd.arg("-sice:ICE57"); let _time = timeit(builder); - builder.run(&mut cmd); + builder.run(cmd); if !builder.config.dry_run() { t!(move_file(exe.join(&filename), distdir(builder).join(&filename))); @@ -1971,7 +1972,7 @@ impl Step for Extended { } } -fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) { +fn add_env(builder: &Builder<'_>, cmd: &mut BootstrapCommand, target: TargetSelection) { let mut parts = builder.version.split('.'); cmd.env("CFG_RELEASE_INFO", builder.rust_version()) .env("CFG_RELEASE_NUM", &builder.version) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 53deef7f4626b..9a26c402077cd 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -249,6 +249,7 @@ impl Step for TheBook { let shared_assets = builder.ensure(SharedAssets { target }); // build the command first so we don't nest GHA groups + // FIXME: this doesn't do anything! builder.rustdoc_cmd(compiler); // build the redirect pages @@ -300,7 +301,7 @@ fn invoke_rustdoc( cmd.arg("-Z").arg("unstable-options").arg("--disable-minification"); } - builder.run(&mut cmd); + builder.run(cmd); } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -394,7 +395,7 @@ impl Step for Standalone { } else { cmd.arg("--markdown-css").arg("rust.css"); } - builder.run(&mut cmd); + builder.run(cmd); } // We open doc/index.html as the default if invoked as `x.py doc --open` @@ -493,7 +494,7 @@ impl Step for Releases { cmd.arg("--disable-minification"); } - builder.run(&mut cmd); + builder.run(cmd); } // We open doc/RELEASES.html as the default if invoked as `x.py doc --open RELEASES.md` diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ce9dec413948d..7c7019d68bb55 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2343,7 +2343,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> let test_args = builder.config.test_args().join(" "); cmd.arg("--test-args").arg(test_args); - let mut cmd = BootstrapCommand::from(&mut cmd).delay_failure(); + cmd = cmd.delay_failure(); if !builder.config.verbose_tests { cmd = cmd.quiet(); } @@ -2941,12 +2941,12 @@ impl Step for Distcheck { let _ = fs::remove_dir_all(&dir); t!(fs::create_dir_all(&dir)); - let mut cmd = Command::new("tar"); + let mut cmd = BootstrapCommand::new("tar"); cmd.arg("-xf") .arg(builder.ensure(dist::Src).tarball()) .arg("--strip-components=1") .current_dir(&dir); - builder.run(&mut cmd); + builder.run(cmd); let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml"); builder.run( diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index a6d6326077048..2c1754d8813a8 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -24,8 +24,8 @@ use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, output, t, LldT use crate::EXTRA_CHECK_CFGS; use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode}; -pub use crate::Compiler; use crate::utils::exec::BootstrapCommand; +pub use crate::Compiler; use clap::ValueEnum; // FIXME: replace with std::lazy after it gets stabilized and reaches beta @@ -1311,8 +1311,8 @@ impl<'a> Builder<'a> { cmd } - pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command { - let mut cmd = Command::new(self.bootstrap_out.join("rustdoc")); + pub fn rustdoc_cmd(&self, compiler: Compiler) -> BootstrapCommand { + let mut cmd = BootstrapCommand::new(self.bootstrap_out.join("rustdoc")); cmd.env("RUSTC_STAGE", compiler.stage.to_string()) .env("RUSTC_SYSROOT", self.sysroot(compiler)) // Note that this is *not* the sysroot_libdir because rustdoc must be linked diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 81ab204210c8b..4dbcc2b54f1a9 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,4 +1,5 @@ use std::ffi::OsStr; +use std::ops::{Deref, DerefMut}; use std::path::Path; use std::process::{Command, ExitStatus, Output}; @@ -46,6 +47,38 @@ pub struct BootstrapCommand { } impl BootstrapCommand { + pub fn new>(program: S) -> Self { + Command::new(program).into() + } + + pub fn arg>(&mut self, arg: S) -> &mut Self { + self.command.arg(arg.as_ref()); + self + } + + pub fn args(&mut self, args: I) -> &mut Self + where + I: IntoIterator, + S: AsRef, + { + self.command.args(args); + self + } + + pub fn env(&mut self, key: K, val: V) -> &mut Self + where + K: AsRef, + V: AsRef, + { + self.command.env(key, val); + self + } + + pub fn current_dir>(&mut self, dir: P) -> &mut Self { + self.command.current_dir(dir); + self + } + pub fn delay_failure(self) -> Self { Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self } } @@ -101,6 +134,24 @@ impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { } } +/// This implementation is temporary, until all `Command` invocations are migrated to +/// `BootstrapCommand`. +impl Deref for BootstrapCommand { + type Target = Command; + + fn deref(&self) -> &Self::Target { + &self.command + } +} + +/// This implementation is temporary, until all `Command` invocations are migrated to +/// `BootstrapCommand`. +impl DerefMut for BootstrapCommand { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.command + } +} + impl From for BootstrapCommand { fn from(command: Command) -> Self { Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None } From f7d954333810544743c5571f975421bd92e200a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:19:23 +0200 Subject: [PATCH 115/217] Migrate `cargo_clippy_cmd` and `cargo_miri_cmd` to `BootstrapCommand` --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/run.rs | 3 +-- src/bootstrap/src/core/builder.rs | 27 +++++++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a7cb8424a4b3f..a6172589dbb0f 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2077,7 +2077,7 @@ pub fn stream_cargo( tail_args: Vec, cb: &mut dyn FnMut(CargoMessage<'_>), ) -> bool { - let mut cargo = Command::from(cargo); + let mut cargo = BootstrapCommand::from(cargo).command; // Instruct Cargo to give us json messages on stdout, critically leaving // stderr as piped so we can get those pretty colors. let mut message_format = if builder.config.json_output { diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 9268b335db7c2..8a6dec854a776 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -158,8 +158,7 @@ impl Step for Miri { // after another --, so this must be at the end. miri.args(builder.config.args()); - let mut miri = Command::from(miri); - builder.run(&mut miri); + builder.run(miri); } } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 2c1754d8813a8..9fb0f92a605cf 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1251,11 +1251,11 @@ impl<'a> Builder<'a> { self.ensure(tool::Rustdoc { compiler }) } - pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> Command { + pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { if run_compiler.stage == 0 { // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy. let cargo_clippy = self.build.config.download_clippy(); - let mut cmd = Command::new(cargo_clippy); + let mut cmd = BootstrapCommand::new(cargo_clippy); cmd.env("CARGO", &self.initial_cargo); return cmd; } @@ -1274,13 +1274,13 @@ impl<'a> Builder<'a> { let mut dylib_path = helpers::dylib_path(); dylib_path.insert(0, self.sysroot(run_compiler).join("lib")); - let mut cmd = Command::new(cargo_clippy); + let mut cmd = BootstrapCommand::new(cargo_clippy); cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); cmd.env("CARGO", &self.initial_cargo); cmd } - pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> Command { + pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0"); let build_compiler = self.compiler(run_compiler.stage - 1, self.build.build); @@ -1296,7 +1296,7 @@ impl<'a> Builder<'a> { extra_features: Vec::new(), }); // Invoke cargo-miri, make sure it can find miri and cargo. - let mut cmd = Command::new(cargo_miri); + let mut cmd = BootstrapCommand::new(cargo_miri); cmd.env("MIRI", &miri); cmd.env("CARGO", &self.initial_cargo); // Need to add the `run_compiler` libs. Those are the libs produces *by* `build_compiler`, @@ -1353,7 +1353,7 @@ impl<'a> Builder<'a> { mode: Mode, target: TargetSelection, cmd: &str, // FIXME make this properly typed - ) -> Command { + ) -> BootstrapCommand { let mut cargo; if cmd == "clippy" { cargo = self.cargo_clippy_cmd(compiler); @@ -1366,7 +1366,7 @@ impl<'a> Builder<'a> { cargo = self.cargo_miri_cmd(compiler); cargo.arg("miri").arg(subcmd); } else { - cargo = Command::new(&self.initial_cargo); + cargo = BootstrapCommand::new(&self.initial_cargo); cargo.arg(cmd); } @@ -2374,7 +2374,7 @@ impl HostFlags { #[derive(Debug)] pub struct Cargo { - command: Command, + command: BootstrapCommand, compiler: Compiler, target: TargetSelection, rustflags: Rustflags, @@ -2599,8 +2599,8 @@ impl Cargo { } } -impl From for Command { - fn from(mut cargo: Cargo) -> Command { +impl From for BootstrapCommand { + fn from(mut cargo: Cargo) -> BootstrapCommand { let rustflags = &cargo.rustflags.0; if !rustflags.is_empty() { cargo.command.env("RUSTFLAGS", rustflags); @@ -2619,13 +2619,12 @@ impl From for Command { if !cargo.allow_features.is_empty() { cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features); } - cargo.command } } -impl From for BootstrapCommand { - fn from(cargo: Cargo) -> BootstrapCommand { - Command::from(cargo).into() +impl From for Command { + fn from(cargo: Cargo) -> Command { + BootstrapCommand::from(cargo).command } } From 8a890cb6cb359a264f6ae0c34dd20ecaacbb0aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:22:39 +0200 Subject: [PATCH 116/217] Migrate a few command usages to `BootstrapCommand` --- src/bootstrap/src/core/build_steps/doc.rs | 4 ++-- src/bootstrap/src/core/build_steps/install.rs | 6 +++--- src/bootstrap/src/core/build_steps/run.rs | 12 ++++++------ src/bootstrap/src/core/build_steps/test.rs | 16 ++++++++-------- src/bootstrap/src/core/build_steps/tool.rs | 10 +++++----- src/bootstrap/src/core/build_steps/vendor.rs | 6 +++--- src/bootstrap/src/core/builder.rs | 2 +- src/bootstrap/src/utils/helpers.rs | 3 ++- src/bootstrap/src/utils/tarball.rs | 2 +- 9 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 9a26c402077cd..0395d093ae302 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1116,7 +1116,7 @@ impl Step for UnstableBookGen { cmd.arg(builder.src.join("src")); cmd.arg(out); - builder.run(&mut cmd); + builder.run(cmd); } } @@ -1211,7 +1211,7 @@ impl Step for RustcBook { self.compiler.host, self.target, ); - builder.run(&mut cmd); + builder.run(cmd); drop(doc_generator_guard); // Run rustbook/mdbook to generate the HTML pages. diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index c47233ca42abe..7ee1aca2abcd4 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -6,11 +6,11 @@ use std::env; use std::fs; use std::path::{Component, Path, PathBuf}; -use std::process::Command; use crate::core::build_steps::dist; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::{Config, TargetSelection}; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::t; use crate::utils::tarball::GeneratedTarball; use crate::{Compiler, Kind}; @@ -102,7 +102,7 @@ fn install_sh( let empty_dir = builder.out.join("tmp/empty_dir"); t!(fs::create_dir_all(&empty_dir)); - let mut cmd = Command::new(SHELL); + let mut cmd = BootstrapCommand::new(SHELL); cmd.current_dir(&empty_dir) .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh"))) .arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix))) @@ -113,7 +113,7 @@ fn install_sh( .arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir))) .arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir))) .arg("--disable-ldconfig"); - builder.run(&mut cmd); + builder.run(cmd); t!(fs::remove_dir_all(&empty_dir)); } diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 8a6dec854a776..22d5efa5d95dd 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -50,7 +50,7 @@ impl Step for BuildManifest { cmd.arg(&builder.config.channel); builder.create_dir(&distdir(builder)); - builder.run(&mut cmd); + builder.run(cmd); } } @@ -72,7 +72,7 @@ impl Step for BumpStage0 { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::BumpStage0); cmd.args(builder.config.args()); - builder.run(&mut cmd); + builder.run(cmd); } } @@ -94,7 +94,7 @@ impl Step for ReplaceVersionPlaceholder { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder); cmd.arg(&builder.src); - builder.run(&mut cmd); + builder.run(cmd); } } @@ -188,7 +188,7 @@ impl Step for CollectLicenseMetadata { let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata); cmd.env("REUSE_EXE", reuse); cmd.env("DEST", &dest); - builder.run(&mut cmd); + builder.run(cmd); dest } @@ -218,7 +218,7 @@ impl Step for GenerateCopyright { let mut cmd = builder.tool_cmd(Tool::GenerateCopyright); cmd.env("LICENSE_METADATA", &license_metadata); cmd.env("DEST", &dest); - builder.run(&mut cmd); + builder.run(cmd); dest } @@ -242,7 +242,7 @@ impl Step for GenerateWindowsSys { fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::GenerateWindowsSys); cmd.arg(&builder.src); - builder.run(&mut cmd); + builder.run(cmd); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7c7019d68bb55..9dea8f912efb9 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2874,19 +2874,19 @@ impl Step for RemoteCopyLibs { // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); - let mut cmd = Command::new(&tool); + let mut cmd = BootstrapCommand::new(&tool); cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.tempdir()); if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); } - builder.run(&mut cmd); + builder.run(cmd); // Push all our dylibs to the emulator for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) { let f = t!(f); let name = f.file_name().into_string().unwrap(); if helpers::is_dylib(&name) { - builder.run(Command::new(&tool).arg("push").arg(f.path())); + builder.run(BootstrapCommand::new(&tool).arg("push").arg(f.path())); } } } @@ -2917,20 +2917,20 @@ impl Step for Distcheck { builder.ensure(dist::PlainSourceTarball); builder.ensure(dist::Src); - let mut cmd = Command::new("tar"); + let mut cmd = BootstrapCommand::new("tar"); cmd.arg("-xf") .arg(builder.ensure(dist::PlainSourceTarball).tarball()) .arg("--strip-components=1") .current_dir(&dir); - builder.run(&mut cmd); + builder.run(cmd); builder.run( - Command::new("./configure") + BootstrapCommand::new("./configure") .args(&builder.config.configure_args) .arg("--enable-vendor") .current_dir(&dir), ); builder.run( - Command::new(helpers::make(&builder.config.build.triple)) + BootstrapCommand::new(helpers::make(&builder.config.build.triple)) .arg("check") .current_dir(&dir), ); @@ -2950,7 +2950,7 @@ impl Step for Distcheck { let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml"); builder.run( - Command::new(&builder.initial_cargo) + BootstrapCommand::new(&builder.initial_cargo) // Will read the libstd Cargo.toml // which uses the unstable `public-dependency` feature. .env("RUSTC_BOOTSTRAP", "1") diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 351af7697bc45..eb8c62759c8e2 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -433,12 +433,12 @@ pub struct ErrorIndex { } impl ErrorIndex { - pub fn command(builder: &Builder<'_>) -> Command { + pub fn command(builder: &Builder<'_>) -> BootstrapCommand { // Error-index-generator links with the rustdoc library, so we need to add `rustc_lib_paths` // for rustc_private and libLLVM.so, and `sysroot_lib` for libstd, etc. let host = builder.config.build; let compiler = builder.compiler_for(builder.top_stage, host, host); - let mut cmd = Command::new(builder.ensure(ErrorIndex { compiler })); + let mut cmd = BootstrapCommand::new(builder.ensure(ErrorIndex { compiler })); let mut dylib_paths = builder.rustc_lib_paths(compiler); dylib_paths.push(PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))); add_dylib_path(dylib_paths, &mut cmd); @@ -1046,10 +1046,10 @@ tool_extended!((self, builder), ); impl<'a> Builder<'a> { - /// Gets a `Command` which is ready to run `tool` in `stage` built for + /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for /// `host`. - pub fn tool_cmd(&self, tool: Tool) -> Command { - let mut cmd = Command::new(self.tool_exe(tool)); + pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand { + let mut cmd = BootstrapCommand::new(self.tool_exe(tool)); let compiler = self.compiler(0, self.config.build); let host = &compiler.host; // Prepares the `cmd` provided to be able to run the `compiler` provided. diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index e92ab57619b6a..5886c93024c85 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,6 +1,6 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use std::path::{Path, PathBuf}; -use std::process::Command; +use crate::utils::exec::BootstrapCommand; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub(crate) struct Vendor { @@ -27,7 +27,7 @@ impl Step for Vendor { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let mut cmd = Command::new(&builder.initial_cargo); + let mut cmd = BootstrapCommand::new(&builder.initial_cargo); cmd.arg("vendor"); if self.versioned_dirs { @@ -59,6 +59,6 @@ impl Step for Vendor { cmd.current_dir(self.root_dir); - builder.run(&mut cmd); + builder.run(cmd); } } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 9fb0f92a605cf..08866d1a97d5c 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1218,7 +1218,7 @@ impl<'a> Builder<'a> { /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic /// library lookup path. - pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Command) { + pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut BootstrapCommand) { // Windows doesn't need dylib path munging because the dlls for the // compiler live next to the compiler and the system will find them // automatically. diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 59b29eedb7971..04869719d4e01 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -47,6 +47,7 @@ macro_rules! t { } }; } +use crate::utils::exec::BootstrapCommand; pub use t; pub fn exe(name: &str, target: TargetSelection) -> String { @@ -72,7 +73,7 @@ pub fn libdir(target: TargetSelection) -> &'static str { /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. /// If the dylib_path_var is already set for this cmd, the old value will be overwritten! -pub fn add_dylib_path(path: Vec, cmd: &mut Command) { +pub fn add_dylib_path(path: Vec, cmd: &mut BootstrapCommand) { let mut list = dylib_path(); for path in path { list.insert(0, path); diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index fd934f18de23f..6219ec895b5e5 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -353,7 +353,7 @@ impl<'a> Tarball<'a> { }; cmd.args(["--compression-profile", compression_profile]); - self.builder.run(&mut cmd); + self.builder.run(cmd); // Ensure there are no symbolic links in the tarball. In particular, // rustup-toolchain-install-master and most versions of Windows can't handle symbolic links. From 83d33c2cf57c3be1c0035b492c8b98a5b5f52456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:27:15 +0200 Subject: [PATCH 117/217] Migrate a few command usages to `BootstrapCommand` --- src/bootstrap/src/core/build_steps/clean.rs | 2 +- src/bootstrap/src/core/build_steps/doc.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 15 +++++++-------- src/bootstrap/src/core/download.rs | 5 +++-- src/bootstrap/src/utils/helpers.rs | 5 +++-- src/bootstrap/src/utils/tarball.rs | 10 ++++------ 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index a81d640301363..479af4af66665 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -85,7 +85,7 @@ macro_rules! clean_crate_tree { // NOTE: doesn't use `run_cargo` because we don't want to save a stamp file, // and doesn't use `stream_cargo` to avoid passing `--message-format` which `clean` doesn't accept. - builder.run(&mut cargo); + builder.run(cargo); } } )+ } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 0395d093ae302..4a5af25b3b2f8 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1080,7 +1080,7 @@ impl Step for ErrorIndex { index.arg(out); index.arg(&builder.version); - builder.run(&mut index); + builder.run(index); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9dea8f912efb9..db6f54a49acca 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -465,7 +465,7 @@ impl Miri { // Tell it where to put the sysroot. cargo.env("MIRI_SYSROOT", &miri_sysroot); - let mut cargo = Command::from(cargo); + let mut cargo = BootstrapCommand::from(cargo); let _guard = builder.msg(Kind::Build, compiler.stage, "miri sysroot", compiler.host, target); builder.run(&mut cargo); @@ -596,7 +596,7 @@ impl Step for Miri { target, ); let _time = helpers::timeit(builder); - builder.run(&mut cargo); + builder.run(cargo); } } } @@ -661,11 +661,11 @@ impl Step for CargoMiri { // Finally, pass test-args and run everything. cargo.arg("--").args(builder.config.test_args()); - let mut cargo = Command::from(cargo); + let cargo = BootstrapCommand::from(cargo); { let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "cargo-miri", host, target); let _time = helpers::timeit(builder); - builder.run(&mut cargo); + builder.run(cargo); } } } @@ -845,7 +845,7 @@ impl Step for RustdocJSStd { fn run(self, builder: &Builder<'_>) { let nodejs = builder.config.nodejs.as_ref().expect("need nodejs to run rustdoc-js-std tests"); - let mut command = Command::new(nodejs); + let mut command = BootstrapCommand::new(nodejs); command .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) .arg("--crate-name") @@ -879,7 +879,7 @@ impl Step for RustdocJSStd { builder.config.build, self.target, ); - builder.run(&mut command); + builder.run(command); } } @@ -1304,8 +1304,7 @@ impl Step for RunMakeSupport { &[], ); - let mut cargo = Command::from(cargo); - builder.run(&mut cargo); + builder.run(cargo); let lib_name = "librun_make_support.rlib"; let lib = builder.tools_dir(self.compiler).join(lib_name); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index fd077ab2d7c7a..c35398e2eb764 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -11,6 +11,7 @@ use std::{ use build_helper::ci::CiEnv; use xz2::bufread::XzDecoder; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::hex_encode; use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date}; use crate::{t, Config}; @@ -56,7 +57,7 @@ impl Config { /// Runs a command, printing out nice contextual information if it fails. /// Returns false if do not execute at all, otherwise returns its /// `status.success()`. - pub(crate) fn check_run(&self, cmd: &mut Command) -> bool { + pub(crate) fn check_run(&self, cmd: &mut BootstrapCommand) -> bool { if self.dry_run() { return true; } @@ -211,7 +212,7 @@ impl Config { fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { println!("downloading {url}"); // Try curl. If that fails and we are on windows, fallback to PowerShell. - let mut curl = Command::new("curl"); + let mut curl = BootstrapCommand::new("curl"); curl.args([ "-y", "30", diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 04869719d4e01..ee2caef4684e7 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -242,8 +242,9 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef>( } } -pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { - let status = match cmd.status() { +// FIXME: get rid of this function +pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool { + let status = match cmd.command.status() { Ok(status) => status, Err(e) => { println!("failed to execute command: {cmd:?}\nERROR: {e}"); diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 6219ec895b5e5..5cc319826dbf3 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -5,14 +5,12 @@ //! In uplifting, a tarball from Stage N captures essential components //! to assemble Stage N + 1 compiler. -use std::{ - path::{Path, PathBuf}, - process::Command, -}; +use std::path::{Path, PathBuf}; use crate::core::builder::Builder; use crate::core::{build_steps::dist::distdir, builder::Kind}; use crate::utils::channel; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{move_file, t}; #[derive(Copy, Clone)] @@ -300,7 +298,7 @@ impl<'a> Tarball<'a> { } } - fn non_bare_args(&self, cmd: &mut Command) { + fn non_bare_args(&self, cmd: &mut BootstrapCommand) { cmd.arg("--rel-manifest-dir=rustlib") .arg("--legacy-manifest-dirs=rustlib,cargo") .arg(format!("--product-name={}", self.product_name)) @@ -312,7 +310,7 @@ impl<'a> Tarball<'a> { .arg(distdir(self.builder)); } - fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball { + fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut BootstrapCommand)) -> GeneratedTarball { t!(std::fs::create_dir_all(&self.overlay_dir)); self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder)); if let Some(info) = self.builder.rust_info().info() { From bed2cbd2cef6080ba35fe1554f6ba82634590134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:33:11 +0200 Subject: [PATCH 118/217] Get rid of `Deref/DerefMut` impl for `BootstrapCmd` --- src/bootstrap/src/core/build_steps/suggest.rs | 1 + src/bootstrap/src/core/build_steps/test.rs | 21 +++++++----- src/bootstrap/src/core/builder.rs | 2 +- src/bootstrap/src/lib.rs | 2 +- src/bootstrap/src/utils/exec.rs | 34 ++++++++----------- src/bootstrap/src/utils/helpers.rs | 4 +-- src/bootstrap/src/utils/render_tests.rs | 17 +++++++--- 7 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 754d1e61da8c6..7c5e0d4e13ebb 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -16,6 +16,7 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { .tool_cmd(Tool::SuggestTests) .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch) + .command .output() .expect("failed to run `suggest-tests` tool"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index db6f54a49acca..e5243e26f2b56 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -482,8 +482,10 @@ impl Miri { String::new() } else { builder.verbose(|| println!("running: {cargo:?}")); - let out = - cargo.output().expect("We already ran `cargo miri setup` before and that worked"); + let out = cargo + .command + .output() + .expect("We already ran `cargo miri setup` before and that worked"); assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code"); // Output is "\n". let stdout = String::from_utf8(out.stdout) @@ -2065,7 +2067,8 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--git-repository").arg(git_config.git_repository); cmd.arg("--nightly-branch").arg(git_config.nightly_branch); - builder.ci_env.force_coloring_in_ci(&mut cmd); + // FIXME: Move CiEnv back to bootstrap, it is only used here anyway + builder.ci_env.force_coloring_in_ci(&mut cmd.command); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -2424,7 +2427,7 @@ impl Step for CrateLibrustc { /// Returns whether the test succeeded. #[allow(clippy::too_many_arguments)] // FIXME: reduce the number of args and remove this. fn run_cargo_test<'a>( - cargo: impl Into, + cargo: impl Into, libtest_args: &[&str], crates: &[String], primary_crate: &str, @@ -2455,14 +2458,14 @@ fn run_cargo_test<'a>( /// Given a `cargo test` subcommand, pass it the appropriate test flags given a `builder`. fn prepare_cargo_test( - cargo: impl Into, + cargo: impl Into, libtest_args: &[&str], crates: &[String], primary_crate: &str, compiler: Compiler, target: TargetSelection, builder: &Builder<'_>, -) -> Command { +) -> BootstrapCommand { let mut cargo = cargo.into(); // Propegate `--bless` if it has not already been set/unset @@ -2978,7 +2981,7 @@ impl Step for Bootstrap { // Some tests require cargo submodule to be present. builder.build.update_submodule(Path::new("src/tools/cargo")); - let mut check_bootstrap = Command::new(builder.python()); + let mut check_bootstrap = BootstrapCommand::new(builder.python()); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) @@ -2986,9 +2989,9 @@ impl Step for Bootstrap { .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. - builder.run(BootstrapCommand::from(&mut check_bootstrap).delay_failure()); + builder.run(check_bootstrap.delay_failure()); - let mut cmd = Command::new(&builder.initial_cargo); + let mut cmd = BootstrapCommand::new(&builder.initial_cargo); cmd.arg("test") .args(["--features", "bootstrap-self-test"]) .current_dir(builder.src.join("src/bootstrap")) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 08866d1a97d5c..58d6e7a58e308 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2105,7 +2105,7 @@ impl<'a> Builder<'a> { // Try to use a sysroot-relative bindir, in case it was configured absolutely. cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative()); - self.ci_env.force_coloring_in_ci(&mut cargo); + self.ci_env.force_coloring_in_ci(&mut cargo.command); // When we build Rust dylibs they're all intended for intermediate // usage, so make sure we pass the -Cprefer-dynamic flag instead of diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index cee6b34490292..8361e01014b22 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -937,7 +937,7 @@ impl Build { } /// Adds the `RUST_TEST_THREADS` env var if necessary - fn add_rust_test_threads(&self, cmd: &mut Command) { + fn add_rust_test_threads(&self, cmd: &mut BootstrapCommand) { if env::var_os("RUST_TEST_THREADS").is_none() { cmd.env("RUST_TEST_THREADS", self.jobs().to_string()); } diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 4dbcc2b54f1a9..8bcb2301f1ace 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,7 +1,6 @@ use std::ffi::OsStr; -use std::ops::{Deref, DerefMut}; use std::path::Path; -use std::process::{Command, ExitStatus, Output}; +use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output}; /// What should be done when the command fails. #[derive(Debug, Copy, Clone)] @@ -74,6 +73,19 @@ impl BootstrapCommand { self } + pub fn get_envs(&self) -> CommandEnvs<'_> { + self.command.get_envs() + } + + pub fn get_args(&self) -> CommandArgs<'_> { + self.command.get_args() + } + + pub fn env_remove>(&mut self, key: K) -> &mut Self { + self.command.env_remove(key); + self + } + pub fn current_dir>(&mut self, dir: P) -> &mut Self { self.command.current_dir(dir); self @@ -134,24 +146,6 @@ impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { } } -/// This implementation is temporary, until all `Command` invocations are migrated to -/// `BootstrapCommand`. -impl Deref for BootstrapCommand { - type Target = Command; - - fn deref(&self) -> &Self::Target { - &self.command - } -} - -/// This implementation is temporary, until all `Command` invocations are migrated to -/// `BootstrapCommand`. -impl DerefMut for BootstrapCommand { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.command - } -} - impl From for BootstrapCommand { fn from(command: Command) -> Self { Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index ee2caef4684e7..ab53c08ba217f 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -82,7 +82,7 @@ pub fn add_dylib_path(path: Vec, cmd: &mut BootstrapCommand) { } /// Adds a list of lookup paths to `cmd`'s link library lookup path. -pub fn add_link_lib_path(path: Vec, cmd: &mut Command) { +pub fn add_link_lib_path(path: Vec, cmd: &mut BootstrapCommand) { let mut list = link_lib_path(); for path in path { list.insert(0, path); @@ -439,7 +439,7 @@ pub fn linker_flags( } pub fn add_rustdoc_cargo_linker_args( - cmd: &mut Command, + cmd: &mut BootstrapCommand, builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 5c9918bce32e1..2e99bc68a8b75 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -7,14 +7,18 @@ //! to reimplement all the rendering logic in this module because of that. use crate::core::builder::Builder; +use crate::utils::exec::BootstrapCommand; use std::io::{BufRead, BufReader, Read, Write}; -use std::process::{ChildStdout, Command, Stdio}; +use std::process::{ChildStdout, Stdio}; use std::time::Duration; use termcolor::{Color, ColorSpec, WriteColor}; const TERSE_TESTS_PER_LINE: usize = 88; -pub(crate) fn add_flags_and_try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool { +pub(crate) fn add_flags_and_try_run_tests( + builder: &Builder<'_>, + cmd: &mut BootstrapCommand, +) -> bool { if !cmd.get_args().any(|arg| arg == "--") { cmd.arg("--"); } @@ -23,7 +27,11 @@ pub(crate) fn add_flags_and_try_run_tests(builder: &Builder<'_>, cmd: &mut Comma try_run_tests(builder, cmd, false) } -pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool { +pub(crate) fn try_run_tests( + builder: &Builder<'_>, + cmd: &mut BootstrapCommand, + stream: bool, +) -> bool { if builder.config.dry_run() { return true; } @@ -41,7 +49,8 @@ pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bo } } -fn run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool { +fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> bool { + let cmd = &mut cmd.command; cmd.stdout(Stdio::piped()); builder.verbose(|| println!("running: {cmd:?}")); From 2ebfccecd027587777309e90f99408f79128e009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 11:35:03 +0200 Subject: [PATCH 119/217] Migrate more `Command` usages to `BootstrapCmd` --- src/bootstrap/src/core/build_steps/dist.rs | 18 +++++++++--------- src/bootstrap/src/core/build_steps/test.rs | 11 ++++------- src/bootstrap/src/core/build_steps/tool.rs | 4 ++-- src/bootstrap/src/core/build_steps/vendor.rs | 2 +- src/bootstrap/src/lib.rs | 2 +- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index a46a9373d9cae..e420840fdbf25 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1705,7 +1705,7 @@ impl Step for Extended { let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"]; builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rustc") @@ -1721,7 +1721,7 @@ impl Step for Extended { ); if built_tools.contains("rust-docs") { builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rust-docs") @@ -1739,7 +1739,7 @@ impl Step for Extended { ); } builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("cargo") @@ -1756,7 +1756,7 @@ impl Step for Extended { .arg(etc.join("msi/remove-duplicates.xsl")), ); builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rust-std") @@ -1772,7 +1772,7 @@ impl Step for Extended { ); if built_tools.contains("rust-analyzer") { builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rust-analyzer") @@ -1791,7 +1791,7 @@ impl Step for Extended { } if built_tools.contains("clippy") { builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("clippy") @@ -1810,7 +1810,7 @@ impl Step for Extended { } if built_tools.contains("miri") { builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("miri") @@ -1828,7 +1828,7 @@ impl Step for Extended { ); } builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rust-analysis") @@ -1846,7 +1846,7 @@ impl Step for Extended { ); if target.ends_with("windows-gnu") { builder.run( - Command::new(&heat) + BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") .arg("rust-mingw") diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e5243e26f2b56..d891a52f1ef1b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3142,8 +3142,7 @@ impl Step for RustInstaller { return; } - let mut cmd = - std::process::Command::new(builder.src.join("src/tools/rust-installer/test.sh")); + let mut cmd = BootstrapCommand::new(builder.src.join("src/tools/rust-installer/test.sh")); let tmpdir = testdir(builder, compiler.host).join("rust-installer"); let _ = std::fs::remove_dir_all(&tmpdir); let _ = std::fs::create_dir_all(&tmpdir); @@ -3152,7 +3151,7 @@ impl Step for RustInstaller { cmd.env("CARGO", &builder.initial_cargo); cmd.env("RUSTC", &builder.initial_rustc); cmd.env("TMP_DIR", &tmpdir); - builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(cmd.delay_failure()); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3346,8 +3345,7 @@ impl Step for CodegenCranelift { .arg("testsuite.extended_sysroot"); cargo.args(builder.config.test_args()); - let mut cmd: Command = cargo.into(); - builder.run(BootstrapCommand::from(&mut cmd)); + builder.run(cargo); } } @@ -3472,7 +3470,6 @@ impl Step for CodegenGCC { .arg("--std-tests"); cargo.args(builder.config.test_args()); - let mut cmd: Command = cargo.into(); - builder.run(BootstrapCommand::from(&mut cmd)); + builder.run(cargo); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index eb8c62759c8e2..f6258121c50db 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -912,13 +912,13 @@ impl Step for LibcxxVersionTool { } let compiler = builder.cxx(self.target).unwrap(); - let mut cmd = Command::new(compiler); + let mut cmd = BootstrapCommand::new(compiler); cmd.arg("-o") .arg(&executable) .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - builder.run(BootstrapCommand::from(&mut cmd)); + builder.run(cmd); if !executable.exists() { panic!("Something went wrong. {} is not present", executable.display()); diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 5886c93024c85..0b999a24a1fb9 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,6 +1,6 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; -use std::path::{Path, PathBuf}; use crate::utils::exec::BootstrapCommand; +use std::path::{Path, PathBuf}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub(crate) struct Vendor { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 8361e01014b22..730d0ae5f3d7c 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -575,7 +575,7 @@ impl Build { }; // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. if !update(true).status().map_or(false, |status| status.success()) { - self.run(&mut update(false)); + self.run(update(false)); } // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). From 72e8244e64b284f8f93a778e804b59c10305fc59 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 14 Jun 2024 12:16:15 +0000 Subject: [PATCH 120/217] implement new effects desugaring --- compiler/rustc_ast_lowering/src/expr.rs | 1 - compiler/rustc_ast_lowering/src/item.rs | 111 ++++++++---- compiler/rustc_ast_lowering/src/lib.rs | 91 ++-------- compiler/rustc_ast_lowering/src/path.rs | 9 - .../src/const_eval/fn_queries.rs | 5 +- compiler/rustc_feature/src/builtin_attrs.rs | 4 + compiler/rustc_hir/src/hir.rs | 2 + compiler/rustc_hir/src/intravisit.rs | 3 +- compiler/rustc_hir/src/lang_items.rs | 8 + compiler/rustc_hir_analysis/src/bounds.rs | 102 ++++++++++- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_impl_item.rs | 8 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- compiler/rustc_hir_analysis/src/collect.rs | 49 ++--- .../src/collect/generics_of.rs | 6 +- .../src/collect/item_bounds.rs | 4 +- .../src/collect/predicates_of.rs | 65 +++++-- .../src/collect/resolve_bound_vars.rs | 2 +- .../src/hir_ty_lowering/generics.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 9 +- .../src/hir_ty_lowering/object_safety.rs | 6 +- compiler/rustc_hir_pretty/src/lib.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 1 + compiler/rustc_hir_typeck/src/method/mod.rs | 15 +- compiler/rustc_hir_typeck/src/method/probe.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 5 +- .../src/rmeta/decoder/cstore_impl.rs | 3 + compiler/rustc_metadata/src/rmeta/encoder.rs | 6 + compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 8 + compiler/rustc_middle/src/ty/assoc.rs | 2 + compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/generics.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 12 +- compiler/rustc_smir/src/rustc_smir/context.rs | 6 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 2 +- compiler/rustc_span/src/symbol.rs | 9 + .../src/traits/error_reporting/suggestions.rs | 6 + compiler/rustc_ty_utils/src/assoc.rs | 168 +++++++++++++++++- library/core/src/lib.rs | 1 + library/core/src/marker.rs | 38 ++++ src/librustdoc/clean/mod.rs | 14 +- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/json/conversions.rs | 16 +- .../const_trait_fn-issue-88433.rs | 1 + .../effects/group-traits.rs | 14 ++ .../issue-92230-wf-super-trait-env.rs | 3 +- .../tilde-const-invalid-places.stderr | 11 +- .../unsatisfied-const-trait-bound.rs | 1 + 50 files changed, 636 insertions(+), 228 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 624bca525b9f3..218fa9740229d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -103,7 +103,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, // Method calls can't have bound modifiers None, )); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 74e04eff4f3e0..d59ac5766298d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -56,7 +56,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { owner: NodeId, f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, ) { - let mut lctx = LoweringContext::new(self.tcx, self.resolver); + let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.ast_index); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); for (def_id, info) in lctx.children { @@ -190,6 +190,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, (ty, body_id)) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -221,7 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let itctx = ImplTraitContext::Universal; let (generics, decl) = - this.lower_generics(generics, header.constness, id, itctx, |this| { + this.lower_generics(generics, header.constness, false, id, itctx, |this| { this.lower_fn_decl( decl, id, @@ -265,6 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, ty) = self.lower_generics( &generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -293,6 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, variants) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -307,6 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, struct_def) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, struct_def), @@ -317,6 +321,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, vdata) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, vdata), @@ -348,12 +353,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // parent lifetime. let itctx = ImplTraitContext::Universal; let (generics, (trait_ref, lowered_ty)) = - self.lower_generics(ast_generics, *constness, id, itctx, |this| { + self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| { let modifiers = TraitBoundModifiers { - constness: match *constness { - Const::Yes(span) => BoundConstness::Maybe(span), - Const::No => BoundConstness::Never, - }, + constness: BoundConstness::Never, asyncness: BoundAsyncness::Normal, // we don't use this in bound lowering polarity: BoundPolarity::Positive, @@ -389,6 +391,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)), }; hir::ItemKind::Impl(self.arena.alloc(hir::Impl { + constness: self.lower_constness(*constness), safety: self.lower_safety(*safety, hir::Safety::Safe), polarity, defaultness, @@ -400,15 +403,10 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { - // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible - let constness = attrs - .unwrap_or(&[]) - .iter() - .find(|x| x.has_name(sym::const_trait)) - .map_or(Const::No, |x| Const::Yes(x.span)); let (generics, (safety, items, bounds)) = self.lower_generics( generics, - constness, + Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -429,6 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, bounds) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -609,30 +608,45 @@ impl<'hir> LoweringContext<'_, 'hir> { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - let generics = match parent_hir.node().expect_item().kind { + let parent_item = parent_hir.node().expect_item(); + let constness = match parent_item.kind { hir::ItemKind::Impl(impl_) => { self.is_in_trait_impl = impl_.of_trait.is_some(); - &impl_.generics + // N.B. the impl should always lower to methods that have `const host: bool` params if the trait + // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from + // calling non-const impls are done through associated types. + if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) { + if let Some(local_def) = def_id.as_local() { + match &self.ast_index[local_def] { + AstOwner::Item(ast::Item { attrs, .. }) => attrs + .iter() + .find(|attr| attr.has_name(sym::const_trait)) + .map_or(Const::No, |attr| Const::Yes(attr.span)), + _ => Const::No, + } + } else { + self.tcx + .get_attr(def_id, sym::const_trait) + .map_or(Const::No, |attr| Const::Yes(attr.span)) + } + } else { + Const::No + } } - hir::ItemKind::Trait(_, _, generics, _, _) => generics, + hir::ItemKind::Trait(_, _, _, _, _) => parent_hir + .attrs + .get(parent_item.hir_id().local_id) + .iter() + .find(|attr| attr.has_name(sym::const_trait)) + .map_or(Const::No, |attr| Const::Yes(attr.span)), kind => { span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) } }; - if self.tcx.features().effects { - self.host_param_id = generics - .params - .iter() - .find(|param| { - matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. }) - }) - .map(|param| param.def_id); - } - match ctxt { - AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), - AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)), + AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)), + AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)), } } @@ -648,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let fdec = &sig.decl; let itctx = ImplTraitContext::Universal; let (generics, (fn_dec, fn_args)) = - self.lower_generics(generics, Const::No, i.id, itctx, |this| { + self.lower_generics(generics, Const::No, false, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. this.lower_fn_decl( @@ -765,7 +779,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { + fn lower_trait_item( + &mut self, + i: &AssocItem, + trait_constness: Const, + ) -> &'hir hir::TraitItem<'hir> { let hir_id = self.lower_node_id(i.id); self.lower_attrs(hir_id, &i.attrs); let trait_item_def_id = hir_id.expect_owner(); @@ -775,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = self.lower_generics( generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -795,6 +814,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, FnDeclKind::Trait, sig.header.coroutine_kind, + trait_constness, ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } @@ -813,6 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, FnDeclKind::Trait, sig.header.coroutine_kind, + trait_constness, ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) } @@ -822,6 +843,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = self.lower_generics( &generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -894,7 +916,11 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err(guar)) } - fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item( + &mut self, + i: &AssocItem, + constness_of_trait: Const, + ) -> &'hir hir::ImplItem<'hir> { // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); @@ -905,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics( generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -930,6 +957,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent }, sig.header.coroutine_kind, + constness_of_trait, ); (generics, hir::ImplItemKind::Fn(sig, body_id)) @@ -940,6 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics( &generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -1352,15 +1381,18 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, kind: FnDeclKind, coroutine_kind: Option, + parent_constness: Const, ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { let header = self.lower_fn_header(sig.header); // Don't pass along the user-provided constness of trait associated functions; we don't want to // synthesize a host effect param for them. We reject `const` on them during AST validation. - let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No }; + let constness = + if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness }; let itctx = ImplTraitContext::Universal; - let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| { - this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind) - }); + let (generics, decl) = + self.lower_generics(generics, constness, kind == FnDeclKind::Impl, id, itctx, |this| { + this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind) + }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1436,6 +1468,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, generics: &Generics, constness: Const, + force_append_constness: bool, parent_node_id: NodeId, itctx: ImplTraitContext, f: impl FnOnce(&mut Self) -> T, @@ -1496,7 +1529,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // if the effects feature is enabled. This needs to be done before we lower where // clauses since where clauses need to bind to the DefId of the host param let host_param_parts = if let Const::Yes(span) = constness - && self.tcx.features().effects + // if this comes from implementing a `const` trait, we must force constness to be appended + // to the impl item, no matter whether effects is enabled. + && (self.tcx.features().effects || force_append_constness) { let span = self.lower_span(span); let param_node_id = self.next_node_id(); @@ -1609,6 +1644,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )), )), + // FIXME(effects) we might not need a default. default: Some(self.arena.alloc(hir::AnonConst { def_id: anon_const, hir_id: const_id, @@ -1616,6 +1652,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span, })), is_host_effect: true, + synthetic: true, }, colon_span: None, pure_wrt_drop: false, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0a06304fcecfa..8fba46625ab9a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -142,14 +142,19 @@ struct LoweringContext<'a, 'hir> { generics_def_id_map: Vec>, host_param_id: Option, + ast_index: &'a IndexSlice>, } impl<'a, 'hir> LoweringContext<'a, 'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self { + fn new( + tcx: TyCtxt<'hir>, + resolver: &'a mut ResolverAstLowering, + ast_index: &'a IndexSlice>, + ) -> Self { Self { // Pseudo-globals. tcx, - resolver: resolver, + resolver, arena: tcx.hir_arena, // HirId handling. @@ -185,6 +190,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { allow_async_iterator: [sym::gen_future, sym::async_iterator].into(), generics_def_id_map: Default::default(), host_param_id: None, + ast_index, } } @@ -2135,7 +2141,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param: &GenericParam, source: hir::GenericParamSource, ) -> hir::GenericParam<'hir> { - let (name, kind) = self.lower_generic_param_kind(param, source); + let (name, kind) = self.lower_generic_param_kind( + param, + source, + attr::contains_name(¶m.attrs, sym::rustc_runtime), + ); let hir_id = self.lower_node_id(param.id); self.lower_attrs(hir_id, ¶m.attrs); @@ -2155,6 +2165,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, param: &GenericParam, source: hir::GenericParamSource, + is_host_effect: bool, ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { match ¶m.kind { GenericParamKind::Lifetime => { @@ -2220,7 +2231,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ( hir::ParamName::Plain(self.lower_ident(param.ident)), - hir::GenericParamKind::Const { ty, default, is_host_effect: false }, + hir::GenericParamKind::Const { ty, default, is_host_effect, synthetic: false }, ) } } @@ -2607,78 +2618,6 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { - fn push_constness( - &mut self, - lcx: &mut LoweringContext<'_, 'hir>, - constness: ast::BoundConstness, - ) { - if !lcx.tcx.features().effects { - return; - } - - let (span, body) = match constness { - BoundConstness::Never => return, - BoundConstness::Always(span) => { - let span = lcx.lower_span(span); - - let body = hir::ExprKind::Lit( - lcx.arena.alloc(hir::Lit { node: LitKind::Bool(false), span }), - ); - - (span, body) - } - BoundConstness::Maybe(span) => { - let span = lcx.lower_span(span); - - let Some(host_param_id) = lcx.host_param_id else { - lcx.dcx().span_delayed_bug( - span, - "no host param id for call in const yet no errors reported", - ); - return; - }; - - let hir_id = lcx.next_id(); - let res = Res::Def(DefKind::ConstParam, host_param_id.to_def_id()); - let body = hir::ExprKind::Path(hir::QPath::Resolved( - None, - lcx.arena.alloc(hir::Path { - span, - res, - segments: arena_vec![ - lcx; - hir::PathSegment::new( - Ident { name: sym::host, span }, - hir_id, - res - ) - ], - }), - )); - - (span, body) - } - }; - let body = lcx.lower_body(|lcx| (&[], lcx.expr(span, body))); - - let id = lcx.next_node_id(); - let hir_id = lcx.next_id(); - - let def_id = lcx.create_def( - lcx.current_hir_id_owner.def_id, - id, - kw::Empty, - DefKind::AnonConst, - span, - ); - - lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); - self.args.push(hir::GenericArg::Const(hir::ConstArg { - value: lcx.arena.alloc(hir::AnonConst { def_id, hir_id, body, span }), - is_desugared_from_effects: true, - })) - } - fn is_empty(&self) -> bool { self.args.is_empty() && self.constraints.is_empty() diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9d38e1e678471..9a1ca703699a8 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -107,8 +107,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, parenthesized_generic_args, itctx, - // if this is the last segment, add constness to the trait path - if i == proj_start - 1 { modifiers.map(|m| m.constness) } else { None }, bound_modifier_allowed_features.clone(), ) }, @@ -165,7 +163,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ParenthesizedGenericArgs::Err, itctx, None, - None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -208,7 +205,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, - None, ) })), span: self.lower_span(p.span), @@ -222,7 +218,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: ImplTraitContext, - constness: Option, // Additional features ungated with a bound modifier like `async`. // This is passed down to the implicit associated type binding in // parenthesized bounds. @@ -289,10 +284,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }; - if let Some(constness) = constness { - generic_args.push_constness(self, constness); - } - let has_lifetimes = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 8c66888d1007e..7acd08e0cceb6 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -42,10 +42,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { hir::Constness::Const } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx - .generics_of(def_id) - .host_effect_index - .map_or(hir::Constness::NotConst, |_| hir::Constness::Const), + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f884f99692779..a4245f0908e33 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -833,6 +833,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_const_panic_str, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), + rustc_attr!( + rustc_runtime, Normal, template!(Word), WarnFollowing, + EncodeCrossCrate::No, INTERNAL_UNSTABLE + ), // ========================================================================== // Internal attributes, Layout related: diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 22a6c06bba323..6cccdec94c0b5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -526,6 +526,7 @@ pub enum GenericParamKind<'hir> { /// Optional default value for the const generic param default: Option<&'hir AnonConst>, is_host_effect: bool, + synthetic: bool, }, } @@ -3364,6 +3365,7 @@ pub enum ItemKind<'hir> { /// Refer to [`ImplItem`] for an associated item within an impl block. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { + pub constness: Constness, pub safety: Safety, pub polarity: ImplPolarity, pub defaultness: Defaultness, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 065ecc5d7b7ba..9bb3245ae05af 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -543,6 +543,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_enum_def(enum_definition, item.hir_id())); } ItemKind::Impl(Impl { + constness: _, safety: _, defaultness: _, polarity: _, @@ -915,7 +916,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { ref default, .. } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ref ty, ref default, is_host_effect: _ } => { + GenericParamKind::Const { ref ty, ref default, is_host_effect: _, synthetic: _ } => { try_visit!(visitor.visit_ty(ty)); if let Some(ref default) = default { try_visit!(visitor.visit_const_param_default(param.hir_id, default)); diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 69461957f804d..d49eb4ece99f8 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -393,6 +393,14 @@ language_item_table! { String, sym::String, string, Target::Struct, GenericRequirement::None; CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; + + EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None; + EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None; + EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None; + EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; + EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None; + EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1); + EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1); } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 7f0d72b3a8d4d..18a29c10b61a3 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -1,9 +1,13 @@ //! Bounds are restrictions applied to some types after they've been lowered from the HIR to the //! [`rustc_middle::ty`] form. +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::def::DefKind; use rustc_hir::LangItem; +use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; -use rustc_span::Span; +use rustc_span::def_id::DefId; +use rustc_span::{sym, Span}; /// Collects together a list of type bounds. These lists of bounds occur in many places /// in Rust's syntax: @@ -24,6 +28,7 @@ use rustc_span::Span; #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { clauses: Vec<(ty::Clause<'tcx>, Span)>, + effects_min_tys: FxIndexMap, Span>, } impl<'tcx> Bounds<'tcx> { @@ -40,12 +45,14 @@ impl<'tcx> Bounds<'tcx> { pub fn push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + defining_def_id: DefId, + bound_trait_ref: ty::PolyTraitRef<'tcx>, span: Span, polarity: ty::PredicatePolarity, + constness: ty::BoundConstness, ) { let clause = ( - trait_ref + bound_trait_ref .map_bound(|trait_ref| { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) }) @@ -53,11 +60,88 @@ impl<'tcx> Bounds<'tcx> { span, ); // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. - if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) { self.clauses.insert(0, clause); } else { self.clauses.push(clause); } + // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the + // associated type of `` and make sure that the effect is compatible. + if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + // TODO: do we need `T: const Trait` anymore? + (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + // body owners that can have trait bounds + (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { + Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + } + + (_, ty::BoundConstness::NotConst) => { + tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + } + + ( + DefKind::Trait | DefKind::Impl { of_trait: true }, + ty::BoundConstness::ConstIfConst, + ) => { + // this is either a where clause on an impl/trait header or on a trait. + // push `::Effects` into the set for the `Min` bound. + let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { + tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc"); + return; + }; + + let ty = bound_trait_ref + .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); + + // Replace the binder with dummy types/lifetimes. This should work for any + // binder as long as they don't have any bounds e.g. `for`. + let ty = tcx.replace_bound_vars_uncached( + ty, + FnMutDelegate { + regions: &mut |_| tcx.lifetimes.re_static, + types: &mut |_| tcx.types.unit, + consts: &mut |_| unimplemented!("`~const` does not support const binders"), + }, + ); + + self.effects_min_tys.insert(ty, span); + return; + } + // for + // ``` + // trait Foo { type Bar: ~const Trait } + // ``` + // ensure that `::Effects: TyCompat`. + // + // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor + // that uses a `Bar` that implements `Trait` with `Maybe` effects. + (DefKind::AssocTy, ty::BoundConstness::ConstIfConst) => { + // TODO write the actual impl + return; + } + // probably illegal in this position. + (_, ty::BoundConstness::ConstIfConst) => { + tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered"); + return; + } + } { + // create a new projection type `::Effects` + let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { + tcx.dcx().span_delayed_bug( + span, + "`~const` trait bound has no effect assoc yet no errors encountered?", + ); + return; + }; + let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); + // make `::Effects: Compat` + let new_trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), + [ty::GenericArg::from(self_ty), compat_val.into()], + ); + self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); + } } pub fn push_projection_bound( @@ -79,7 +163,15 @@ impl<'tcx> Bounds<'tcx> { self.clauses.insert(0, (trait_ref.upcast(tcx), span)); } - pub fn clauses(&self) -> impl Iterator, Span)> + '_ { + pub fn clauses( + &self, + // TODO remove tcx + _tcx: TyCtxt<'tcx>, + ) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() } + + pub fn effects_min_tys(&self) -> impl Iterator> + '_ { + self.effects_min_tys.keys().copied() + } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e13ea1a1935b4..e1813029778ee 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -879,7 +879,7 @@ pub(super) fn check_specialization_validity<'tcx>( let result = opt_result.unwrap_or(Ok(())); if let Err(parent_impl) = result { - if !tcx.is_impl_trait_in_trait(impl_item) { + if !tcx.is_impl_trait_in_trait(impl_item) && !tcx.is_effects_desugared_assoc_ty(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { tcx.dcx().delayed_bug(format!("parent item: {parent_impl:?} not marked as default")); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7fa5c96bc9ab4..b5b68471b9d16 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1985,10 +1985,10 @@ pub(super) fn check_type_bounds<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - // A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the - // span for an impl's associated type. Instead, for these, use the def_span for the synthesized - // associated type. - let impl_ty_span = if impl_ty.is_impl_trait_in_trait() { + // A synthetic impl Trait for RPITIT desugaring or assoc type for effects desugaring has no HIR, + // which we currently use to get the span for an impl's associated type. Instead, for these, + // use the def_span for the synthesized associated type. + let impl_ty_span = if impl_ty.is_impl_trait_in_trait() || impl_ty.is_effects_desugaring { tcx.def_span(impl_ty_def_id) } else { match tcx.hir_node_by_def_id(impl_ty_def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a188c1b12aeb6..2230528a5ae11 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -913,7 +913,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()), // Const parameters are well formed if their type is structural match. - hir::GenericParamKind::Const { ty: hir_ty, default: _, is_host_effect: _ } => { + hir::GenericParamKind::Const { + ty: hir_ty, + default: _, + is_host_effect: _, + synthetic: _, + } => { let ty = tcx.type_of(param.def_id).instantiate_identity(); if tcx.features().adt_const_params { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e7892f1766067..f453dcfe90d1b 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1638,44 +1638,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> ty::Generics { kind, }) } - GenericParamKind::Const { ty: _, default, is_host_effect } => { + GenericParamKind::Const { ty: _, default, is_host_effect, synthetic } => { if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() // `host` effect params are allowed to have defaults. @@ -388,6 +388,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { kind: ty::GenericParamDefKind::Const { has_default: default.is_some(), is_host_effect, + synthetic, }, }) } @@ -541,7 +542,8 @@ struct AnonConstInParamTyDetector { impl<'v> Visitor<'v> for AnonConstInParamTyDetector { fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { - if let GenericParamKind::Const { ty, default: _, is_host_effect: _ } = p.kind { + if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind + { let prev = self.in_param_ty; self.in_param_ty = true; self.visit_ty(ty); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index d084d3aefeb17..57142414b9d81 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -46,7 +46,7 @@ fn associated_type_bounds<'tcx>( } }); - let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses(tcx).chain(bounds_from_parent)); debug!( "associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id.to_def_id()), @@ -75,7 +75,7 @@ fn opaque_type_bounds<'tcx>( icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.clauses()) + tcx.arena.alloc_from_iter(bounds.clauses(tcx)) }) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 3421c8da4e9f3..087e02a030511 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,6 +57,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic #[instrument(level = "trace", skip(tcx), ret)] fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; + use rustc_middle::ty::Ty; // to override hir::Ty match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -84,6 +85,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(tcx.parent(def_id.to_def_id())), predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: ty::List::empty(), }; } @@ -105,12 +107,43 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(impl_def_id), predicates: tcx.arena.alloc_from_iter(impl_predicates), + effects_min_tys: ty::List::empty(), }; } None => {} } + if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { + let mut predicates = Vec::new(); + + // Inherit predicates of parent (impl or trait) + let parent = tcx.local_parent(def_id); + + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let preds = tcx.explicit_predicates_of(parent); + predicates.extend(preds.instantiate_own(tcx, identity_args)); + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { + // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` + // TODO do the same for impls + let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); + // TODO span + let span = tcx.def_span(def_id); + let assoc = tcx.require_lang_item(LangItem::EffectsMinOutput, Some(span)); + let proj = Ty::new_projection(tcx, assoc, [tup]); + // TODO this is bad + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let trait_ = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + return ty::GenericPredicates { + parent: Some(parent.to_def_id()), + predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: ty::List::empty(), + }; + } + let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); @@ -124,6 +157,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // We use an `IndexSet` to preserve order of insertion. // Preserving the order of insertion is important here so as not to break UI tests. let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); + let mut effects_min_tys = Vec::new(); let hir_generics = node.generics().unwrap_or(NO_GENERICS); if let Node::Item(item) = node { @@ -150,11 +184,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. if let Some(self_bounds) = is_trait { - predicates.extend( - icx.lowerer() - .lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All) - .clauses(), + let bounds = icx.lowerer().lower_mono_bounds( + tcx.types.self_param, + self_bounds, + PredicateFilter::All, ); + predicates.extend(bounds.clauses(tcx)); + effects_min_tys.extend(bounds.effects_min_tys()); } // In default impls, we can assume that the self type implements @@ -187,7 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen param.span, ); trace!(?bounds); - predicates.extend(bounds.clauses()); + predicates.extend(bounds.clauses(tcx)); trace!(?predicates); } hir::GenericParamKind::Const { .. } => { @@ -238,7 +274,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, OnlySelfBounds(false), ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds.clauses(tcx)); + effects_min_tys.extend(bounds.effects_min_tys()); } hir::WherePredicate::RegionPredicate(region_pred) => { @@ -297,7 +334,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { let opaque_ty_node = tcx.parent_hir_node(hir_id); - let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { + let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node + else { bug!("unexpected {opaque_ty_node:?}") }; debug!(?lifetimes); @@ -309,6 +347,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: tcx.mk_type_list(&effects_min_tys), } } @@ -459,6 +498,7 @@ pub(super) fn explicit_predicates_of<'tcx>( ty::GenericPredicates { parent: predicates_and_bounds.parent, predicates: tcx.arena.alloc_slice(&predicates), + effects_min_tys: predicates_and_bounds.effects_min_tys, } } } else { @@ -510,6 +550,7 @@ pub(super) fn explicit_predicates_of<'tcx>( return GenericPredicates { parent: parent_preds.parent, predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, + effects_min_tys: parent_preds.effects_min_tys, }; } gather_explicit_predicates_of(tcx, def_id) @@ -587,7 +628,7 @@ pub(super) fn implied_predicates_with_filter( // Combine the two lists to form the complete set of superbounds: let implied_bounds = - &*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match)); + &*tcx.arena.alloc_from_iter(superbounds.clauses(tcx).chain(where_bounds_that_match)); debug!(?implied_bounds); // Now require that immediate supertraits are lowered, which will, in @@ -618,7 +659,11 @@ pub(super) fn implied_predicates_with_filter( _ => {} } - ty::GenericPredicates { parent: None, predicates: implied_bounds } + ty::GenericPredicates { + parent: None, + predicates: implied_bounds, + effects_min_tys: ty::List::empty(), + } } /// Returns the predicates defined on `item_def_id` of the form @@ -744,7 +789,7 @@ impl<'tcx> ItemCtxt<'tcx> { ); } - bounds.clauses().collect() + bounds.clauses(self.tcx).collect() } #[instrument(level = "trace", skip(self))] diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index abc3bb838db3e..5c54c9d8e53d2 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -951,7 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.visit_ty(ty); } } - GenericParamKind::Const { ty, default, is_host_effect: _ } => { + GenericParamKind::Const { ty, default, .. } => { self.visit_ty(ty); if let Some(default) = default { self.visit_body(self.tcx.hir().body(default.body)); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 3f888c4e2722b..67046b5ac0e40 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -256,6 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( | GenericParamDefKind::Lifetime, _, ) => { + // TODO: this should be removed // SPECIAL CASE FOR DESUGARED EFFECT PARAMS // This comes from the following example: // @@ -445,7 +446,7 @@ pub(crate) fn check_generic_arg_count( .own_params .iter() .filter(|param| { - matches!(param.kind, ty::GenericParamDefKind::Const { is_host_effect: true, .. }) + matches!(param.kind, ty::GenericParamDefKind::Const { synthetic: true, .. }) }) .count(); let named_const_param_count = param_counts.consts - synth_const_param_count; 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 24ea328889c6b..2a68d3915bbbc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -698,7 +698,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + bounds.push_trait_bound( + tcx, + self.item_def_id().to_def_id(), + poly_trait_ref, + span, + polarity, + constness, + ); let mut dup_constraints = FxIndexMap::default(); for constraint in trait_segment.args().constraints { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 34924f09d09ed..df69c1938dd75 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -59,7 +59,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut trait_bounds = vec![]; let mut projection_bounds = vec![]; - for (pred, span) in bounds.clauses() { + for (pred, span) in bounds.clauses(tcx) { let bound_pred = pred.kind(); match bound_pred.skip_binder() { ty::ClauseKind::Trait(trait_pred) => { @@ -133,7 +133,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.associated_items(pred.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| { + !item.is_impl_trait_in_trait() && !item.is_effects_desugaring + }) .map(|item| item.def_id), ); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 25b0cbdc026af..5105d60ae188c 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -585,6 +585,7 @@ impl<'a> State<'a> { self.print_struct(struct_def, generics, item.ident.name, item.span, true); } hir::ItemKind::Impl(&hir::Impl { + constness, safety, polarity, defaultness, @@ -599,6 +600,10 @@ impl<'a> State<'a> { self.print_safety(safety); self.word_nbsp("impl"); + if let hir::Constness::Const = constness { + self.word_nbsp("const"); + } + if !generics.params.is_empty() { self.print_generic_params(generics.params); self.space(); @@ -2144,7 +2149,7 @@ impl<'a> State<'a> { self.print_type(default); } } - GenericParamKind::Const { ty, ref default, is_host_effect: _ } => { + GenericParamKind::Const { ty, ref default, is_host_effect: _, synthetic: _ } => { self.word_space(":"); self.print_type(ty); if let Some(default) = default { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 061afd0306230..f6e21262b6ac7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1304,7 +1304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.ty_infer(Some(param), inf.span).into() } ( - &GenericParamDefKind::Const { has_default, is_host_effect }, + &GenericParamDefKind::Const { has_default, is_host_effect, .. }, GenericArg::Infer(inf), ) => { if has_default && is_host_effect { @@ -1346,7 +1346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.var_for_def(self.span, param) } } - GenericParamDefKind::Const { has_default, is_host_effect } => { + GenericParamDefKind::Const { has_default, is_host_effect, .. } => { if has_default { // N.B. this is a bit of a hack. `infer_args` is passed depending on // whether the user has provided generic args. E.g. for `Vec::new` diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c0d604779677b..ed3cbb0663efa 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -274,6 +274,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { } }), ), + effects_min_tys: ty::List::empty(), } } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index e1223307b53e3..dad909fc4e102 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, NormalizeExt}; @@ -356,6 +356,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option>> { let (obligation, args) = self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types); + // FIXME(effects) find a better way to do this + // Operators don't have generic methods, but making them `#[const_trait]` gives them + // `const host: bool`. + let args = if self.tcx.has_attr(trait_def_id, sym::const_trait) { + self.tcx.mk_args_from_iter( + args.iter() + .chain([self.tcx.expected_host_effect_param_for_body(self.body_id).into()]), + ) + } else { + args + }; self.construct_obligation_for_trait(m_name, trait_def_id, obligation, args) } @@ -393,6 +404,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; + // TODO there is something wrong here because now methods for binops may get `const host: bool` + // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. // diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 9747a91ccbfad..63b30d79aba14 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1279,6 +1279,7 @@ impl<'tcx> Pick<'tcx> { trait_item_def_id: _, fn_has_self_parameter: _, opt_rpitit_info: _, + is_effects_desugaring: _, }, kind: _, import_ids: _, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ea7037740f17e..83b41e0540edf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1348,7 +1348,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() { + let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() + || self.root.tables.is_effects_desugaring.get(self, id) + { kw::Empty } else { self.item_name(id) @@ -1371,6 +1373,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { container, fn_has_self_parameter: has_self, opt_rpitit_info, + is_effects_desugaring: self.root.tables.is_effects_desugaring.get(self, id), } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c9450142cd3be..f696be08cb228 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -279,6 +279,9 @@ provide! { tcx, def_id, other, cdata, .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } + associated_type_for_effects => { + table + } associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array } visibility => { cdata.get_visibility(def_id.index) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4bd2ec09a6e6f..f985c55eeec50 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1454,6 +1454,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &def_id in associated_item_def_ids { self.encode_info_for_assoc_item(def_id); } + if let Some(assoc_def_id) = self.tcx.associated_type_for_effects(def_id) { + record!(self.tables.associated_type_for_effects[def_id] <- assoc_def_id); + } } if def_kind == DefKind::Closure && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) @@ -1634,6 +1637,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ); } } + if item.is_effects_desugaring { + self.tables.is_effects_desugaring.set(def_id.index, true); + } } fn encode_mir(&mut self) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 87900c23d8daf..cb5f3d20d99a8 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -391,7 +391,9 @@ define_tables! { inferred_outlives_of: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, + associated_type_for_effects: Table>>, opt_rpitit_info: Table>>, + is_effects_desugaring: Table, unused_generic_params: Table, // Reexported names are not associated with individual `DefId`s, // e.g. a glob import can introduce a lot of names, all with the same `DefId`. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 230a44bcf2452..d94f12af448e2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -368,6 +368,7 @@ rustc_queries! { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern + feedable } /// The set of item bounds (see [`TyCtxt::explicit_item_bounds`]) that @@ -378,6 +379,7 @@ rustc_queries! { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern + feedable } /// Elaborated version of the predicates from `explicit_item_bounds`. @@ -847,6 +849,12 @@ rustc_queries! { separate_provide_extern } + query associated_type_for_effects(def_id: DefId) -> Option { + desc { |tcx| "creating associated items for effects in `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding /// associated item. query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 1cdde3f057c67..820f5e950a9d9 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -34,6 +34,8 @@ pub struct AssocItem { /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` /// provides additional information about its source. pub opt_rpitit_info: Option, + + pub is_effects_desugaring: bool, } impl AssocItem { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4bac9396e59a9..656aba67112cc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3095,9 +3095,9 @@ impl<'tcx> TyCtxt<'tcx> { matches!( node, hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), + kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. - }) if generics.params.iter().any(|p| matches!(p.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })) + }) if matches!(constness, hir::Constness::Const) ) } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 6467689a8aa15..844023df1e315 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -14,7 +14,7 @@ use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt}; pub enum GenericParamDefKind { Lifetime, Type { has_default: bool, synthetic: bool }, - Const { has_default: bool, is_host_effect: bool }, + Const { has_default: bool, is_host_effect: bool, synthetic: bool }, } impl GenericParamDefKind { @@ -371,6 +371,7 @@ impl<'tcx> Generics { pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: &'tcx [(Clause<'tcx>, Span)], + pub effects_min_tys: &'tcx ty::List>, } impl<'tcx> GenericPredicates<'tcx> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9c2bfc12a18a1..7d57d88f40f4a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1608,7 +1608,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// If the def-id is an associated type that was desugared from a + /// If the `def_id` is an associated type that was desugared from a /// return-position `impl Trait` from a trait, then provide the source info /// about where that RPITIT came from. pub fn opt_rpitit_info(self, def_id: DefId) -> Option { @@ -1619,6 +1619,16 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Whether the `def_id` is an associated type that was desugared from a + /// `#[const_trait]` or `impl_const`. + pub fn is_effects_desugared_assoc_ty(self, def_id: DefId) -> bool { + if let DefKind::AssocTy = self.def_kind(def_id) { + self.associated_item(def_id).is_effects_desugaring + } else { + false + } + } + pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { variant.fields.iter_enumerated().find_map(|(i, field)| { self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i) diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index e23f4289e981a..4eefd0eb17c40 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -160,7 +160,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); + let GenericPredicates { parent, predicates, effects_min_tys: _ } = + tables.tcx.predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates @@ -181,7 +182,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id); + let GenericPredicates { parent, predicates, effects_min_tys: _ } = + tables.tcx.explicit_predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 74c3fcc9b9ea9..9382460d6d403 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -600,7 +600,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { ty::GenericParamDefKind::Type { has_default, synthetic } => { GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic } } - ty::GenericParamDefKind::Const { has_default, is_host_effect: _ } => { + ty::GenericParamDefKind::Const { has_default, is_host_effect: _, synthetic: _ } => { GenericParamDefKind::Const { has_default: *has_default } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3b6147c4c0f64..4a26e8ae09734 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -194,6 +194,14 @@ symbols! { Display, DoubleEndedIterator, Duration, + EffectsCompat, + EffectsMaybe, + EffectsMin, + EffectsMinOutput, + EffectsNoRuntime, + EffectsRuntime, + EffectsTyCompat, + Effects__, Encodable, Encoder, Enumerate, @@ -1658,6 +1666,7 @@ symbols! { rustc_reallocator, rustc_regions, rustc_reservation_impl, + rustc_runtime, rustc_safe_intrinsic, rustc_serialize, rustc_skip_during_method_dispatch, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f4a026c0367f4..599a95f2300b9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4995,6 +4995,12 @@ fn point_at_assoc_type_restriction( let ty::ClauseKind::Projection(proj) = clause else { return; }; + // avoid ICEing since effects desugared associated types don't have names. + // this path should only be hit for `~const` on invalid places, so they + // will have an informative error already. + if tcx.is_effects_desugared_assoc_ty(proj.projection_term.def_id) { + return; + } let name = tcx.item_name(proj.projection_term.def_id); let mut predicates = generics.predicates.iter().peekable(); let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 4395eb57cd6d2..df6c54ab289ae 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,8 +4,9 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; +use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; +use rustc_span::sym; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { @@ -14,6 +15,7 @@ pub(crate) fn provide(providers: &mut Providers) { associated_item_def_ids, associated_items, associated_types_for_impl_traits_in_associated_fn, + associated_type_for_effects, associated_type_for_impl_trait_in_trait, impl_item_implementor_ids, ..*providers @@ -44,7 +46,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied(), - ), + ) + .chain(tcx.associated_type_for_effects(def_id)), ) } hir::ItemKind::Impl(impl_) => { @@ -70,7 +73,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied() - })), + })) + .chain(tcx.associated_type_for_effects(def_id)), ) } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), @@ -143,6 +147,7 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty container: ty::TraitContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, } } @@ -162,6 +167,161 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A container: ty::ImplContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, + } +} + +/// Given an `def_id` of a trait or a trait impl: +/// +/// If `def_id` is a trait that has `#[const_trait]`, then it synthesizes +/// a new def id corresponding to a new associated type for the effects. +/// +/// If `def_id` is an impl, then synthesize the associated type according +/// to the constness of the impl. +fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { + match tcx.def_kind(def_id) { + DefKind::Trait => { + let trait_def_id = def_id; + let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { + return None; + }; + + let span = attr.span; + let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); + + let local_def_id = trait_assoc_ty.def_id(); + let def_id = local_def_id.to_def_id(); + + trait_assoc_ty.feed_hir(); + + // Copy span of the attribute. + trait_assoc_ty.def_ident_span(Some(span)); + + trait_assoc_ty.associated_item(ty::AssocItem { + name: kw::Empty, + kind: ty::AssocKind::Type, + def_id, + trait_item_def_id: None, + container: ty::TraitContainer, + fn_has_self_parameter: false, + opt_rpitit_info: None, + is_effects_desugaring: true, + }); + + // visibility is public. + trait_assoc_ty.visibility(ty::Visibility::Public); + + // No default type + trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false }); + + trait_assoc_ty.is_type_alias_impl_trait(false); + + // Copy generics_of of the trait, making the trait as parent. + trait_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(trait_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(trait_def_id.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + + trait_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + trait_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + trait_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + DefKind::Impl { .. } => { + let impl_def_id = def_id; + let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + + // first get the DefId of the assoc type on the trait, if there is not, + // then we don't need to generate it on the impl. + let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { + return None; + }; + + // TODO span is bad + let span = tcx.def_ident_span(def_id).unwrap(); + + let impl_assoc_ty = tcx.at(span).create_def(def_id, kw::Empty, DefKind::AssocTy); + + let local_def_id = impl_assoc_ty.def_id(); + let def_id = local_def_id.to_def_id(); + + impl_assoc_ty.feed_hir(); + + impl_assoc_ty.def_ident_span(Some(span)); + + impl_assoc_ty.associated_item(ty::AssocItem { + name: kw::Empty, + kind: ty::AssocKind::Type, + def_id, + trait_item_def_id: Some(trait_assoc_id), + container: ty::ImplContainer, + fn_has_self_parameter: false, + opt_rpitit_info: None, + is_effects_desugaring: true, + }); + + // visibility is public. + impl_assoc_ty.visibility(ty::Visibility::Public); + + // no default value. + impl_assoc_ty.defaultness(hir::Defaultness::Final); + + // set the type of the associated type! If this is a const impl, + // we set to Maybe, otherwise we set to `Runtime`. + let type_def_id = if tcx.is_const_trait_impl_raw(impl_def_id.to_def_id()) { + tcx.require_lang_item(hir::LangItem::EffectsMaybe, Some(span)) + } else { + tcx.require_lang_item(hir::LangItem::EffectsRuntime, Some(span)) + }; + // TODO this is wrong + impl_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_adt( + tcx, + tcx.adt_def(type_def_id), + ty::GenericArgs::empty(), + ))); + + // Copy generics_of of the impl, making the impl as parent. + impl_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(impl_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(impl_def_id.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + + impl_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + impl_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + impl_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + def_kind => bug!( + "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", + def_id, + def_kind + ), } } @@ -275,6 +435,7 @@ fn associated_type_for_impl_trait_in_trait( fn_def_id: fn_def_id.to_def_id(), opaque_def_id: opaque_ty_def_id.to_def_id(), }), + is_effects_desugaring: false, }); // Copy visility of the containing function. @@ -326,6 +487,7 @@ fn associated_type_for_impl_trait_in_impl( container: ty::ImplContainer, fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), + is_effects_desugaring: false, }); // Copy visility of the containing function. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d1692729a31b4..cfadfb0233ea7 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -231,6 +231,7 @@ #![feature(let_chains)] #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] +#![feature(marker_trait_attr)] #![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 0fedb8835d1ae..b3f3cc021261f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1027,3 +1027,41 @@ pub trait FnPtr: Copy + Clone { pub macro SmartPointer($item:item) { /* compiler built-in */ } + +#[doc(hidden)] +#[unstable( + feature = "effect_types", + issue = "none", + reason = "internal module for implementing effects" +)] +#[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls. +#[cfg(not(bootstrap))] +// TODO docs +pub mod effects { + #[lang = "EffectsNoRuntime"] + pub struct NoRuntime; + #[lang = "EffectsMaybe"] + pub struct Maybe; + #[lang = "EffectsRuntime"] + pub struct Runtime; + + #[lang = "EffectsCompat"] + pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} + + impl Compat for NoRuntime {} + impl Compat for Runtime {} + impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} + + #[lang = "EffectsTyCompat"] + #[marker] + pub trait TyCompat {} + + impl TyCompat for T {} + impl TyCompat for Maybe {} + + #[lang = "EffectsMin"] + pub trait Min { + #[lang = "EffectsMinOutput"] + type Output; + } +} diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 22565ea402803..b5660cd849246 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -549,7 +549,7 @@ fn clean_generic_param_def<'tcx>( }, ) } - ty::GenericParamDefKind::Const { has_default, is_host_effect } => ( + ty::GenericParamDefKind::Const { has_default, synthetic, is_host_effect: _ } => ( def.name, GenericParamDefKind::Const { ty: Box::new(clean_middle_ty( @@ -572,7 +572,7 @@ fn clean_generic_param_def<'tcx>( } else { None }, - is_host_effect, + synthetic, }, ), }; @@ -628,13 +628,13 @@ fn clean_generic_param<'tcx>( }, ) } - hir::GenericParamKind::Const { ty, default, is_host_effect } => ( + hir::GenericParamKind::Const { ty, default, synthetic, is_host_effect: _ } => ( param.name.ident().name, GenericParamDefKind::Const { ty: Box::new(clean_ty(ty, cx)), default: default .map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())), - is_host_effect, + synthetic, }, ), }; @@ -1411,7 +1411,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), - ty::GenericPredicates { parent: None, predicates }, + ty::GenericPredicates { + parent: None, + predicates, + effects_min_tys: ty::List::empty(), + }, ); simplify::move_bounds_to_generic_parameters(&mut generics); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c4020f2a450bc..9050a1c12078b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1321,7 +1321,7 @@ pub(crate) enum GenericParamDefKind { Lifetime { outlives: ThinVec }, Type { bounds: ThinVec, default: Option>, synthetic: bool }, // Option> makes this type smaller than `Option` would. - Const { ty: Box, default: Option>, is_host_effect: bool }, + Const { ty: Box, default: Option>, synthetic: bool }, } impl GenericParamDefKind { @@ -1345,7 +1345,7 @@ impl GenericParamDef { pub(crate) fn is_synthetic_param(&self) -> bool { match self.kind { GenericParamDefKind::Lifetime { .. } => false, - GenericParamDefKind::Const { is_host_effect, .. } => is_host_effect, + GenericParamDefKind::Const { synthetic: is_host_effect, .. } => is_host_effect, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index d099a97f1cba2..b965ab019cc4f 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -466,7 +466,7 @@ impl FromWithTcx for GenericParamDefKind { default: default.map(|x| (*x).into_tcx(tcx)), synthetic, }, - Const { ty, default, is_host_effect: _ } => GenericParamDefKind::Const { + Const { ty, default, synthetic: _ } => GenericParamDefKind::Const { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, @@ -501,14 +501,12 @@ impl FromWithTcx for WherePredicate { synthetic, } } - clean::GenericParamDefKind::Const { - ty, - default, - is_host_effect: _, - } => GenericParamDefKind::Const { - type_: (*ty).into_tcx(tcx), - default: default.map(|d| *d), - }, + clean::GenericParamDefKind::Const { ty, default, synthetic: _ } => { + GenericParamDefKind::Const { + type_: (*ty).into_tcx(tcx), + default: default.map(|d| *d), + } + } }; GenericParamDef { name, kind } }) diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs index cd008aa2c9f2d..f3271f833cc64 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,4 +1,5 @@ //@ build-pass +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs new file mode 100644 index 0000000000000..2c5b6cc40e638 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs @@ -0,0 +1,14 @@ +//@ check-pass +use std::ops::Add; + +pub trait GroupOpsOwned: for<'r> Add<&'r Rhs, Output = Output> {} + +pub trait Curve: Sized + GroupOpsOwned { + type AffineRepr; +} + +pub trait CofactorCurve: Curve::Affine> { + type Affine; +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs index 825ddb6a5cdb9..a587de9f17963 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs @@ -1,8 +1,9 @@ // Regression test for #92230. // //@ check-pass +//@ compile-flags: -Znext-solver -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Super {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 8151b9aaa23de..3b320f1c5424a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -282,12 +282,21 @@ help: wrap the field type in `ManuallyDrop<...>` LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + -error[E0275]: overflow evaluating the requirement `(): Trait` +error[E0275]: overflow evaluating the requirement `Trait::{opaque#0} == _` --> $DIR/tilde-const-invalid-places.rs:34:34 | LL | type Type = (); | ^^ | +note: required for `()` to implement `Trait` + --> $DIR/tilde-const-invalid-places.rs:56:23 + | +LL | impl Trait for T {} + | ------------ ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 1 redundant requirement hidden + = note: required for `()` to implement `Trait` note: required by a bound in `NonConstTrait::Type` --> $DIR/tilde-const-invalid-places.rs:25:33 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs index 8f441410c1784..3a8c6d5b1a4fa 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -1,4 +1,5 @@ // Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics. +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] From c7d27a15d0a28d66d9a6b279e6005b6fcd861ae2 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 24 Jun 2024 16:25:17 +0000 Subject: [PATCH 121/217] Implement `Min` trait in new solver --- .../src/collect/predicates_of.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 ++ .../src/solve/assembly/mod.rs | 7 +++ .../src/solve/normalizes_to/mod.rs | 59 +++++++++++++++++++ .../src/solve/trait_goals.rs | 41 +++++++++++++ compiler/rustc_type_ir/src/effects.rs | 56 ++++++++++++++++++ compiler/rustc_type_ir/src/lang_items.rs | 5 ++ compiler/rustc_type_ir/src/lib.rs | 2 + library/core/src/marker.rs | 9 +-- .../trait-where-clause-run.rs | 1 + 10 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_type_ir/src/effects.rs diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 087e02a030511..e3d1e1c423e4c 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -122,7 +122,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let preds = tcx.explicit_predicates_of(parent); - predicates.extend(preds.instantiate_own(tcx, identity_args)); + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` // TODO do the same for impls diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 656aba67112cc..c0ebad9616df3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -598,6 +598,11 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::Destruct => LangItem::Destruct, TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, + TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, + TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, + TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, + TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, TraitSolverLangItem::FusedIterator => LangItem::FusedIterator, TraitSolverLangItem::Future => LangItem::Future, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 21439530c08f6..8d57c3d9af004 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -269,6 +269,11 @@ where ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Vec>; + + fn consider_builtin_effects_min_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolution>; } impl EvalCtxt<'_, D> @@ -420,6 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) + } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { + G::consider_builtin_effects_min_candidate(self, goal) } else { Err(NoSolution) }; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 4e8cb4384f462..f75c30eda9949 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -864,6 +864,65 @@ where ) -> Result, NoSolution> { panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } + + fn consider_builtin_effects_min_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolution> { + let ty::Tuple(types) = goal.predicate.self_ty().kind() else { + return Err(NoSolution); + }; + + + let cx = ecx.cx(); + + let mut first_non_maybe = None; + let mut non_maybe_count = 0; + for ty in types { + if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) { + first_non_maybe.get_or_insert(ty); + non_maybe_count += 1; + } + } + + match non_maybe_count { + 0 => { + let ty = ty::EffectKind::Maybe.to_ty(cx); + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.instantiate_normalizes_to_term(goal, ty.into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + 1 => { + let ty = first_non_maybe.unwrap(); + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.instantiate_normalizes_to_term(goal, ty.into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + _ => { + let mut min = ty::EffectKind::Maybe; + + for ty in types { + let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { + return Err(NoSolution); + }; + + let Some(result) = ty::EffectKind::min(min, kind) else { + return Err(NoSolution); + }; + + min = result; + } + + let ty = min.to_ty(cx); + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.instantiate_normalizes_to_term(goal, ty.into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + } + } } impl EvalCtxt<'_, D> diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 2bc9d35c2b020..8c6e5eb5a4d9d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -702,6 +702,47 @@ where } }) } + + fn consider_builtin_effects_min_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolution> { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { + return Err(NoSolution); + } + + let ty::Tuple(types) = goal.predicate.self_ty().kind() else { + return Err(NoSolution); + }; + + let cx = ecx.cx(); + let maybe_count = types + .into_iter() + .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty)) + .filter(|&ty| ty == ty::EffectKind::Maybe) + .count(); + + // Don't do concrete type check unless there are more than one type that will influence the result. + // This would allow `(Maybe, T): Min` pass even if we know nothing about `T`. + if types.len() - maybe_count > 1 { + let mut min = ty::EffectKind::Maybe; + + for ty in types { + let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { + return Err(NoSolution); + }; + + let Some(result) = ty::EffectKind::min(min, kind) else { + return Err(NoSolution); + }; + + min = result; + } + } + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) + } } impl EvalCtxt<'_, D> diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs new file mode 100644 index 0000000000000..259072de6e77d --- /dev/null +++ b/compiler/rustc_type_ir/src/effects.rs @@ -0,0 +1,56 @@ +use crate::lang_items::TraitSolverLangItem::{EffectsMaybe, EffectsRuntime, EffectsNoRuntime}; +use crate::Interner; +use crate::inherent::{AdtDef, IntoKind, Ty}; + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum EffectKind { + Maybe, + Runtime, + NoRuntime, +} + +impl EffectKind { + pub fn try_from_def_id(tcx: I, def_id: I::DefId) -> Option { + if tcx.is_lang_item(def_id, EffectsMaybe) { + Some(EffectKind::Maybe) + } else if tcx.is_lang_item(def_id, EffectsRuntime) { + Some(EffectKind::Runtime) + } else if tcx.is_lang_item(def_id, EffectsNoRuntime) { + Some(EffectKind::NoRuntime) + } else { + None + } + } + + pub fn to_def_id(self, tcx: I) -> I::DefId { + let lang_item = match self { + EffectKind::Maybe => EffectsMaybe, + EffectKind::NoRuntime => EffectsNoRuntime, + EffectKind::Runtime => EffectsRuntime, + }; + + tcx.require_lang_item(lang_item) + } + + pub fn try_from_ty(tcx: I, ty: I::Ty) -> Option { + if let crate::Adt(def, _) = ty.kind() { + Self::try_from_def_id(tcx, def.def_id()) + } else { + None + } + } + + pub fn to_ty(self, tcx: I) -> I::Ty { + I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) + } + + pub fn min(a: Self, b: Self) -> Option { + use EffectKind::*; + match (a, b) { + (Maybe, x) | (x, Maybe) => Some(x), + (Runtime, Runtime) => Some(Runtime), + (NoRuntime, NoRuntime) => Some(NoRuntime), + (Runtime, NoRuntime) | (NoRuntime, Runtime) => None, + } + } +} \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index cf5ec1ab3febc..55b9709b66876 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,6 +17,11 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsMaybe, + EffectsMin, + EffectsMinOutput, + EffectsNoRuntime, + EffectsRuntime, FnPtrTrait, FusedIterator, Future, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9b8ca5efdda82..d7442e7c89c4a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -35,6 +35,7 @@ mod macros; mod binder; mod canonical; mod const_kind; +mod effects; mod flags; mod generic_arg; mod interner; @@ -51,6 +52,7 @@ pub use canonical::*; #[cfg(feature = "nightly")] pub use codec::*; pub use const_kind::*; +pub use effects::*; pub use flags::*; pub use generic_arg::*; pub use interner::*; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b3f3cc021261f..b71bedaa1948f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1054,14 +1054,15 @@ pub mod effects { #[lang = "EffectsTyCompat"] #[marker] - pub trait TyCompat {} + pub trait TyCompat {} - impl TyCompat for T {} - impl TyCompat for Maybe {} + impl TyCompat for T {} + impl TyCompat for Maybe {} + impl TyCompat for T {} #[lang = "EffectsMin"] pub trait Min { #[lang = "EffectsMinOutput"] - type Output; + type Output: ?Sized; } } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index afc5b1c836993..ddb26505202f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete From 3637b153f7cb8de14588ea82a15a28499bcb3b3f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 07:51:44 +0000 Subject: [PATCH 122/217] move desugaring to item bounds --- .../src/collect/item_bounds.rs | 26 ++++++++++++++++ .../src/collect/predicates_of.rs | 31 ------------------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 57142414b9d81..707a3f2d3c715 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -8,6 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFold use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; +use rustc_type_ir::Upcast; /// For associated types we include both bounds written on the type /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`. @@ -124,6 +125,31 @@ pub(super) fn explicit_item_bounds_with_filter( None => {} } + if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { + let mut predicates = Vec::new(); + + let parent = tcx.local_parent(def_id); + + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let preds = tcx.explicit_predicates_of(parent); + + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { + // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` + // TODO do the same for impls + let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); + // TODO span + let span = tcx.def_span(def_id); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let proj = Ty::new_projection(tcx, assoc, [tup]); + // TODO this is bad + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + return ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(predicates)); + } + let bounds = match tcx.hir_node_by_def_id(def_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e3d1e1c423e4c..9a5feaf3d3c65 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,7 +57,6 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic #[instrument(level = "trace", skip(tcx), ret)] fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; - use rustc_middle::ty::Ty; // to override hir::Ty match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -114,36 +113,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen None => {} } - if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { - let mut predicates = Vec::new(); - - // Inherit predicates of parent (impl or trait) - let parent = tcx.local_parent(def_id); - - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - let preds = tcx.explicit_predicates_of(parent); - - if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { - // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` - // TODO do the same for impls - let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); - // TODO span - let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(LangItem::EffectsMinOutput, Some(span)); - let proj = Ty::new_projection(tcx, assoc, [tup]); - // TODO this is bad - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); - let trait_ = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); - predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); - } - return ty::GenericPredicates { - parent: Some(parent.to_def_id()), - predicates: tcx.arena.alloc_from_iter(predicates), - effects_min_tys: ty::List::empty(), - }; - } - let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); From 74e7b5bd762ac9be7d84689271324826d2056a7f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 07:52:44 +0000 Subject: [PATCH 123/217] temporarily disable effects on specialization tests --- .../rustc_hir_analysis/src/check/check.rs | 1 + compiler/rustc_ty_utils/src/assoc.rs | 7 ++- .../const-trait-bounds-trait-objects.rs | 3 +- .../const-trait-bounds-trait-objects.stderr | 19 ++------ .../specializing-constness-2.rs | 2 +- .../specializing-constness-2.stderr | 47 ++++++++++--------- .../trait-where-clause-run.rs | 3 +- .../trait-where-clause-run.stderr | 11 ----- 8 files changed, 43 insertions(+), 50 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e1813029778ee..f93777eda529e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -879,6 +879,7 @@ pub(super) fn check_specialization_validity<'tcx>( let result = opt_result.unwrap_or(Ok(())); if let Err(parent_impl) = result { + // FIXME(effects) the associated type from effects could be specialized if !tcx.is_impl_trait_in_trait(impl_item) && !tcx.is_effects_desugared_assoc_ty(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index df6c54ab289ae..681f089e84fb7 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -179,6 +179,11 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A /// If `def_id` is an impl, then synthesize the associated type according /// to the constness of the impl. fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { + // don't synthesize the associated type even if the user has written `const_trait` + // if the effects feature is disabled. + if !tcx.features().effects { + return None; + } match tcx.def_kind(def_id) { DefKind::Trait => { let trait_def_id = def_id; @@ -309,7 +314,7 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option $DIR/const-trait-bounds-trait-objects.rs:8:17 + --> $DIR/const-trait-bounds-trait-objects.rs:9:17 | LL | let _: &dyn const Trait; | ^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:9:17 + --> $DIR/const-trait-bounds-trait-objects.rs:10:17 | LL | let _: &dyn ~const Trait; | ^^^^^^ @@ -13,27 +13,18 @@ LL | let _: &dyn ~const Trait; = note: trait objects cannot have `~const` trait bounds error: const trait bounds are not allowed in trait object types - --> $DIR/const-trait-bounds-trait-objects.rs:14:25 + --> $DIR/const-trait-bounds-trait-objects.rs:15:25 | LL | const fn handle(_: &dyn const NonConst) {} | ^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:16:23 + --> $DIR/const-trait-bounds-trait-objects.rs:17:23 | LL | const fn take(_: &dyn ~const NonConst) {} | ^^^^^^ | = note: trait objects cannot have `~const` trait bounds -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-trait-bounds-trait-objects.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs index 5218ea925661e..c1fe42b975127 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] +#![feature(const_trait_impl, min_specialization, rustc_attrs)] //@ known-bug: #110395 #[rustc_specialization_trait] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index 7404b6a8b11f2..d082cd6de6097 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -1,31 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specializing-constness-2.rs:1:30 +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/specializing-constness-2.rs:9:1 | -LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters -error[E0119]: conflicting implementations of trait `A` - --> $DIR/specializing-constness-2.rs:20:1 +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/specializing-constness-2.rs:9:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters | -LL | impl A for T { - | ------------------------ first implementation here -... -LL | impl const A for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0308]: mismatched types +error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | LL | ::a(); - | ^^^^^^^^^^^^^ expected `host`, found `true` + | ^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | - = note: expected constant `host` - found constant `true` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0308. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index ddb26505202f4..2837c83542999 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -1,7 +1,8 @@ //@ run-pass //@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] trait Bar { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr deleted file mode 100644 index aef4f569d5e11..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-run.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - From b9886c6872b1fc7fe8d67c7eea8a20eb9a666200 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 08:36:40 +0000 Subject: [PATCH 124/217] bless tests part 1 --- compiler/rustc_hir_analysis/src/bounds.rs | 4 + .../const_trait_fn-issue-88433.rs | 3 +- .../const_trait_fn-issue-88433.stderr | 11 - .../unify-op-with-fn-call.rs | 2 +- .../unify-op-with-fn-call.stderr | 55 +---- tests/ui/const-generics/issues/issue-88119.rs | 2 +- tests/ui/consts/const-float-classify.rs | 1 + tests/ui/consts/const-float-classify.stderr | 216 +----------------- tests/ui/consts/const-try.rs | 3 +- tests/ui/consts/const-try.stderr | 41 +--- .../constifconst-call-in-const-position.rs | 3 +- ...constifconst-call-in-const-position.stderr | 37 +-- tests/ui/consts/promoted-const-drop.rs | 1 + tests/ui/consts/promoted-const-drop.stderr | 15 +- tests/ui/consts/promoted_const_call.stderr | 34 ++- .../consts/rustc-impl-const-stability.stderr | 12 +- .../auxiliary/cross-crate.rs | 3 +- ...fault-bound-non-const-specialized-bound.rs | 2 +- ...t-bound-non-const-specialized-bound.stderr | 41 ++++ .../const-default-const-specialized.rs | 5 +- .../const-default-const-specialized.stderr | 39 +++- .../specialization/default-keyword.rs | 3 +- .../specialization/default-keyword.stderr | 12 + .../issue-95186-specialize-on-tilde-const.rs | 3 +- ...sue-95186-specialize-on-tilde-const.stderr | 43 ++++ ...87-same-trait-bound-different-constness.rs | 3 +- ...ame-trait-bound-different-constness.stderr | 43 ++++ .../non-const-default-const-specialized.rs | 4 +- ...non-const-default-const-specialized.stderr | 45 ++-- .../trait-where-clause-const.rs | 6 +- .../ui/specialization/const_trait_impl.stderr | 68 +++++- 31 files changed, 368 insertions(+), 392 deletions(-) delete mode 100644 tests/ui/const-generics/const_trait_fn-issue-88433.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 18a29c10b61a3..0b03eeaced1be 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -65,6 +65,10 @@ impl<'tcx> Bounds<'tcx> { } else { self.clauses.push(clause); } + + if !tcx.features().effects { + return; + } // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `` and make sure that the effect is compatible. if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs index f3271f833cc64..5e0ea6fc168ef 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,7 +1,8 @@ //@ build-pass //@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Func { diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.stderr b/tests/ui/const-generics/const_trait_fn-issue-88433.stderr deleted file mode 100644 index 4e0d6370fbd50..0000000000000 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const_trait_fn-issue-88433.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index 2f903ea419efa..bd9c08e5ad895 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,6 +1,6 @@ //@ known-bug: #110395 -#![feature(generic_const_exprs, adt_const_params, const_trait_impl)] +#![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)] #![allow(incomplete_features)] // test `N + N` unifies with explicit function calls for non-builtin-types diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index 335130c958f0e..cf03bb9ad7612 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/unify-op-with-fn-call.rs:10:12 + | +LL | impl const std::ops::Add for Foo { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/unify-op-with-fn-call.rs:18:29 | @@ -45,48 +54,6 @@ help: try adding a `where` bound LL | fn foo2(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: { | +++++++++++++++++++++++++++++++++++++++++ -error[E0015]: cannot call non-const operator in constants - --> $DIR/unify-op-with-fn-call.rs:20:39 - | -LL | fn foo(a: Evaluatable<{ N + N }>) { - | ^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/unify-op-with-fn-call.rs:10:1 - | -LL | impl const std::ops::Add for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::add` in constants - --> $DIR/unify-op-with-fn-call.rs:21:13 - | -LL | bar::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::add` in constants - --> $DIR/unify-op-with-fn-call.rs:30:14 - | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0015, E0741. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index bcbb26f0d8e68..128e0b64a2bfa 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,7 +1,7 @@ //@ check-pass #![allow(incomplete_features)] -#![feature(const_trait_impl, generic_const_exprs)] +#![feature(const_trait_impl, effects, generic_const_exprs)] #[const_trait] trait ConstName { diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index ae094003c89e2..acc8d00f83e60 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -5,6 +5,7 @@ #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] // Don't promote const fn nop(x: T) -> T { x } diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr index 1de27a072cf73..38acb8a228104 100644 --- a/tests/ui/consts/const-float-classify.stderr +++ b/tests/ui/consts/const-float-classify.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-float-classify.rs:7:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/const-float-classify.rs:12:12 + --> $DIR/const-float-classify.rs:13:12 | LL | impl const PartialEq for bool { | ^^^^^^^^^^^^^^^^^ @@ -16,208 +7,5 @@ LL | impl const PartialEq for bool { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/const-float-classify.rs:12:6 - | -LL | impl const PartialEq for bool { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index f2d3db9be9c5b..9089dd70a26a6 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -4,8 +4,9 @@ #![crate_type = "lib"] #![feature(try_trait_v2)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(const_try)] +#![allow(incomplete_features)] use std::ops::{ControlFlow, FromResidual, Try}; diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 2d91424c8d320..27eb1252d7b7d 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,37 +1,20 @@ -error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions - --> $DIR/const-try.rs:33:5 +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:16:12 | -LL | TryMe?; - | ^^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/const-try.rs:21:1 - | -LL | impl const Try for TryMe { - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] +LL | impl const FromResidual for TryMe { + | ^^^^^^^^^^^^^^^^^^^ | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions - --> $DIR/const-try.rs:33:5 +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:22:12 | -LL | TryMe?; - | ^^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/const-try.rs:15:1 - | -LL | impl const FromResidual for TryMe { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] +LL | impl const Try for TryMe { + | ^^^ | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.rs b/tests/ui/consts/constifconst-call-in-const-position.rs index 29c967f38a7d9..757e35bbab209 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.rs +++ b/tests/ui/consts/constifconst-call-in-const-position.rs @@ -1,6 +1,7 @@ //@ known-bug: #102498 -#![feature(const_trait_impl, generic_const_exprs)] +#![feature(const_trait_impl, effects, generic_const_exprs)] +#![allow(incomplete_features)] #[const_trait] pub trait Tr { diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 09827f29baf96..f980b8969de85 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,36 +1,9 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/constifconst-call-in-const-position.rs:3:30 - | -LL | #![feature(const_trait_impl, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0015]: cannot call non-const fn `::a` in constants - --> $DIR/constifconst-call-in-const-position.rs:17:9 - | -LL | [0; T::a()] - | ^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::a` in constants - --> $DIR/constifconst-call-in-const-position.rs:16:38 +error[E0080]: evaluation of `foo::<()>::{constant#0}` failed + --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | + | ^^^^^^ calling non-const function `<() as Tr>::a` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/promoted-const-drop.rs b/tests/ui/consts/promoted-const-drop.rs index c896c011ab66a..b7d92d6523a81 100644 --- a/tests/ui/consts/promoted-const-drop.rs +++ b/tests/ui/consts/promoted-const-drop.rs @@ -4,6 +4,7 @@ struct A(); impl const Drop for A { + //~^ ERROR const `impl` for trait `Drop` which is not marked with `#[const_trait]` fn drop(&mut self) {} } diff --git a/tests/ui/consts/promoted-const-drop.stderr b/tests/ui/consts/promoted-const-drop.stderr index 4802834173fc5..1201f608232df 100644 --- a/tests/ui/consts/promoted-const-drop.stderr +++ b/tests/ui/consts/promoted-const-drop.stderr @@ -1,5 +1,14 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/promoted-const-drop.rs:6:12 + | +LL | impl const Drop for A { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:13:26 + --> $DIR/promoted-const-drop.rs:14:26 | LL | let _: &'static A = &A(); | ---------- ^^^ creates a temporary value which is freed while still in use @@ -10,7 +19,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:14:28 + --> $DIR/promoted-const-drop.rs:15:28 | LL | let _: &'static [A] = &[C]; | ------------ ^^^ creates a temporary value which is freed while still in use @@ -19,6 +28,6 @@ LL | let _: &'static [A] = &[C]; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index ace449fae9ce6..64bf6bd73b0a5 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,10 +1,31 @@ -error[E0493]: destructor of `Panic` cannot be evaluated at compile-time +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/promoted_const_call.rs:7:12 + | +LL | impl const Drop for Panic { fn drop(&mut self) { panic!(); } } + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promoted_const_call.rs:11:26 + | +LL | let _: &'static _ = &id(&Panic); + | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +... +LL | }; + | - temporary value is freed at the end of this statement + +error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:11:30 | LL | let _: &'static _ = &id(&Panic); - | ^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants + | ---------- ^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:17:26 @@ -48,7 +69,6 @@ LL | let _: &'static _ = &&(Panic, 0).1; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0493, E0716. -For more information about an error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 250d1c3fc0553..84bd375ea406e 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -16,15 +16,5 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/rustc-impl-const-stability.rs:15:6 - | -LL | impl const Default for Data { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index 62609384cff08..78e41ca6b7519 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs index fe4df09342f77..69dcb403aa908 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs @@ -1,6 +1,6 @@ // Tests that trait bounds on specializing trait impls must be `~const` if the // same bound is present on the default impl and is `~const` there. -//@ check-pass +//@ known-bug: #110395 // FIXME(effects) ^ should error #![feature(const_trait_impl)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr new file mode 100644 index 0000000000000..b4c4cf0a89059 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -0,0 +1,41 @@ +error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Bar { +LL | fn bar(); + | - expected 0 const parameters + +error: cannot specialize on const impl with non-const impl + --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1 + | +LL | / impl Bar for T +LL | | where +LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier +LL | | T: Specialize, + | |__________________^ + +error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Baz { +LL | fn baz(); + | - expected 0 const parameters + +error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Baz { +LL | fn baz(); + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs index c653e62032e6e..a48a50b9e5ce4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs @@ -1,9 +1,10 @@ // Tests that a const default trait impl can be specialized by another const // trait impl and that the specializing impl will be used during const-eval. -//@ run-pass +//@ known-bug: #110395 +// FIXME(effects) run-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl)] #![feature(min_specialization)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr index f533fb61aad75..cabf201405f55 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr @@ -1,11 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-default-const-specialized.rs:6:30 +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-const-specialized.rs:10:1 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters + +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-const-specialized.rs:10:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0015]: cannot call non-const fn `::value` in constant functions + --> $DIR/const-default-const-specialized.rs:16:5 + | +LL | T::value() + | ^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs index bc45a70777ca5..d9ffd237dcefd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs @@ -1,4 +1,5 @@ -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(const_trait_impl)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr new file mode 100644 index 0000000000000..52c8708f2c88d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr @@ -0,0 +1,12 @@ +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/default-keyword.rs:7:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Foo { +LL | fn foo(); + | - expected 0 const parameters + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs index d80370aee8209..219e5f3a600c1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs @@ -1,6 +1,7 @@ // Tests that `~const` trait bounds can be used to specialize const trait impls. -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(const_trait_impl)] #![feature(rustc_attrs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr new file mode 100644 index 0000000000000..1aa34637ca482 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr @@ -0,0 +1,43 @@ +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Foo { +LL | fn foo(); + | - expected 0 const parameters + +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Foo { +LL | fn foo(); + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Bar { +LL | fn bar() {} + | - expected 0 const parameters + +error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Bar { +LL | fn bar() {} + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs index d97469edaf97f..7514baa2fd554 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -2,7 +2,8 @@ // `T: Foo` in the default impl for the purposes of specialization (i.e., it // does not think that the user is attempting to specialize on trait `Foo`). -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(rustc_attrs)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr new file mode 100644 index 0000000000000..0e0f391b0865e --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr @@ -0,0 +1,43 @@ +error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Bar { +LL | fn bar(); + | - expected 0 const parameters + +error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Bar { +LL | fn bar(); + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Baz { +LL | fn baz(); + | - expected 0 const parameters + +error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Baz { +LL | fn baz(); + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs index fc8fc3f2a1d9c..912b35095f918 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs @@ -1,9 +1,9 @@ // Tests that a non-const default impl can be specialized by a const trait impl, // but that the default impl cannot be used in a const context. //@ known-bug: #110395 -// FIXME run-pass +// FIXME(effects) run-pass -#![feature(const_trait_impl, effects)] +#![feature(const_trait_impl)] #![feature(min_specialization)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr index bcccc855aab52..d49beb932591c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr @@ -1,21 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non-const-default-const-specialized.rs:6:30 +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/non-const-default-const-specialized.rs:9:1 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters + +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/non-const-default-const-specialized.rs:9:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/non-const-default-const-specialized.rs:27:1 +error[E0015]: cannot call non-const fn `::value` in constant functions + --> $DIR/non-const-default-const-specialized.rs:15:5 + | +LL | T::value() + | ^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | -LL | impl Value for T { - | ------------------- first implementation here -... -LL | impl const Value for FortyTwo { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 364ddfcc8ddd5..516451d881106 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -3,8 +3,8 @@ // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a // test is not enough. //@ known-bug: #110395 -// FIXME check-pass #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] trait Bar {} @@ -19,9 +19,9 @@ trait Foo { const fn test1() { T::a(); T::b(); - //FIXME ~^ ERROR the trait bound + //~^ ERROR mismatched types T::c::(); - //FIXME ~^ ERROR the trait bound + //~^ ERROR mismatched types } const fn test2() { diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index fc02f6f8f7433..e39138983c6e6 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,3 +1,23 @@ +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const_trait_impl.rs:6:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub unsafe trait Sup { +LL | fn foo() -> u32; + | - expected 0 const parameters + +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const_trait_impl.rs:6:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub unsafe trait Sup { +LL | fn foo() -> u32; + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:34:16 | @@ -16,6 +36,37 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const A for T { | ^^^^^^^ +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const_trait_impl.rs:29:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters + +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const_trait_impl.rs:29:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const_trait_impl.rs:29:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const fn `<() as A>::a` in constants --> $DIR/const_trait_impl.rs:52:23 | @@ -52,6 +103,19 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 6 previous errors +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const_trait_impl.rs:48:9 + | +LL | T::foo() + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. From f852a2c17373eda6994d83f75d8192ba4c2a653e Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:19:23 +0000 Subject: [PATCH 125/217] Implement `Self::Effects: Compat` desugaring --- .../src/collect/item_bounds.rs | 4 +--- .../src/collect/predicates_of.rs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 707a3f2d3c715..c8c82c711de18 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -130,7 +130,6 @@ pub(super) fn explicit_item_bounds_with_filter( let parent = tcx.local_parent(def_id); - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let preds = tcx.explicit_predicates_of(parent); if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { @@ -141,8 +140,7 @@ pub(super) fn explicit_item_bounds_with_filter( let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - // TODO this is bad - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9a5feaf3d3c65..cc3078f037a06 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,6 +57,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic #[instrument(level = "trace", skip(tcx), ret)] fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; + use rustc_middle::ty::Ty; match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -313,6 +314,24 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen debug!(?predicates); } + // add `Self::Effects: Compat` to ensure non-const impls don't get called + // in const contexts. + if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(..), .. }) = node + && let Some(host_effect_index) = generics.host_effect_index + { + let parent = generics.parent.unwrap(); + let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else { + bug!("associated_type_for_effects returned None when there is host effect in generics"); + }; + let effects = Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); + let param = generics.param_at(host_effect_index, tcx); + let span = tcx.def_span(param.def_id); + let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param)); + let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), From 373e906296059e3fea51323e07fcf5b0cea41d11 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:50:01 +0000 Subject: [PATCH 126/217] bless UI tests --- ...constifconst-call-in-const-position.stderr | 20 ++- ...-type-const-bound-usage-0.qualified.stderr | 16 ++- .../assoc-type-const-bound-usage-0.rs | 12 +- .../assoc-type-const-bound-usage-0.stderr | 33 +++++ ...-type-const-bound-usage-1.qualified.stderr | 35 +++-- .../assoc-type-const-bound-usage-1.rs | 7 +- ...ype-const-bound-usage-1.unqualified.stderr | 33 +++++ .../rfc-2632-const-trait-impl/assoc-type.rs | 3 +- .../assoc-type.stderr | 16 +-- .../call-const-trait-method-fail.stderr | 14 +- .../call-const-trait-method-pass.stderr | 61 +++++++- .../call-generic-in-impl.stderr | 25 +++- .../call-generic-method-chain.stderr | 41 +----- .../call-generic-method-dup-bound.stderr | 55 +------ .../call-generic-method-nonconst.rs | 3 +- .../call-generic-method-nonconst.stderr | 6 +- .../call-generic-method-pass.stderr | 41 +----- .../const-and-non-const-impl.stderr | 20 ++- .../const-bound-on-not-const-associated-fn.rs | 3 +- ...st-bound-on-not-const-associated-fn.stderr | 8 +- .../const-closure-trait-method-fail.stderr | 14 +- .../const-closure-trait-method.stderr | 14 +- .../const-default-method-bodies.stderr | 14 +- .../const-drop-fail-2.stderr | 26 +++- .../const-drop-fail.precise.stderr | 15 +- .../const-drop-fail.stock.stderr | 11 +- .../const-drop.precise.stderr | 136 ++++++++---------- .../const-drop.stock.stderr | 77 ++++++++-- .../const-fns-are-early-bound.rs | 58 +++++++- .../const-fns-are-early-bound.stderr | 23 ++- .../const-impl-requires-const-trait.stderr | 12 +- .../const_derives/derive-const-gate.rs | 1 + .../const_derives/derive-const-gate.stderr | 12 +- .../derive-const-non-const-type.stderr | 8 +- .../const_derives/derive-const-use.stderr | 111 +++----------- .../derive-const-with-params.stderr | 22 +-- .../cross-crate.gatednc.stderr | 14 +- ...-method-body-is-const-same-trait-ck.stderr | 14 +- .../effects/minicore.stderr | 9 +- ...o-explicit-const-params-cross-crate.stderr | 16 ++- .../effects/no-explicit-const-params.stderr | 16 ++- .../effects/project.rs | 10 +- .../effects/project.stderr | 74 ---------- .../effects/span-bug-issue-121418.rs | 1 - .../effects/span-bug-issue-121418.stderr | 19 +-- .../effects/spec-effectvar-ice.rs | 5 +- .../effects/spec-effectvar-ice.stderr | 37 ++--- .../generic-bound.stderr | 16 ++- .../impl-with-default-fn-fail.rs | 3 +- .../impl-with-default-fn-fail.stderr | 2 +- .../impl-with-default-fn-pass.rs | 4 +- .../rfc-2632-const-trait-impl/issue-100222.rs | 3 +- .../issue-92230-wf-super-trait-env.rs | 1 + .../non-const-op-in-closure-in-const.stderr | 25 +++- .../specializing-constness.rs | 2 + .../specializing-constness.stderr | 14 +- .../super-traits-fail-2.rs | 2 +- .../super-traits-fail-2.yn.stderr | 22 ++- .../super-traits-fail-2.yy.stderr | 22 ++- .../super-traits-fail-3.nn.stderr | 23 +-- .../super-traits-fail-3.ny.stderr | 17 +-- .../super-traits-fail-3.rs | 7 +- .../super-traits-fail-3.yn.stderr | 39 ++--- .../super-traits-fail-3.yy.stderr | 25 +++- .../super-traits-fail.rs | 4 +- .../rfc-2632-const-trait-impl/super-traits.rs | 5 +- .../super-traits.stderr | 24 +++- .../tilde-const-invalid-places.stderr | 11 +- .../trait-default-body-stability.stderr | 109 +------------- .../trait-where-clause-const.rs | 4 +- .../trait-where-clause-const.stderr | 68 +++++---- .../unsatisfied-const-trait-bound.rs | 3 +- .../unsatisfied-const-trait-bound.stderr | 13 +- 73 files changed, 870 insertions(+), 819 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index f980b8969de85..9096bd7868272 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,9 +1,21 @@ -error[E0080]: evaluation of `foo::<()>::{constant#0}` failed +error[E0308]: mismatched types --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ calling non-const function `<() as Tr>::a` + | ^^^^^^ expected `false`, found `host` + | + = note: expected constant `false` + found constant `host` + +error[E0308]: mismatched types + --> $DIR/constifconst-call-in-const-position.rs:18:9 + | +LL | [0; T::a()] + | ^^^^^^ expected `false`, found `host` + | + = note: expected constant `false` + found constant `host` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr index 3aec4383eab3a..1af0f481943ab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr @@ -7,16 +7,20 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:21:6 +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:21:5 | LL | ::Assoc::func() - | ^ the trait `Trait` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | -help: consider further restricting this bound +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-0.rs:8:1 | -LL | const fn qualified() -> i32 { - | +++++++ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs index eecd6e6109c1e..4399ae2d1be32 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs @@ -1,9 +1,7 @@ -// FIXME(effects): Collapse the revisions into one once we support `::Proj`. -//@ revisions: unqualified qualified -//@[unqualified] check-pass -//@[qualified] known-bug: unknown +//@ known-bug: unknown -#![feature(const_trait_impl, effects)] //[unqualified]~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { @@ -11,14 +9,12 @@ trait Trait { fn func() -> i32; } -#[cfg(unqualified)] const fn unqualified() -> i32 { T::Assoc::func() } -#[cfg(qualified)] const fn qualified() -> i32 { - ::Assoc::func() + ::Assoc::func() } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr new file mode 100644 index 0000000000000..919b5b6cd913d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 + | +LL | T::Assoc::func() + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:17:5 + | +LL | ::Assoc::func() + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr index 10e467da9521a..f8bab2d4c27fa 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr @@ -1,14 +1,33 @@ -error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:23:43 +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^ the trait `Trait` is not implemented for `T` +LL | fn unqualified() -> Type<{ T::Assoc::func() }> { + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | -help: consider further restricting this bound +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | +++++++ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function -error: aborting due to 1 previous error +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + | +LL | fn qualified() -> Type<{ ::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs index 8213dae136959..5394c3f2d070c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs @@ -1,7 +1,6 @@ // FIXME(effects): Collapse the revisions into one once we support `::Proj`. //@ revisions: unqualified qualified -//@[unqualified] check-pass -//@[qualified] known-bug: unknown +//@known-bug: unknown #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] @@ -14,13 +13,11 @@ trait Trait { struct Type; -#[cfg(unqualified)] fn unqualified() -> Type<{ T::Assoc::func() }> { Type } -#[cfg(qualified)] -fn qualified() -> Type<{ ::Assoc::func() }> { +fn qualified() -> Type<{ ::Assoc::func() }> { Type } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr new file mode 100644 index 0000000000000..f8bab2d4c27fa --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 + | +LL | fn unqualified() -> Type<{ T::Assoc::func() }> { + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + | +LL | fn qualified() -> Type<{ ::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs index 645fff4e01471..b542ec4e5d0ae 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs @@ -32,12 +32,13 @@ trait Foo { } impl const Foo for NonConstAdd { - type Bar = NonConstAdd; //~ ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + type Bar = NonConstAdd; // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] trait Baz { type Qux: Add; + //~^ ERROR the trait bound } impl const Baz for NonConstAdd { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index cc3abea25eb56..333215adef217 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -7,18 +7,16 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `NonConstAdd: ~const Add` is not satisfied - --> $DIR/assoc-type.rs:35:16 +error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type.rs:40:15 | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ the trait `~const Add` is not implemented for `NonConstAdd` +LL | type Qux: Add; + | ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}` | - = help: the trait `Add` is implemented for `NonConstAdd` -note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:31:15 +help: consider further restricting the associated type | -LL | type Bar: ~const Add; - | ^^^^^^^^^^ required by this bound in `Foo::Bar` +LL | trait Baz where Add::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 0e4dcf0f3026a..336ee01dc8d73 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -7,13 +7,21 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `u32: ~const Plus` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:5 | LL | a.plus(b) - | ^ the trait `~const Plus` is not implemented for `u32` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `Plus` is implemented for `u32` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `Plus::plus` + --> $DIR/call-const-trait-method-fail.rs:3:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Plus::plus` +LL | pub trait Plus { +LL | fn plus(self, rhs: Self) -> Self; + | ---- required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index 22e8e692752cc..bf455a714a343 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -1,20 +1,66 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:7:12 + | +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:15:12 + | +LL | impl const PartialEq for Int { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0049]: method `plus` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/call-const-trait-method-pass.rs:24:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait Plus { +LL | fn plus(self, rhs: Self) -> Self; + | - expected 0 const parameters + error[E0015]: cannot call non-const operator in constants --> $DIR/call-const-trait-method-pass.rs:39:22 | LL | const ADD_INT: Int = Int(1i32) + Int(2i32); | ^^^^^^^^^^^^^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $DIR/call-const-trait-method-pass.rs:7:1 - | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] | +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-pass.rs:11:20 + | +LL | Int(self.0.plus(rhs.0)) + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error[E0015]: cannot call non-const fn `::eq` in constant functions + --> $DIR/call-const-trait-method-pass.rs:20:15 + | +LL | !self.eq(other) + | ^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + error[E0015]: cannot call non-const fn `::plus` in constant functions --> $DIR/call-const-trait-method-pass.rs:36:7 | @@ -27,6 +73,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr index 12027c4d71362..5cd274c6c5a22 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr @@ -4,5 +4,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const MyPartialEq for T { | ^^^^^^^^^ -error: aborting due to 1 previous error +error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/call-generic-in-impl.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait MyPartialEq { +LL | fn eq(&self, other: &Self) -> bool; + | - expected 0 const parameters + +error[E0015]: cannot call non-const fn `::eq` in constant functions + --> $DIR/call-generic-in-impl.rs:12:9 + | +LL | PartialEq::eq(self, other) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 36c7a6544305b..2e1feccd0f358 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for S { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-chain.rs:10:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:19:32 | @@ -37,35 +28,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-chain.rs:27:22 - | -LL | pub const EQ: bool = equals_self_wrapper(&S); - | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-chain.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-chain.rs:15:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-chain.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index 320e420b80a30..d3b009636865a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for S { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-dup-bound.rs:8:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:19:44 | @@ -37,49 +28,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:30:22 - | -LL | pub const EQ: bool = equals_self(&S) && equals_self2(&S); - | ^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:30:41 - | -LL | pub const EQ: bool = equals_self(&S) && equals_self2(&S); - | ^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:13:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index 222bff2db8807..74e33ca72fffc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -21,6 +21,7 @@ const fn equals_self(t: &T) -> bool { // it not using the impl. pub const EQ: bool = equals_self(&S); -//~^ ERROR: the trait bound `S: const Foo` is not satisfied +//~^ ERROR: the trait bound `Runtime: const Compat` is not satisfied +// FIXME(effects) diagnostic fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index fa59e5ee03dd0..d48ee9c95f593 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -7,15 +7,15 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `S: const Foo` is not satisfied +error[E0277]: the trait bound `Runtime: const Compat` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `const Foo` is not implemented for `S` + | ----------- ^^ the trait `const Compat` is not implemented for `Runtime` | | | required by a bound introduced by this call | - = help: the trait `Foo` is implemented for `S` + = help: the trait `Compat` is implemented for `Runtime` note: required by a bound in `equals_self` --> $DIR/call-generic-method-nonconst.rs:16:25 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index 6b9d290839e5f..cab8d6d761195 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -16,50 +16,11 @@ LL | impl const PartialEq for S { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-pass.rs:10:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-pass.rs:19:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-pass.rs:23:22 - | -LL | pub const EQ: bool = equals_self(&S); - | ^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-pass.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-pass.rs:15:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-pass.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 8916450df2d4b..9c1c8df8da459 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,3 +1,21 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:7:12 + | +LL | impl const std::ops::Add for i32 { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:23:12 + | +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error[E0119]: conflicting implementations of trait `Add` for type `Int` --> $DIR/const-and-non-const-impl.rs:23:1 | @@ -19,7 +37,7 @@ LL | impl const std::ops::Add for i32 { | = note: define and implement a trait or new type instead -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0117, E0119. For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs index 0025449c4921f..099cf0b00d3f7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr index db48c170d1c02..42964b9774e29 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/const-bound-on-not-const-associated-fn.rs:9:40 + --> $DIR/const-bound-on-not-const-associated-fn.rs:10:40 | LL | fn do_something_else() where Self: ~const MyTrait; | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/const-bound-on-not-const-associated-fn.rs:9:8 + --> $DIR/const-bound-on-not-const-associated-fn.rs:10:8 | LL | fn do_something_else() where Self: ~const MyTrait; | ^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-bound-on-not-const-associated-fn.rs:20:32 + --> $DIR/const-bound-on-not-const-associated-fn.rs:21:32 | LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/const-bound-on-not-const-associated-fn.rs:20:12 + --> $DIR/const-bound-on-not-const-associated-fn.rs:21:12 | LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index fb2e66db1d488..507ceaae2eab3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,3 +1,12 @@ +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-closure-trait-method-fail.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Tr { +LL | fn a(self) -> i32; + | - expected 0 const parameters + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method-fail.rs:14:39 | @@ -20,6 +29,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr index dede411e69c73..2a54cd5d7f6e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr @@ -1,3 +1,12 @@ +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-closure-trait-method.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Tr { +LL | fn a(self) -> i32; + | - expected 0 const parameters + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method.rs:14:39 | @@ -20,6 +29,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 8e04d0bd20da0..32bc0093347c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -7,13 +7,21 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `ConstDefaultFn::a` + --> $DIR/const-default-method-bodies.rs:3:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a` +... +LL | fn a(self) { + | - required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr index 085d9e710125a..1d56d015dfc15 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:40:25 + | +LL | impl const Drop for ConstDropImplWithNonConstBounds { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail-2.rs:21:26 | @@ -12,6 +21,19 @@ LL | const fn check(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error[E0015]: cannot call non-const fn `::a` in constant functions + --> $DIR/const-drop-fail-2.rs:42:9 + | +LL | T::a(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0015, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index e95215d471566..b251d84a9670e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail.rs:20:12 + | +LL | impl const Drop for ConstImplWithDropGlue { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail.rs:24:26 | @@ -38,8 +47,10 @@ LL | | } error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: calling non-const function `::drop` + = note: calling non-const function `::drop` | +note: inside `std::ptr::drop_in_place:: - shim(Some(NonTrivialDrop))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `std::ptr::drop_in_place:: - shim(Some(ConstImplWithDropGlue))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `check::` @@ -60,7 +71,7 @@ LL | | } | |_- in this macro invocation = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0080, E0493. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index f9bd9953fcfd3..912700f2a8345 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail.rs:20:12 + | +LL | impl const Drop for ConstImplWithDropGlue { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail.rs:24:26 | @@ -12,6 +21,6 @@ LL | const fn check(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr index 6aace10589605..9d1ca5dbf2c03 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr @@ -1,32 +1,64 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:13:16 + | +LL | impl<'a> const Drop for S<'a> { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:47:16 + | +LL | impl const Drop for ConstDrop { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:68:37 + | +LL | impl const Drop for ConstDropWithBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:76:30 + | +LL | impl const Drop for ConstDropWithNonconstBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop.rs:19:22 | LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:24:13 +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 | -LL | let _ = S(&mut c); - | ^^^^^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 | -note: inside `std::ptr::drop_in_place::> - shim(Some(S<'_>))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `b` - --> $DIR/const-drop.rs:24:22 +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters | -LL | let _ = S(&mut c); - | ^ -note: inside `C` - --> $DIR/const-drop.rs:30:15 - | -LL | const C: u8 = b(); - | ^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop.rs:19:32 @@ -34,65 +66,19 @@ error[E0493]: destructor of `T` cannot be evaluated at compile-time LL | const fn a(_: T) {} | ^ the destructor for this type cannot be evaluated in constant functions -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const-drop.rs:70:13 | - = note: calling non-const function `::drop` +LL | T::foo(); + | ^^^^^^^^ | -note: inside `std::ptr::drop_in_place:: - shim(Some(t::ConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `a::` - --> $DIR/const-drop.rs:19:39 + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable | -LL | const fn a(_: T) {} - | ^ -note: inside `_` - --> $DIR/const-drop.rs:35:27 - | -LL | const _: () = a($exp); - | ^^^^^^^ -... -LL | / implements_const_drop! { -LL | | 1u8, -LL | | 2, -LL | | 3.0, -... | -LL | | Result::::Ok(1), -LL | | } - | |_- in this macro invocation - = note: this error originates in the macro `implements_const_drop` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function `::drop` +LL + #![feature(effects)] | -note: inside `std::ptr::drop_in_place:: - shim(Some(t::ConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place:: - shim(Some(t::HasConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `a::` - --> $DIR/const-drop.rs:19:39 - | -LL | const fn a(_: T) {} - | ^ -note: inside `_` - --> $DIR/const-drop.rs:35:27 - | -LL | const _: () = a($exp); - | ^^^^^^^ -... -LL | / implements_const_drop! { -LL | | 1u8, -LL | | 2, -LL | | 3.0, -... | -LL | | Result::::Ok(1), -LL | | } - | |_- in this macro invocation - = note: this error originates in the macro `implements_const_drop` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0080, E0493. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0015, E0049, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr index 18dd4543c3d39..2f93f9a6743b8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr @@ -1,16 +1,64 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:13:16 + | +LL | impl<'a> const Drop for S<'a> { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:47:16 + | +LL | impl const Drop for ConstDrop { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:68:37 + | +LL | impl const Drop for ConstDropWithBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:76:30 + | +LL | impl const Drop for ConstDropWithNonconstBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop.rs:19:22 | LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:24:13 +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters + +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters | -LL | let _ = S(&mut c); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop.rs:19:32 @@ -20,6 +68,19 @@ LL | const fn a(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 3 previous errors +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const-drop.rs:70:13 + | +LL | T::foo(); + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0015, E0049, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index faa913c759884..fdc53dbab1cbc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -1,17 +1,21 @@ -//@ check-pass +//@ known-bug: #110395 +// FIXME(effects) check-pass +//@ compile-flags: -Znext-solver #![crate_type = "lib"] -#![allow(internal_features)] +#![allow(internal_features, incomplete_features)] #![no_std] #![no_core] #![feature( auto_traits, const_trait_impl, - effects, //~ WARN the feature `effects` is incomplete + effects, lang_items, no_core, staged_api, - unboxed_closures + unboxed_closures, + rustc_attrs, + marker_trait_attr, )] #![stable(feature = "minicore", since = "1.0.0")] @@ -84,3 +88,49 @@ trait Receiver {} impl Receiver for &T {} impl Receiver for &mut T {} + +#[stable(feature = "minicore", since = "1.0.0")] +pub mod effects { + use super::Sized; + + #[lang = "EffectsNoRuntime"] + #[stable(feature = "minicore", since = "1.0.0")] + pub struct NoRuntime; + #[lang = "EffectsMaybe"] + #[stable(feature = "minicore", since = "1.0.0")] + pub struct Maybe; + #[lang = "EffectsRuntime"] + #[stable(feature = "minicore", since = "1.0.0")] + pub struct Runtime; + + #[lang = "EffectsCompat"] + #[stable(feature = "minicore", since = "1.0.0")] + pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} + + #[stable(feature = "minicore", since = "1.0.0")] + impl Compat for NoRuntime {} + #[stable(feature = "minicore", since = "1.0.0")] + impl Compat for Runtime {} + #[stable(feature = "minicore", since = "1.0.0")] + impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} + + #[lang = "EffectsTyCompat"] + #[marker] + #[stable(feature = "minicore", since = "1.0.0")] + pub trait TyCompat {} + + #[stable(feature = "minicore", since = "1.0.0")] + impl TyCompat for T {} + #[stable(feature = "minicore", since = "1.0.0")] + impl TyCompat for Maybe {} + #[stable(feature = "minicore", since = "1.0.0")] + impl TyCompat for T {} + + #[lang = "EffectsMin"] + #[stable(feature = "minicore", since = "1.0.0")] + pub trait Min { + #[lang = "EffectsMinOutput"] + #[stable(feature = "minicore", since = "1.0.0")] + type Output: ?Sized; + } +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr index 42b19fce28e9c..7aa3aa8c6bbb3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr @@ -1,11 +1,20 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-fns-are-early-bound.rs:10:5 +error[E0277]: the trait bound `FnOnce<()>::{synthetic#0}: const Compat` is not satisfied + --> $DIR/const-fns-are-early-bound.rs:31:17 | -LL | effects, - | ^^^^^^^ +LL | is_const_fn(foo); + | ----------- ^^^ the trait `const Compat` is not implemented for `FnOnce<()>::{synthetic#0}` + | | + | required by a bound introduced by this call | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +note: required by a bound in `is_const_fn` + --> $DIR/const-fns-are-early-bound.rs:25:12 + | +LL | fn is_const_fn(_: F) + | ----------- required by a bound in this function +LL | where +LL | F: const FnOnce<()>, + | ^^^^^^^^^^^^^^^^ required by this bound in `is_const_fn` -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index fb282d9ee2b47..7925cf53f42c4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -19,15 +19,5 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/const-impl-requires-const-trait.rs:8:6 - | -LL | impl const A for () {} - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs index 348ca0ab1906b..a772d69c9e2e2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -1,4 +1,5 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature +//~^ ERROR const `impl` for trait `Default` which is not marked with `#[const_trait]` pub struct S; fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index 9ec2ac9338175..3ccae5a83e665 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -7,6 +7,16 @@ LL | #[derive_const(Default)] = help: add `#![feature(derive_const)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-gate.rs:1:16 + | +LL | #[derive_const(Default)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 1e091283510d6..78e5b70d41c38 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -17,11 +17,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 925b2c58ed77b..da6b77f623cc1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -28,33 +28,6 @@ LL | impl const Default for A { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/derive-const-use.rs:7:6 - | -LL | impl const Default for A { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:11:12 - | -LL | impl const PartialEq for A { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/derive-const-use.rs:11:6 - | -LL | impl const PartialEq for A { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:15:16 | @@ -65,10 +38,14 @@ LL | #[derive_const(Default, PartialEq)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:11:12 + | +LL | impl const PartialEq for A { + | ^^^^^^^^^ | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:15:25 @@ -80,73 +57,29 @@ LL | #[derive_const(Default, PartialEq)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:18:35 - | -LL | const _: () = assert!(S((), A) == S::default()); - | ^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `Default` - --> $DIR/derive-const-use.rs:15:16 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:18:23 - | -LL | const _: () = assert!(S((), A) == S::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/derive-const-use.rs:15:25 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:16:18 +error[E0080]: evaluation of constant value failed + --> $DIR/derive-const-use.rs:16:14 | LL | #[derive_const(Default, PartialEq)] | ------- in this derive macro expansion LL | pub struct S((), A); - | ^ cannot infer the value of the constant `_` + | ^^ calling non-const function `<() as Default>::default` | -note: required for `A` to implement `Default` - --> $DIR/derive-const-use.rs:7:12 - | -LL | impl const Default for A { - | ----- ^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:16:18 +note: inside `::default` + --> $DIR/derive-const-use.rs:16:14 | LL | #[derive_const(Default, PartialEq)] - | --------- in this derive macro expansion + | ------- in this derive macro expansion LL | pub struct S((), A); - | ^ cannot infer the value of the constant `_` - | -note: required for `A` to implement `PartialEq` - --> $DIR/derive-const-use.rs:11:12 + | ^^ +note: inside `_` + --> $DIR/derive-const-use.rs:18:35 | -LL | impl const PartialEq for A { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | const _: () = assert!(S((), A) == S::default()); + | ^^^^^^^^^^^^ + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 14 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284, E0635. -For more information about an error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0080, E0635. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index 5d3aa250d1854..102458450fbf7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -25,25 +25,5 @@ LL | #[derive_const(PartialEq)] | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/derive-const-with-params.rs:11:5 - | -LL | a == b - | ^^^^^^ cannot infer the value of the constant `_` - | -note: required for `Reverse` to implement `PartialEq` - --> $DIR/derive-const-with-params.rs:7:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index ddb5b3c7c5078..af042ecff953b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -7,13 +7,21 @@ LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/cross-crate.rs:18:14 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `func` + --> $DIR/auxiliary/cross-crate.rs:4:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` +... +LL | fn func(self); + | ---- required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 67a936d0882f4..8b422d62578a0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -7,13 +7,21 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `(): ~const Tr` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() - | ^ the trait `~const Tr` is not implemented for `()` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `Tr` is implemented for `()` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `Tr::a` + --> $DIR/default-method-body-is-const-same-trait-ck.rs:3:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Tr::a` +LL | pub trait Tr { +LL | fn a(&self) {} + | - required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index e4a5f3686084e..1963332b856de 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -7,12 +7,11 @@ LL | #![feature(const_trait_impl, effects, const_mut_refs)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0 - --> $DIR/minicore.rs:517:27 +error: requires `EffectsCompat` lang_item + --> $DIR/minicore.rs:455:9 | -LL | const fn const_eval_select( - | ^^^^^^^^^^^^^^^^^^^^^^^ expected 0 const parameters +LL | impl Clone for RefCell { + | ^^^^^ error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0094`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr index cc870ad336cd1..34732ac4f2ef7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr @@ -16,15 +16,17 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:16:12 | LL | <() as Bar>::bar(); - | ^^^------- help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:6:11 | LL | pub trait Bar { | ^^^ +help: replace the generic bound with the associated type + | +LL | <() as Bar< = false>>::bar(); + | + error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params-cross-crate.rs:7:5 @@ -44,15 +46,17 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:9:12 | LL | <() as Bar>::bar(); - | ^^^------ help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:6:11 | LL | pub trait Bar { | ^^^ +help: replace the generic bound with the associated type + | +LL | <() as Bar< = true>>::bar(); + | + error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr index 39aa5825611f3..c3ff30d2d797b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr @@ -25,15 +25,17 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:24:12 | LL | <() as Bar>::bar(); - | ^^^------- help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ +help: replace the generic bound with the associated type + | +LL | <() as Bar< = false>>::bar(); + | + error[E0308]: mismatched types --> $DIR/no-explicit-const-params.rs:24:5 @@ -62,15 +64,17 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:17:12 | LL | <() as Bar>::bar(); - | ^^^------ help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ +help: replace the generic bound with the associated type + | +LL | <() as Bar< = true>>::bar(); + | + error: aborting due to 5 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs index 0592ac2e0e70c..373a4393713c6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs @@ -1,12 +1,10 @@ -//@ known-bug: #110395 -// FIXME: effects +//@ check-pass #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] -// This fails because `~const Uwu` doesn't imply (non-const) `Uwu`. - -// FIXME: #[const_trait] -pub trait Owo::T> {} +#[const_trait] +pub trait Owo::T> {} #[const_trait] pub trait Uwu: Owo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr deleted file mode 100644 index ab5f7b55a4e47..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr +++ /dev/null @@ -1,74 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/project.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:1 - | -LL | pub trait Uwu: Owo { - | ^^^^^^^^^^^^^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:1 - | -LL | / pub trait Uwu: Owo { -LL | | type T; -LL | | } - | |_^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:16 - | -LL | pub trait Uwu: Owo { - | ^^^ the trait `Uwu` is not implemented for `Self` - | -note: required by a bound in `Owo` - --> $DIR/project.rs:9:15 - | -LL | pub trait Owo::T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Owo` -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:13:5 - | -LL | type T; - | ^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:13:5 - | -LL | type T; - | ^^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error: aborting due to 5 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs index 987a162cd6cae..e6e41c472bdc7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs @@ -6,7 +6,6 @@ trait T {} impl const dyn T { //~^ ERROR inherent impls cannot be `const` - //~| ERROR the const parameter `host` is not constrained by the impl trait, self type, or pub const fn new() -> std::sync::Mutex {} //~^ ERROR mismatched types //~| ERROR cannot be known at compilation time diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr index f24d7c7a16017..313ba4fc9565e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr @@ -17,17 +17,8 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/span-bug-issue-121418.rs:7:6 - | -LL | impl const dyn T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error[E0308]: mismatched types - --> $DIR/span-bug-issue-121418.rs:10:27 + --> $DIR/span-bug-issue-121418.rs:9:27 | LL | pub const fn new() -> std::sync::Mutex {} | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex`, found `()` @@ -38,7 +29,7 @@ LL | pub const fn new() -> std::sync::Mutex {} found unit type `()` error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time - --> $DIR/span-bug-issue-121418.rs:10:27 + --> $DIR/span-bug-issue-121418.rs:9:27 | LL | pub const fn new() -> std::sync::Mutex {} | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -48,7 +39,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>` --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL = note: the return type of a function must have a statically known size -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0277, E0308. -For more information about an error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs index 00465b0f53d5a..0508b1c5e26b6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs @@ -11,12 +11,11 @@ trait Foo {} impl const Foo for T {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` -//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] impl const Foo for T where T: const Specialize {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: `const` can only be applied to `#[const_trait]` traits -//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] -//~| error: conflicting implementations of trait `Foo` +//~| error: specialization impl does not specialize any associated items +//~| error: cannot specialize on trait `Specialize` fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr index 8d69151bf74c3..047549bca75a5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -20,7 +20,7 @@ LL | impl const Foo for T {} = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` - --> $DIR/spec-effectvar-ice.rs:16:15 + --> $DIR/spec-effectvar-ice.rs:15:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -32,39 +32,28 @@ LL | impl const Foo for T where T: const Specialize {} = note: adding a non-const method body in the future would be a breaking change error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/spec-effectvar-ice.rs:16:40 + --> $DIR/spec-effectvar-ice.rs:15:40 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^ -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/spec-effectvar-ice.rs:12:9 +error: specialization impl does not specialize any associated items + --> $DIR/spec-effectvar-ice.rs:15:1 | -LL | impl const Foo for T {} - | ^^^^^ unconstrained const parameter +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0119]: conflicting implementations of trait `Foo` - --> $DIR/spec-effectvar-ice.rs:16:1 +note: impl is a specialization of this impl + --> $DIR/spec-effectvar-ice.rs:12:1 | LL | impl const Foo for T {} - | ----------------------- first implementation here -... -LL | impl const Foo for T where T: const Specialize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + | ^^^^^^^^^^^^^^^^^^^^^^^ -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/spec-effectvar-ice.rs:16:9 +error: cannot specialize on trait `Specialize` + --> $DIR/spec-effectvar-ice.rs:15:34 | LL | impl const Foo for T where T: const Specialize {} - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported + | ^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted -Some errors have detailed explanations: E0119, E0207. -For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr index 7905abfa40ed6..2baac1d2a168e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr @@ -1,20 +1,24 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/generic-bound.rs:16:15 + | +LL | impl const std::ops::Add for S { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error[E0015]: cannot call non-const operator in constant functions --> $DIR/generic-bound.rs:25:5 | LL | arg + arg | ^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $DIR/generic-bound.rs:16:1 - | -LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs index 6df9696f2cbd7..49741ca24c7e7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 36c8163f1c567..0135296526f96 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `req` - --> $DIR/impl-with-default-fn-fail.rs:12:1 + --> $DIR/impl-with-default-fn-fail.rs:13:1 | LL | fn req(&self); | -------------- `req` from trait diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs index c6fab4aabb6b7..0a1d2355a75bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs @@ -1,6 +1,6 @@ //@ check-pass - -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs index 2a40a1b86ca28..10d7a3942e497 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs @@ -1,6 +1,7 @@ //@ revisions: nn ny yn yy //@ check-pass -#![feature(const_trait_impl, associated_type_defaults, const_mut_refs)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)] #[cfg_attr(any(yn, yy), const_trait)] pub trait Index { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs index a587de9f17963..e666355db6ffc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs @@ -4,6 +4,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] pub trait Super {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr index ae76cab2f2e66..de4783bdb3fe6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -4,5 +4,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const Convert for A where B: ~const From
{ | ^^^^^^^ -error: aborting due to 1 previous error +error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/non-const-op-in-closure-in-const.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Convert { +LL | fn to(self) -> T; + | - expected 0 const parameters + +error[E0015]: cannot call non-const fn `>::from` in constant functions + --> $DIR/non-const-op-in-closure-in-const.rs:12:9 + | +LL | B::from(self) + | ^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs index 3aabaf137d54c..4501a218ad723 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs @@ -22,6 +22,8 @@ impl const A for T { impl A for T { //~^ ERROR: cannot specialize +//~| ERROR: cannot specialize +//~| ERROR: cannot specialize //FIXME(effects) ~| ERROR: missing `~const` qualifier fn a() -> u32 { 3 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 226295bf949df..272cb26ff42e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -13,5 +13,17 @@ error: cannot specialize on const impl with non-const impl LL | impl A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: cannot specialize on trait `Compat` + --> $DIR/specializing-constness.rs:23:16 + | +LL | impl A for T { + | ^^^ + +error: cannot specialize on trait `Compat` + --> $DIR/specializing-constness.rs:23:9 + | +LL | impl A for T { + | ^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 2f26eebbe32f9..ba20a79a4df74 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -15,7 +15,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { x.a(); - //[yy,yn]~^ ERROR mismatched types + //[yy,yn]~^ ERROR the trait bound // FIXME(effects) diagnostic } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index f96e6fb4ae468..a4f1c94bca0bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -19,15 +19,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index ffc259e590e80..4e27ebc5e9ec7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -7,15 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index cde4b1ff77f35..a9bf2687cb88f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -34,7 +25,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -42,10 +33,10 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 6f1840181481c..c3811623c1c86 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -22,12 +13,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index f7e85902a41b2..24661f078b017 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,7 +1,8 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ revisions: yy yn ny nn -//@[yy] check-pass +//@[yy] known-bug: #110395 #[cfg_attr(any(yy, yn), const_trait)] trait Foo { @@ -18,7 +19,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` x.a(); - //[yn]~^ ERROR: mismatched types + //[yn]~^ ERROR: the trait bound } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index b0a3b39631dca..34a60329eb5e2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,39 +1,40 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error[E0308]: mismatched types - --> $DIR/super-traits-fail-3.rs:20:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type | - = note: expected constant `host` - found constant `true` +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr index e354c66919ec6..8ac20b3e06852 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr @@ -1,11 +1,22 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | x.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index 0bbf2dabffe57..bb8e06ab2f7a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,7 +1,7 @@ //@ check-pass -//@ known-bug: #110395 -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index cfbb8e9f6be57..b32c8cab7ecbe 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,6 @@ -//@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +// FIXME(effects) check-pass +//@ known-bug: #110395 +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index 2ff1a880d84f0..a9cb68a247ccd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:2:30 + --> $DIR/super-traits.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,5 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits.rs:21:7 + | +LL | t.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 3b320f1c5424a..8151b9aaa23de 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -282,21 +282,12 @@ help: wrap the field type in `ManuallyDrop<...>` LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + -error[E0275]: overflow evaluating the requirement `Trait::{opaque#0} == _` +error[E0275]: overflow evaluating the requirement `(): Trait` --> $DIR/tilde-const-invalid-places.rs:34:34 | LL | type Type = (); | ^^ | -note: required for `()` to implement `Trait` - --> $DIR/tilde-const-invalid-places.rs:56:23 - | -LL | impl Trait for T {} - | ------------ ^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 1 redundant requirement hidden - = note: required for `()` to implement `Trait` note: required by a bound in `NonConstTrait::Type` --> $DIR/tilde-const-invalid-places.rs:25:33 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index adb1b01f08704..d0c2f88005d7a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -25,112 +25,5 @@ LL | impl const FromResidual for T { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:18:6 - | -LL | impl const Try for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 516451d881106..dd5de62aff529 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -2,7 +2,7 @@ // Checking the validity of traits' where clauses happen at a later stage. // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a // test is not enough. -//@ known-bug: #110395 + #![feature(const_trait_impl, effects)] #![allow(incomplete_features)] @@ -20,8 +20,10 @@ const fn test1() { T::a(); T::b(); //~^ ERROR mismatched types + //~| ERROR the trait bound T::c::(); //~^ ERROR mismatched types + //~| ERROR the trait bound } const fn test2() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 95c32b12241c9..877152472c16e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,44 +1,60 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-const.rs:7:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `T: ~const Bar` is not satisfied +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::b(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:15:24 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` +... LL | fn b() where Self: ~const Bar; - | ^^^^^^^^^^ required by this bound in `Foo::b` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:21:5 | -LL | const fn test1() { - | ++++++++++++ +LL | T::b(); + | ^^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` -error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:23:12 +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied + --> $DIR/trait-where-clause-const.rs:24:5 | LL | T::c::(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:16:13 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` +... LL | fn c(); - | ^^^^^^^^^^ required by this bound in `Foo::c` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:24:5 + | +LL | T::c::(); + | ^^^^^^^^^^^ expected `host`, found `true` | -LL | const fn test1() { - | ++++++++++++ + = note: expected constant `host` + found constant `true` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs index 3a8c6d5b1a4fa..c50c755f667fc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -18,7 +18,8 @@ impl Trait for Ty { } fn main() { - require::(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied + // FIXME(effects): improve diagnostics on this + require::(); //~ ERROR the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied } struct Container; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr index 258f95b5c4a89..b9f6c9e883562 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:27:37 + --> $DIR/unsatisfied-const-trait-bound.rs:29:37 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `true` @@ -8,7 +8,7 @@ LL | fn accept0(_: Container<{ T::make() }>) {} found constant `true` error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:32:50 + --> $DIR/unsatisfied-const-trait-bound.rs:34:50 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `host` @@ -16,15 +16,14 @@ LL | const fn accept1(_: Container<{ T::make() }>) {} = note: expected constant `false` found constant `host` -error[E0277]: the trait bound `Ty: const Trait` is not satisfied - --> $DIR/unsatisfied-const-trait-bound.rs:20:15 +error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:22:15 | LL | require::(); - | ^^ the trait `const Trait` is not implemented for `Ty` + | ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}` | - = help: the trait `Trait` is implemented for `Ty` note: required by a bound in `require` - --> $DIR/unsatisfied-const-trait-bound.rs:6:15 + --> $DIR/unsatisfied-const-trait-bound.rs:7:15 | LL | fn require() {} | ^^^^^^^^^^^ required by this bound in `require` From 0a2330630d223ac3601a7b53e65e0d5867b60c2c Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:57:31 +0000 Subject: [PATCH 127/217] general fixups and turn `TODO`s into `FIXME`s --- compiler/rustc_hir_analysis/src/bounds.rs | 6 ++-- .../src/collect/item_bounds.rs | 9 +++-- .../src/collect/predicates_of.rs | 6 ++-- .../src/hir_ty_lowering/generics.rs | 2 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 5 ++- .../src/solve/trait_goals.rs | 4 +-- compiler/rustc_ty_utils/src/assoc.rs | 4 +-- compiler/rustc_type_ir/src/effects.rs | 6 ++-- library/core/src/marker.rs | 4 ++- ...-type-const-bound-usage-0.qualified.stderr | 27 --------------- ...ype-const-bound-usage-0.unqualified.stderr | 11 ------- .../assoc-type-const-bound-usage-1.rs | 5 ++- ... => assoc-type-const-bound-usage-1.stderr} | 0 ...ype-const-bound-usage-1.unqualified.stderr | 33 ------------------- .../rfc-2632-const-trait-impl/assoc-type.rs | 3 +- 16 files changed, 31 insertions(+), 96 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr rename tests/ui/rfcs/rfc-2632-const-trait-impl/{assoc-type-const-bound-usage-1.qualified.stderr => assoc-type-const-bound-usage-1.stderr} (100%) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0b03eeaced1be..61b7dd8bb8c34 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -72,7 +72,7 @@ impl<'tcx> Bounds<'tcx> { // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `` and make sure that the effect is compatible. if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { - // TODO: do we need `T: const Trait` anymore? + // FIXME(effects): revisit the correctness of this (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { @@ -120,7 +120,7 @@ impl<'tcx> Bounds<'tcx> { // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor // that uses a `Bar` that implements `Trait` with `Maybe` effects. (DefKind::AssocTy, ty::BoundConstness::ConstIfConst) => { - // TODO write the actual impl + // FIXME(effects): implement this return; } // probably illegal in this position. @@ -169,7 +169,7 @@ impl<'tcx> Bounds<'tcx> { pub fn clauses( &self, - // TODO remove tcx + // FIXME(effects): remove tcx _tcx: TyCtxt<'tcx>, ) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index c8c82c711de18..b32067ebd6aee 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -134,13 +134,16 @@ pub(super) fn explicit_item_bounds_with_filter( if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` - // TODO do the same for impls let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); - // TODO span + // FIXME(effects) span let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); + let self_proj = Ty::new_projection( + tcx, + def_id.to_def_id(), + ty::GenericArgs::identity_for_item(tcx, def_id), + ); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index cc3078f037a06..1c3c1a79cfbc3 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -323,12 +323,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else { bug!("associated_type_for_effects returned None when there is host effect in generics"); }; - let effects = Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); + let effects = + Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); let param = generics.param_at(host_effect_index, tcx); let span = tcx.def_span(param.def_id); let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param)); let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); + let trait_ref = + ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 67046b5ac0e40..e92c377f0ce2a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -256,7 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( | GenericParamDefKind::Lifetime, _, ) => { - // TODO: this should be removed + // FIXME(effects): this should be removed // SPECIAL CASE FOR DESUGARED EFFECT PARAMS // This comes from the following example: // diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index dad909fc4e102..ff8899ae0368d 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; - // TODO there is something wrong here because now methods for binops may get `const host: bool` + // FIXME(effects): revisit when binops get `#[const_trait]` // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index f75c30eda9949..55c0440a53715 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -873,7 +873,6 @@ where return Err(NoSolution); }; - let cx = ecx.cx(); let mut first_non_maybe = None; @@ -907,11 +906,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 8c6e5eb5a4d9d..73ae1c4b11359 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -731,11 +731,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 681f089e84fb7..6a55e83786cb8 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -255,7 +255,7 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option None, } } -} \ No newline at end of file +} diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b71bedaa1948f..042acbf20b1a0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1028,6 +1028,9 @@ pub macro SmartPointer($item:item) { /* compiler built-in */ } +// Support traits and types for the desugaring of const traits and +// `~const` bounds. Not supposed to be used by anything other than +// the compiler. #[doc(hidden)] #[unstable( feature = "effect_types", @@ -1036,7 +1039,6 @@ pub macro SmartPointer($item:item) { )] #[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls. #[cfg(not(bootstrap))] -// TODO docs pub mod effects { #[lang = "EffectsNoRuntime"] pub struct NoRuntime; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr deleted file mode 100644 index 1af0f481943ab..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr +++ /dev/null @@ -1,27 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:21:5 - | -LL | ::Assoc::func() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error: aborting due to 1 previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr deleted file mode 100644 index 3d592834600e0..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs index 5394c3f2d070c..8a1bf75f87e1a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs @@ -1,6 +1,5 @@ -// FIXME(effects): Collapse the revisions into one once we support `::Proj`. -//@ revisions: unqualified qualified -//@known-bug: unknown +//@ known-bug: unknown +// FIXME(effects) #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr rename to tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr deleted file mode 100644 index f8bab2d4c27fa..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> { - | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs index b542ec4e5d0ae..348bf839b6995 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs @@ -32,7 +32,8 @@ trait Foo { } impl const Foo for NonConstAdd { - type Bar = NonConstAdd; // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + type Bar = NonConstAdd; + // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] From 8b2fac9612e3840f9736bed31502b3b91ba01a08 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 10:44:00 +0000 Subject: [PATCH 128/217] finishing touches, move fixed ICEs to ui tests --- .../src/solve/normalizes_to/mod.rs | 4 +- .../src/solve/trait_goals.rs | 4 +- .../ui/missing_const_for_fn/could_be_const.rs | 3 ++ .../could_be_const.stderr | 20 ++++++---- tests/crashes/119717.rs | 10 ----- tests/crashes/123664.rs | 4 -- tests/crashes/124857.rs | 11 ------ tests/crashes/126148.rs | 23 ----------- tests/rustdoc/rfc-2632-const-trait-impl.rs | 3 +- .../assoc-type-const-bound-usage-1.stderr | 8 ++-- .../assoc-type.stderr | 2 +- .../ice-119717-constant-lifetime.rs | 15 ++++++++ .../ice-119717-constant-lifetime.stderr | 33 ++++++++++++++++ .../ice-123664-unexpected-bound-var.rs | 7 ++++ .../ice-123664-unexpected-bound-var.stderr | 8 ++++ ...-124857-combine-effect-const-infer-vars.rs | 14 +++++++ ...857-combine-effect-const-infer-vars.stderr | 12 ++++++ .../ice-126148-failed-to-normalize.rs | 28 ++++++++++++++ .../ice-126148-failed-to-normalize.stderr | 38 +++++++++++++++++++ 19 files changed, 182 insertions(+), 65 deletions(-) delete mode 100644 tests/crashes/119717.rs delete mode 100644 tests/crashes/123664.rs delete mode 100644 tests/crashes/124857.rs delete mode 100644 tests/crashes/126148.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 55c0440a53715..7a81c210c5d04 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -877,7 +877,7 @@ where let mut first_non_maybe = None; let mut non_maybe_count = 0; - for ty in types { + for ty in types.iter() { if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) { first_non_maybe.get_or_insert(ty); non_maybe_count += 1; @@ -902,7 +902,7 @@ where _ => { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 73ae1c4b11359..08ed729b14405 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -717,7 +717,7 @@ where let cx = ecx.cx(); let maybe_count = types - .into_iter() + .iter() .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty)) .filter(|&ty| ty == ty::EffectKind::Maybe) .count(); @@ -727,7 +727,7 @@ where if types.len() - maybe_count > 1 { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs index 58e639cc7fd1f..5e4e2c58e5a4d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8999af761e314..8ba42c0e5b673 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -157,7 +157,13 @@ LL | const fn msrv_1_46() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:122:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:117:1 + | +LL | fn d(this: D) {} + | ^^^^^^^^^^^^^^^^ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 | LL | / fn deref_ptr_can_be_const(self) -> usize { LL | | @@ -171,7 +177,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:127:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:130:9 | LL | / fn deref_copied_val(self) -> usize { LL | | @@ -185,7 +191,7 @@ LL | const fn deref_copied_val(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:138:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:141:5 | LL | / fn union_access_can_be_const() { LL | | @@ -200,7 +206,7 @@ LL | const fn union_access_can_be_const() { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:155:9 | LL | / pub fn new(strings: Vec) -> Self { LL | | Self { strings } @@ -213,7 +219,7 @@ LL | pub const fn new(strings: Vec) -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:157:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:160:9 | LL | / pub fn empty() -> Self { LL | | Self { strings: Vec::new() } @@ -226,7 +232,7 @@ LL | pub const fn empty() -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:168:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:171:9 | LL | / pub fn new(text: String) -> Self { LL | | let vec = Vec::new(); @@ -239,5 +245,5 @@ help: make the function `const` LL | pub const fn new(text: String) -> Self { | +++++ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/crashes/119717.rs b/tests/crashes/119717.rs deleted file mode 100644 index 22746548e02cb..0000000000000 --- a/tests/crashes/119717.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #119717 -#![feature(const_trait_impl, effects)] - -use std::ops::{FromResidual, Try}; - -impl const FromResidual for T { - fn from_residual(t: T) -> _ { - t - } -} diff --git a/tests/crashes/123664.rs b/tests/crashes/123664.rs deleted file mode 100644 index 80c415fe07bd7..0000000000000 --- a/tests/crashes/123664.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #123664 -#![feature(generic_const_exprs, effects)] -const fn with_positive() {} -pub fn main() {} diff --git a/tests/crashes/124857.rs b/tests/crashes/124857.rs deleted file mode 100644 index 4b952fd64ccfb..0000000000000 --- a/tests/crashes/124857.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#124857 -//@ compile-flags: -Znext-solver=coherence - -#![feature(effects)] - -#[const_trait] -trait Foo {} - -impl const Foo for i32 {} - -impl const Foo for T where T: ~const Foo {} diff --git a/tests/crashes/126148.rs b/tests/crashes/126148.rs deleted file mode 100644 index 79f8887b40154..0000000000000 --- a/tests/crashes/126148.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: rust-lang/rust#126148 - -#![feature(effects)] -use std::ops::{FromResidual, Try}; - -struct TryMe; -struct Error; - -impl const FromResidual for TryMe {} - -impl const Try for TryMe { - type Output = (); - type Residual = Error; -} - -const fn t() -> TryMe { - TryMe?; - TryMe -} - -const _: () = { - t(); -}; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index f6a5555dbadd0..eb3e00af3b0b5 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -8,7 +8,8 @@ // // FIXME(effects) add `const_trait` to `Fn` so we use `~const` // FIXME(effects) restore `const_trait` to `Destruct` -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #![crate_name = "foo"] use std::marker::Destruct; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index f8bab2d4c27fa..48855d64b58a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 + --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 | LL | fn unqualified() -> Type<{ T::Assoc::func() }> { | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` @@ -14,13 +14,13 @@ LL | fn func() -> i32; | ---- required by a bound in this associated function error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 | LL | fn qualified() -> Type<{ ::Assoc::func() }> { | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 333215adef217..1862339cddc5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type.rs:40:15 + --> $DIR/assoc-type.rs:41:15 | LL | type Qux: Add; | ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs new file mode 100644 index 0000000000000..c2f452a9925c6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs @@ -0,0 +1,15 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2)] + +use std::ops::FromResidual; + +impl const FromResidual for T { + //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + //~| type parameter `T` must be used as the type parameter for some local type + fn from_residual(t: T) -> _ { + //~^ the placeholder `_` is not allowed + t + } +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr new file mode 100644 index 0000000000000..9e22422ad3b94 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr @@ -0,0 +1,33 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-119717-constant-lifetime.rs:6:15 + | +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/ice-119717-constant-lifetime.rs:6:6 + | +LL | impl const FromResidual for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/ice-119717-constant-lifetime.rs:9:31 + | +LL | fn from_residual(t: T) -> _ { + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn from_residual(t: T) -> T { + | ~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0121, E0210. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs new file mode 100644 index 0000000000000..64634e7b7ac30 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs @@ -0,0 +1,7 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs, const_trait_impl, effects)] + +const fn with_positive() {} +//~^ ERROR `~const` can only be applied to `#[const_trait]` traits + +pub fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr new file mode 100644 index 0000000000000..19369e38964f4 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -0,0 +1,8 @@ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 + | +LL | const fn with_positive() {} + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs new file mode 100644 index 0000000000000..d4fcbfb1b83e6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Znext-solver=coherence + +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] + +#[const_trait] +trait Foo {} + +impl const Foo for i32 {} + +impl const Foo for T where T: ~const Foo {} +//~^ ERROR conflicting implementations of trait `Foo` for type `i32` + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr new file mode 100644 index 0000000000000..0b1f8b40898e3 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `i32` + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 + | +LL | impl const Foo for i32 {} + | ---------------------- first implementation here +LL | +LL | impl const Foo for T where T: ~const Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs new file mode 100644 index 0000000000000..717c0e7c08829 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs @@ -0,0 +1,28 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2, const_try)] +use std::ops::{FromResidual, Try}; + +struct TryMe; +struct Error; + +impl const FromResidual for TryMe {} +//~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +//~| ERROR not all trait items implemented + +impl const Try for TryMe { + //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` + //~| ERROR not all trait items implemented + type Output = (); + type Residual = Error; +} + +const fn t() -> TryMe { + TryMe?; + TryMe +} + +const _: () = { + t(); +}; + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr new file mode 100644 index 0000000000000..e641b457ef9c8 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr @@ -0,0 +1,38 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:8:12 + | +LL | impl const FromResidual for TryMe {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0046]: not all trait items implemented, missing: `from_residual` + --> $DIR/ice-126148-failed-to-normalize.rs:8:1 + | +LL | impl const FromResidual for TryMe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_residual` in implementation + | + = help: implement the missing item: `fn from_residual(_: Error) -> Self { todo!() }` + +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:12:12 + | +LL | impl const Try for TryMe { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0046]: not all trait items implemented, missing: `from_output`, `branch` + --> $DIR/ice-126148-failed-to-normalize.rs:12:1 + | +LL | impl const Try for TryMe { + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_output`, `branch` in implementation + | + = help: implement the missing item: `fn from_output(_: ::Output) -> Self { todo!() }` + = help: implement the missing item: `fn branch(self) -> ControlFlow<::Residual, ::Output> { todo!() }` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0046`. From cc05efe29e7184efa127d235d00be6ec2332d123 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:50:15 +0000 Subject: [PATCH 129/217] Introduce UnwindModule wrapper around a Module and UnwindContext This way all UnwindContext::add_function calls can be done automatically in a single place. --- src/allocator.rs | 10 +--- src/base.rs | 3 -- src/common.rs | 2 - src/driver/aot.rs | 31 +++++------- src/driver/jit.rs | 50 ++++++------------- src/inline_asm.rs | 16 +----- src/lib.rs | 13 +---- src/main_shim.rs | 6 +-- src/unwind_module.rs | 115 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 148 insertions(+), 98 deletions(-) create mode 100644 src/unwind_module.rs diff --git a/src/allocator.rs b/src/allocator.rs index e8af3e8c2555f..0d01cfd32395d 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -11,15 +11,10 @@ use rustc_session::config::OomStrategy; use crate::prelude::*; /// Returns whether an allocator shim was created -pub(crate) fn codegen( - tcx: TyCtxt<'_>, - module: &mut impl Module, - unwind_context: &mut UnwindContext, -) -> bool { +pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; codegen_inner( module, - unwind_context, kind, tcx.alloc_error_handler_kind(()).unwrap(), tcx.sess.opts.unstable_opts.oom, @@ -29,7 +24,6 @@ pub(crate) fn codegen( fn codegen_inner( module: &mut impl Module, - unwind_context: &mut UnwindContext, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, @@ -67,7 +61,6 @@ fn codegen_inner( }; crate::common::create_wrapper_function( module, - unwind_context, sig, &global_fn_name(method.name), &default_fn_name(method.name), @@ -82,7 +75,6 @@ fn codegen_inner( }; crate::common::create_wrapper_function( module, - unwind_context, sig, "__rust_alloc_error_handler", &alloc_error_handler_name(alloc_error_handler_kind), diff --git a/src/base.rs b/src/base.rs index 6c7f75f41d5ff..c5b4277015a9e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -249,9 +249,7 @@ pub(crate) fn compile_fn( } // Define debuginfo for function - let isa = module.isa(); let debug_context = &mut cx.debug_context; - let unwind_context = &mut cx.unwind_context; cx.profiler.generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { codegened_func.func_debug_cx.unwrap().finalize( @@ -260,7 +258,6 @@ pub(crate) fn compile_fn( context, ); } - unwind_context.add_function(codegened_func.func_id, &context, isa); }); } diff --git a/src/common.rs b/src/common.rs index 817498b195690..0931713993691 100644 --- a/src/common.rs +++ b/src/common.rs @@ -247,7 +247,6 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool { pub(crate) fn create_wrapper_function( module: &mut dyn Module, - unwind_context: &mut UnwindContext, sig: Signature, wrapper_name: &str, callee_name: &str, @@ -280,7 +279,6 @@ pub(crate) fn create_wrapper_function( bcx.finalize(); } module.define_function(wrapper_func_id, &mut ctx).unwrap(); - unwind_context.add_function(wrapper_func_id, &ctx, module.isa()); } pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { diff --git a/src/driver/aot.rs b/src/driver/aot.rs index dcafac21bc742..763d9a484077e 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -26,6 +26,7 @@ use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; use crate::debuginfo::TypeDebugContext; use crate::global_asm::GlobalAsmConfig; +use crate::unwind_module::UnwindModule; use crate::{prelude::*, BackendConfig}; struct ModuleCodegenResult { @@ -318,7 +319,11 @@ fn produce_final_output_artifacts( // These are used in linking steps and will be cleaned up afterward. } -fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule { +fn make_module( + sess: &Session, + backend_config: &BackendConfig, + name: String, +) -> UnwindModule { let isa = crate::build_isa(sess, backend_config); let mut builder = @@ -327,16 +332,15 @@ fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> // is important, while cg_clif cares more about compilation times. Enabling -Zfunction-sections // can easily double the amount of time necessary to perform linking. builder.per_function_section(sess.opts.unstable_opts.function_sections.unwrap_or(false)); - ObjectModule::new(builder) + UnwindModule::new(ObjectModule::new(builder), true) } fn emit_cgu( output_filenames: &OutputFilenames, prof: &SelfProfilerRef, name: String, - module: ObjectModule, + module: UnwindModule, debug: Option, - unwind_context: UnwindContext, global_asm_object_file: Option, producer: &str, ) -> Result { @@ -346,8 +350,6 @@ fn emit_cgu( debug.emit(&mut product); } - unwind_context.emit(&mut product); - let module_regular = emit_module( output_filenames, prof, @@ -494,7 +496,6 @@ fn module_codegen( let mut cx = crate::CodegenCx::new( tcx, - backend_config.clone(), module.isa(), tcx.sess.opts.debuginfo != DebugInfo::None, cgu_name, @@ -531,13 +532,7 @@ fn module_codegen( } } } - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut module, - &mut cx.unwind_context, - false, - cgu.is_primary(), - ); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, false, cgu.is_primary()); let cgu_name = cgu.name().as_str().to_owned(); @@ -571,7 +566,6 @@ fn module_codegen( cgu_name, module, cx.debug_context, - cx.unwind_context, global_asm_object_file, &producer, ) @@ -665,13 +659,10 @@ pub(crate) fn run_aot( }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); - let mut allocator_unwind_context = UnwindContext::new(allocator_module.isa(), true); - let created_alloc_shim = - crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context); + let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module); let allocator_module = if created_alloc_shim { - let mut product = allocator_module.finish(); - allocator_unwind_context.emit(&mut product); + let product = allocator_module.finish(); match emit_module( tcx.output_filenames(()), diff --git a/src/driver/jit.rs b/src/driver/jit.rs index ae0e45ae5312b..dfee8e714e64a 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -14,12 +14,12 @@ use rustc_session::Session; use rustc_span::Symbol; use crate::debuginfo::TypeDebugContext; +use crate::unwind_module::UnwindModule; use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; struct JitState { - backend_config: BackendConfig, - jit_module: JITModule, + jit_module: UnwindModule, } thread_local! { @@ -63,7 +63,7 @@ fn create_jit_module( tcx: TyCtxt<'_>, backend_config: &BackendConfig, hotswap: bool, -) -> (JITModule, CodegenCx) { +) -> (UnwindModule, CodegenCx) { let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let isa = crate::build_isa(tcx.sess, backend_config); @@ -72,17 +72,11 @@ fn create_jit_module( crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8); - let mut jit_module = JITModule::new(jit_builder); + let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); - let mut cx = crate::CodegenCx::new( - tcx, - backend_config.clone(), - jit_module.isa(), - false, - Symbol::intern("dummy_cgu_name"), - ); + let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, Symbol::intern("dummy_cgu_name")); - crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); + crate::allocator::codegen(tcx, &mut jit_module); (jit_module, cx) } @@ -128,7 +122,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { ); } CodegenMode::JitLazy => { - codegen_shim(tcx, &mut cx, &mut cached_context, &mut jit_module, inst) + codegen_shim(tcx, &mut cached_context, &mut jit_module, inst) } }, MonoItem::Static(def_id) => { @@ -146,18 +140,11 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, true, true); tcx.dcx().abort_if_errors(); - jit_module.finalize_definitions().unwrap(); - unsafe { cx.unwind_context.register_jit(&jit_module) }; + jit_module.finalize_definitions(); println!( "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" @@ -177,12 +164,12 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { call_conv: jit_module.target_config().default_call_conv, }; let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap(); - let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id); + let finalized_start: *const u8 = jit_module.module.get_finalized_function(start_func_id); LAZY_JIT_STATE.with(|lazy_jit_state| { let mut lazy_jit_state = lazy_jit_state.borrow_mut(); assert!(lazy_jit_state.is_none()); - *lazy_jit_state = Some(JitState { backend_config, jit_module }); + *lazy_jit_state = Some(JitState { jit_module }); }); let f: extern "C" fn(c_int, *const *const c_char) -> c_int = @@ -268,7 +255,6 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> let mut lazy_jit_state = lazy_jit_state.borrow_mut(); let lazy_jit_state = lazy_jit_state.as_mut().unwrap(); let jit_module = &mut lazy_jit_state.jit_module; - let backend_config = lazy_jit_state.backend_config.clone(); let name = tcx.symbol_name(instance).name; let sig = crate::abi::get_function_sig( @@ -278,7 +264,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> ); let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap(); - let current_ptr = jit_module.read_got_entry(func_id); + let current_ptr = jit_module.module.read_got_entry(func_id); // If the function's GOT entry has already been updated to point at something other // than the shim trampoline, don't re-jit but just return the new pointer instead. @@ -288,11 +274,10 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> return current_ptr; } - jit_module.prepare_for_function_redefine(func_id).unwrap(); + jit_module.module.prepare_for_function_redefine(func_id).unwrap(); let mut cx = crate::CodegenCx::new( tcx, - backend_config, jit_module.isa(), false, Symbol::intern("dummy_cgu_name"), @@ -300,9 +285,8 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance); assert!(cx.global_asm.is_empty()); - jit_module.finalize_definitions().unwrap(); - unsafe { cx.unwind_context.register_jit(&jit_module) }; - jit_module.get_finalized_function(func_id) + jit_module.finalize_definitions(); + jit_module.module.get_finalized_function(func_id) }) }) } @@ -362,9 +346,8 @@ fn dep_symbol_lookup_fn( fn codegen_shim<'tcx>( tcx: TyCtxt<'tcx>, - cx: &mut CodegenCx, cached_context: &mut Context, - module: &mut JITModule, + module: &mut UnwindModule, inst: Instance<'tcx>, ) { let pointer_type = module.target_config().pointer_type(); @@ -413,5 +396,4 @@ fn codegen_shim<'tcx>( trampoline_builder.ins().return_(&ret_vals); module.define_function(func_id, context).unwrap(); - cx.unwind_context.add_function(func_id, context, module.isa()); } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index c6b26dd873bdc..c88230c936056 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -113,13 +113,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( ); let sig = get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); - create_wrapper_function( - fx.module, - &mut fx.cx.unwind_context, - sig, - &wrapper_name, - symbol.name, - ); + create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); CInlineAsmOperand::Symbol { symbol: wrapper_name } } else { @@ -283,13 +277,7 @@ pub(crate) fn codegen_naked_asm<'tcx>( ); let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); - create_wrapper_function( - module, - &mut cx.unwind_context, - sig, - &wrapper_name, - symbol.name, - ); + create_wrapper_function(module, sig, &wrapper_name, symbol.name); CInlineAsmOperand::Symbol { symbol: wrapper_name } } else { diff --git a/src/lib.rs b/src/lib.rs index 22c723e1a79b4..192e6c91ea38b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,6 +79,7 @@ mod pretty_clif; mod toolchain; mod trap; mod unsize; +mod unwind_module; mod value_and_place; mod vtable; @@ -130,22 +131,13 @@ struct CodegenCx { global_asm: String, inline_asm_index: Cell, debug_context: Option, - unwind_context: UnwindContext, cgu_name: Symbol, } impl CodegenCx { - fn new( - tcx: TyCtxt<'_>, - backend_config: BackendConfig, - isa: &dyn TargetIsa, - debug_info: bool, - cgu_name: Symbol, - ) -> Self { + fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol) -> Self { assert_eq!(pointer_ty(tcx), isa.pointer_type()); - let unwind_context = - UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot)); let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { Some(DebugContext::new(tcx, isa, cgu_name.as_str())) } else { @@ -158,7 +150,6 @@ impl CodegenCx { global_asm: String::new(), inline_asm_index: Cell::new(0), debug_context, - unwind_context, cgu_name, } } diff --git a/src/main_shim.rs b/src/main_shim.rs index f9a729618a51a..3e85abde14ee5 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -12,7 +12,6 @@ use crate::prelude::*; pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, module: &mut impl Module, - unwind_context: &mut UnwindContext, is_jit: bool, is_primary_cgu: bool, ) { @@ -36,12 +35,11 @@ pub(crate) fn maybe_create_entry_wrapper( return; } - create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn, sigpipe); + create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe); fn create_entry_fn( tcx: TyCtxt<'_>, m: &mut impl Module, - unwind_context: &mut UnwindContext, rust_main_def_id: DefId, ignore_lang_start_wrapper: bool, is_main_fn: bool, @@ -170,7 +168,5 @@ pub(crate) fn maybe_create_entry_wrapper( if let Err(err) = m.define_function(cmain_func_id, &mut ctx) { tcx.dcx().fatal(format!("entry symbol `{entry_name}` defined multiple times: {err}")); } - - unwind_context.add_function(cmain_func_id, &ctx, m.isa()); } } diff --git a/src/unwind_module.rs b/src/unwind_module.rs new file mode 100644 index 0000000000000..b950aaa29ce04 --- /dev/null +++ b/src/unwind_module.rs @@ -0,0 +1,115 @@ +use cranelift_codegen::control::ControlPlane; +use cranelift_codegen::ir::{Function, Signature}; +use cranelift_codegen::isa::{TargetFrontendConfig, TargetIsa}; +use cranelift_codegen::{Context, FinalizedMachReloc}; +use cranelift_module::{ + DataDescription, DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleDeclarations, + ModuleResult, +}; +use cranelift_object::{ObjectModule, ObjectProduct}; + +use crate::UnwindContext; + +/// A wrapper around a [Module] which adds any defined function to the [UnwindContext]. +pub(crate) struct UnwindModule { + pub(crate) module: T, + unwind_context: UnwindContext, +} + +impl UnwindModule { + pub(crate) fn new(module: T, pic_eh_frame: bool) -> Self { + let unwind_context = UnwindContext::new(module.isa(), pic_eh_frame); + UnwindModule { module, unwind_context } + } +} + +impl UnwindModule { + pub(crate) fn finish(self) -> ObjectProduct { + let mut product = self.module.finish(); + self.unwind_context.emit(&mut product); + product + } +} + +#[cfg(feature = "jit")] +impl UnwindModule { + pub(crate) fn finalize_definitions(&mut self) { + self.module.finalize_definitions().unwrap(); + let prev_unwind_context = std::mem::replace( + &mut self.unwind_context, + UnwindContext::new(self.module.isa(), false), + ); + unsafe { prev_unwind_context.register_jit(&self.module) }; + } +} + +impl Module for UnwindModule { + fn isa(&self) -> &dyn TargetIsa { + self.module.isa() + } + + fn declarations(&self) -> &ModuleDeclarations { + self.module.declarations() + } + + fn get_name(&self, name: &str) -> Option { + self.module.get_name(name) + } + + fn target_config(&self) -> TargetFrontendConfig { + self.module.target_config() + } + + fn declare_function( + &mut self, + name: &str, + linkage: Linkage, + signature: &Signature, + ) -> ModuleResult { + self.module.declare_function(name, linkage, signature) + } + + fn declare_anonymous_function(&mut self, signature: &Signature) -> ModuleResult { + self.module.declare_anonymous_function(signature) + } + + fn declare_data( + &mut self, + name: &str, + linkage: Linkage, + writable: bool, + tls: bool, + ) -> ModuleResult { + self.module.declare_data(name, linkage, writable, tls) + } + + fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult { + self.module.declare_anonymous_data(writable, tls) + } + + fn define_function_with_control_plane( + &mut self, + func: FuncId, + ctx: &mut Context, + ctrl_plane: &mut ControlPlane, + ) -> ModuleResult<()> { + self.module.define_function_with_control_plane(func, ctx, ctrl_plane)?; + self.unwind_context.add_function(func, ctx, self.module.isa()); + Ok(()) + } + + fn define_function_bytes( + &mut self, + _func_id: FuncId, + _func: &Function, + _alignment: u64, + _bytes: &[u8], + _relocs: &[FinalizedMachReloc], + ) -> ModuleResult<()> { + unimplemented!() + } + + fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> { + self.module.define_data(data_id, data) + } +} From e97cebb2b121038d5255257993b936c909f5cc05 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:21:42 +0000 Subject: [PATCH 130/217] Use dyn Module instead of impl Module where possible --- src/allocator.rs | 4 ++-- src/main_shim.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 0d01cfd32395d..b4a3825e9965f 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -11,7 +11,7 @@ use rustc_session::config::OomStrategy; use crate::prelude::*; /// Returns whether an allocator shim was created -pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { +pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; codegen_inner( module, @@ -23,7 +23,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { } fn codegen_inner( - module: &mut impl Module, + module: &mut dyn Module, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, diff --git a/src/main_shim.rs b/src/main_shim.rs index 3e85abde14ee5..33d3f9b8a90a3 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -11,7 +11,7 @@ use crate::prelude::*; /// users main function. pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, - module: &mut impl Module, + module: &mut dyn Module, is_jit: bool, is_primary_cgu: bool, ) { @@ -39,7 +39,7 @@ pub(crate) fn maybe_create_entry_wrapper( fn create_entry_fn( tcx: TyCtxt<'_>, - m: &mut impl Module, + m: &mut dyn Module, rust_main_def_id: DefId, ignore_lang_start_wrapper: bool, is_main_fn: bool, From 90c2b238e6a38e3309a7ffc1162e6361db14ffdd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 19:54:28 -0400 Subject: [PATCH 131/217] Failing test for computing drop shim that has const param --- .../const-generics/polymorphic-drop-shim.rs | 21 ++ .../polymorphic-drop-shim.stderr | 257 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 tests/ui/const-generics/polymorphic-drop-shim.rs create mode 100644 tests/ui/const-generics/polymorphic-drop-shim.stderr diff --git a/tests/ui/const-generics/polymorphic-drop-shim.rs b/tests/ui/const-generics/polymorphic-drop-shim.rs new file mode 100644 index 0000000000000..97ade9fe69a30 --- /dev/null +++ b/tests/ui/const-generics/polymorphic-drop-shim.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Zinline-mir=yes --crate-type=lib + +//@ known-bug: unknown +//@ build-fail +//@ failure-status: 101 + +use std::mem::ManuallyDrop; + +pub struct Foo([T; N]); + +pub struct Dorp {} + +impl Drop for Dorp { + fn drop(&mut self) {} +} + +#[inline] +// SAFETY: call this with a valid allocation idk +pub unsafe fn drop(x: *mut Foo) { + std::ptr::drop_in_place(x); +} diff --git a/tests/ui/const-generics/polymorphic-drop-shim.stderr b/tests/ui/const-generics/polymorphic-drop-shim.stderr new file mode 100644 index 0000000000000..3a445a524097d --- /dev/null +++ b/tests/ui/const-generics/polymorphic-drop-shim.stderr @@ -0,0 +1,257 @@ +thread 'rustc' panicked at compiler/rustc_middle/src/ty/sty.rs:360:36: +called `Option::unwrap()` on a `None` value +stack backtrace: + 0: begin_panic_handler + at ./library/std/src/panicking.rs:661:5 + 1: panic_fmt + at ./library/core/src/panicking.rs:74:14 + 2: panic + at ./library/core/src/panicking.rs:148:5 + 3: core::option::unwrap_failed + at ./library/core/src/option.rs:2013:5 + 4: unwrap + at ./library/core/src/option.rs:963:21 + 5: find_ty_from_env + at ./compiler/rustc_middle/src/ty/sty.rs:360:18 + 6: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1016:29 + 7: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 + 8: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at ./compiler/rustc_data_structures/src/stack.rs:17:5 + 9: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 + 10: evaluate_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 + 11: evaluate_predicates_recursively, alloc::alloc::Global>> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:631:24 + 12: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1317:21 + 13: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 + 14: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> + at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 + 15: ::evaluation_probe::<::evaluate_candidate::{closure#0}::{closure#0}> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:594:9 + 16: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1298:26 + 17: evaluate_candidate + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1286:5 + 18: evaluate_stack + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1257:28 + 19: {closure#1} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1083:30 + 20: {closure#0}> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:88 + 21: with_anon_task>, core::result::Result> + at ./compiler/rustc_query_system/src/dep_graph/graph.rs:306:22 + 22: in_task> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:13 + 23: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1082:34 + 24: evaluate_trait_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1037:5 + 25: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:671:21 + 26: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 + 27: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at ./compiler/rustc_data_structures/src/stack.rs:17:5 + 28: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 + 29: evaluate_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 + 30: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:572:30 + 31: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 + 32: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> + at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 + 33: evaluate_obligation + at ./compiler/rustc_traits/src/evaluate_obligation.rs:29:5 + 34: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 35: query_get_at>, rustc_middle::query::erase::Erased<[u8; 2]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 36: evaluate_obligation + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 37: evaluate_obligation + at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:93:13 + 38: evaluate_obligation_no_overflow + at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:107:15 + 39: {closure#0}> + at ./compiler/rustc_trait_selection/src/traits/mod.rs:221:18 + 40: pred_known_to_hold_modulo_regions> + at ./compiler/rustc_trait_selection/src/traits/mod.rs:213:1 + 41: rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions + at ./compiler/rustc_trait_selection/src/traits/mod.rs:206:5 + 42: rustc_ty_utils::common_traits::is_item_raw + at ./compiler/rustc_ty_utils/src/common_traits.rs:33:5 + 43: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 44: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 45: is_copy_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 46: is_copy_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 47: is_copy_modulo_regions + at ./compiler/rustc_middle/src/ty/util.rs:1243:48 + 48: next, alloc::vec::into_iter::IntoIter> + at ./compiler/rustc_ty_utils/src/needs_drop.rs:184:26 + 49: try_fold>, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}>, core::ops::control_flow::ControlFlow, ()>> + at ./library/core/src/iter/traits/iterator.rs:2409:29 + 50: find>, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> + at ./library/core/src/iter/traits/iterator.rs:2880:9 + 51: next>, rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> + at ./library/core/src/iter/adapters/filter.rs:96:9 + 52: needs_drop_raw + at ./compiler/rustc_ty_utils/src/needs_drop.rs:24:15 + 53: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 54: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 55: needs_drop_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 56: needs_drop_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 57: needs_drop + at ./compiler/rustc_middle/src/ty/util.rs:1433:17 + 58: {closure#0} + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:378:13 + 59: {closure#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> + at ./library/alloc/src/vec/mod.rs:1683:32 + 60: process_loop), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>, (rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, false> + at ./library/alloc/src/vec/mod.rs:1763:21 + 61: retain_mut<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, alloc::vec::{impl#1}::retain::{closure_env#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>> + at ./library/alloc/src/vec/mod.rs:1789:9 + 62: retain<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> + at ./library/alloc/src/vec/mod.rs:1683:9 + 63: drop_ladder + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:377:9 + 64: open_drop_for_adt_contents + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:488:13 + 65: {closure#0} + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:461:13 + 66: open_drop_for_adt + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:440:5 + 67: open_drop + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:869:35 + 68: elaborate_drop + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:253:31 + 69: rustc_mir_dataflow::elaborate_drops::elaborate_drop:: + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:192:5 + 70: build_drop_shim + at ./compiler/rustc_mir_transform/src/shim.rs:283:13 + 71: make_shim + at ./compiler/rustc_mir_transform/src/shim.rs:128:13 + 72: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 73: query_get_at>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 74: mir_shims + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 75: mir_shims + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 76: instance_mir + at ./compiler/rustc_middle/src/ty/mod.rs:1738:62 + 77: try_instance_mir + at ./compiler/rustc_mir_transform/src/inline.rs:1082:8 + 78: try_inlining + at ./compiler/rustc_mir_transform/src/inline.rs:194:27 + 79: process_blocks + at ./compiler/rustc_mir_transform/src/inline.rs:139:19 + 80: inline + at ./compiler/rustc_mir_transform/src/inline.rs:97:5 + 81: run_pass + at ./compiler/rustc_mir_transform/src/inline.rs:62:12 + 82: run_passes_inner + at ./compiler/rustc_mir_transform/src/pass_manager.rs:144:17 + 83: rustc_mir_transform::pass_manager::run_passes + at ./compiler/rustc_mir_transform/src/pass_manager.rs:87:5 + 84: run_optimization_passes + at ./compiler/rustc_mir_transform/src/lib.rs:561:5 + 85: inner_optimized_mir + at ./compiler/rustc_mir_transform/src/lib.rs:667:5 + 86: optimized_mir + at ./compiler/rustc_mir_transform/src/lib.rs:630:21 + 87: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:285:13 + [... omitted 22 frames ...] + 88: query_get_at>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 89: optimized_mir + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 90: optimized_mir + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 91: encode_mir + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1656:74 + 92: {closure#15} + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:639:29 + 93: encode_crate_root + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:600:27 + 94: encode_metadata + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2269:16 + 95: encode_and_write_metadata + at ./compiler/rustc_metadata/src/fs.rs:65:13 + 96: start_codegen + at ./compiler/rustc_interface/src/passes.rs:1024:44 + 97: {closure#0} + at ./compiler/rustc_interface/src/queries.rs:122:35 + 98: {closure#1}> + at ./compiler/rustc_middle/src/ty/context.rs:1288:37 + 99: {closure#0}>, core::result::Result> + at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9 + 100: try_with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> + at ./library/std/src/thread/local.rs:283:12 + 101: with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> + at ./library/std/src/thread/local.rs:260:9 + 102: enter_context>, core::result::Result> + at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5 + 103: enter> + at ./compiler/rustc_middle/src/ty/context.rs:1288:9 + 104: >::enter::, ::codegen_and_build_linker::{closure#0}> + at ./compiler/rustc_interface/src/queries.rs:64:9 + 105: codegen_and_build_linker + at ./compiler/rustc_interface/src/queries.rs:121:9 + 106: {closure#1} + at ./compiler/rustc_driver_impl/src/lib.rs:451:26 + 107: enter, rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/queries.rs:202:19 + 108: {closure#0} + at ./compiler/rustc_driver_impl/src/lib.rs:389:22 + 109: {closure#1}, rustc_driver_impl::run_compiler::{closure_env#0}> + at ./compiler/rustc_interface/src/interface.rs:502:27 + 110: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:154:13 + 111: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:106:21 + 112: set, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9 + 113: create_session_globals_then, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>> + at ./compiler/rustc_span/src/lib.rs:134:5 + 114: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:105:17 +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + +error: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md + +note: please make sure that you have updated to the latest nightly + +note: rustc 1.81.0-dev running on x86_64-unknown-linux-gnu + +note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/programming/rust2/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 -Z inline-mir=yes --crate-type lib + +query stack during panic: +#0 [evaluate_obligation] evaluating trait selection obligation `[Dorp; M]: core::marker::Copy` +#1 [is_copy_raw] computing whether `[Dorp; M]` is `Copy` +#2 [needs_drop_raw] computing whether `[Dorp; M]` needs drop +#3 [mir_shims] generating MIR shim for `core::ptr::drop_in_place` +#4 [optimized_mir] optimizing MIR for `drop` +end of query stack From f17b27b3014adea0c40df55b31bd2fbbd72e76c4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 10:18:13 -0400 Subject: [PATCH 132/217] Don't inline drop shims with unsubstituted generic consts in MIR inliner --- compiler/rustc_mir_transform/src/inline.rs | 12 +- .../const-generics/polymorphic-drop-shim.rs | 5 +- .../polymorphic-drop-shim.stderr | 257 ------------------ 3 files changed, 12 insertions(+), 262 deletions(-) delete mode 100644 tests/ui/const-generics/polymorphic-drop-shim.stderr diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 0a5fc697d0321..07482d0571a2f 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -11,7 +11,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TypeVisitableExt; -use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags}; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::source_map::Spanned; use rustc_span::sym; @@ -306,6 +306,16 @@ impl<'tcx> Inliner<'tcx> { InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => { return Err("instance without MIR (intrinsic / virtual)"); } + + // FIXME(#127030): `ConstParamHasTy` has bad interactions with + // the drop shim builder, which does not evaluate predicates in + // the correct param-env for types being dropped. Stall resolving + // the MIR for this instance until all of its const params are + // substituted. + InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { + return Err("still needs substitution"); + } + // This cannot result in an immediate cycle since the callee MIR is a shim, which does // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue diff --git a/tests/ui/const-generics/polymorphic-drop-shim.rs b/tests/ui/const-generics/polymorphic-drop-shim.rs index 97ade9fe69a30..4ca2e86cff915 100644 --- a/tests/ui/const-generics/polymorphic-drop-shim.rs +++ b/tests/ui/const-generics/polymorphic-drop-shim.rs @@ -1,8 +1,5 @@ //@ compile-flags: -Zinline-mir=yes --crate-type=lib - -//@ known-bug: unknown -//@ build-fail -//@ failure-status: 101 +//@ build-pass use std::mem::ManuallyDrop; diff --git a/tests/ui/const-generics/polymorphic-drop-shim.stderr b/tests/ui/const-generics/polymorphic-drop-shim.stderr deleted file mode 100644 index 3a445a524097d..0000000000000 --- a/tests/ui/const-generics/polymorphic-drop-shim.stderr +++ /dev/null @@ -1,257 +0,0 @@ -thread 'rustc' panicked at compiler/rustc_middle/src/ty/sty.rs:360:36: -called `Option::unwrap()` on a `None` value -stack backtrace: - 0: begin_panic_handler - at ./library/std/src/panicking.rs:661:5 - 1: panic_fmt - at ./library/core/src/panicking.rs:74:14 - 2: panic - at ./library/core/src/panicking.rs:148:5 - 3: core::option::unwrap_failed - at ./library/core/src/option.rs:2013:5 - 4: unwrap - at ./library/core/src/option.rs:963:21 - 5: find_ty_from_env - at ./compiler/rustc_middle/src/ty/sty.rs:360:18 - 6: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1016:29 - 7: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 - 8: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at ./compiler/rustc_data_structures/src/stack.rs:17:5 - 9: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 - 10: evaluate_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 - 11: evaluate_predicates_recursively, alloc::alloc::Global>> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:631:24 - 12: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1317:21 - 13: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 - 14: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> - at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 - 15: ::evaluation_probe::<::evaluate_candidate::{closure#0}::{closure#0}> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:594:9 - 16: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1298:26 - 17: evaluate_candidate - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1286:5 - 18: evaluate_stack - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1257:28 - 19: {closure#1} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1083:30 - 20: {closure#0}> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:88 - 21: with_anon_task>, core::result::Result> - at ./compiler/rustc_query_system/src/dep_graph/graph.rs:306:22 - 22: in_task> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:13 - 23: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1082:34 - 24: evaluate_trait_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1037:5 - 25: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:671:21 - 26: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 - 27: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at ./compiler/rustc_data_structures/src/stack.rs:17:5 - 28: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 - 29: evaluate_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 - 30: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:572:30 - 31: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 - 32: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> - at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 - 33: evaluate_obligation - at ./compiler/rustc_traits/src/evaluate_obligation.rs:29:5 - 34: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 35: query_get_at>, rustc_middle::query::erase::Erased<[u8; 2]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 36: evaluate_obligation - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 37: evaluate_obligation - at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:93:13 - 38: evaluate_obligation_no_overflow - at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:107:15 - 39: {closure#0}> - at ./compiler/rustc_trait_selection/src/traits/mod.rs:221:18 - 40: pred_known_to_hold_modulo_regions> - at ./compiler/rustc_trait_selection/src/traits/mod.rs:213:1 - 41: rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions - at ./compiler/rustc_trait_selection/src/traits/mod.rs:206:5 - 42: rustc_ty_utils::common_traits::is_item_raw - at ./compiler/rustc_ty_utils/src/common_traits.rs:33:5 - 43: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 44: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 45: is_copy_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 46: is_copy_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 47: is_copy_modulo_regions - at ./compiler/rustc_middle/src/ty/util.rs:1243:48 - 48: next, alloc::vec::into_iter::IntoIter> - at ./compiler/rustc_ty_utils/src/needs_drop.rs:184:26 - 49: try_fold>, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}>, core::ops::control_flow::ControlFlow, ()>> - at ./library/core/src/iter/traits/iterator.rs:2409:29 - 50: find>, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> - at ./library/core/src/iter/traits/iterator.rs:2880:9 - 51: next>, rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> - at ./library/core/src/iter/adapters/filter.rs:96:9 - 52: needs_drop_raw - at ./compiler/rustc_ty_utils/src/needs_drop.rs:24:15 - 53: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 54: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 55: needs_drop_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 56: needs_drop_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 57: needs_drop - at ./compiler/rustc_middle/src/ty/util.rs:1433:17 - 58: {closure#0} - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:378:13 - 59: {closure#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> - at ./library/alloc/src/vec/mod.rs:1683:32 - 60: process_loop), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>, (rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, false> - at ./library/alloc/src/vec/mod.rs:1763:21 - 61: retain_mut<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, alloc::vec::{impl#1}::retain::{closure_env#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>> - at ./library/alloc/src/vec/mod.rs:1789:9 - 62: retain<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> - at ./library/alloc/src/vec/mod.rs:1683:9 - 63: drop_ladder - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:377:9 - 64: open_drop_for_adt_contents - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:488:13 - 65: {closure#0} - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:461:13 - 66: open_drop_for_adt - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:440:5 - 67: open_drop - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:869:35 - 68: elaborate_drop - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:253:31 - 69: rustc_mir_dataflow::elaborate_drops::elaborate_drop:: - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:192:5 - 70: build_drop_shim - at ./compiler/rustc_mir_transform/src/shim.rs:283:13 - 71: make_shim - at ./compiler/rustc_mir_transform/src/shim.rs:128:13 - 72: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 73: query_get_at>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 74: mir_shims - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 75: mir_shims - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 76: instance_mir - at ./compiler/rustc_middle/src/ty/mod.rs:1738:62 - 77: try_instance_mir - at ./compiler/rustc_mir_transform/src/inline.rs:1082:8 - 78: try_inlining - at ./compiler/rustc_mir_transform/src/inline.rs:194:27 - 79: process_blocks - at ./compiler/rustc_mir_transform/src/inline.rs:139:19 - 80: inline - at ./compiler/rustc_mir_transform/src/inline.rs:97:5 - 81: run_pass - at ./compiler/rustc_mir_transform/src/inline.rs:62:12 - 82: run_passes_inner - at ./compiler/rustc_mir_transform/src/pass_manager.rs:144:17 - 83: rustc_mir_transform::pass_manager::run_passes - at ./compiler/rustc_mir_transform/src/pass_manager.rs:87:5 - 84: run_optimization_passes - at ./compiler/rustc_mir_transform/src/lib.rs:561:5 - 85: inner_optimized_mir - at ./compiler/rustc_mir_transform/src/lib.rs:667:5 - 86: optimized_mir - at ./compiler/rustc_mir_transform/src/lib.rs:630:21 - 87: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:285:13 - [... omitted 22 frames ...] - 88: query_get_at>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 89: optimized_mir - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 90: optimized_mir - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 91: encode_mir - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1656:74 - 92: {closure#15} - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:639:29 - 93: encode_crate_root - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:600:27 - 94: encode_metadata - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2269:16 - 95: encode_and_write_metadata - at ./compiler/rustc_metadata/src/fs.rs:65:13 - 96: start_codegen - at ./compiler/rustc_interface/src/passes.rs:1024:44 - 97: {closure#0} - at ./compiler/rustc_interface/src/queries.rs:122:35 - 98: {closure#1}> - at ./compiler/rustc_middle/src/ty/context.rs:1288:37 - 99: {closure#0}>, core::result::Result> - at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9 - 100: try_with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> - at ./library/std/src/thread/local.rs:283:12 - 101: with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> - at ./library/std/src/thread/local.rs:260:9 - 102: enter_context>, core::result::Result> - at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5 - 103: enter> - at ./compiler/rustc_middle/src/ty/context.rs:1288:9 - 104: >::enter::, ::codegen_and_build_linker::{closure#0}> - at ./compiler/rustc_interface/src/queries.rs:64:9 - 105: codegen_and_build_linker - at ./compiler/rustc_interface/src/queries.rs:121:9 - 106: {closure#1} - at ./compiler/rustc_driver_impl/src/lib.rs:451:26 - 107: enter, rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/queries.rs:202:19 - 108: {closure#0} - at ./compiler/rustc_driver_impl/src/lib.rs:389:22 - 109: {closure#1}, rustc_driver_impl::run_compiler::{closure_env#0}> - at ./compiler/rustc_interface/src/interface.rs:502:27 - 110: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:154:13 - 111: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:106:21 - 112: set, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9 - 113: create_session_globals_then, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>> - at ./compiler/rustc_span/src/lib.rs:134:5 - 114: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:105:17 -note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. - -error: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md - -note: please make sure that you have updated to the latest nightly - -note: rustc 1.81.0-dev running on x86_64-unknown-linux-gnu - -note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/programming/rust2/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 -Z inline-mir=yes --crate-type lib - -query stack during panic: -#0 [evaluate_obligation] evaluating trait selection obligation `[Dorp; M]: core::marker::Copy` -#1 [is_copy_raw] computing whether `[Dorp; M]` is `Copy` -#2 [needs_drop_raw] computing whether `[Dorp; M]` needs drop -#3 [mir_shims] generating MIR shim for `core::ptr::drop_in_place` -#4 [optimized_mir] optimizing MIR for `drop` -end of query stack From c7ac9bb30910227b95eb9fb7dc8d0a31b78bdbfe Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Fri, 28 Jun 2024 15:57:14 +0800 Subject: [PATCH 133/217] Enable full tools and profiler for dist-loongarch64-{linux,musl} When the LoongArch targets were first introduced, the LLVM support was still immature and various tools were not supported on LoongArch. Nowadays most infra is in place, so it is time to enable them on LoongArch to provide a better experience for users of these targets. Plus, the profiler support is needed by Chromium, so better provide it in the official artifacts. --- .../docker/host-x86_64/dist-loongarch64-linux/Dockerfile | 7 ++++++- src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 55c737bd0aa31..7e35f781b6bb8 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -25,5 +25,10 @@ ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \ ENV HOSTS=loongarch64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs +ENV RUST_CONFIGURE_ARGS \ + --enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --disable-docs + ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 560adf971ba48..62dbfaaa67315 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -27,7 +27,8 @@ ENV HOSTS=loongarch64-unknown-linux-musl ENV RUST_CONFIGURE_ARGS \ --enable-extended \ - --enable-lld \ + --enable-full-tools \ + --enable-profiler \ --disable-docs \ --set target.loongarch64-unknown-linux-musl.crt-static=false \ --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr From acb6078d9183c41e39495ff075cd01b3d68fe967 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 20 Jun 2024 11:21:56 -0400 Subject: [PATCH 134/217] rewrite remap-path-prefix to rmake --- src/tools/run-make-support/src/rustc.rs | 11 +++++ tests/run-make/remap-path-prefix/Makefile | 30 ------------ tests/run-make/remap-path-prefix/rmake.rs | 58 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 30 deletions(-) delete mode 100644 tests/run-make/remap-path-prefix/Makefile create mode 100644 tests/run-make/remap-path-prefix/rmake.rs diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 28ece1dff128d..df843d74fc927 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -106,6 +106,17 @@ impl Rustc { self } + /// Remap source path prefixes in all output. + pub fn remap_path_prefix>(&mut self, from: P, to: P) -> &mut Self { + let from = from.as_ref().to_string_lossy(); + let to = to.as_ref().to_string_lossy(); + + self.cmd.arg("--remap-path-prefix"); + self.cmd.arg(format!("{from}={to}")); + + self + } + /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); diff --git a/tests/run-make/remap-path-prefix/Makefile b/tests/run-make/remap-path-prefix/Makefile deleted file mode 100644 index 02423dea7d26c..0000000000000 --- a/tests/run-make/remap-path-prefix/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -include ../tools.mk - -# ignore-windows - -ifeq ($(UNAME),Darwin) - DEBUGINFOOPTS := -Csplit-debuginfo=off -else - DEBUGINFOOPTS := -endif - -all: remap remap-with-scope - -# Checks if remapping works if the remap-from string contains path to the working directory plus more -remap: - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - -remap-with-scope: - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=object $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=macro $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=diagnostics,object $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs new file mode 100644 index 0000000000000..4d98dcf6131cd --- /dev/null +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -0,0 +1,58 @@ +// Generating metadata alongside remap-path-prefix would fail to actually remap the path +// in the metadata. After this was fixed in #85344, this test checks that "auxiliary" is being +// successfully remapped to "/the/aux" in the rmeta files. +// See https://github.com/rust-lang/rust/pull/85344 + +// FIXME(Oneirical): check if works without ignore-windows + +use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, is_darwin, rustc}; + +fn main() { + let mut out_simple = rustc(); + let mut out_object = rustc(); + let mut out_macro = rustc(); + let mut out_diagobj = rustc(); + out_simple + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_object + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_macro + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_diagobj + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + + out_simple.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + + out_object.arg("-Zremap-path-scope=object"); + out_macro.arg("-Zremap-path-scope=macro"); + out_diagobj.arg("-Zremap-path-scope=diagnostics,object"); + if is_darwin() { + out_object.arg("-Csplit-debuginfo=off"); + out_macro.arg("-Csplit-debuginfo=off"); + out_diagobj.arg("-Csplit-debuginfo=off"); + } + + out_object.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + out_macro.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + out_diagobj.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); +} From cb1281b76d4d90fd66bd76507e583c69625e037d Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 13:35:47 -0400 Subject: [PATCH 135/217] rewrite debug-assertions to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/debug-assertions/Makefile | 27 -------------- tests/run-make/debug-assertions/debug.rs | 9 ++--- tests/run-make/debug-assertions/rmake.rs | 37 +++++++++++++++++++ 4 files changed, 40 insertions(+), 34 deletions(-) delete mode 100644 tests/run-make/debug-assertions/Makefile create mode 100644 tests/run-make/debug-assertions/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2bc3acc58cb22..6199dce7d9830 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -18,7 +18,6 @@ run-make/cross-lang-lto-clang/Makefile run-make/cross-lang-lto-pgo-smoketest/Makefile run-make/cross-lang-lto-upstream-rlibs/Makefile run-make/cross-lang-lto/Makefile -run-make/debug-assertions/Makefile run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile diff --git a/tests/run-make/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile deleted file mode 100644 index 4501459e9d1d8..0000000000000 --- a/tests/run-make/debug-assertions/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# ignore-cross-compile -# needs-unwind -include ../tools.mk - -all: - $(RUSTC) debug.rs -C debug-assertions=no - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=0 - $(call RUN,debug) bad - $(RUSTC) debug.rs -C opt-level=1 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=2 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=3 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=s - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=z - $(call RUN,debug) good - $(RUSTC) debug.rs -O - $(call RUN,debug) good - $(RUSTC) debug.rs - $(call RUN,debug) bad - $(RUSTC) debug.rs -C debug-assertions=yes -O - $(call RUN,debug) bad - $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1 - $(call RUN,debug) bad diff --git a/tests/run-make/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs index 9eebf60ded09b..c6e4bddc34c75 100644 --- a/tests/run-make/debug-assertions/debug.rs +++ b/tests/run-make/debug-assertions/debug.rs @@ -1,15 +1,12 @@ #![feature(rustc_attrs)] #![deny(warnings)] -use std::env; use std::thread; fn main() { - let should_fail = env::args().nth(1) == Some("bad".to_string()); - - assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail); - assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail); - assert_eq!(thread::spawn(overflow).join().is_err(), should_fail); + assert!(thread::spawn(debug_assert_eq).join().is_ok()); + assert!(thread::spawn(debug_assert).join().is_ok()); + assert!(thread::spawn(overflow).join().is_ok()); } fn debug_assert_eq() { diff --git a/tests/run-make/debug-assertions/rmake.rs b/tests/run-make/debug-assertions/rmake.rs new file mode 100644 index 0000000000000..ba8be9488a8d8 --- /dev/null +++ b/tests/run-make/debug-assertions/rmake.rs @@ -0,0 +1,37 @@ +// debug.rs contains some "debug assertion" statements which +// should only be enabled in either non-optimized builds or when +// `-C debug-assertions` is set to yes. These debug assertions +// are guaranteed to fail, so this test checks that the run command +// fails where debug assertions should be activated, and succeeds where +// debug assertions should be disabled. +// See https://github.com/rust-lang/rust/pull/22980 + +//@ ignore-cross-compile +//@ needs-unwind + +use run_make_support::{run, run_fail, rustc}; + +fn main() { + rustc().input("debug.rs").arg("-Cdebug-assertions=no").run(); + run("debug"); + rustc().input("debug.rs").opt_level("0").run(); + run_fail("debug"); + rustc().input("debug.rs").opt_level("1").run(); + run("debug"); + rustc().input("debug.rs").opt_level("2").run(); + run("debug"); + rustc().input("debug.rs").opt_level("3").run(); + run("debug"); + rustc().input("debug.rs").opt_level("s").run(); + run("debug"); + rustc().input("debug.rs").opt_level("z").run(); + run("debug"); + rustc().input("debug.rs").opt().run(); + run("debug"); + rustc().input("debug.rs").run(); + run_fail("debug"); + rustc().input("debug.rs").opt().arg("-Cdebug-assertions=yes").run(); + run_fail("debug"); + rustc().input("debug.rs").opt_level("1").arg("-Cdebug-assertions=yes").run(); + run_fail("debug"); +} From 133b47ab3837baf7d1a7f9f03a7166c137667797 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:05:54 -0400 Subject: [PATCH 136/217] rewrite emit-stack-sizes to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 2 -- tests/run-make/debug-assertions/debug.rs | 1 + tests/run-make/emit-stack-sizes/Makefile | 12 ---------- tests/run-make/emit-stack-sizes/rmake.rs | 23 +++++++++++++++++++ 4 files changed, 24 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/emit-stack-sizes/Makefile create mode 100644 tests/run-make/emit-stack-sizes/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 6199dce7d9830..f6c091ee4129e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -26,7 +26,6 @@ run-make/dump-mono-stats/Makefile run-make/dylib-chain/Makefile run-make/emit-path-unhashed/Makefile run-make/emit-shared-files/Makefile -run-make/emit-stack-sizes/Makefile run-make/emit-to-stdout/Makefile run-make/env-dep-info/Makefile run-make/export-executable-symbols/Makefile @@ -147,7 +146,6 @@ run-make/raw-dylib-link-ordinal/Makefile run-make/raw-dylib-stdcall-ordinal/Makefile run-make/redundant-libs/Makefile run-make/remap-path-prefix-dwarf/Makefile -run-make/remap-path-prefix/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/return-non-c-like-enum-from-c/Makefile diff --git a/tests/run-make/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs index c6e4bddc34c75..1f27c04a16d45 100644 --- a/tests/run-make/debug-assertions/debug.rs +++ b/tests/run-make/debug-assertions/debug.rs @@ -1,3 +1,4 @@ +#![allow(internal_features)] #![feature(rustc_attrs)] #![deny(warnings)] diff --git a/tests/run-make/emit-stack-sizes/Makefile b/tests/run-make/emit-stack-sizes/Makefile deleted file mode 100644 index b546fcba5121e..0000000000000 --- a/tests/run-make/emit-stack-sizes/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# ignore-windows -# ignore-apple -# -# This feature only works when the output object format is ELF so we ignore -# Apple and Windows - -# check that the .stack_sizes section is generated -all: - $(RUSTC) -C opt-level=3 -Z emit-stack-sizes --emit=obj foo.rs - size -A $(TMPDIR)/foo.o | $(CGREP) .stack_sizes diff --git a/tests/run-make/emit-stack-sizes/rmake.rs b/tests/run-make/emit-stack-sizes/rmake.rs new file mode 100644 index 0000000000000..53cc9ee5943f8 --- /dev/null +++ b/tests/run-make/emit-stack-sizes/rmake.rs @@ -0,0 +1,23 @@ +// Running rustc with the -Z emit-stack-sizes +// flag enables diagnostics to seek stack overflows +// at compile time. This test compiles a rust file +// with this flag, then checks that the output object +// file contains the section "stack_sizes", where +// this diagnostics information should be located. +// See https://github.com/rust-lang/rust/pull/51946 + +//@ ignore-windows +//@ ignore-apple +// Reason: this feature only works when the output object format is ELF. +// This won't be the case on Windows/OSX - for example, OSX produces a Mach-O binary. + +use run_make_support::{llvm_readobj, rustc}; + +fn main() { + rustc().opt_level("3").arg("-Zemit-stack-sizes").emit("obj").input("foo.rs").run(); + llvm_readobj() + .arg("--section-headers") + .input("foo.o") + .run() + .assert_stdout_contains(".stack_sizes"); +} From 65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jun 2024 16:36:42 +0000 Subject: [PATCH 137/217] address review comments --- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir_analysis/src/bounds.rs | 52 +++++----- .../src/collect/item_bounds.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +- .../src/solve/assembly/mod.rs | 6 +- .../src/solve/normalizes_to/mod.rs | 8 +- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_span/src/symbol.rs | 4 +- compiler/rustc_ty_utils/src/assoc.rs | 99 +++++++------------ compiler/rustc_type_ir/src/effects.rs | 5 +- compiler/rustc_type_ir/src/lang_items.rs | 4 +- library/core/src/marker.rs | 11 ++- .../missing_const_for_fn/could_be_const.fixed | 5 +- .../could_be_const.stderr | 5 + .../const-fns-are-early-bound.rs | 6 +- .../super-traits-fail.rs | 1 + .../rfc-2632-const-trait-impl/super-traits.rs | 2 + .../super-traits.stderr | 15 +-- 18 files changed, 113 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index d49eb4ece99f8..3c44acb16577a 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -397,8 +397,8 @@ language_item_table! { EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None; EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None; EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None; - EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; - EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None; + EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None; + EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None; EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1); EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1); } diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 61b7dd8bb8c34..c7ee89e73c273 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -71,16 +71,19 @@ impl<'tcx> Bounds<'tcx> { } // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `` and make sure that the effect is compatible. - if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + let compat_val = match (tcx.def_kind(defining_def_id), constness) { // FIXME(effects): revisit the correctness of this - (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + (_, ty::BoundConstness::Const) => tcx.consts.false_, // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { - Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + tcx.expected_host_effect_param_for_body(defining_def_id) } (_, ty::BoundConstness::NotConst) => { - tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) { + return; + } + tcx.consts.true_ } ( @@ -97,8 +100,12 @@ impl<'tcx> Bounds<'tcx> { let ty = bound_trait_ref .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); - // Replace the binder with dummy types/lifetimes. This should work for any - // binder as long as they don't have any bounds e.g. `for`. + // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the + // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in + // the `Min` associated type properly (which doesn't allow using `for<>`) + // This should work for any bound variables as long as they don't have any + // bounds e.g. `for`. + // FIXME(effects) reconsider this approach to allow compatibility with `for` let ty = tcx.replace_bound_vars_uncached( ty, FnMutDelegate { @@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> { tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered"); return; } - } { - // create a new projection type `::Effects` - let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { - tcx.dcx().span_delayed_bug( - span, - "`~const` trait bound has no effect assoc yet no errors encountered?", - ); - return; - }; - let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); - // make `::Effects: Compat` - let new_trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), - [ty::GenericArg::from(self_ty), compat_val.into()], + }; + // create a new projection type `::Effects` + let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { + tcx.dcx().span_delayed_bug( + span, + "`~const` trait bound has no effect assoc yet no errors encountered?", ); - self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); - } + return; + }; + let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); + // make `::Effects: Compat` + let new_trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), + [ty::GenericArg::from(self_ty), compat_val.into()], + ); + self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); } pub fn push_projection_bound( diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index b32067ebd6aee..c03e074c80b7a 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter( let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); // FIXME(effects) span let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); let self_proj = Ty::new_projection( tcx, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c0ebad9616df3..fabbec683506c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, - TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, - TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection, + TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput, TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 8d57c3d9af004..6ee684605ac60 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -270,7 +270,7 @@ where goal: Goal, ) -> Vec>; - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution>; @@ -425,8 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) - } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { - G::consider_builtin_effects_min_candidate(self, goal) + } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) { + G::consider_builtin_effects_intersection_candidate(self, goal) } else { Err(NoSolution) }; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 7a81c210c5d04..9275bcc8e97c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -865,7 +865,7 @@ where panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -903,11 +903,15 @@ where let mut min = ty::EffectKind::Maybe; for ty in types.iter() { + // We can't find the intersection if the types used are generic. + // + // FIXME(effects) do we want to look at where clauses to get some + // clue for the case where generic types are being used? let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 08ed729b14405..f5832f7e5b4c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -703,7 +703,7 @@ where }) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -732,7 +732,7 @@ where return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a26e8ae09734..8b7a63f5eb9b6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,9 +195,9 @@ symbols! { DoubleEndedIterator, Duration, EffectsCompat, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, EffectsTyCompat, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a55e83786cb8..6726db8bb54df 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -184,12 +184,10 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { let trait_def_id = def_id; - let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { - return None; - }; + let attr = tcx.get_attr(def_id, sym::const_trait)?; let span = attr.span; let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); @@ -197,8 +195,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option { let impl_def_id = def_id; - let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?; // first get the DefId of the assoc type on the trait, if there is not, // then we don't need to generate it on the impl. - let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { - return None; - }; + let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?; // FIXME(effects): span let span = tcx.def_ident_span(def_id).unwrap(); @@ -263,8 +232,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option bug!( "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", def_id, def_kind ), - } + }; + + feed.feed_hir(); + + // visibility is public. + feed.visibility(ty::Visibility::Public); + + // Copy generics_of of the trait/impl, making the trait/impl as parent. + feed.generics_of({ + let parent_generics = tcx.generics_of(parent_did); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(parent_did.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + feed.inferred_outlives_of(&[]); + + Some(feed.def_id().to_def_id()) } /// Given an `fn_def_id` of a trait or a trait implementation: diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs index 39605936e3031..f7942f2f982f5 100644 --- a/compiler/rustc_type_ir/src/effects.rs +++ b/compiler/rustc_type_ir/src/effects.rs @@ -44,7 +44,10 @@ impl EffectKind { I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) } - pub fn min(a: Self, b: Self) -> Option { + /// Returns an intersection between two effect kinds. If one effect kind + /// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this + /// returns the less permissive effect kind (`Runtime`). + pub fn intersection(a: Self, b: Self) -> Option { use EffectKind::*; match (a, b) { (Maybe, x) | (x, Maybe) => Some(x), diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 55b9709b66876..cf00c37caa287 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,9 +17,9 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, FnPtrTrait, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 042acbf20b1a0..9f5818f675d86 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1062,9 +1062,14 @@ pub mod effects { impl TyCompat for Maybe {} impl TyCompat for T {} - #[lang = "EffectsMin"] - pub trait Min { - #[lang = "EffectsMinOutput"] + #[lang = "EffectsIntersection"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] type Output: ?Sized; } + + // FIXME(effects): remove this after next trait solver lands + impl Intersection for () { + type Output = Maybe; + } } diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed index 921dcf0b16261..f8fc935f3679d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) -fn d(this: D) {} +const fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8ba42c0e5b673..8302b074127e6 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -161,6 +161,11 @@ error: this could be a `const fn` | LL | fn d(this: D) {} | ^^^^^^^^^^^^^^^^ + | +help: make the function `const` + | +LL | const fn d(this: D) {} + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index fdc53dbab1cbc..b3087349e4d3c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -126,10 +126,10 @@ pub mod effects { #[stable(feature = "minicore", since = "1.0.0")] impl TyCompat for T {} - #[lang = "EffectsMin"] + #[lang = "EffectsIntersection"] #[stable(feature = "minicore", since = "1.0.0")] - pub trait Min { - #[lang = "EffectsMinOutput"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] #[stable(feature = "minicore", since = "1.0.0")] type Output: ?Sized; } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index bb8e06ab2f7a1..637a24f53bc63 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index b32c8cab7ecbe..fbe89b00b974b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,7 @@ // FIXME(effects) check-pass //@ known-bug: #110395 +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(const_trait_impl, effects)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index a9cb68a247ccd..5b6b39ee05ef6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits.rs:21:7 + --> $DIR/super-traits.rs:23:7 | LL | t.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits.rs:5:1 + --> $DIR/super-traits.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::a` @@ -26,6 +17,6 @@ help: consider further restricting the associated type LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. From 4061fd9e4e415f4c09b221895039c7c9d9d8eb9e Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 28 Jun 2024 18:15:12 +0100 Subject: [PATCH 138/217] Reduce merge conflicts from rustfmt's wrapping --- compiler/rustc_interface/src/tests.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 02322c9b2828f..9bd67a1154b7d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -2,14 +2,22 @@ use crate::interface::{initialize_checked_jobserver, parse_cfg}; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; +use rustc_session::config::{build_configuration, build_session_options, rustc_optgroups}; use rustc_session::config::{ - build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, - ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, - Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, - LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, - PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, - SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, + DebugInfo, DumpMonoStatsFormat, ErrorOutputType, +}; +use rustc_session::config::{ + ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, + InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, +}; +use rustc_session::config::{ + LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, + OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, +}; +use rustc_session::config::{ + Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; From 55b581689d5e75349c1b2a4e44d0b3177a4f945b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 10:45:45 -0400 Subject: [PATCH 139/217] rewrite unknown-mod-stdin to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/unknown-mod-stdin/Makefile | 8 ------ tests/run-make/unknown-mod-stdin/rmake.rs | 25 +++++++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 tests/run-make/unknown-mod-stdin/Makefile create mode 100644 tests/run-make/unknown-mod-stdin/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a29d57d160312..21e20d1026efa 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -187,7 +187,6 @@ run-make/track-path-dep-info/Makefile run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile -run-make/unknown-mod-stdin/Makefile run-make/unstable-flag-required/Makefile run-make/used-cdylib-macos/Makefile run-make/volatile-intrinsics/Makefile diff --git a/tests/run-make/unknown-mod-stdin/Makefile b/tests/run-make/unknown-mod-stdin/Makefile deleted file mode 100644 index 313b0ba837e83..0000000000000 --- a/tests/run-make/unknown-mod-stdin/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-windows - -include ../tools.mk - -all: - echo 'mod unknown;' | $(RUSTC) --crate-type rlib - >$(TMPDIR)/unknown-mod.stdout 2>$(TMPDIR)/unknown-mod.stderr || echo "failed successfully" - $(RUSTC_TEST_OP) "$(TMPDIR)"/unknown-mod.stdout unknown-mod.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/unknown-mod.stderr unknown-mod.stderr diff --git a/tests/run-make/unknown-mod-stdin/rmake.rs b/tests/run-make/unknown-mod-stdin/rmake.rs new file mode 100644 index 0000000000000..0fe5c78ed0ff0 --- /dev/null +++ b/tests/run-make/unknown-mod-stdin/rmake.rs @@ -0,0 +1,25 @@ +// Rustc displays a compilation error when it finds a `mod` (module) +// statement referencing a file that does not exist. However, a bug from 2019 +// caused invalid `mod` statements to silently insert empty inline modules +// instead of showing an error if the invalid `mod` statement had been passed +// through standard input. This test checks that this bug does not make a resurgence. +// See https://github.com/rust-lang/rust/issues/65601 + +// NOTE: This is not a UI test, because the bug which this test +// is checking for is specifically tied to passing +// `mod unknown;` through standard input. + +use run_make_support::{diff, rustc}; + +fn main() { + let out = rustc().crate_type("rlib").stdin(b"mod unknown;").arg("-").run_fail(); + diff() + .actual_text("actual-stdout", out.stdout_utf8()) + .expected_file("unknown-mod.stdout") + .run(); + diff() + .actual_text("actual-stderr", out.stderr_utf8()) + .expected_file("unknown-mod.stderr") + .normalize(r#"\\"#, "/") + .run(); +} From a4f3e5f725c82b22eecf6576798f07a60b5ea7f5 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:09:05 -0400 Subject: [PATCH 140/217] rewrite and slightly rename issue-68794-textrel-on-minimal-lib --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../Makefile | 18 ----------- .../bar.c | 0 .../foo.rs | 0 .../run-make/textrel-on-minimal-lib/rmake.rs | 30 +++++++++++++++++++ 5 files changed, 30 insertions(+), 19 deletions(-) delete mode 100644 tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile rename tests/run-make/{issue-68794-textrel-on-minimal-lib => textrel-on-minimal-lib}/bar.c (100%) rename tests/run-make/{issue-68794-textrel-on-minimal-lib => textrel-on-minimal-lib}/foo.rs (100%) create mode 100644 tests/run-make/textrel-on-minimal-lib/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 21e20d1026efa..dfbd3773d46c4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -70,7 +70,6 @@ run-make/issue-37839/Makefile run-make/issue-40535/Makefile run-make/issue-47384/Makefile run-make/issue-47551/Makefile -run-make/issue-68794-textrel-on-minimal-lib/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile run-make/issue-83112-incr-test-moved-file/Makefile diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile b/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile deleted file mode 100644 index 6140b39c0e2aa..0000000000000 --- a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# ignore-cross-compile -# Regression test for issue #68794 -# -# Verify that no text relocations are accidentally introduced by linking a -# minimal rust staticlib. -# -# The test links a rust static library into a shared library, and checks that -# the linker doesn't have to flag the resulting file as containing TEXTRELs. - -include ../tools.mk - -# only-linux - -all: - $(RUSTC) foo.rs - $(CC) bar.c $(call STATICLIB,foo) -fPIC -shared -o $(call DYLIB,bar) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - readelf -d $(call DYLIB,bar) | grep TEXTREL; test $$? -eq 1 diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c b/tests/run-make/textrel-on-minimal-lib/bar.c similarity index 100% rename from tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c rename to tests/run-make/textrel-on-minimal-lib/bar.c diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs b/tests/run-make/textrel-on-minimal-lib/foo.rs similarity index 100% rename from tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs rename to tests/run-make/textrel-on-minimal-lib/foo.rs diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs new file mode 100644 index 0000000000000..4c27295591595 --- /dev/null +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -0,0 +1,30 @@ +// Verify that no text relocations are accidentally introduced by linking a +// minimal rust staticlib. +// The test links a rust static library into a shared library, and checks that +// the linker doesn't have to flag the resulting file as containing TEXTRELs. +// This bug otherwise breaks Android builds, which forbid TEXTRELs. +// See https://github.com/rust-lang/rust/issues/68794 + +//@ ignore-cross-compile +//FIXME(Oneirical): check that it works on more than just only-linux + +use run_make_support::{ + cc, dynamic_lib_name, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name, +}; + +fn main() { + rustc().input("foo.rs").run(); + cc().input("bar.c") + .input(static_lib_name("foo")) + .out_exe(&dynamic_lib_name("bar")) + .arg("-fPIC") + .arg("-shared") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + llvm_readobj() + .input(dynamic_lib_name("bar")) + .arg("--dynamic") + .run() + .assert_stdout_not_contains("TEXTREL"); +} From ec1ed26263b85fcc22eed85cb8836b14275e1e49 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:31:13 -0400 Subject: [PATCH 141/217] rewrite raw-dylib-cross-compilation to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../raw-dylib-cross-compilation/Makefile | 20 --------- .../raw-dylib-cross-compilation/rmake.rs | 41 +++++++++++++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/raw-dylib-cross-compilation/Makefile create mode 100644 tests/run-make/raw-dylib-cross-compilation/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index dfbd3773d46c4..336d894ac7501 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -136,7 +136,6 @@ run-make/profile/Makefile run-make/prune-link-args/Makefile run-make/raw-dylib-alt-calling-convention/Makefile run-make/raw-dylib-c/Makefile -run-make/raw-dylib-cross-compilation/Makefile run-make/raw-dylib-custom-dlltool/Makefile run-make/raw-dylib-import-name-type/Makefile run-make/raw-dylib-inline-cross-dylib/Makefile diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile deleted file mode 100644 index 2524f8500e154..0000000000000 --- a/tests/run-make/raw-dylib-cross-compilation/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Tests that raw-dylib cross compilation works correctly - -# needs-dlltool - -# i686 dlltool.exe can't product x64 binaries. -# ignore-i686-pc-windows-gnu - -include ../tools.mk - -all: - # Build as x86 and make sure that we have x86 objects only. - $(RUSTC) --crate-type lib --crate-name i686_raw_dylib_test --target i686-pc-windows-gnu lib.rs - "$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libi686_raw_dylib_test.rlib > $(TMPDIR)/i686.objdump.txt - $(CGREP) "file format coff-i386" < $(TMPDIR)/i686.objdump.txt - $(CGREP) -v "file format coff-x86-64" < $(TMPDIR)/i686.objdump.txt - # Build as x64 and make sure that we have x64 objects only. - $(RUSTC) --crate-type lib --crate-name x64_raw_dylib_test --target x86_64-pc-windows-gnu lib.rs - "$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libx64_raw_dylib_test.rlib > $(TMPDIR)/x64.objdump.txt - $(CGREP) "file format coff-x86-64" < $(TMPDIR)/x64.objdump.txt - $(CGREP) -v "file format coff-i386" < $(TMPDIR)/x64.objdump.txt diff --git a/tests/run-make/raw-dylib-cross-compilation/rmake.rs b/tests/run-make/raw-dylib-cross-compilation/rmake.rs new file mode 100644 index 0000000000000..994345a197c40 --- /dev/null +++ b/tests/run-make/raw-dylib-cross-compilation/rmake.rs @@ -0,0 +1,41 @@ +// When cross-compiling using `raw-dylib`, rustc would try to fetch some +// very specific `dlltool` to complete the cross-compilation (such as `i686-w64-mingw32-dlltool`) +// when Windows only calls it `dlltool`. This test performs some cross-compilation in a +// way that previously failed due to this bug, and checks that it succeeds. +// See https://github.com/rust-lang/rust/pull/108355 + +//@ ignore-i686-pc-windows-msvc +// Reason: dlltool on this distribution is unable to produce x64 binaries +//@ needs-dlltool +// Reason: this is the utility being checked by this test + +use run_make_support::{llvm_objdump, rust_lib_name, rustc}; + +fn main() { + // Build as x86 and make sure that we have x86 objects only. + rustc() + .crate_type("lib") + .crate_name("i686_raw_dylib_test") + .target("i686-pc-windows-gnu") + .input("lib.rs") + .run(); + llvm_objdump() + .arg("-a") + .input(rust_lib_name("i686_raw_dylib_test")) + .run() + .assert_stdout_contains("file format coff-i386") + .assert_stdout_not_contains("file format coff-x86-64"); + // Build as x64 and make sure that we have x64 objects only. + rustc() + .crate_type("lib") + .crate_name("x64_raw_dylib_test") + .target("x86-64-pc-windows-gnu") + .input("lib.rs") + .run(); + llvm_objdump() + .arg("-a") + .input(rust_lib_name("i686_raw_dylib_test")) + .run() + .assert_stdout_not_contains("file format coff-i386") + .assert_stdout_contains("file format coff-x86-64"); +} From 4c9eeda36d24e1da8bdf74bd344cd98cb4b98c09 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:38:22 -0400 Subject: [PATCH 142/217] rewrite used-cdylib-macos to rmake --- src/tools/compiletest/src/command-list.rs | 2 ++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../raw-dylib-cross-compilation/rmake.rs | 6 +++--- tests/run-make/textrel-on-minimal-lib/rmake.rs | 3 ++- tests/run-make/used-cdylib-macos/Makefile | 11 ----------- tests/run-make/used-cdylib-macos/rmake.rs | 16 ++++++++++++++++ 6 files changed, 23 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/used-cdylib-macos/Makefile create mode 100644 tests/run-make/used-cdylib-macos/rmake.rs diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index 6e1685a8a9456..6735e9faa7a67 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -53,6 +53,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-gnu", "ignore-haiku", "ignore-horizon", + "ignore-i686-pc-windows-gnu", "ignore-i686-pc-windows-msvc", "ignore-illumos", "ignore-ios", @@ -174,6 +175,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-bpf", "only-cdb", "only-gnu", + "only-i686-pc-windows-gnu", "only-i686-pc-windows-msvc", "only-ios", "only-linux", diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 336d894ac7501..73ef7c5ba2579 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,7 +186,6 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/used-cdylib-macos/Makefile run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile diff --git a/tests/run-make/raw-dylib-cross-compilation/rmake.rs b/tests/run-make/raw-dylib-cross-compilation/rmake.rs index 994345a197c40..3eb55546314df 100644 --- a/tests/run-make/raw-dylib-cross-compilation/rmake.rs +++ b/tests/run-make/raw-dylib-cross-compilation/rmake.rs @@ -4,7 +4,7 @@ // way that previously failed due to this bug, and checks that it succeeds. // See https://github.com/rust-lang/rust/pull/108355 -//@ ignore-i686-pc-windows-msvc +//@ ignore-i686-pc-windows-gnu // Reason: dlltool on this distribution is unable to produce x64 binaries //@ needs-dlltool // Reason: this is the utility being checked by this test @@ -29,12 +29,12 @@ fn main() { rustc() .crate_type("lib") .crate_name("x64_raw_dylib_test") - .target("x86-64-pc-windows-gnu") + .target("x86_64-pc-windows-gnu") .input("lib.rs") .run(); llvm_objdump() .arg("-a") - .input(rust_lib_name("i686_raw_dylib_test")) + .input(rust_lib_name("x64_raw_dylib_test")) .run() .assert_stdout_not_contains("file format coff-i386") .assert_stdout_contains("file format coff-x86-64"); diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs index 4c27295591595..eba664479f112 100644 --- a/tests/run-make/textrel-on-minimal-lib/rmake.rs +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -6,7 +6,8 @@ // See https://github.com/rust-lang/rust/issues/68794 //@ ignore-cross-compile -//FIXME(Oneirical): check that it works on more than just only-linux +//@ ignore-windows +// Reason: There is no `bar.dll` produced by CC to run readobj on use run_make_support::{ cc, dynamic_lib_name, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name, diff --git a/tests/run-make/used-cdylib-macos/Makefile b/tests/run-make/used-cdylib-macos/Makefile deleted file mode 100644 index bdf914a1ca950..0000000000000 --- a/tests/run-make/used-cdylib-macos/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -# only-apple -# -# This checks that `#[used]` passes through to the linker on -# Apple targets. This is subject to change in the future, see -# https://github.com/rust-lang/rust/pull/93718 for discussion - -all: - $(RUSTC) -Copt-level=3 dylib_used.rs - nm $(TMPDIR)/libdylib_used.dylib | $(CGREP) VERY_IMPORTANT_SYMBOL diff --git a/tests/run-make/used-cdylib-macos/rmake.rs b/tests/run-make/used-cdylib-macos/rmake.rs new file mode 100644 index 0000000000000..ad95ad640f0c1 --- /dev/null +++ b/tests/run-make/used-cdylib-macos/rmake.rs @@ -0,0 +1,16 @@ +// This checks that `#[used]` passes through to the linker on +// Apple targets. This is subject to change in the future. +// See https://github.com/rust-lang/rust/pull/93718 + +//@ only-apple + +use run_make_support::{dynamic_lib_name, llvm_readobj, rustc}; + +fn main() { + rustc().opt_level("3").input("dylib_used.rs").run(); + llvm_readobj() + .input(dynamic_lib_name("dylib_used")) + .arg("--all") + .run() + .assert_stdout_contains("VERY_IMPORTANT_SYMBOL"); +} From 17950828420fa2068214b906e9fea98a771e64e8 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 14:38:30 -0400 Subject: [PATCH 143/217] rmeta_contains functions for remap-path-prefix --- Cargo.lock | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + tests/run-make/remap-path-prefix/rmake.rs | 51 ++++++++++++++++++----- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0182eca05058d..f6293f9626e13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3401,6 +3401,7 @@ name = "run_make_support" version = "0.2.0" dependencies = [ "ar", + "bstr", "gimli 0.28.1", "object 0.34.0", "regex", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index e3837a2f8cc4e..ec3b8a96ef3b6 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -4,6 +4,7 @@ version = "0.2.0" edition = "2021" [dependencies] +bstr = "1.6.0" object = "0.34.0" similar = "2.5.0" wasmparser = "0.118.2" diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 771cda630af6a..31b913810b665 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -21,6 +21,7 @@ use std::io; use std::panic; use std::path::{Path, PathBuf}; +pub use bstr; pub use gimli; pub use object; pub use regex; diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index 4d98dcf6131cd..62c0368e4b3a4 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -3,9 +3,8 @@ // successfully remapped to "/the/aux" in the rmeta files. // See https://github.com/rust-lang/rust/pull/85344 -// FIXME(Oneirical): check if works without ignore-windows - -use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, is_darwin, rustc}; +use run_make_support::bstr::ByteSlice; +use run_make_support::{bstr, fs_wrapper, is_darwin, rustc}; fn main() { let mut out_simple = rustc(); @@ -34,8 +33,8 @@ fn main() { .input("auxiliary/lib.rs"); out_simple.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_object.arg("-Zremap-path-scope=object"); out_macro.arg("-Zremap-path-scope=macro"); @@ -47,12 +46,42 @@ fn main() { } out_object.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_macro.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_diagobj.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); +} + +//FIXME(Oneirical): These could be generalized into run_make_support +// helper functions. +fn rmeta_contains(expected: &str) { + // Normalize to account for path differences in Windows. + if !bstr::BString::from(fs_wrapper::read("liblib.rmeta")) + .replace(b"\\", b"/") + .contains_str(expected) + { + eprintln!("=== FILE CONTENTS (LOSSY) ==="); + eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta"))); + eprintln!("=== SPECIFIED TEXT ==="); + eprintln!("{}", expected); + panic!("specified text was not found in file"); + } +} + +fn rmeta_not_contains(expected: &str) { + // Normalize to account for path differences in Windows. + if bstr::BString::from(fs_wrapper::read("liblib.rmeta")) + .replace(b"\\", b"/") + .contains_str(expected) + { + eprintln!("=== FILE CONTENTS (LOSSY) ==="); + eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta"))); + eprintln!("=== SPECIFIED TEXT ==="); + eprintln!("{}", expected); + panic!("specified text was not found in file"); + } } From 1483815aa268b3a3dbfb3c4242772c88690a887e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:44:33 -0700 Subject: [PATCH 144/217] Bump Fuchsia This includes the quality-of-life improvements for developers in https://fxrev.dev/1061894. --- .../docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh index 2bb1d0a633871..e6d7eabf4e723 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=737ebdd83afa47b742ca8325fad0176952fcefbd +INTEGRATION_SHA=d1d2f20efe46e22be179953dd6726c96eced54ab checkout=fuchsia jiri=.jiri_root/bin/jiri From 45efd9ca8b60c792785741b91e8a19c983f958b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 29 Jun 2024 00:48:05 +0200 Subject: [PATCH 145/217] remove some amusing but redundant code --- compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 0fd85eb345d0c..8b965f4d18e45 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -181,11 +181,6 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { state.insert_value_idx(value_target, val, self.map()); } if let Some(overflow_target) = overflow_target { - let overflow = match overflow { - FlatSet::Top => FlatSet::Top, - FlatSet::Elem(overflow) => FlatSet::Elem(overflow), - FlatSet::Bottom => FlatSet::Bottom, - }; // We have flooded `target` earlier. state.insert_value_idx(overflow_target, overflow, self.map()); } From 1727e59ad2b2b8793bda3efac453ea556eb2cdcb Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:49:02 -0700 Subject: [PATCH 146/217] Remove wasm target This should no longer be required to build Fuchsia. --- src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index a944f370c6b30..a137808940716 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -24,7 +24,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Duplicated in dist-various-2 Dockerfile. -# FIXME: Move to canonical triple ENV \ AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \ @@ -48,10 +47,6 @@ ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS \ ENV TARGETS=x86_64-unknown-fuchsia ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu -ENV TARGETS=$TARGETS,wasm32-unknown-unknown - -# Fuchsia clang does not have wasm target enabled, use system clang. -ENV CC_wasm32_unknown_unknown=clang-15 COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh From a8382023b4a4de1d9babe4ef2ce432fd8a3951f5 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:51:32 -0700 Subject: [PATCH 147/217] Clarify docs --- src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index a137808940716..be209a9de9f91 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -1,5 +1,6 @@ # This job builds a toolchain capable of building Fuchsia, and then builds -# Fuchsia. See the build-fuchsia.sh script in this directory for more details. +# Fuchsia as an integration test of the toolchain. See the build-fuchsia.sh +# script in this directory for more details. FROM ubuntu:22.04 From 078d9d8aa98fc1490734b51e6e151659c953bed7 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 16:08:57 -0700 Subject: [PATCH 148/217] Rename x86_64-gnu-integration builder to x86_64-fuchsia This better reflects what the builder actually does. --- .../Dockerfile | 2 +- .../build-fuchsia.sh | 8 ++++---- src/ci/github-actions/jobs.yml | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/ci/docker/host-x86_64/{x86_64-gnu-integration => x86_64-fuchsia}/Dockerfile (97%) rename src/ci/docker/host-x86_64/{x86_64-gnu-integration => x86_64-fuchsia}/build-fuchsia.sh (91%) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile similarity index 97% rename from src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile rename to src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile index be209a9de9f91..ba3e8bdb68754 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile @@ -72,4 +72,4 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld ENV SCRIPT \ python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ - bash ../src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh + bash ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh similarity index 91% rename from src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh rename to src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh index e6d7eabf4e723..c806b886dae8f 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh @@ -5,14 +5,14 @@ # # You may run this script locally using Docker with the following command: # -# $ src/ci/docker/run.sh x86_64-gnu-integration +# $ src/ci/docker/run.sh x86_64-fuchsia # # Alternatively, from within the container with --dev, assuming you have made it # as far as building the toolchain with the above command: # -# $ src/ci/docker/run.sh --dev x86_64-gnu-integration +# $ src/ci/docker/run.sh --dev x86_64-fuchsia # docker# git config --global --add safe.directory /checkout/obj/fuchsia -# docker# ../src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +# docker# ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh # # Also see the docs in the rustc-dev-guide for more info: # https://github.com/rust-lang/rustc-dev-guide/pull/1989 @@ -21,7 +21,7 @@ set -euf -o pipefail # Set this variable to 1 to disable updating the Fuchsia checkout. This is # useful for making local changes. You can find the Fuchsia checkout in -# `obj/x86_64-gnu-integration/fuchsia` in your local checkout after running this +# `obj/x86_64-fuchsia/fuchsia` in your local checkout after running this # job for the first time. KEEP_CHECKOUT= diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index e3903c3dd5a1f..cf750bbd0c568 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -208,6 +208,13 @@ auto: - image: test-various <<: *job-linux-4c + - image: x86_64-fuchsia + # Only run this job on the nightly channel. Fuchsia requires + # nightly features to compile, and this job would fail if + # executed on beta and stable. + only_on_channel: nightly + <<: *job-linux-8c + - image: x86_64-gnu <<: *job-linux-4c @@ -229,13 +236,6 @@ auto: - image: x86_64-gnu-aux <<: *job-linux-4c - - image: x86_64-gnu-integration - # Only run this job on the nightly channel. Fuchsia requires - # nightly features to compile, and this job would fail if - # executed on beta and stable. - only_on_channel: nightly - <<: *job-linux-8c - - image: x86_64-gnu-debug <<: *job-linux-4c From 3bc32472008387ab2adca98dcfd0bef6207357c1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 19:37:21 -0400 Subject: [PATCH 149/217] Move binder and polarity parsing into parse_generic_ty_bound --- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/generics.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 98 ++++++++++++------- .../higher-ranked/erroneous-lifetime-bound.rs | 5 + .../erroneous-lifetime-bound.stderr | 25 +++++ .../precise-capturing/bound-modifiers.rs | 25 +++++ .../precise-capturing/bound-modifiers.stderr | 87 ++++++++++++++++ 7 files changed, 204 insertions(+), 40 deletions(-) create mode 100644 tests/ui/higher-ranked/erroneous-lifetime-bound.rs create mode 100644 tests/ui/higher-ranked/erroneous-lifetime-bound.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/bound-modifiers.rs create mode 100644 tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0c70884feea3..ac66edeb95e45 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2327,7 +2327,7 @@ impl<'a> Parser<'a> { let before = self.prev_token.clone(); let binder = if self.check_keyword(kw::For) { let lo = self.token.span; - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; let span = lo.to(self.prev_token.span); self.psess.gated_spans.gate(sym::closure_lifetime_binder, span); diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index fde16ac957dfe..10c7715c7dcd5 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -457,7 +457,7 @@ impl<'a> Parser<'a> { // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>` // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>` // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; // Parse type with mandatory colon and (possibly empty) bounds, // or with mandatory equality sign and the second type. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d2043c353fed9..1e5b227aaa9be 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -18,7 +18,7 @@ use rustc_ast::{ }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{Span, Symbol}; +use rustc_span::{ErrorGuaranteed, Span, Symbol}; use thin_vec::{thin_vec, ThinVec}; #[derive(Copy, Clone, PartialEq)] @@ -280,7 +280,7 @@ impl<'a> Parser<'a> { // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; if self.check_fn_front_matter(false, Case::Sensitive) { self.parse_ty_bare_fn( lo, @@ -833,12 +833,9 @@ impl<'a> Parser<'a> { let lo = self.token.span; let leading_token = self.prev_token.clone(); let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis)); - let inner_lo = self.token.span; - let modifiers = self.parse_trait_bound_modifiers()?; let bound = if self.token.is_lifetime() { - self.error_lt_bound_with_modifiers(modifiers); - self.parse_generic_lt_bound(lo, inner_lo, has_parens)? + self.parse_generic_lt_bound(lo, has_parens)? } else if self.eat_keyword(kw::Use) { // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of // lifetimes and ident params (including SelfUpper). These are validated later @@ -848,7 +845,7 @@ impl<'a> Parser<'a> { let (args, args_span) = self.parse_precise_capturing_args()?; GenericBound::Use(args, use_span.to(args_span)) } else { - self.parse_generic_ty_bound(lo, has_parens, modifiers, &leading_token)? + self.parse_generic_ty_bound(lo, has_parens, &leading_token)? }; Ok(bound) @@ -858,50 +855,64 @@ impl<'a> Parser<'a> { /// ```ebnf /// LT_BOUND = LIFETIME /// ``` - fn parse_generic_lt_bound( - &mut self, - lo: Span, - inner_lo: Span, - has_parens: bool, - ) -> PResult<'a, GenericBound> { - let bound = GenericBound::Outlives(self.expect_lifetime()); + fn parse_generic_lt_bound(&mut self, lo: Span, has_parens: bool) -> PResult<'a, GenericBound> { + let lt = self.expect_lifetime(); + let bound = GenericBound::Outlives(lt); if has_parens { // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead, // possibly introducing `GenericBound::Paren(P)`? - self.recover_paren_lifetime(lo, inner_lo)?; + self.recover_paren_lifetime(lo, lt.ident.span)?; } Ok(bound) } /// Emits an error if any trait bound modifiers were present. - fn error_lt_bound_with_modifiers(&self, modifiers: TraitBoundModifiers) { - match modifiers.constness { + fn error_lt_bound_with_modifiers( + &self, + modifiers: TraitBoundModifiers, + binder_span: Option, + ) -> ErrorGuaranteed { + let TraitBoundModifiers { constness, asyncness, polarity } = modifiers; + + match constness { BoundConstness::Never => {} BoundConstness::Always(span) | BoundConstness::Maybe(span) => { - self.dcx().emit_err(errors::ModifierLifetime { - span, - modifier: modifiers.constness.as_str(), - }); + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() }); } } - match modifiers.polarity { + match polarity { BoundPolarity::Positive => {} BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => { - self.dcx().emit_err(errors::ModifierLifetime { - span, - modifier: modifiers.polarity.as_str(), - }); + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() }); + } + } + + match asyncness { + BoundAsyncness::Normal => {} + BoundAsyncness::Async(span) => { + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() }); } } + + if let Some(span) = binder_span { + return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" }); + } + + unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?") } /// Recover on `('lifetime)` with `(` already eaten. - fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> { - let inner_span = inner_lo.to(self.prev_token.span); + fn recover_paren_lifetime(&mut self, lo: Span, lt_span: Span) -> PResult<'a, ()> { self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let span = lo.to(self.prev_token.span); - let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(inner_span) { + let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(lt_span) { (Some(span), snippet) } else { (None, String::new()) @@ -916,7 +927,7 @@ impl<'a> Parser<'a> { /// If no modifiers are present, this does not consume any tokens. /// /// ```ebnf - /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["?" | "!"] + /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"] /// ``` fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> { let constness = if self.eat(&token::Tilde) { @@ -970,15 +981,23 @@ impl<'a> Parser<'a> { /// TY_BOUND_NOPAREN = [TRAIT_BOUND_MODIFIERS] [for] SIMPLE_PATH /// ``` /// - /// For example, this grammar accepts `~const ?for<'a: 'b> m::Trait<'a>`. + /// For example, this grammar accepts `for<'a: 'b> ~const ?m::Trait<'a>`. fn parse_generic_ty_bound( &mut self, lo: Span, has_parens: bool, - modifiers: TraitBoundModifiers, leading_token: &Token, ) -> PResult<'a, GenericBound> { - let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let modifiers = self.parse_trait_bound_modifiers()?; + let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?; + + // Recover erroneous lifetime bound with modifiers or binder. + // e.g. `T: for<'a> 'a` or `T: ~const 'a`. + if self.token.is_lifetime() { + let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span); + return self.parse_generic_lt_bound(lo, has_parens); + } + let mut path = if self.token.is_keyword(kw::Fn) && self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis)) && let Some(path) = self.recover_path_from_fn() @@ -1094,16 +1113,19 @@ impl<'a> Parser<'a> { } /// Optionally parses `for<$generic_params>`. - pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec> { + pub(super) fn parse_late_bound_lifetime_defs( + &mut self, + ) -> PResult<'a, (ThinVec, Option)> { if self.eat_keyword(kw::For) { + let lo = self.token.span; self.expect_lt()?; let params = self.parse_generic_params()?; self.expect_gt()?; - // We rely on AST validation to rule out invalid cases: There must not be type - // parameters, and the lifetime parameters must not have bounds. - Ok(params) + // We rely on AST validation to rule out invalid cases: There must not be + // type or const parameters, and parameters must not have bounds. + Ok((params, Some(lo.to(self.prev_token.span)))) } else { - Ok(ThinVec::new()) + Ok((ThinVec::new(), None)) } } diff --git a/tests/ui/higher-ranked/erroneous-lifetime-bound.rs b/tests/ui/higher-ranked/erroneous-lifetime-bound.rs new file mode 100644 index 0000000000000..b1720087b5f6d --- /dev/null +++ b/tests/ui/higher-ranked/erroneous-lifetime-bound.rs @@ -0,0 +1,5 @@ +fn foo() where T: for<'a> 'a {} +//~^ ERROR `for<...>` may only modify trait bounds, not lifetime bounds +//~| ERROR use of undeclared lifetime name `'a` [E0261] + +fn main() {} diff --git a/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr b/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr new file mode 100644 index 0000000000000..5b104f45d2361 --- /dev/null +++ b/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr @@ -0,0 +1,25 @@ +error: `for<...>` may only modify trait bounds, not lifetime bounds + --> $DIR/erroneous-lifetime-bound.rs:1:25 + | +LL | fn foo() where T: for<'a> 'a {} + | ^^^^ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/erroneous-lifetime-bound.rs:1:30 + | +LL | fn foo() where T: for<'a> 'a {} + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | fn foo() where for<'a> T: for<'a> 'a {} + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | fn foo<'a, T>() where T: for<'a> 'a {} + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs new file mode 100644 index 0000000000000..15f2188262869 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -0,0 +1,25 @@ +//@ edition: 2021 + +#![feature(precise_capturing)] + +fn polarity() -> impl Sized + ?use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| WARN relaxing a default bound only does something for `?Sized` +//~| WARN relaxing a default bound only does something for `?Sized` + +fn asyncness() -> impl Sized + async use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR async closures are unstable + +fn constness() -> impl Sized + const use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR const trait impls are experimental + +fn binder() -> impl Sized + for<'a> use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr new file mode 100644 index 0000000000000..4602225e7b922 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -0,0 +1,87 @@ +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:5:32 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:11:38 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:16:38 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:21:37 + | +LL | fn binder() -> impl Sized + for<'a> use<> {} + | ^^^ expected identifier, found keyword + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:5:32 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:11:38 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:16:38 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:21:37 + | +LL | fn binder() -> impl Sized + for<'a> use<> {} + | ^^^ not found in this scope + +error[E0658]: async closures are unstable + --> $DIR/bound-modifiers.rs:11:32 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error[E0658]: const trait impls are experimental + --> $DIR/bound-modifiers.rs:16:32 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/bound-modifiers.rs:5:31 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/bound-modifiers.rs:5:31 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0405, E0658. +For more information about an error, try `rustc --explain E0405`. From c9f36f8cd7a6b0c76b5c99e12e888405fffdb829 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 28 Jun 2024 19:05:01 -0700 Subject: [PATCH 150/217] Only update `Eq` operands in GVN if you can update both sides Otherwise the types might not match Fixes 127089 --- compiler/rustc_mir_transform/src/gvn.rs | 10 ++-- .../gvn_ptr_eq_with_constant.main.GVN.diff | 52 +++++++++++++++++++ tests/mir-opt/gvn_ptr_eq_with_constant.rs | 23 ++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff create mode 100644 tests/mir-opt/gvn_ptr_eq_with_constant.rs diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 936a7e2d9dedd..3dbdeb615cfe2 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1074,11 +1074,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { { lhs = *lhs_value; rhs = *rhs_value; - if let Some(op) = self.try_as_operand(lhs, location) { - *lhs_operand = op; - } - if let Some(op) = self.try_as_operand(rhs, location) { - *rhs_operand = op; + if let Some(lhs_op) = self.try_as_operand(lhs, location) + && let Some(rhs_op) = self.try_as_operand(rhs, location) + { + *lhs_operand = lhs_op; + *rhs_operand = rhs_op; } } diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff new file mode 100644 index 0000000000000..3af78d9b6ce98 --- /dev/null +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before GVN ++ // MIR for `main` after GVN + + fn main() -> () { + let mut _0: (); + let _1: bool; + let mut _2: *mut u8; + scope 1 (inlined dangling_mut::) { + let mut _3: usize; + scope 2 (inlined align_of::) { + } + scope 3 (inlined without_provenance_mut::) { + } + } + scope 4 (inlined Foo::::cmp_ptr) { + let mut _4: *const u8; + let mut _5: *mut u8; + let mut _6: *const u8; + scope 5 (inlined std::ptr::eq::) { + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); +- _3 = AlignOf(u8); +- _2 = _3 as *mut u8 (Transmute); ++ _3 = const 1_usize; ++ _2 = const {0x1 as *mut u8}; + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; +- _4 = _2 as *const u8 (PtrToPtr); ++ _5 = const {0x1 as *mut u8}; ++ _4 = const {0x1 as *const u8}; + StorageDead(_5); + StorageLive(_6); +- _6 = const Foo::::SENTINEL as *const u8 (PtrToPtr); +- _1 = Eq(_4, _6); ++ _6 = const {0x1 as *const u8}; ++ _1 = const true; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.rs b/tests/mir-opt/gvn_ptr_eq_with_constant.rs new file mode 100644 index 0000000000000..d8025072ee3d3 --- /dev/null +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.rs @@ -0,0 +1,23 @@ +// skip-filecheck +//@ test-mir-pass: GVN +//@ only-64bit +//@ compile-flags: -Z mir-enable-passes=+Inline + +// Regression for + +#![feature(strict_provenance)] + +struct Foo(std::marker::PhantomData); + +impl Foo { + const SENTINEL: *mut T = std::ptr::dangling_mut(); + + fn cmp_ptr(a: *mut T) -> bool { + std::ptr::eq(a, Self::SENTINEL) + } +} + +// EMIT_MIR gvn_ptr_eq_with_constant.main.GVN.diff +pub fn main() { + Foo::::cmp_ptr(std::ptr::dangling_mut()); +} From a62cbda57e23105d68d146cafce94b882882c0e1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jun 2024 23:13:33 -0300 Subject: [PATCH 151/217] Add feature diagnostic for unsafe_extern_blocks --- compiler/rustc_ast_passes/src/ast_validation.rs | 10 +++++++++- .../feature-gate-unsafe-extern-blocks.stderr | 4 ++++ tests/ui/parser/unsafe-foreign-mod-2.stderr | 4 ++++ tests/ui/parser/unsafe-foreign-mod.stderr | 4 ++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ba4b6130b60c8..d02b8510975fc 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1088,7 +1088,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } else if let &Safety::Unsafe(span) = safety { - this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" }); + let mut diag = this + .dcx() + .create_err(errors::UnsafeItem { span, kind: "extern block" }); + rustc_session::parse::add_feature_diagnostics( + &mut diag, + self.session, + sym::unsafe_extern_blocks, + ); + diag.emit(); } if abi.is_none() { diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr index 84f00827c6010..5653494630899 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr +++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr @@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe | LL | unsafe extern "C" { | ^^^^^^ + | + = note: see issue #123743 for more information + = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental --> $DIR/feature-gate-unsafe-extern-blocks.rs:9:5 diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr index 77a383d5efa26..07dbd5568d053 100644 --- a/tests/ui/parser/unsafe-foreign-mod-2.stderr +++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr @@ -9,6 +9,10 @@ error: extern block cannot be declared unsafe | LL | extern "C" unsafe { | ^^^^^^ + | + = note: see issue #123743 for more information + = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: items in unadorned `extern` blocks cannot have safety qualifiers --> $DIR/unsafe-foreign-mod-2.rs:4:5 diff --git a/tests/ui/parser/unsafe-foreign-mod.stderr b/tests/ui/parser/unsafe-foreign-mod.stderr index 77f6e93be10bb..60b918a89b34d 100644 --- a/tests/ui/parser/unsafe-foreign-mod.stderr +++ b/tests/ui/parser/unsafe-foreign-mod.stderr @@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe | LL | unsafe extern "C" { | ^^^^^^ + | + = note: see issue #123743 for more information + = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 1 previous error From 0afc774e9dc3d000ecd3df05d14cfe0304908fbe Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 29 Jun 2024 08:05:53 +0300 Subject: [PATCH 152/217] unify `bin_helpers` and `dylib` utility modules Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/dylib.rs | 40 ------------- src/bootstrap/src/utils/mod.rs | 2 +- .../{bin_helpers.rs => shared_helpers.rs} | 59 +++++++++++++++++-- 3 files changed, 54 insertions(+), 47 deletions(-) delete mode 100644 src/bootstrap/src/utils/dylib.rs rename src/bootstrap/src/utils/{bin_helpers.rs => shared_helpers.rs} (50%) diff --git a/src/bootstrap/src/utils/dylib.rs b/src/bootstrap/src/utils/dylib.rs deleted file mode 100644 index 90bcff59a647c..0000000000000 --- a/src/bootstrap/src/utils/dylib.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Various utilities for working with dylib paths. - -/// Returns the environment variable which the dynamic library lookup path -/// resides in for this platform. -pub fn dylib_path_var() -> &'static str { - if cfg!(target_os = "windows") { - "PATH" - } else if cfg!(target_vendor = "apple") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else if cfg!(target_os = "aix") { - "LIBPATH" - } else { - "LD_LIBRARY_PATH" - } -} - -/// Parses the `dylib_path_var()` environment variable, returning a list of -/// paths that are members of this lookup path. -pub fn dylib_path() -> Vec { - let var = match std::env::var_os(dylib_path_var()) { - Some(v) => v, - None => return vec![], - }; - std::env::split_paths(&var).collect() -} - -/// Given an executable called `name`, return the filename for the -/// executable for a particular target. -#[allow(dead_code)] -pub fn exe(name: &str, target: &str) -> String { - if target.contains("windows") { - format!("{name}.exe") - } else if target.contains("uefi") { - format!("{name}.efi") - } else { - name.to_string() - } -} diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index cb535f0e1632a..53b41f1578060 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -6,11 +6,11 @@ pub(crate) mod cache; pub(crate) mod cc_detect; pub(crate) mod change_tracker; pub(crate) mod channel; -pub(crate) mod dylib; pub(crate) mod exec; pub(crate) mod helpers; pub(crate) mod job; #[cfg(feature = "build-metrics")] pub(crate) mod metrics; pub(crate) mod render_tests; +pub(crate) mod shared_helpers; pub(crate) mod tarball; diff --git a/src/bootstrap/src/utils/bin_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs similarity index 50% rename from src/bootstrap/src/utils/bin_helpers.rs rename to src/bootstrap/src/utils/shared_helpers.rs index 5fbbe0bde0e28..8ec7116f6cab1 100644 --- a/src/bootstrap/src/utils/bin_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -1,18 +1,65 @@ -//! This file is meant to be included directly from bootstrap shims to avoid a -//! dependency on the bootstrap library. This reduces the binary size and -//! improves compilation time by reducing the linking time. +//! This module serves two purposes: +//! 1. It is part of the `utils` module and used in other parts of bootstrap. +//! 2. It is embedded inside bootstrap shims to avoid a dependency on the bootstrap library. +//! Therefore, this module should never use any other bootstrap module. This reduces binary +//! size and improves compilation time by minimizing linking time. + +#![allow(dead_code)] use std::env; +use std::ffi::OsString; use std::fs::OpenOptions; use std::io::Write; use std::process::Command; use std::str::FromStr; +#[cfg(test)] +mod tests; + +/// Returns the environment variable which the dynamic library lookup path +/// resides in for this platform. +pub fn dylib_path_var() -> &'static str { + if cfg!(target_os = "windows") { + "PATH" + } else if cfg!(target_vendor = "apple") { + "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" + } else if cfg!(target_os = "aix") { + "LIBPATH" + } else { + "LD_LIBRARY_PATH" + } +} + +/// Parses the `dylib_path_var()` environment variable, returning a list of +/// paths that are members of this lookup path. +pub fn dylib_path() -> Vec { + let var = match std::env::var_os(dylib_path_var()) { + Some(v) => v, + None => return vec![], + }; + std::env::split_paths(&var).collect() +} + +/// Given an executable called `name`, return the filename for the +/// executable for a particular target. +#[allow(dead_code)] +pub fn exe(name: &str, target: &str) -> String { + if target.contains("windows") { + format!("{name}.exe") + } else if target.contains("uefi") { + format!("{name}.efi") + } else { + name.to_string() + } +} + /// Parses the value of the "RUSTC_VERBOSE" environment variable and returns it as a `usize`. /// If it was not defined, returns 0 by default. /// /// Panics if "RUSTC_VERBOSE" is defined with the value that is not an unsigned integer. -pub(crate) fn parse_rustc_verbose() -> usize { +pub fn parse_rustc_verbose() -> usize { match env::var("RUSTC_VERBOSE") { Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"), Err(_) => 0, @@ -22,7 +69,7 @@ pub(crate) fn parse_rustc_verbose() -> usize { /// Parses the value of the "RUSTC_STAGE" environment variable and returns it as a `String`. /// /// If "RUSTC_STAGE" was not set, the program will be terminated with 101. -pub(crate) fn parse_rustc_stage() -> String { +pub fn parse_rustc_stage() -> String { env::var("RUSTC_STAGE").unwrap_or_else(|_| { // Don't panic here; it's reasonable to try and run these shims directly. Give a helpful error instead. eprintln!("rustc shim: FATAL: RUSTC_STAGE was not set"); @@ -35,7 +82,7 @@ pub(crate) fn parse_rustc_stage() -> String { /// /// Before writing it, replaces user-specific values to create generic dumps for cross-environment /// comparisons. -pub(crate) fn maybe_dump(dump_name: String, cmd: &Command) { +pub fn maybe_dump(dump_name: String, cmd: &Command) { if let Ok(dump_dir) = env::var("DUMP_BOOTSTRAP_SHIMS") { let dump_file = format!("{dump_dir}/{dump_name}"); From 50edb32939898fa6c22f3e2b2596317a031acaa7 Mon Sep 17 00:00:00 2001 From: surechen Date: Sat, 29 Jun 2024 14:23:33 +0800 Subject: [PATCH 153/217] Fix a error suggestion for E0121 when using placeholder _ as return types on function signature. Recommit after refactoring based on comment: https://github.com/rust-lang/rust/pull/126017#issuecomment-2189149361 But when changing return type's lifetime to `ReError` will affect the subsequent borrow check process and cause test11 in typeck_type_placeholder_item.rs to lost E0515 message. ```rust fn test11(x: &usize) -> &_ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types &x //~ ERROR cannot return reference to function parameter(this E0515 msg will disappear) } ``` --- compiler/rustc_hir_analysis/src/collect.rs | 19 ++++++++- ...er-return-ty-for-fn-sig-issue-125488.fixed | 33 ++++++++++++++++ ...infer-return-ty-for-fn-sig-issue-125488.rs | 33 ++++++++++++++++ ...r-return-ty-for-fn-sig-issue-125488.stderr | 39 +++++++++++++++++++ .../ui/typeck/typeck_type_placeholder_item.rs | 2 +- .../typeck_type_placeholder_item.stderr | 12 ++---- 6 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c6e8759327f03..36d0704b5b036 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1459,8 +1459,25 @@ fn infer_return_ty_for_fn_sig<'tcx>( Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; // Typeck doesn't expect erased regions to be returned from `type_of`. + // This is a heuristic approach. If the scope has region paramters, + // we should change fn_sig's lifetime from `ReErased` to `ReError`, + // otherwise to `ReStatic`. + let has_region_params = generics.params.iter().any(|param| match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + }); let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r { - ty::ReErased => tcx.lifetimes.re_static, + ty::ReErased => { + if has_region_params { + ty::Region::new_error_with_message( + tcx, + DUMMY_SP, + "erased region is not allowed here in return type", + ) + } else { + tcx.lifetimes.re_static + } + } _ => r, }); diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed new file mode 100644 index 0000000000000..442ade6abf16d --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed @@ -0,0 +1,33 @@ +//@ run-rustfix + +#[allow(dead_code)] + +fn main() { + struct S<'a>(&'a ()); + + fn f1(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + s + } + + fn f2(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + let x = true; + if x { + s + } else { + s + } + } + + fn f3(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + return s; + } + + fn f4(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + let _x = 1; + return s; + } +} diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs new file mode 100644 index 0000000000000..04ea3a28addfb --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs @@ -0,0 +1,33 @@ +//@ run-rustfix + +#[allow(dead_code)] + +fn main() { + struct S<'a>(&'a ()); + + fn f1(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + s + } + + fn f2(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + let x = true; + if x { + s + } else { + s + } + } + + fn f3(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + return s; + } + + fn f4(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + let _x = 1; + return s; + } +} diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr new file mode 100644 index 0000000000000..8b7c5e1681ad1 --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr @@ -0,0 +1,39 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:8:24 + | +LL | fn f1(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:13:24 + | +LL | fn f2(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:23:24 + | +LL | fn f3(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:28:24 + | +LL | fn f4(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index a95b44e807c5d..29a21a1f45f56 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -47,7 +47,7 @@ impl Test9 { fn test11(x: &usize) -> &_ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types - &x //~ ERROR cannot return reference to function parameter + &x } unsafe fn test12(x: *const usize) -> *const *const _ { diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 7977504dae1d6..9d295f88da5aa 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -158,7 +158,7 @@ LL | fn test11(x: &usize) -> &_ { | -^ | || | |not allowed in type signatures - | help: replace with the correct return type: `&'static &'static usize` + | help: replace with the correct return type: `&&usize` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:53:52 @@ -687,13 +687,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | -error[E0515]: cannot return reference to function parameter `x` - --> $DIR/typeck_type_placeholder_item.rs:50:5 - | -LL | &x - | ^^ returns a reference to data owned by the current function - -error: aborting due to 75 previous errors +error: aborting due to 74 previous errors -Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515. +Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403. For more information about an error, try `rustc --explain E0015`. From 9098474dadaa7a6034652313bd4914ddbcf764c5 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 29 Jun 2024 08:06:26 +0300 Subject: [PATCH 154/217] create `shared_helpers::parse_value_from_args` Signed-off-by: onur-ozkan --- src/bootstrap/src/bin/rustc.rs | 27 +++++++++--------- src/bootstrap/src/bin/rustdoc.rs | 20 ++++++------- src/bootstrap/src/utils/helpers.rs | 4 +-- src/bootstrap/src/utils/shared_helpers.rs | 17 ++++++++++- .../src/utils/shared_helpers/tests.rs | 28 +++++++++++++++++++ 5 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 src/bootstrap/src/utils/shared_helpers/tests.rs diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index d227419917767..009e62469b4d1 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -20,26 +20,24 @@ use std::path::{Path, PathBuf}; use std::process::{Child, Command}; use std::time::Instant; -use dylib_util::{dylib_path, dylib_path_var, exe}; +use shared_helpers::{ + dylib_path, dylib_path_var, exe, maybe_dump, parse_rustc_stage, parse_rustc_verbose, + parse_value_from_args, +}; -#[path = "../utils/bin_helpers.rs"] -mod bin_helpers; - -#[path = "../utils/dylib.rs"] -mod dylib_util; +#[path = "../utils/shared_helpers.rs"] +mod shared_helpers; fn main() { let orig_args = env::args_os().skip(1).collect::>(); let mut args = orig_args.clone(); - let arg = - |name| orig_args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); - let stage = bin_helpers::parse_rustc_stage(); - let verbose = bin_helpers::parse_rustc_verbose(); + let stage = parse_rustc_stage(); + let verbose = parse_rustc_verbose(); // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = arg("--target"); + let target = parse_value_from_args(&orig_args, "--target"); let version = args.iter().find(|w| &**w == "-vV"); // Use a different compiler for build scripts, since there may not yet be a @@ -102,7 +100,7 @@ fn main() { cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. - let crate_name = arg("--crate-name"); + let crate_name = parse_value_from_args(&orig_args, "--crate-name"); if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { @@ -143,10 +141,11 @@ fn main() { cmd.arg("-C").arg("panic=abort"); } + let crate_type = parse_value_from_args(&orig_args, "--crate-type"); // `-Ztls-model=initial-exec` must not be applied to proc-macros, see // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() - && arg("--crate-type") != Some("proc-macro") + && crate_type != Some("proc-macro") && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) { cmd.arg("-Ztls-model=initial-exec"); @@ -251,7 +250,7 @@ fn main() { eprintln!("{prefix} libdir: {libdir:?}"); } - bin_helpers::maybe_dump(format!("stage{stage}-rustc"), &cmd); + maybe_dump(format!("stage{stage}-rustc"), &cmd); let start = Instant::now(); let (child, status) = { diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index b4d1415189cfa..ba6b0c2dbdad7 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -6,19 +6,19 @@ use std::env; use std::path::PathBuf; use std::process::Command; -use dylib_util::{dylib_path, dylib_path_var}; +use shared_helpers::{ + dylib_path, dylib_path_var, maybe_dump, parse_rustc_stage, parse_rustc_verbose, + parse_value_from_args, +}; -#[path = "../utils/bin_helpers.rs"] -mod bin_helpers; - -#[path = "../utils/dylib.rs"] -mod dylib_util; +#[path = "../utils/shared_helpers.rs"] +mod shared_helpers; fn main() { let args = env::args_os().skip(1).collect::>(); - let stage = bin_helpers::parse_rustc_stage(); - let verbose = bin_helpers::parse_rustc_verbose(); + let stage = parse_rustc_stage(); + let verbose = parse_rustc_verbose(); let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set"); let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set"); @@ -26,7 +26,7 @@ fn main() { // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str()); + let target = parse_value_from_args(&args, "--target"); let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(libdir.clone())); @@ -62,7 +62,7 @@ fn main() { cmd.arg("-Zunstable-options"); cmd.arg("--check-cfg=cfg(bootstrap)"); - bin_helpers::maybe_dump(format!("stage{stage}-rustdoc"), &cmd); + maybe_dump(format!("stage{stage}-rustdoc"), &cmd); if verbose > 1 { eprintln!( diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 59b29eedb7971..9fed7de681458 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -18,7 +18,7 @@ use crate::core::builder::Builder; use crate::core::config::{Config, TargetSelection}; use crate::LldMode; -pub use crate::utils::dylib::{dylib_path, dylib_path_var}; +pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var}; #[cfg(test)] mod tests; @@ -50,7 +50,7 @@ macro_rules! t { pub use t; pub fn exe(name: &str, target: TargetSelection) -> String { - crate::utils::dylib::exe(name, &target.triple) + crate::utils::shared_helpers::exe(name, &target.triple) } /// Returns `true` if the file name given looks like a dynamic library. diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 8ec7116f6cab1..7150c84313c55 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -44,7 +44,6 @@ pub fn dylib_path() -> Vec { /// Given an executable called `name`, return the filename for the /// executable for a particular target. -#[allow(dead_code)] pub fn exe(name: &str, target: &str) -> String { if target.contains("windows") { format!("{name}.exe") @@ -95,3 +94,19 @@ pub fn maybe_dump(dump_name: String, cmd: &Command) { file.write_all(cmd_dump.as_bytes()).expect("Unable to write file"); } } + +/// Finds `key` and returns its value from the given list of arguments `args`. +pub fn parse_value_from_args<'a>(args: &'a [OsString], key: &str) -> Option<&'a str> { + let mut args = args.iter(); + while let Some(arg) = args.next() { + let arg = arg.to_str().unwrap(); + + if let Some(value) = arg.strip_prefix(&format!("{key}=")) { + return Some(value); + } else if arg == key { + return args.next().map(|v| v.to_str().unwrap()); + } + } + + None +} diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/shared_helpers/tests.rs new file mode 100644 index 0000000000000..da7924276f7c8 --- /dev/null +++ b/src/bootstrap/src/utils/shared_helpers/tests.rs @@ -0,0 +1,28 @@ +use super::parse_value_from_args; + +#[test] +fn test_parse_value_from_args() { + let args = vec![ + "--stage".into(), + "1".into(), + "--version".into(), + "2".into(), + "--target".into(), + "x86_64-unknown-linux".into(), + ]; + + assert_eq!(parse_value_from_args(args.as_slice(), "--stage").unwrap(), "1"); + assert_eq!(parse_value_from_args(args.as_slice(), "--version").unwrap(), "2"); + assert_eq!(parse_value_from_args(args.as_slice(), "--target").unwrap(), "x86_64-unknown-linux"); + assert!(parse_value_from_args(args.as_slice(), "random-key").is_none()); + + let args = vec![ + "app-name".into(), + "--key".into(), + "value".into(), + "random-value".into(), + "--sysroot=/x/y/z".into(), + ]; + assert_eq!(parse_value_from_args(args.as_slice(), "--key").unwrap(), "value"); + assert_eq!(parse_value_from_args(args.as_slice(), "--sysroot").unwrap(), "/x/y/z"); +} From fa12064d6de52baeb3ca4f5fdc26828facb6c11c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 29 Jun 2024 07:27:25 +0000 Subject: [PATCH 155/217] Don't get output if `lldb --version` errors --- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1ef5af7cc2daf..55010f09049eb 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -7,6 +7,7 @@ use std::env; use std::ffi::OsStr; use std::ffi::OsString; use std::fs; +use std::io::ErrorKind; use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1830,6 +1831,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let lldb_version = Command::new(&lldb_exe) .arg("--version") .output() + .and_then(|output| { + if output.status.success() { Ok(output) } else { Err(ErrorKind::Other.into()) } + }) .map(|output| String::from_utf8_lossy(&output.stdout).to_string()) .ok(); if let Some(ref vers) = lldb_version { From c59e7fd95b985cb3622cdbf46cf31b7b250a0342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 23 Jun 2024 18:14:44 +0200 Subject: [PATCH 156/217] crashes: add more tests --- tests/crashes/126646.rs | 18 ++++++++++++++++++ tests/crashes/126648.rs | 8 ++++++++ tests/crashes/126666.rs | 18 ++++++++++++++++++ tests/crashes/126667.rs | 14 ++++++++++++++ tests/crashes/126680.rs | 21 +++++++++++++++++++++ tests/crashes/126696.rs | 24 ++++++++++++++++++++++++ tests/crashes/126725.rs | 20 ++++++++++++++++++++ tests/crashes/126744.rs | 8 ++++++++ tests/crashes/126850.rs | 11 +++++++++++ 9 files changed, 142 insertions(+) create mode 100644 tests/crashes/126646.rs create mode 100644 tests/crashes/126648.rs create mode 100644 tests/crashes/126666.rs create mode 100644 tests/crashes/126667.rs create mode 100644 tests/crashes/126680.rs create mode 100644 tests/crashes/126696.rs create mode 100644 tests/crashes/126725.rs create mode 100644 tests/crashes/126744.rs create mode 100644 tests/crashes/126850.rs diff --git a/tests/crashes/126646.rs b/tests/crashes/126646.rs new file mode 100644 index 0000000000000..24e3530320a89 --- /dev/null +++ b/tests/crashes/126646.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#126646 +mod foo { + pub trait Callable { + type Output; + fn call() -> Self::Output; + } + + impl<'a, V: ?Sized> Callable for &'a () { + type Output = (); + } +} +use foo::*; + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn main() {} diff --git a/tests/crashes/126648.rs b/tests/crashes/126648.rs new file mode 100644 index 0000000000000..1cf3e44bba9bc --- /dev/null +++ b/tests/crashes/126648.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#126648 +struct Outest(*const &'a ()); + +fn make() -> Outest {} + +fn main() { + if let Outest("foo") = make() {} +} diff --git a/tests/crashes/126666.rs b/tests/crashes/126666.rs new file mode 100644 index 0000000000000..58526707c9ab4 --- /dev/null +++ b/tests/crashes/126666.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#126666 +#![feature(const_mut_refs)] +#![feature(const_refs_to_static)] +#![feature(object_safe_for_dispatch)] + +struct Meh { + x: &'static dyn UnsafeCell, +} + +const MUH: Meh = Meh { + x: &mut *(&READONLY as *const _ as *mut _), +}; + +static READONLY: i32 = 0; + +trait UnsafeCell<'a> {} + +pub fn main() {} diff --git a/tests/crashes/126667.rs b/tests/crashes/126667.rs new file mode 100644 index 0000000000000..27b170d6da5fc --- /dev/null +++ b/tests/crashes/126667.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#126667 +#![warn(rust_2021_compatibility)] + +trait Static<'a> {} + +struct Foo((u32, u32)); + +fn main() { + type T = impl Static; + let foo: T = Foo((1u32, 2u32)); + let x = move || { + let Foo((a, b)) = foo; + }; +} diff --git a/tests/crashes/126680.rs b/tests/crashes/126680.rs new file mode 100644 index 0000000000000..b1566d5e6beed --- /dev/null +++ b/tests/crashes/126680.rs @@ -0,0 +1,21 @@ +//@ known-bug: rust-lang/rust#126680 +//@ compile-flags: -Zvalidate-mir +#![feature(type_alias_impl_trait)] +type Bar = impl std::fmt::Display; + +use std::path::Path; + +struct A { + pub func: fn(check: Bar, b: Option<&Path>), +} +const MY_A: A = A { + func: |check, b| { + if check { + () + } else if let Some(_) = b.and_then(|p| p.parent()) { + () + } + }, +}; + +fn main() {} diff --git a/tests/crashes/126696.rs b/tests/crashes/126696.rs new file mode 100644 index 0000000000000..51dcf6cf29405 --- /dev/null +++ b/tests/crashes/126696.rs @@ -0,0 +1,24 @@ +//@ known-bug: rust-lang/rust#126696 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn can_double(x: [(); N]) +where + [(); N * 2]:, +{ + x[0]; + unimplemented!() +} + +fn foo() +where + [(); (N + 1) * 2]:, +{ + can_double([(); { N + 1 }]); + // Adding an explicit constant generic causes the ICE to go away + // can_double::<{N + 1}>([(); { N + 1 }]); +} + +fn main() { + foo::<1>(); +} diff --git a/tests/crashes/126725.rs b/tests/crashes/126725.rs new file mode 100644 index 0000000000000..d7a7d21ae4244 --- /dev/null +++ b/tests/crashes/126725.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#126725 +trait Foo { + fn foo<'a>(&'a self) -> <&'a impl Sized as Bar>::Output; +} + +trait Bar { + type Output; +} + +struct X(i32); + +impl<'a> Bar for &'a X { + type Output = &'a i32; +} + +impl Foo for X { + fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output { + &self.0 + } +} diff --git a/tests/crashes/126744.rs b/tests/crashes/126744.rs new file mode 100644 index 0000000000000..ed562c86e61b2 --- /dev/null +++ b/tests/crashes/126744.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#126744 +struct X {,} + +fn main() { + || { + if let X { x: 1,} = (X {}) {} + }; +} diff --git a/tests/crashes/126850.rs b/tests/crashes/126850.rs new file mode 100644 index 0000000000000..0ddc24c8bb151 --- /dev/null +++ b/tests/crashes/126850.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#126850 +fn bug() -> impl Iterator< + Item = [(); { + |found: &String| Some(false); + 4 + }], +> { + std::iter::empty() +} + +fn main() {} From a6ef91e41425ba315cb11ee20a99f3fdc714c6cf Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 29 Jun 2024 07:57:58 +0000 Subject: [PATCH 157/217] Update test.rs --- src/bootstrap/src/core/build_steps/test.rs | 28 ++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 55010f09049eb..7ac39227d3f17 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -7,7 +7,6 @@ use std::env; use std::ffi::OsStr; use std::ffi::OsString; use std::fs; -use std::io::ErrorKind; use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1817,26 +1816,25 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--gdb").arg(gdb); } - let run = |cmd: &mut Command| { - cmd.output().map(|output| { - String::from_utf8_lossy(&output.stdout) - .lines() - .next() - .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) - .to_string() - }) - }; - let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); let lldb_version = Command::new(&lldb_exe) .arg("--version") .output() - .and_then(|output| { - if output.status.success() { Ok(output) } else { Err(ErrorKind::Other.into()) } + .map(|output| { + (String::from_utf8_lossy(&output.stdout).to_string(), output.status.success()) }) - .map(|output| String::from_utf8_lossy(&output.stdout).to_string()) - .ok(); + .ok() + .and_then(|(output, success)| if success { Some(output) } else { None }); if let Some(ref vers) = lldb_version { + let run = |cmd: &mut Command| { + cmd.output().map(|output| { + String::from_utf8_lossy(&output.stdout) + .lines() + .next() + .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) + .to_string() + }) + }; cmd.arg("--lldb-version").arg(vers); let lldb_python_dir = run(Command::new(&lldb_exe).arg("-P")).ok(); if let Some(ref dir) = lldb_python_dir { From 4442fd7a0985ad3ac219b4f9ce8f26a27500acac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 28 Jun 2024 12:18:32 +0200 Subject: [PATCH 158/217] Add a run-make test that LLD is not being used by default on the x64 beta/stable channel --- .../rust-lld-by-default-beta-stable/main.rs | 1 + .../rust-lld-by-default-beta-stable/rmake.rs | 29 +++++++++++++++++++ .../main.rs | 0 .../rmake.rs | 4 +-- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/run-make/rust-lld-by-default-beta-stable/main.rs create mode 100644 tests/run-make/rust-lld-by-default-beta-stable/rmake.rs rename tests/run-make/{rust-lld-by-default => rust-lld-by-default-nightly}/main.rs (100%) rename tests/run-make/{rust-lld-by-default => rust-lld-by-default-nightly}/rmake.rs (93%) diff --git a/tests/run-make/rust-lld-by-default-beta-stable/main.rs b/tests/run-make/rust-lld-by-default-beta-stable/main.rs new file mode 100644 index 0000000000000..f328e4d9d04c3 --- /dev/null +++ b/tests/run-make/rust-lld-by-default-beta-stable/main.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs new file mode 100644 index 0000000000000..fc3dffdbaf42a --- /dev/null +++ b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs @@ -0,0 +1,29 @@ +// Ensure that rust-lld is *not* used as the default linker on `x86_64-unknown-linux-gnu` on stable +// or beta. + +//@ ignore-nightly +//@ only-x86_64-unknown-linux-gnu + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // A regular compilation should not use rust-lld by default. We'll check that by asking the + // linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .link_arg("-Wl,-v") + .input("main.rs") + .run(); + assert!( + !find_lld_version_in_logs(output.stderr_utf8()), + "the LLD version string should not be present in the output logs:\n{}", + output.stderr_utf8() + ); +} + +fn find_lld_version_in_logs(stderr: String) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line.trim())) +} diff --git a/tests/run-make/rust-lld-by-default/main.rs b/tests/run-make/rust-lld-by-default-nightly/main.rs similarity index 100% rename from tests/run-make/rust-lld-by-default/main.rs rename to tests/run-make/rust-lld-by-default-nightly/main.rs diff --git a/tests/run-make/rust-lld-by-default/rmake.rs b/tests/run-make/rust-lld-by-default-nightly/rmake.rs similarity index 93% rename from tests/run-make/rust-lld-by-default/rmake.rs rename to tests/run-make/rust-lld-by-default-nightly/rmake.rs index 94857a57dfb7c..f3ce9ada15709 100644 --- a/tests/run-make/rust-lld-by-default/rmake.rs +++ b/tests/run-make/rust-lld-by-default-nightly/rmake.rs @@ -1,5 +1,5 @@ -// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu`, and that it can -// also be turned off with a CLI flag. +// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` on the nightly +// channel, and that it can also be turned off with a CLI flag. //@ needs-rust-lld //@ ignore-beta From 4ee077aa63cbcf0e4f398988939fdb6bb020c322 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Jun 2024 16:15:08 +0200 Subject: [PATCH 159/217] Migrate `run-make/override-aliased-flags` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/override-aliased-flags/Makefile | 23 ------------------ .../run-make/override-aliased-flags/rmake.rs | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 tests/run-make/override-aliased-flags/Makefile create mode 100644 tests/run-make/override-aliased-flags/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..f601151294eb9 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -114,7 +114,6 @@ run-make/obey-crate-type-flag/Makefile run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile -run-make/override-aliased-flags/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile diff --git a/tests/run-make/override-aliased-flags/Makefile b/tests/run-make/override-aliased-flags/Makefile deleted file mode 100644 index db1ff1ff98161..0000000000000 --- a/tests/run-make/override-aliased-flags/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# FIXME: it would be good to check that it's actually the rightmost flags -# that are used when multiple flags are specified, but I can't think of a -# reliable way to check this. - -all: - # Test that `-O` and `-C opt-level` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -O -O main.rs - $(RUSTC) -O -C opt-level=0 main.rs - $(RUSTC) -C opt-level=0 -O main.rs - $(RUSTC) -C opt-level=0 -C opt-level=2 main.rs - $(RUSTC) -C opt-level=2 -C opt-level=0 main.rs - - # Test that `-g` and `-C debuginfo` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -g -g main.rs - $(RUSTC) -g -C debuginfo=0 main.rs - $(RUSTC) -C debuginfo=0 -g main.rs - $(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs - $(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs diff --git a/tests/run-make/override-aliased-flags/rmake.rs b/tests/run-make/override-aliased-flags/rmake.rs new file mode 100644 index 0000000000000..e610c04651e95 --- /dev/null +++ b/tests/run-make/override-aliased-flags/rmake.rs @@ -0,0 +1,24 @@ +//@ ignore-cross-compile + +use run_make_support::rustc; + +// FIXME: it would be good to check that it's actually the rightmost flags +// that are used when multiple flags are specified, but I can't think of a +// reliable way to check this. +fn main() { + // Test that `-O` and `-C opt-level` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-O").arg("-O").input("main.rs").run(); + rustc().arg("-O").arg("-C").arg("opt-level=0").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-O").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-C").arg("opt-level=2").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=2").arg("-C").arg("opt-level=0").input("main.rs").run(); + + // Test that `-g` and `-C debuginfo` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-g").arg("-g").input("main.rs").run(); + rustc().arg("-g").arg("-C").arg("debuginfo=0").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-g").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-C").arg("debuginfo=2").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=2").arg("-C").arg("debuginfo=0").input("main.rs").run(); +} From b1d1e663892f43ca8ea9efe999e25e83f9b6dded Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 13:40:17 +0200 Subject: [PATCH 160/217] Add back `help-page.goml` rustdoc GUI test --- tests/rustdoc-gui/help-page.goml | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tests/rustdoc-gui/help-page.goml diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml new file mode 100644 index 0000000000000..09d33af139cdd --- /dev/null +++ b/tests/rustdoc-gui/help-page.goml @@ -0,0 +1,69 @@ +// This test ensures that opening the help page in its own tab works. +include: "utils.goml" +go-to: "file://" + |DOC_PATH| + "/help.html" +set-window-size: (1000, 1000) // Try desktop size first. +wait-for: "#help" +assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) +click: "#help-button > a" +assert-css: ("#help", {"display": "block"}) +compare-elements-property: (".sub", "#help", ["offsetWidth"]) +compare-elements-position: (".sub", "#help", ["x"]) +set-window-size: (500, 1000) // Try mobile next. +assert-css: ("#help", {"display": "block"}) +compare-elements-property: (".sub", "#help", ["offsetWidth"]) +compare-elements-position: (".sub", "#help", ["x"]) + +// Checking the color of the elements of the help menu. +show-text: true +define-function: ( + "check-colors", + [theme, color, background, box_shadow], + block { + call-function: ("switch-theme", {"theme": |theme|}) + assert-css: ("#help kbd", { + "color": |color|, + "background-color": |background|, + "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset", + }, ALL) + }, +) + +call-function: ("check-colors", { + "theme": "ayu", + "color": "#c5c5c5", + "background": "#314559", + "box_shadow": "#5c6773", +}) +call-function: ("check-colors", { + "theme": "dark", + "color": "#000", + "background": "#fafbfc", + "box_shadow": "#c6cbd1", +}) +call-function: ("check-colors", { + "theme": "light", + "color": "#000", + "background": "#fafbfc", + "box_shadow": "#c6cbd1", +}) + +// This test ensures that opening the help popover without switching pages works. +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1000, 1000) // Only supported on desktop. +assert-false: "#help" +click: "#help-button > a" +assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) +click: "#help-button > a" +assert-css: ("#help", {"display": "none"}) +compare-elements-property-false: (".sub", "#help", ["offsetWidth"]) +compare-elements-position-false: (".sub", "#help", ["x"]) + +// This test ensures that the "the rustdoc book" anchor link within the help popover works. +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1000, 1000) // Popover only appears when the screen width is >700px. +assert-false: "#help" +click: "#help-button > a" +click: "//*[@id='help']//a[text()='the rustdoc book']" +wait-for-document-property: ({"URL": "https://doc.rust-lang.org/"}, STARTS_WITH) From c8bbeef12ff7499aa163aef79447677b47499006 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 14:24:41 +0200 Subject: [PATCH 161/217] Don't call `switch-theme` function --- tests/rustdoc-gui/help-page.goml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml index 09d33af139cdd..f1a2675128ce4 100644 --- a/tests/rustdoc-gui/help-page.goml +++ b/tests/rustdoc-gui/help-page.goml @@ -1,5 +1,4 @@ // This test ensures that opening the help page in its own tab works. -include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/help.html" set-window-size: (1000, 1000) // Try desktop size first. wait-for: "#help" @@ -20,7 +19,9 @@ define-function: ( "check-colors", [theme, color, background, box_shadow], block { - call-function: ("switch-theme", {"theme": |theme|}) + // FIXME: no clue why we can't call the `switch-theme` function here... + set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: assert-css: ("#help kbd", { "color": |color|, "background-color": |background|, From 8cbeedac8de7bbf7676129f07f338d106a162036 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 29 Jun 2024 12:18:26 +0200 Subject: [PATCH 162/217] Migrate `run-make/return-non-c-like-enum` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/return-non-c-like-enum/Makefile | 8 -------- tests/run-make/return-non-c-like-enum/rmake.rs | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) delete mode 100644 tests/run-make/return-non-c-like-enum/Makefile create mode 100644 tests/run-make/return-non-c-like-enum/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..8c59112f595f4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -147,7 +147,6 @@ run-make/remap-path-prefix/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/return-non-c-like-enum-from-c/Makefile -run-make/return-non-c-like-enum/Makefile run-make/rlib-chain/Makefile run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile diff --git a/tests/run-make/return-non-c-like-enum/Makefile b/tests/run-make/return-non-c-like-enum/Makefile deleted file mode 100644 index 0c8d8bf3acc60..0000000000000 --- a/tests/run-make/return-non-c-like-enum/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) --crate-type=staticlib nonclike.rs - $(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - $(call RUN,test) diff --git a/tests/run-make/return-non-c-like-enum/rmake.rs b/tests/run-make/return-non-c-like-enum/rmake.rs new file mode 100644 index 0000000000000..e698790b43c06 --- /dev/null +++ b/tests/run-make/return-non-c-like-enum/rmake.rs @@ -0,0 +1,18 @@ +// Check that we treat enum variants like union members in call ABIs. +// Added in #68443. +// Original issue: #68190. + +//@ ignore-cross-compile + +use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib_name}; + +fn main() { + rustc().crate_type("staticlib").input("nonclike.rs").run(); + cc().input("test.c") + .arg(&static_lib_name("nonclike")) + .out_exe("test") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + run("test"); +} From 61ede075bfbb1bcbe09595565381ab9c5ef5deec Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 14:21:13 +0000 Subject: [PATCH 163/217] Stop ICEing on impossible predicates. --- compiler/rustc_mir_dataflow/src/value_analysis.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 5e2d88f94ca28..bfbfff7e25944 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -846,9 +846,10 @@ impl Map { if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ref_ty, _) = ty.kind() && let ty::Slice(..) = ref_ty.kind() + // The user may have written a predicate like `[T]: Sized` in their where clauses, + // which makes slices scalars. + && self.places[place].value_index.is_none() { - assert!(self.places[place].value_index.is_none(), "slices are not scalars"); - // Prepend new child to the linked list. let len = self.places.push(PlaceInfo::new(Some(TrackElem::DerefLen))); self.places[len].next_sibling = self.places[place].first_child; From a175817ea6b554a3baa2debc4bcfdea88e467eeb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 22:25:03 +0000 Subject: [PATCH 164/217] Avoid cloning state when possible. --- compiler/rustc_mir_transform/src/jump_threading.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 23cc0c46e7397..0dad003ee5f42 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -270,12 +270,13 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { self.process_switch_int(discr, targets, bb, &mut state); self.find_opportunity(pred, state, cost, depth + 1); } - _ => self.recurse_through_terminator(pred, &state, &cost, depth), + _ => self.recurse_through_terminator(pred, || state, &cost, depth), } - } else { + } else if let &[ref predecessors @ .., last_pred] = &predecessors[..] { for &pred in predecessors { - self.recurse_through_terminator(pred, &state, &cost, depth); + self.recurse_through_terminator(pred, || state.clone(), &cost, depth); } + self.recurse_through_terminator(last_pred, || state, &cost, depth); } let new_tos = &mut self.opportunities[last_non_rec..]; @@ -566,11 +567,12 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { None } - #[instrument(level = "trace", skip(self, cost))] + #[instrument(level = "trace", skip(self, state, cost))] fn recurse_through_terminator( &mut self, bb: BasicBlock, - state: &State>, + // Pass a closure that may clone the state, as we don't want to do it each time. + state: impl FnOnce() -> State>, cost: &CostChecker<'_, 'tcx>, depth: usize, ) { @@ -600,7 +602,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { }; // We can recurse through this terminator. - let mut state = state.clone(); + let mut state = state(); if let Some(place_to_flood) = place_to_flood { state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::default()); } From dec4e985221cfa0a45828903f998ce4631c511d5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 16:18:03 +0000 Subject: [PATCH 165/217] Move entry point to a method. --- .../rustc_mir_transform/src/jump_threading.rs | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 0dad003ee5f42..27e506a920bce 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -91,43 +91,8 @@ impl<'tcx> MirPass<'tcx> for JumpThreading { opportunities: Vec::new(), }; - for (bb, bbdata) in body.basic_blocks.iter_enumerated() { - debug!(?bb, term = ?bbdata.terminator()); - if bbdata.is_cleanup || loop_headers.contains(bb) { - continue; - } - let Some((discr, targets)) = bbdata.terminator().kind.as_switch() else { continue }; - let Some(discr) = discr.place() else { continue }; - debug!(?discr, ?bb); - - let discr_ty = discr.ty(body, tcx).ty; - let Ok(discr_layout) = finder.ecx.layout_of(discr_ty) else { continue }; - - let Some(discr) = finder.map.find(discr.as_ref()) else { continue }; - debug!(?discr); - - let cost = CostChecker::new(tcx, param_env, None, body); - - let mut state = State::new(ConditionSet::default(), finder.map); - - let conds = if let Some((value, then, else_)) = targets.as_static_if() { - let Some(value) = ScalarInt::try_from_uint(value, discr_layout.size) else { - continue; - }; - arena.alloc_from_iter([ - Condition { value, polarity: Polarity::Eq, target: then }, - Condition { value, polarity: Polarity::Ne, target: else_ }, - ]) - } else { - arena.alloc_from_iter(targets.iter().filter_map(|(value, target)| { - let value = ScalarInt::try_from_uint(value, discr_layout.size)?; - Some(Condition { value, polarity: Polarity::Eq, target }) - })) - }; - let conds = ConditionSet(conds); - state.insert_value_idx(discr, conds, finder.map); - - finder.find_opportunity(bb, state, cost, 0); + for bb in body.basic_blocks.indices() { + finder.start_from_switch(bb); } let opportunities = finder.opportunities; @@ -216,6 +181,46 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { } /// Recursion entry point to find threading opportunities. + #[instrument(level = "trace", skip(self))] + fn start_from_switch(&mut self, bb: BasicBlock) -> Option { + let bbdata = &self.body[bb]; + if bbdata.is_cleanup || self.loop_headers.contains(bb) { + return None; + } + let (discr, targets) = bbdata.terminator().kind.as_switch()?; + let discr = discr.place()?; + debug!(?discr, ?bb); + + let discr_ty = discr.ty(self.body, self.tcx).ty; + let discr_layout = self.ecx.layout_of(discr_ty).ok()?; + + let discr = self.map.find(discr.as_ref())?; + debug!(?discr); + + let cost = CostChecker::new(self.tcx, self.param_env, None, self.body); + let mut state = State::new(ConditionSet::default(), self.map); + + let conds = if let Some((value, then, else_)) = targets.as_static_if() { + let value = ScalarInt::try_from_uint(value, discr_layout.size)?; + self.arena.alloc_from_iter([ + Condition { value, polarity: Polarity::Eq, target: then }, + Condition { value, polarity: Polarity::Ne, target: else_ }, + ]) + } else { + self.arena.alloc_from_iter(targets.iter().filter_map(|(value, target)| { + let value = ScalarInt::try_from_uint(value, discr_layout.size)?; + Some(Condition { value, polarity: Polarity::Eq, target }) + })) + }; + let conds = ConditionSet(conds); + state.insert_value_idx(discr, conds, self.map); + + self.find_opportunity(bb, state, cost, 0); + None + } + + /// Recursively walk statements backwards from this bb's terminator to find threading + /// opportunities. #[instrument(level = "trace", skip(self, cost), ret)] fn find_opportunity( &mut self, From c81481fdb91cca96635017e7275139b0f2cd8fe6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 27 Jun 2024 09:39:37 +0000 Subject: [PATCH 166/217] Move crash test. --- .../116721.rs => ui/mir/sized-slice-predicate-116721.rs} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename tests/{crashes/116721.rs => ui/mir/sized-slice-predicate-116721.rs} (82%) diff --git a/tests/crashes/116721.rs b/tests/ui/mir/sized-slice-predicate-116721.rs similarity index 82% rename from tests/crashes/116721.rs rename to tests/ui/mir/sized-slice-predicate-116721.rs index fc1a6530bc82b..c6a0aca2da80d 100644 --- a/tests/crashes/116721.rs +++ b/tests/ui/mir/sized-slice-predicate-116721.rs @@ -1,5 +1,6 @@ -//@ known-bug: #116721 +//@ build-pass //@ compile-flags: -Zmir-opt-level=3 --emit=mir + fn hey(it: &[T]) where [T]: Clone, From 9c0ce05d246811a977b6564b7df2b6947bd6903b Mon Sep 17 00:00:00 2001 From: surechen Date: Sat, 29 Jun 2024 18:45:07 +0800 Subject: [PATCH 167/217] Show `used attribute`'s kind for user when find it isn't applied to a `static` variable. fixes #126789 --- compiler/rustc_passes/messages.ftl | 1 + compiler/rustc_passes/src/check_attr.rs | 10 +++++++--- compiler/rustc_passes/src/errors.rs | 3 +++ tests/ui/attributes/used-issue-126789.rs | 6 ++++++ tests/ui/attributes/used-issue-126789.stderr | 10 ++++++++++ tests/ui/used.stderr | 8 ++++++++ 6 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tests/ui/attributes/used-issue-126789.rs create mode 100644 tests/ui/attributes/used-issue-126789.stderr diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 07c82065a80d1..3cc909a9d6e45 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -786,6 +786,7 @@ passes_used_compiler_linker = passes_used_static = attribute must be applied to a `static` variable + .label = but this is a {$target} passes_useless_assignment = useless assignment of {$is_field_assign -> diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a0b3470df6dba..238e40022c9cf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -278,7 +278,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } self.check_repr(attrs, span, target, item, hir_id); - self.check_used(attrs, target); + self.check_used(attrs, target, span); } fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { @@ -1978,12 +1978,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_used(&self, attrs: &[Attribute], target: Target) { + fn check_used(&self, attrs: &[Attribute], target: Target, target_span: Span) { let mut used_linker_span = None; let mut used_compiler_span = None; for attr in attrs.iter().filter(|attr| attr.has_name(sym::used)) { if target != Target::Static { - self.dcx().emit_err(errors::UsedStatic { span: attr.span }); + self.dcx().emit_err(errors::UsedStatic { + attr_span: attr.span, + span: target_span, + target: target.name(), + }); } let inner = attr.meta_item_list(); match inner.as_deref() { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 25df80d5a92ca..897a377ce3461 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -563,7 +563,10 @@ pub struct ReprConflictingLint; #[diag(passes_used_static)] pub struct UsedStatic { #[primary_span] + pub attr_span: Span, + #[label] pub span: Span, + pub target: &'static str, } #[derive(Diagnostic)] diff --git a/tests/ui/attributes/used-issue-126789.rs b/tests/ui/attributes/used-issue-126789.rs new file mode 100644 index 0000000000000..90a1aa8d5cc3d --- /dev/null +++ b/tests/ui/attributes/used-issue-126789.rs @@ -0,0 +1,6 @@ +extern "C" { + #[used] //~ ERROR attribute must be applied to a `static` variable + static FOO: i32; +} + +fn main() {} diff --git a/tests/ui/attributes/used-issue-126789.stderr b/tests/ui/attributes/used-issue-126789.stderr new file mode 100644 index 0000000000000..6014f7af95c55 --- /dev/null +++ b/tests/ui/attributes/used-issue-126789.stderr @@ -0,0 +1,10 @@ +error: attribute must be applied to a `static` variable + --> $DIR/used-issue-126789.rs:2:5 + | +LL | #[used] + | ^^^^^^^ +LL | static FOO: i32; + | ---------------- but this is a foreign static item + +error: aborting due to 1 previous error + diff --git a/tests/ui/used.stderr b/tests/ui/used.stderr index ea77f129d8ef0..c586dc722932f 100644 --- a/tests/ui/used.stderr +++ b/tests/ui/used.stderr @@ -3,24 +3,32 @@ error: attribute must be applied to a `static` variable | LL | #[used] | ^^^^^^^ +LL | fn foo() {} + | ----------- but this is a function error: attribute must be applied to a `static` variable --> $DIR/used.rs:7:1 | LL | #[used] | ^^^^^^^ +LL | struct Foo {} + | ------------- but this is a struct error: attribute must be applied to a `static` variable --> $DIR/used.rs:10:1 | LL | #[used] | ^^^^^^^ +LL | trait Bar {} + | ------------ but this is a trait error: attribute must be applied to a `static` variable --> $DIR/used.rs:13:1 | LL | #[used] | ^^^^^^^ +LL | impl Bar for Foo {} + | ------------------- but this is a implementation block error: aborting due to 4 previous errors From 64b3492c30eaa3a963ed87a3c306f2cb29baa5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 13:51:50 +0200 Subject: [PATCH 168/217] Rename Rust for Linux CI job to make its name clearer --- .../{rfl => x86_64-rust-for-linux}/Dockerfile | 0 src/ci/github-actions/jobs.yml | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/ci/docker/host-x86_64/{rfl => x86_64-rust-for-linux}/Dockerfile (100%) diff --git a/src/ci/docker/host-x86_64/rfl/Dockerfile b/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile similarity index 100% rename from src/ci/docker/host-x86_64/rfl/Dockerfile rename to src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index cf750bbd0c568..a6e12c6ff954d 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -215,6 +215,11 @@ auto: only_on_channel: nightly <<: *job-linux-8c + # Tests integration with Rust for Linux. + # Builds stage 1 compiler and tries to compile a few RfL examples with it. + - image: x86_64-rust-for-linux + <<: *job-linux-8c + - image: x86_64-gnu <<: *job-linux-4c @@ -465,8 +470,3 @@ auto: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths <<: *job-windows-8c - - # Tests integration with Rust for Linux. - # Builds stage 1 compiler and tries to compile a few RfL examples with it. - - image: rfl - <<: *job-linux-8c From 8dc36c16470d60fa1bd7bc370c77ac63ef25bfe4 Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Sat, 29 Jun 2024 16:49:35 +0800 Subject: [PATCH 169/217] fix: prefer `(*p).clone` to `p.clone` if the `p` is a raw pointer --- .../src/diagnostics/conflict_errors.rs | 26 +++++++++++++++--- .../src/diagnostics/move_errors.rs | 27 ++++++++++++++----- .../borrowck-move-from-unsafe-ptr.stderr | 10 ++----- tests/ui/borrowck/issue-20801.stderr | 10 ------- .../move-from-union-field-issue-66500.stderr | 10 +++---- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1cc7fee718e87..c26bbb926eaa1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1288,7 +1288,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return false; } // Try to find predicates on *generic params* that would allow copying `ty` - let suggestion = + let mut suggestion = if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { format!(": {symbol}.clone()") } else { @@ -1296,6 +1296,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { }; let mut sugg = Vec::with_capacity(2); let mut inner_expr = expr; + let mut is_raw_ptr = false; + let typeck_result = self.infcx.tcx.typeck(self.mir_def_id()); // Remove uses of `&` and `*` when suggesting `.clone()`. while let hir::ExprKind::AddrOf(.., inner) | hir::ExprKind::Unary(hir::UnOp::Deref, inner) = &inner_expr.kind @@ -1306,14 +1308,32 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return false; } inner_expr = inner; + if let Some(inner_type) = typeck_result.node_type_opt(inner.hir_id) { + if matches!(inner_type.kind(), ty::RawPtr(..)) { + is_raw_ptr = true; + break; + } + } } - if inner_expr.span.lo() != expr.span.lo() { + // Cloning the raw pointer doesn't make sense in some cases and would cause a type mismatch error. (see #126863) + if inner_expr.span.lo() != expr.span.lo() && !is_raw_ptr { + // Remove "(*" or "(&" sugg.push((expr.span.with_hi(inner_expr.span.lo()), String::new())); } + // Check whether `expr` is surrounded by parentheses or not. let span = if inner_expr.span.hi() != expr.span.hi() { // Account for `(*x)` to suggest `x.clone()`. - expr.span.with_lo(inner_expr.span.hi()) + if is_raw_ptr { + expr.span.shrink_to_hi() + } else { + // Remove the close parenthesis ")" + expr.span.with_lo(inner_expr.span.hi()) + } } else { + if is_raw_ptr { + sugg.push((expr.span.shrink_to_lo(), "(".to_string())); + suggestion = ").clone()".to_string(); + } expr.span.shrink_to_hi() }; sugg.push((span, suggestion)); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 12fa4c4f5ee05..407b83d497793 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -639,12 +639,27 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn add_borrow_suggestions(&self, err: &mut Diag<'_>, span: Span) { match self.infcx.tcx.sess.source_map().span_to_snippet(span) { Ok(snippet) if snippet.starts_with('*') => { - err.span_suggestion_verbose( - span.with_hi(span.lo() + BytePos(1)), - "consider removing the dereference here", - String::new(), - Applicability::MaybeIncorrect, - ); + let sp = span.with_lo(span.lo() + BytePos(1)); + let inner = self.find_expr(sp); + let mut is_raw_ptr = false; + if let Some(inner) = inner { + let typck_result = self.infcx.tcx.typeck(self.mir_def_id()); + if let Some(inner_type) = typck_result.node_type_opt(inner.hir_id) { + if matches!(inner_type.kind(), ty::RawPtr(..)) { + is_raw_ptr = true; + } + } + } + // If the `inner` is a raw pointer, do not suggest removing the "*", see #126863 + // FIXME: need to check whether the assigned object can be a raw pointer, see `tests/ui/borrowck/issue-20801.rs`. + if !is_raw_ptr { + err.span_suggestion_verbose( + span.with_hi(span.lo() + BytePos(1)), + "consider removing the dereference here", + String::new(), + Applicability::MaybeIncorrect, + ); + } } _ => { err.span_suggestion_verbose( diff --git a/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr b/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr index ebc3b6ebcacda..79f18624c618b 100644 --- a/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr +++ b/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr @@ -4,16 +4,10 @@ error[E0507]: cannot move out of `*x` which is behind a raw pointer LL | let y = *x; | ^^ move occurs because `*x` has type `Box`, which does not implement the `Copy` trait | -help: consider removing the dereference here - | -LL - let y = *x; -LL + let y = x; - | help: consider cloning the value if the performance cost is acceptable | -LL - let y = *x; -LL + let y = x.clone(); - | +LL | let y = (*x).clone(); + | + +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr index 20a4bd4e42378..c1d06ac3e2196 100644 --- a/tests/ui/borrowck/issue-20801.stderr +++ b/tests/ui/borrowck/issue-20801.stderr @@ -67,11 +67,6 @@ LL | struct T(u8); ... LL | let c = unsafe { *mut_ptr() }; | ---------- you could clone this value -help: consider removing the dereference here - | -LL - let c = unsafe { *mut_ptr() }; -LL + let c = unsafe { mut_ptr() }; - | error[E0507]: cannot move out of a raw pointer --> $DIR/issue-20801.rs:36:22 @@ -87,11 +82,6 @@ LL | struct T(u8); ... LL | let d = unsafe { *const_ptr() }; | ------------ you could clone this value -help: consider removing the dereference here - | -LL - let d = unsafe { *const_ptr() }; -LL + let d = unsafe { const_ptr() }; - | error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/borrowck/move-from-union-field-issue-66500.stderr b/tests/ui/borrowck/move-from-union-field-issue-66500.stderr index c951ce8e3cd8f..7f4593eefcaf6 100644 --- a/tests/ui/borrowck/move-from-union-field-issue-66500.stderr +++ b/tests/ui/borrowck/move-from-union-field-issue-66500.stderr @@ -30,9 +30,8 @@ LL | *u.c | help: consider cloning the value if the performance cost is acceptable | -LL - *u.c -LL + u.c.clone() - | +LL | (*u.c).clone() + | + +++++++++ error[E0507]: cannot move out of `*u.d` which is behind a raw pointer --> $DIR/move-from-union-field-issue-66500.rs:24:5 @@ -42,9 +41,8 @@ LL | *u.d | help: consider cloning the value if the performance cost is acceptable | -LL - *u.d -LL + u.d.clone() - | +LL | (*u.d).clone() + | + +++++++++ error: aborting due to 4 previous errors From 614e04226df82e04c8c3ce30abfda67f26a93bc2 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:13:55 -0400 Subject: [PATCH 170/217] Migrate `volatile-intrinsics` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/volatile-intrinsics/Makefile | 10 ---------- tests/run-make/volatile-intrinsics/rmake.rs | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 11 deletions(-) delete mode 100644 tests/run-make/volatile-intrinsics/Makefile create mode 100644 tests/run-make/volatile-intrinsics/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..ad80ac8d7c951 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,7 +186,6 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile run-make/weird-output-filenames/Makefile diff --git a/tests/run-make/volatile-intrinsics/Makefile b/tests/run-make/volatile-intrinsics/Makefile deleted file mode 100644 index 5672a045873dd..0000000000000 --- a/tests/run-make/volatile-intrinsics/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - # The tests must pass... - $(RUSTC) main.rs - $(call RUN,main) - # ... and the loads/stores must not be optimized out. - $(RUSTC) main.rs --emit=llvm-ir - $(CGREP) "load volatile" "store volatile" < $(TMPDIR)/main.ll diff --git a/tests/run-make/volatile-intrinsics/rmake.rs b/tests/run-make/volatile-intrinsics/rmake.rs new file mode 100644 index 0000000000000..fb9be4bb9ba23 --- /dev/null +++ b/tests/run-make/volatile-intrinsics/rmake.rs @@ -0,0 +1,18 @@ +//@ ignore-cross-compile + +use run_make_support::fs_wrapper::read; +use run_make_support::{assert_contains, run, rustc}; + +fn main() { + // The tests must pass... + rustc().input("main.rs").run(); + run("main"); + + // ... and the loads/stores must not be optimized out. + rustc().input("main.rs").emit("llvm-ir").run(); + + let raw_llvm_ir = read("main.ll"); + let llvm_ir = String::from_utf8_lossy(&raw_llvm_ir); + assert_contains(&llvm_ir, "load volatile"); + assert_contains(&llvm_ir, "store volatile"); +} From 56fe015d4a2dac7281f573d52aef61835cab3bf9 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:31:27 -0400 Subject: [PATCH 171/217] Migrate `weird-output-filenames` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/weird-output-filenames/Makefile | 15 --------------- .../run-make/weird-output-filenames/rmake.rs | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/weird-output-filenames/Makefile create mode 100644 tests/run-make/weird-output-filenames/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index ad80ac8d7c951..f7e1aeb75276a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -188,5 +188,4 @@ run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile -run-make/weird-output-filenames/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/weird-output-filenames/Makefile b/tests/run-make/weird-output-filenames/Makefile deleted file mode 100644 index d3a34e3b46e89..0000000000000 --- a/tests/run-make/weird-output-filenames/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../tools.mk - -all: - cp foo.rs $(TMPDIR)/.foo.rs - $(RUSTC) $(TMPDIR)/.foo.rs 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/.foo.bar - $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/+foo+bar.rs - $(RUSTC) $(TMPDIR)/+foo+bar.rs 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/-foo.rs - $(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \ - | $(CGREP) 'crate names cannot start with a `-`' diff --git a/tests/run-make/weird-output-filenames/rmake.rs b/tests/run-make/weird-output-filenames/rmake.rs new file mode 100644 index 0000000000000..ed331a0b8d4ea --- /dev/null +++ b/tests/run-make/weird-output-filenames/rmake.rs @@ -0,0 +1,19 @@ +use run_make_support::fs_wrapper::copy; +use run_make_support::regex::Regex; +use run_make_support::{cwd, rustc}; + +fn main() { + let invalid_characters = [".foo.rs", ".foo.bar", "+foo+bar.rs"]; + let re = Regex::new(r"invalid character.*in crate name:").unwrap(); + for f in invalid_characters { + copy("foo.rs", f); + let stderr = rustc().input(f).run_fail().stderr_utf8(); + assert!(re.is_match(&stderr)); + } + + copy("foo.rs", "-foo.rs"); + rustc() + .input(cwd().join("-foo.rs")) + .run_fail() + .assert_stderr_contains("crate names cannot start with a `-`"); +} From 189232bc42b7c66d1f75a40a806680b3935f96ca Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:41:36 -0400 Subject: [PATCH 172/217] Migrate `wasm-override-linker` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/wasm-override-linker/Makefile | 16 ---------------- tests/run-make/wasm-override-linker/rmake.rs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 tests/run-make/wasm-override-linker/Makefile create mode 100644 tests/run-make/wasm-override-linker/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7e1aeb75276a..2ab97c3c43751 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -187,5 +187,4 @@ run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile run-make/wasm-exceptions-nostd/Makefile -run-make/wasm-override-linker/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile deleted file mode 100644 index 1a01a574dee28..0000000000000 --- a/tests/run-make/wasm-override-linker/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# needs-force-clang-based-tests - -# FIXME(#126180): This test doesn't actually run anywhere, because the only -# CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. - -include ../tools.mk - -ifeq ($(TARGET),wasm32-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) -else ifeq ($(TARGET),wasm64-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) -else -all: -endif diff --git a/tests/run-make/wasm-override-linker/rmake.rs b/tests/run-make/wasm-override-linker/rmake.rs new file mode 100644 index 0000000000000..01bc08e990159 --- /dev/null +++ b/tests/run-make/wasm-override-linker/rmake.rs @@ -0,0 +1,17 @@ +// How to run this +// $ RUSTBUILD_FORCE_CLANG_BASED_TESTS=1 ./x.py test tests/run-make/wasm-override-linker/ + +//@ needs-force-clang-based-tests + +use run_make_support::{env_var, rustc, target}; + +fn main() { + if matches!(target().as_str(), "wasm32-unknown-unknown" | "wasm64-unknown-unknown") { + rustc() + .input("foo.rs") + .crate_type("cdylib") + .target(&target()) + .linker(&env_var("CLANG")) + .run(); + } +} From 68b6bb27c1d34e6cd9fe5d6c2d8f954e0f2a0690 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:03:36 -0400 Subject: [PATCH 173/217] Migrate `wasm-exceptions-nostd` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/wasm-exceptions-nostd/Makefile | 12 ------------ tests/run-make/wasm-exceptions-nostd/rmake.rs | 18 ++++++++++++++++++ .../wasm-exceptions-nostd/src/panicking.rs | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) delete mode 100644 tests/run-make/wasm-exceptions-nostd/Makefile create mode 100644 tests/run-make/wasm-exceptions-nostd/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2ab97c3c43751..c78f9dc4c6ebf 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,5 +186,4 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/wasm-exceptions-nostd/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/wasm-exceptions-nostd/Makefile b/tests/run-make/wasm-exceptions-nostd/Makefile deleted file mode 100644 index 34755ec14b745..0000000000000 --- a/tests/run-make/wasm-exceptions-nostd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# only-wasm32-bare - -# Add a few command line args to make exceptions work -RUSTC := $(RUSTC) -C llvm-args=-wasm-enable-eh -RUSTC := $(RUSTC) -C target-feature=+exception-handling -RUSTC := $(RUSTC) -C panic=unwind - -all: - $(RUSTC) src/lib.rs --target wasm32-unknown-unknown - $(NODE) verify.mjs $(TMPDIR)/lib.wasm diff --git a/tests/run-make/wasm-exceptions-nostd/rmake.rs b/tests/run-make/wasm-exceptions-nostd/rmake.rs new file mode 100644 index 0000000000000..720ee9909d2ab --- /dev/null +++ b/tests/run-make/wasm-exceptions-nostd/rmake.rs @@ -0,0 +1,18 @@ +//@ only-wasm32-bare + +use std::path::Path; + +use run_make_support::{cmd, env_var, rustc}; + +fn main() { + // Add a few command line args to make exceptions work + rustc() + .input(Path::new("src").join("lib.rs")) + .target("wasm32-unknown-unknown") + .panic("unwind") + .arg("-Cllvm-args=-wasm-enable-eh") + .arg("-Ctarget-feature=+exception-handling") + .run(); + + cmd(&env_var("NODE")).arg("verify.mjs").arg("lib.wasm").run(); +} diff --git a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs index 52a32f3cd3034..414c9f6a1650b 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs @@ -17,8 +17,8 @@ fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { use alloc::boxed::Box; use alloc::string::ToString; - let msg = info.message().map(|msg| msg.to_string()).unwrap_or("(no message)".to_string()); - let exception = Box::new(msg.to_string()); + let msg = info.message().to_string(); + let exception = Box::new(msg); unsafe { let exception_raw = Box::into_raw(exception); wasm_throw(exception_raw as *mut u8); From 0c1df370caf489a38e8d263bb9a72565fd3ab718 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:31:08 -0400 Subject: [PATCH 174/217] Refactor `wasm-abi` to use `cmd` --- tests/run-make/wasm-abi/rmake.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index 0fc326babd943..ff12bcd536e7f 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,9 +1,8 @@ //@ only-wasm32-wasip1 //@ needs-wasmtime -use run_make_support::rustc; +use run_make_support::{cmd, rustc}; use std::path::Path; -use std::process::Command; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").run(); @@ -19,14 +18,12 @@ fn main() { } fn run(file: &Path, method: &str, expected_output: &str) { - let output = Command::new("wasmtime") + cmd("wasmtime") .arg("run") .arg("--preload=host=host.wat") .arg("--invoke") .arg(method) .arg(file) - .output() - .unwrap(); - assert!(output.status.success()); - assert_eq!(expected_output, String::from_utf8_lossy(&output.stdout)); + .run() + .assert_stdout_equals(expected_output); } From 2ef269953a99182db6d6ca9901c566eaab15d471 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:44:58 -0400 Subject: [PATCH 175/217] Refactor `compressed-debuginfo` to use `llvm_readobj` --- tests/run-make/compressed-debuginfo/rmake.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 9c6d50ab243cd..37002c672d8c0 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -5,7 +5,7 @@ // FIXME: This test isn't comprehensive and isn't covering all possible combinations. -use run_make_support::{assert_contains, cmd, run_in_tmpdir, rustc}; +use run_make_support::{assert_contains, cmd, llvm_readobj, run_in_tmpdir, rustc}; fn check_compression(compression: &str, to_find: &str) { run_in_tmpdir(|| { @@ -19,8 +19,7 @@ fn check_compression(compression: &str, to_find: &str) { .run(); let stderr = out.stderr_utf8(); if stderr.is_empty() { - // FIXME: `readelf` might need to be replaced with `llvm-readelf`. - cmd("readelf").arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); + llvm_readobj().arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); } else { assert_contains( &stderr, From 28ba5e4124659107bd0ed08ba5c480d0e71c3aa1 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Wed, 19 Jun 2024 21:19:20 +0300 Subject: [PATCH 176/217] Updated docs on `#[panic_handler]` in `library/core/src/lib.rs` --- library/core/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ef28bc99c4fc8..4bc0e37800ed5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -34,12 +34,9 @@ //! Rust user code is to call the functions provided by this library instead (such as //! `ptr::copy`). //! -//! * `rust_begin_panic` - This function takes four arguments, a -//! `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments -//! dictate the panic message, the file at which panic was invoked, and the -//! line and column inside the file. It is up to consumers of this core +//! * Panic handler - This function takes one argument, a `&panic::PanicInfo`. It is up to consumers of this core //! library to define this panic function; it is only required to never -//! return. This requires a `lang` attribute named `panic_impl`. +//! return. You should mark your implementation using `#[panic_handler]`. //! //! * `rust_eh_personality` - is used by the failure mechanisms of the //! compiler. This is often mapped to GCC's personality function, but crates From 5dece2b2bd97c56f9abe2599ec1b4957fd63be55 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Sat, 29 Jun 2024 15:08:59 +0200 Subject: [PATCH 177/217] Remove uneccessary condition in `div_ceil` --- library/core/src/num/uint_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index cd74cece0d12e..ad72c29758bd7 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2726,7 +2726,7 @@ macro_rules! uint_impl { pub const fn div_ceil(self, rhs: Self) -> Self { let d = self / rhs; let r = self % rhs; - if r > 0 && rhs > 0 { + if r > 0 { d + 1 } else { d From 3d54358b643fc258b19688f6c6f8cc3d8831855c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:13:31 +0200 Subject: [PATCH 178/217] Update object to 0.36.1 This fixes a crash with macOS's ld-prime on arm64. Fixes rust-lang/rustc_codegen_cranelift#1501 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4959eed37a00..15c9e9d66fac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,9 +279,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "object" -version = "0.36.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "crc32fast", "hashbrown 0.14.3", From f6f21a8f11a51336784e93d6ea712f4484d7caef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 16:07:22 +0200 Subject: [PATCH 179/217] Review changes --- src/bootstrap/src/core/build_steps/perf.rs | 2 +- src/tools/rustc-perf-wrapper/README.md | 2 +- src/tools/rustc-perf-wrapper/src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index f8170580722bf..f41b5fe10f1d9 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -27,7 +27,7 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let args = std::env::args().skip_while(|a| a != "--").skip(1); let mut cmd = builder.tool_cmd(Tool::RustcPerfWrapper); - cmd.env("PERF_RUSTC", rustc) + cmd.env("RUSTC_REAL", rustc) .env("PERF_COLLECTOR", collector) .env("PERF_RESULT_DIR", profile_results_dir) .args(args); diff --git a/src/tools/rustc-perf-wrapper/README.md b/src/tools/rustc-perf-wrapper/README.md index 7c096e3081416..d7655459a2fe1 100644 --- a/src/tools/rustc-perf-wrapper/README.md +++ b/src/tools/rustc-perf-wrapper/README.md @@ -1,3 +1,3 @@ # rustc-perf wrapper Utility tool for invoking [`rustc-perf`](https://github.com/rust-lang/rustc-perf) for benchmarking/profiling -a stage1/2 compiler built by bootstrap using `x run perf`. +a stage1/2 compiler built by bootstrap using `x perf -- `. diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 0974661f99787..1c0d1745f3d98 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -68,7 +68,7 @@ struct SharedOpts { #[derive(Debug, clap::Parser)] struct BuildContext { /// Compiler binary that will be benchmarked/profiled. - #[clap(long, hide = true, env = "PERF_RUSTC")] + #[clap(long, hide = true, env = "RUSTC_REAL")] compiler: PathBuf, /// rustc-perf collector binary that will be used for running benchmarks/profilers. #[clap(long, hide = true, env = "PERF_COLLECTOR")] From 6a2638e6c49817de9c2b1d56261de37c6a352571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 16:07:39 +0200 Subject: [PATCH 180/217] Autolabel `rustc-perf-wrapper` changes with t-bootstrap label --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 62e0917efabed..8ae454d412a6f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -331,6 +331,7 @@ trigger_files = [ "src/tools/tidy", "src/tools/rustdoc-gui-test", "src/tools/libcxx-version", + "src/tools/rustc-perf-wrapper", ] [autolabel."T-infra"] From 35f209361fcd0751b3d260d67962b0af2d455596 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 27 Jun 2024 22:27:59 -0400 Subject: [PATCH 181/217] small correction to fmt::Pointer impl the `expose_provenance` method does not require `T: Sized` --- library/core/src/fmt/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c25bc5a1b13c9..69ccc6ce3ca3d 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2478,8 +2478,7 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - // Cast is needed here because `.expose_provenance()` requires `T: Sized`. - pointer_fmt_inner((*self as *const ()).expose_provenance(), f) + pointer_fmt_inner(self.expose_provenance(), f) } } From 30be8bcb45d108158c6553eff63db0d9ffb9f88a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:06:08 +0000 Subject: [PATCH 182/217] Remove --cfg no_unstable_features --- build_system/tests.rs | 36 ++++---------------------------- example/mini_core_hello_world.rs | 20 +++++------------- 2 files changed, 9 insertions(+), 47 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 278f334796a9b..790d9cbd9fc59 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -329,7 +329,6 @@ pub(crate) fn run_tests( struct TestRunner<'a> { is_native: bool, jit_supported: bool, - use_unstable_features: bool, skip_tests: &'a [&'a str], dirs: Dirs, target_compiler: Compiler, @@ -361,15 +360,7 @@ impl<'a> TestRunner<'a> { && target_compiler.triple.contains("x86_64") && !target_compiler.triple.contains("windows"); - Self { - is_native, - jit_supported, - use_unstable_features, - skip_tests, - dirs, - target_compiler, - stdlib_source, - } + Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source } } fn run_testsuite(&self, tests: &[TestCase]) { @@ -393,31 +384,13 @@ impl<'a> TestRunner<'a> { match *cmd { TestCaseCmd::Custom { func } => func(self), TestCaseCmd::BuildLib { source, crate_types } => { - if self.use_unstable_features { - self.run_rustc([source, "--crate-type", crate_types]); - } else { - self.run_rustc([ - source, - "--crate-type", - crate_types, - "--cfg", - "no_unstable_features", - ]); - } + self.run_rustc([source, "--crate-type", crate_types]); } TestCaseCmd::BuildBin { source } => { - if self.use_unstable_features { - self.run_rustc([source]); - } else { - self.run_rustc([source, "--cfg", "no_unstable_features"]); - } + self.run_rustc([source]); } TestCaseCmd::BuildBinAndRun { source, args } => { - if self.use_unstable_features { - self.run_rustc([source]); - } else { - self.run_rustc([source, "--cfg", "no_unstable_features"]); - } + self.run_rustc([source]); self.run_out_command( source.split('/').last().unwrap().split('.').next().unwrap(), args, @@ -472,7 +445,6 @@ impl<'a> TestRunner<'a> { cmd.arg(&self.target_compiler.triple); cmd.arg("-Cpanic=abort"); cmd.arg("-Zunstable-options"); - cmd.arg("--check-cfg=cfg(no_unstable_features)"); cmd.arg("--check-cfg=cfg(jit)"); cmd.args(args); cmd diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index aab20f672487b..7d361a9ab2bb6 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -333,12 +333,7 @@ fn main() { #[cfg(all(not(jit), not(all(windows, target_env = "gnu"))))] test_tls(); - #[cfg(all( - not(jit), - not(no_unstable_features), - target_arch = "x86_64", - any(target_os = "linux", target_os = "macos") - ))] + #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] unsafe { global_asm_test(); naked_test(); @@ -367,17 +362,12 @@ fn stack_val_align() { assert_eq!(&a as *const Foo as usize % 8192, 0); } -#[cfg(all( - not(jit), - not(no_unstable_features), - target_arch = "x86_64", - any(target_os = "linux", target_os = "macos") -))] +#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] extern "C" { fn global_asm_test(); } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64", target_os = "linux"))] +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))] global_asm! { " .global global_asm_test @@ -387,7 +377,7 @@ global_asm! { " } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64", target_os = "macos"))] +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "macos"))] global_asm! { " .global _global_asm_test @@ -397,7 +387,7 @@ global_asm! { " } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[cfg(all(not(jit), target_arch = "x86_64"))] #[naked] extern "C" fn naked_test() { unsafe { From 45600348c009303847e8cddcfa8483f1f3d56625 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:08:04 +0000 Subject: [PATCH 183/217] Stop pinning XCode 14 The linker issue with XCode 15 has been fixed. --- .github/workflows/abi-cafe.yml | 4 ---- .github/workflows/main.yml | 8 -------- 2 files changed, 12 deletions(-) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index b7063f35a3e80..1ed6f8fc359db 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -55,10 +55,6 @@ jobs: if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' run: rustup set default-host x86_64-apple-darwin - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1fc7087170065..a2ae3d63fb907 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -111,10 +111,6 @@ jobs: sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare @@ -254,10 +250,6 @@ jobs: sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare From 15d5dac32ecd54745d6f61659628286bd2678e03 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jun 2024 23:14:09 -0300 Subject: [PATCH 184/217] Avoid suggesting to add unsafe when the extern block is already unsafe --- .../rustc_ast_passes/src/ast_validation.rs | 19 ++++++++++++------- compiler/rustc_ast_passes/src/errors.rs | 2 +- tests/ui/parser/unsafe-foreign-mod-2.stderr | 5 ----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d02b8510975fc..60690a7e2cd83 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -459,13 +459,18 @@ impl<'a> AstValidator<'a> { fn check_item_safety(&self, span: Span, safety: Safety) { match self.extern_mod_safety { Some(extern_safety) => { - if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) - && (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks) - { - self.dcx().emit_err(errors::InvalidSafetyOnExtern { - item_span: span, - block: self.current_extern_span().shrink_to_lo(), - }); + if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) { + if extern_safety == Safety::Default { + self.dcx().emit_err(errors::InvalidSafetyOnExtern { + item_span: span, + block: Some(self.current_extern_span().shrink_to_lo()), + }); + } else if !self.features.unsafe_extern_blocks { + self.dcx().emit_err(errors::InvalidSafetyOnExtern { + item_span: span, + block: None, + }); + } } } None => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 965d8fac712ae..bfb9047645011 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -222,7 +222,7 @@ pub struct InvalidSafetyOnExtern { #[primary_span] pub item_span: Span, #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] - pub block: Span, + pub block: Option, } #[derive(Diagnostic)] diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr index 07dbd5568d053..8bd592b5d4311 100644 --- a/tests/ui/parser/unsafe-foreign-mod-2.stderr +++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr @@ -19,11 +19,6 @@ error: items in unadorned `extern` blocks cannot have safety qualifiers | LL | unsafe fn foo(); | ^^^^^^^^^^^^^^^^ - | -help: add unsafe to this `extern` block - | -LL | unsafe extern "C" unsafe { - | ++++++ error: aborting due to 3 previous errors From 7f383d098a0c3ed0c1360aad5cb6825a2981866f Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Sat, 29 Jun 2024 20:39:13 +0200 Subject: [PATCH 185/217] Stabilize `duration_abs_diff` --- library/core/src/time.rs | 5 +++-- library/core/tests/lib.rs | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 73c556249bedf..d66f558078ea8 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -620,13 +620,14 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_abs_diff)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(100, 0).abs_diff(Duration::new(80, 0)), Duration::new(20, 0)); /// assert_eq!(Duration::new(100, 400_000_000).abs_diff(Duration::new(110, 0)), Duration::new(9, 600_000_000)); /// ``` - #[unstable(feature = "duration_abs_diff", issue = "117618")] + #[stable(feature = "duration_abs_diff", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_abs_diff", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 57127df51ebdd..83a615fcd8be3 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -30,7 +30,6 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] -#![feature(duration_abs_diff)] #![feature(duration_consts_float)] #![feature(duration_constants)] #![feature(duration_constructors)] From e52d95bc823fc27d7f69f7aab980b278a6772a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 22:09:58 +0200 Subject: [PATCH 186/217] Remove unused compiler dependencies --- Cargo.lock | 4 ---- compiler/rustc_trait_selection/Cargo.toml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0182eca05058d..16ed81bcd3897 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4752,8 +4752,6 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f" name = "rustc_trait_selection" version = "0.0.0" dependencies = [ - "bitflags 2.5.0", - "derivative", "itertools", "rustc_ast", "rustc_ast_ir", @@ -4762,7 +4760,6 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_hir", - "rustc_index", "rustc_infer", "rustc_macros", "rustc_middle", @@ -4775,7 +4772,6 @@ dependencies = [ "rustc_target", "rustc_transmute", "rustc_type_ir", - "rustc_type_ir_macros", "smallvec", "tracing", ] diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 1f4fb57d996cc..f023a0eb53aeb 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -5,8 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -bitflags = "2.4.1" -derivative = "2.2.0" itertools = "0.12" rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } @@ -15,7 +13,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } -rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } @@ -28,7 +25,6 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir" } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end From 682e7c1174161c6e4e48a50e188e09f2dec80712 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 29 Jun 2024 16:14:34 -0400 Subject: [PATCH 187/217] Print `TypeId` as a `u128` for `Debug` Since , `TypeId` is represented as a `(u64, u64)`. This also made the debug implementation a lot larger, which is especially apparent with pretty formatting. Make this less noisy by converting the inner value back to a `u128` then printing as a tuple struct. Current: TypeId { t: (1403077013027291752, 4518903163082958039) } TypeId { t: ( 1403077013027291752, 4518903163082958039, ), } New: TypeId(25882202575019293479932656973818029271) TypeId( 25882202575019293479932656973818029271, ) --- library/core/src/any.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 37cb8e7d303af..eab11ae288a95 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -602,7 +602,7 @@ impl dyn Any + Send + Sync { /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! -#[derive(Clone, Copy, Debug, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] pub struct TypeId { // We avoid using `u128` because that imposes higher alignment requirements on many platforms. @@ -644,6 +644,10 @@ impl TypeId { let t2 = t as u64; TypeId { t: (t1, t2) } } + + fn as_u128(self) -> u128 { + u128::from(self.t.0) << 64 | u128::from(self.t.1) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -666,6 +670,13 @@ impl hash::Hash for TypeId { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for TypeId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_tuple("TypeId").field(&self.as_u128()).finish() + } +} + /// Returns the name of a type as a string slice. /// /// # Note From 03fce3648db08c8fdc726408930c276fec5af124 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Sun, 30 Jun 2024 14:55:36 +0800 Subject: [PATCH 188/217] Fix x86_64 code being produced for bare-metal LoongArch targets' `compiler_builtins` Formerly the `loongarch*-*-none*` targets were added to the `dist-various-2` CI job, but no corresponding toolchain was added along with them. This meant the `compiler_builtins` for the targets were built with the host toolchain. As the other `dist-various` toolchains are mostly pre-built so far, to avoid burdening them with crosstool-ng builds, simply move the two bare-metal LoongArch targets to the `dist-loongarch64-linux` job which has a ready-to-use LoongArch toolchain. With the proper CFLAGS applied it is possible to build artifacts suitable for bare-metal. I verified that the `compiler_builtins` objects are now correctly produced regarding architecture and ABI, with the changes here applied. Fixes #125908. cc @heiher try-job: dist-loongarch64-linux try-job: dist-various-2 --- .../dist-loongarch64-linux/Dockerfile | 20 ++++++++++++++++++- .../host-x86_64/dist-various-2/Dockerfile | 2 -- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 7e35f781b6bb8..d395665166365 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -23,7 +23,25 @@ ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \ AR_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-ar \ CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++ +# We re-use the Linux toolchain for bare-metal, because upstream bare-metal +# target support for LoongArch is only available from GCC 14+. +# +# See: https://github.com/gcc-mirror/gcc/commit/976f4f9e4770 +ENV CC_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-gcc \ + AR_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-ar \ + CXX_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-g++ \ + CFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d" \ + CXXFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d" \ + CC_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-gcc \ + AR_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-ar \ + CXX_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-g++ \ + CFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none" \ + CXXFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none" + ENV HOSTS=loongarch64-unknown-linux-gnu +ENV TARGETS=$HOSTS +ENV TARGETS=$TARGETS,loongarch64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV RUST_CONFIGURE_ARGS \ --enable-extended \ @@ -31,4 +49,4 @@ ENV RUST_CONFIGURE_ARGS \ --enable-profiler \ --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $TARGETS diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index bb6254942cbab..e3cb396b78297 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -121,8 +121,6 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none -ENV TARGETS=$TARGETS,loongarch64-unknown-none -ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi From 617de8cfb59252a501fc7e0ab7c2510dd8a8a7f4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 30 Jun 2024 17:36:16 +1000 Subject: [PATCH 189/217] coverage: Move span unexpansion into its own submodule --- .../src/coverage/mappings.rs | 5 +- .../rustc_mir_transform/src/coverage/mod.rs | 1 + .../rustc_mir_transform/src/coverage/spans.rs | 5 -- .../src/coverage/spans/from_mir.rs | 56 +------------------ .../src/coverage/unexpand.rs | 54 ++++++++++++++++++ 5 files changed, 59 insertions(+), 62 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/coverage/unexpand.rs diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 759bb7c1f9d96..e003de4e1fd71 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -9,9 +9,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; -use crate::coverage::spans::{ - extract_refined_covspans, unexpand_into_body_span_with_visible_macro, -}; +use crate::coverage::spans::extract_refined_covspans; +use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; use crate::coverage::ExtractedHirInfo; /// Associates an ordinary executable code span with its corresponding BCB. diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 4a64d21f3d17b..d55bde311c17e 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -6,6 +6,7 @@ mod mappings; mod spans; #[cfg(test)] mod tests; +mod unexpand; use rustc_middle::mir::coverage::{ CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 84a70d1f02d75..7612c01c52ec4 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -14,11 +14,6 @@ use crate::coverage::ExtractedHirInfo; mod from_mir; -// FIXME(#124545) It's awkward that we have to re-export this, because it's an -// internal detail of `from_mir` that is also needed when handling branch and -// MC/DC spans. Ideally we would find a more natural home for it. -pub(super) use from_mir::unexpand_into_body_span_with_visible_macro; - pub(super) fn extract_refined_covspans( mir_body: &mir::Body<'_>, hir_info: &ExtractedHirInfo, diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 09deb7534bfde..2ca166929eec8 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -4,12 +4,13 @@ use rustc_middle::mir::{ self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; -use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; +use rustc_span::{Span, Symbol}; use crate::coverage::graph::{ BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB, }; use crate::coverage::spans::Covspan; +use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; use crate::coverage::ExtractedHirInfo; pub(crate) struct ExtractedCovspans { @@ -215,59 +216,6 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { } } -/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range -/// within the function's body source. This span is guaranteed to be contained -/// within, or equal to, the `body_span`. If the extrapolated span is not -/// contained within the `body_span`, `None` is returned. -/// -/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, -/// etc.). -pub(crate) fn unexpand_into_body_span_with_visible_macro( - original_span: Span, - body_span: Span, -) -> Option<(Span, Option)> { - let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?; - - let visible_macro = prev - .map(|prev| match prev.ctxt().outer_expn_data().kind { - ExpnKind::Macro(MacroKind::Bang, name) => Some(name), - _ => None, - }) - .flatten(); - - Some((span, visible_macro)) -} - -/// Walks through the expansion ancestors of `original_span` to find a span that -/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. -/// The ancestor that was traversed just before the matching span (if any) is -/// also returned. -/// -/// For example, a return value of `Some((ancestor, Some(prev))` means that: -/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` -/// - `ancestor == prev.parent_callsite()` -/// -/// [`SyntaxContext`]: rustc_span::SyntaxContext -fn unexpand_into_body_span_with_prev( - original_span: Span, - body_span: Span, -) -> Option<(Span, Option)> { - let mut prev = None; - let mut curr = original_span; - - while !body_span.contains(curr) || !curr.eq_ctxt(body_span) { - prev = Some(curr); - curr = curr.parent_callsite()?; - } - - debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); - if let Some(prev) = prev { - debug_assert_eq!(Some(curr), prev.parent_callsite()); - } - - Some((curr, prev)) -} - #[derive(Debug)] pub(crate) struct Hole { pub(crate) span: Span, diff --git a/compiler/rustc_mir_transform/src/coverage/unexpand.rs b/compiler/rustc_mir_transform/src/coverage/unexpand.rs new file mode 100644 index 0000000000000..18532b8ee4581 --- /dev/null +++ b/compiler/rustc_mir_transform/src/coverage/unexpand.rs @@ -0,0 +1,54 @@ +use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; + +/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range +/// within the function's body source. This span is guaranteed to be contained +/// within, or equal to, the `body_span`. If the extrapolated span is not +/// contained within the `body_span`, `None` is returned. +/// +/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, +/// etc.). +pub(crate) fn unexpand_into_body_span_with_visible_macro( + original_span: Span, + body_span: Span, +) -> Option<(Span, Option)> { + let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?; + + let visible_macro = prev + .map(|prev| match prev.ctxt().outer_expn_data().kind { + ExpnKind::Macro(MacroKind::Bang, name) => Some(name), + _ => None, + }) + .flatten(); + + Some((span, visible_macro)) +} + +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. +/// The ancestor that was traversed just before the matching span (if any) is +/// also returned. +/// +/// For example, a return value of `Some((ancestor, Some(prev))` means that: +/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` +/// - `ancestor == prev.parent_callsite()` +/// +/// [`SyntaxContext`]: rustc_span::SyntaxContext +fn unexpand_into_body_span_with_prev( + original_span: Span, + body_span: Span, +) -> Option<(Span, Option)> { + let mut prev = None; + let mut curr = original_span; + + while !body_span.contains(curr) || !curr.eq_ctxt(body_span) { + prev = Some(curr); + curr = curr.parent_callsite()?; + } + + debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); + if let Some(prev) = prev { + debug_assert_eq!(Some(curr), prev.parent_callsite()); + } + + Some((curr, prev)) +} From 3d6cc605356f0919ae0bd024aba6cec5a9981ea7 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 30 Jun 2024 08:21:20 +0000 Subject: [PATCH 190/217] Try renaming the file if removing fails --- src/bootstrap/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 730d0ae5f3d7c..6d00ff9982d96 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -26,6 +26,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; use std::sync::OnceLock; +use std::time::SystemTime; use build_helper::ci::{gha, CiEnv}; use build_helper::exit; @@ -1676,7 +1677,14 @@ impl Build { if src == dst { return; } - let _ = fs::remove_file(dst); + if let Err(e) = fs::remove_file(dst) { + if e.kind() != io::ErrorKind::NotFound { + // workaround for https://github.com/rust-lang/rust/issues/127126 + // if removing the file fails, attempt to rename it instead. + let now = t!(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)); + let _ = fs::rename(dst, format!("{}-{}", dst.display(), now.as_nanos())); + } + } let metadata = t!(src.symlink_metadata(), format!("src = {}", src.display())); let mut src = src.to_path_buf(); if metadata.file_type().is_symlink() { From ad575b093bee669258b1d4914bccf56c5b9d1e82 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 11:34:31 +1000 Subject: [PATCH 191/217] Replace a magic boolean with enum `DeclareLetBindings` The new enum `DeclareLetBindings` has three variants: - `Yes`: Declare `let` bindings as normal, for `if` conditions. - `No`: Don't declare bindings, for match guards and let-else. - `LetNotPermitted`: Assert that `let` expressions should not occur. --- compiler/rustc_mir_build/src/build/block.rs | 3 +- .../rustc_mir_build/src/build/expr/into.rs | 5 +- .../rustc_mir_build/src/build/matches/mod.rs | 73 +++++++++++++++---- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 476969a1bd7ad..4616018c3c690 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,3 +1,4 @@ +use crate::build::matches::DeclareLetBindings; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -213,7 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, None, initializer_span, - false, + DeclareLetBindings::No, true, ) }); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 76bdc26a501a6..942c69b5c0a75 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -1,6 +1,7 @@ //! See docs in build/expr/mod.rs use crate::build::expr::category::{Category, RvalueFunc}; +use crate::build::matches::DeclareLetBindings; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, NeedsTemporary}; use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxHashMap; @@ -86,7 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { cond, Some(condition_scope), // Temp scope source_info, - true, // Declare `let` bindings normally + DeclareLetBindings::Yes, // Declare `let` bindings normally )); // Lower the `then` arm into its block. @@ -163,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, // This flag controls how inner `let` expressions are lowered, // but either way there shouldn't be any of those in here. - true, + DeclareLetBindings::LetNotPermitted, ) }); let (short_circuit, continuation, constant) = match op { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 6d52c30823769..71c065b3574c7 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -39,9 +39,27 @@ struct ThenElseArgs { /// `self.local_scope()` is used. temp_scope_override: Option, variable_source_info: SourceInfo, + /// Determines how bindings should be handled when lowering `let` expressions. + /// /// Forwarded to [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`]. - /// When false (for match guards), `let` bindings won't be declared. - declare_let_bindings: bool, + declare_let_bindings: DeclareLetBindings, +} + +/// Should lowering a `let` expression also declare its bindings? +/// +/// Used by [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`]. +#[derive(Clone, Copy)] +pub(crate) enum DeclareLetBindings { + /// Yes, declare `let` bindings as normal for `if` conditions. + Yes, + /// No, don't declare `let` bindings, because the caller declares them + /// separately due to special requirements. + /// + /// Used for match guards and let-else. + No, + /// Let expressions are not permitted in this context, so it is a bug to + /// try to lower one (e.g inside lazy-boolean-or or boolean-not). + LetNotPermitted, } impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -57,7 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr_id: ExprId, temp_scope_override: Option, variable_source_info: SourceInfo, - declare_let_bindings: bool, + declare_let_bindings: DeclareLetBindings, ) -> BlockAnd<()> { self.then_else_break_inner( block, @@ -91,13 +109,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.then_else_break_inner( block, lhs, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, ) }); let rhs_success_block = unpack!(this.then_else_break_inner( failure_block, rhs, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, )); // Make the LHS and RHS success arms converge to a common block. @@ -127,7 +151,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.then_else_break_inner( block, arg, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, ) }); this.break_for_else(success_block, args.variable_source_info); @@ -1991,8 +2018,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Pat binding - used for `let` and function parameters as well. impl<'a, 'tcx> Builder<'a, 'tcx> { - /// If the bindings have already been declared, set `declare_bindings` to - /// `false` to avoid duplicated bindings declaration; used for if-let guards. + /// Lowers a `let` expression that appears in a suitable context + /// (e.g. an `if` condition or match guard). + /// + /// Also used for lowering let-else statements, since they have similar + /// needs despite not actually using `let` expressions. + /// + /// Use [`DeclareLetBindings`] to control whether the `let` bindings are + /// declared or not. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, @@ -2000,7 +2033,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pat: &Pat<'tcx>, source_scope: Option, scope_span: Span, - declare_bindings: bool, + declare_let_bindings: DeclareLetBindings, storages_alive: bool, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; @@ -2017,10 +2050,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.break_for_else(otherwise_block, self.source_info(expr_span)); - if declare_bindings { - let expr_place = scrutinee.try_to_place(self); - let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); - self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place); + match declare_let_bindings { + DeclareLetBindings::Yes => { + let expr_place = scrutinee.try_to_place(self); + let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.declare_bindings( + source_scope, + pat.span.to(scope_span), + pat, + None, + opt_expr_place, + ); + } + DeclareLetBindings::No => {} // Caller is responsible for bindings. + DeclareLetBindings::LetNotPermitted => { + self.tcx.dcx().span_bug(expr_span, "let expression not expected in this context") + } } let success = self.bind_pattern( @@ -2203,7 +2248,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard, None, // Use `self.local_scope()` as the temp scope this.source_info(arm.span), - false, // For guards, `let` bindings are declared separately + DeclareLetBindings::No, // For guards, `let` bindings are declared separately ) }); From 3b22589cfa0015535ae08082b2cecf77ac1b5c33 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 12:40:47 +1000 Subject: [PATCH 192/217] Replace a magic boolean with enum `EmitStorageLive` The previous boolean used `true` to indicate that storage-live should _not_ be emitted, so all occurrences of `Yes` and `No` should be the logical opposite of the previous value. --- compiler/rustc_mir_build/src/build/block.rs | 4 +- .../rustc_mir_build/src/build/matches/mod.rs | 47 ++++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 4616018c3c690..80db30f0ae600 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,4 +1,4 @@ -use crate::build::matches::DeclareLetBindings; +use crate::build::matches::{DeclareLetBindings, EmitStorageLive}; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -215,7 +215,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, initializer_span, DeclareLetBindings::No, - true, + EmitStorageLive::No, ) }); matching.and(failure) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 71c065b3574c7..4827d2dbfa85c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -62,6 +62,18 @@ pub(crate) enum DeclareLetBindings { LetNotPermitted, } +/// Used by [`Builder::bind_matched_candidate_for_arm_body`] to determine +/// whether or not to call [`Builder::storage_live_binding`] to emit +/// [`StatementKind::StorageLive`]. +#[derive(Clone, Copy)] +pub(crate) enum EmitStorageLive { + /// Yes, emit `StorageLive` as normal. + Yes, + /// No, don't emit `StorageLive`. The caller has taken responsibility for + /// emitting `StorageLive` as appropriate. + No, +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Lowers a condition in a way that ensures that variables bound in any let /// expressions are definitely initialized in the if body. @@ -174,7 +186,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(args.variable_source_info.scope), args.variable_source_info.span, args.declare_let_bindings, - false, + EmitStorageLive::Yes, ), _ => { let mut block = block; @@ -467,7 +479,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &fake_borrow_temps, scrutinee_span, Some((arm, match_scope)), - false, + EmitStorageLive::Yes, ); this.fixed_temps_scope = old_dedup_scope; @@ -512,7 +524,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrow_temps: &[(Place<'tcx>, Local, FakeBorrowKind)], scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BasicBlock { if candidate.subcandidates.is_empty() { // Avoid generating another `BasicBlock` when we only have one @@ -524,7 +536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span, arm_match_scope, true, - storages_alive, + emit_storage_live, ) } else { // It's helpful to avoid scheduling drops multiple times to save @@ -561,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span, arm_match_scope, schedule_drops, - storages_alive, + emit_storage_live, ); if arm.is_none() { schedule_drops = false; @@ -731,7 +743,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &[], irrefutable_pat.span, None, - false, + EmitStorageLive::Yes, ) .unit() } @@ -807,6 +819,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + /// Emits a [`StatementKind::StorageLive`] for the given var, and also + /// schedules a drop if requested (and possible). pub(crate) fn storage_live_binding( &mut self, block: BasicBlock, @@ -2034,7 +2048,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_scope: Option, scope_span: Span, declare_let_bindings: DeclareLetBindings, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); @@ -2074,7 +2088,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &[], expr_span, None, - storages_alive, + emit_storage_live, ); // If branch coverage is enabled, record this branch. @@ -2099,7 +2113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, schedule_drops: bool, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -2314,7 +2328,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { post_guard_block, true, by_value_bindings, - storages_alive, + emit_storage_live, ); post_guard_block @@ -2326,7 +2340,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, schedule_drops, bindings, - storages_alive, + emit_storage_live, ); block } @@ -2417,7 +2431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block: BasicBlock, schedule_drops: bool, bindings: impl IntoIterator>, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) where 'tcx: 'b, { @@ -2427,19 +2441,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Assign each of the bindings. This may trigger moves out of the candidate. for binding in bindings { let source_info = self.source_info(binding.span); - let local = if storages_alive { + let local = match emit_storage_live { // Here storages are already alive, probably because this is a binding // from let-else. // We just need to schedule drop for the value. - self.var_local_id(binding.var_id, OutsideGuard).into() - } else { - self.storage_live_binding( + EmitStorageLive::No => self.var_local_id(binding.var_id, OutsideGuard).into(), + EmitStorageLive::Yes => self.storage_live_binding( block, binding.var_id, binding.span, OutsideGuard, schedule_drops, - ) + ), }; if schedule_drops { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); From ed07712e96506ca827ced41d748550b99318d47f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 13:44:25 +1000 Subject: [PATCH 193/217] Replace a magic boolean with enum `ScheduleDrops` --- compiler/rustc_mir_build/src/build/block.rs | 18 +++++- .../rustc_mir_build/src/build/matches/mod.rs | 56 ++++++++++++++----- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 80db30f0ae600..5ccbd7c59cfba 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,4 +1,4 @@ -use crate::build::matches::{DeclareLetBindings, EmitStorageLive}; +use crate::build::matches::{DeclareLetBindings, EmitStorageLive, ScheduleDrops}; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -202,7 +202,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, UserTypeProjections::none(), &mut |this, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard, true); + this.storage_live_binding( + block, + node, + span, + OutsideGuard, + ScheduleDrops::Yes, + ); }, ); let else_block_span = this.thir[*else_block].span; @@ -292,7 +298,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, UserTypeProjections::none(), &mut |this, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard, true); + this.storage_live_binding( + block, + node, + span, + OutsideGuard, + ScheduleDrops::Yes, + ); this.schedule_drop_for_binding(node, span, OutsideGuard); }, ) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 4827d2dbfa85c..efed52231e3fa 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -28,6 +28,7 @@ mod simplify; mod test; mod util; +use std::assert_matches::assert_matches; use std::borrow::Borrow; use std::mem; @@ -74,6 +75,17 @@ pub(crate) enum EmitStorageLive { No, } +/// Used by [`Builder::storage_live_binding`] and [`Builder::bind_matched_candidate_for_arm_body`] +/// to decide whether to schedule drops. +#[derive(Clone, Copy, Debug)] +pub(crate) enum ScheduleDrops { + /// Yes, the relevant functions should also schedule drops as appropriate. + Yes, + /// No, don't schedule drops. The caller has taken responsibility for any + /// appropriate drops. + No, +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Lowers a condition in a way that ensures that variables bound in any let /// expressions are definitely initialized in the if body. @@ -535,7 +547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrow_temps, scrutinee_span, arm_match_scope, - true, + ScheduleDrops::Yes, emit_storage_live, ) } else { @@ -554,7 +566,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // To handle this we instead unschedule it's drop after each time // we lower the guard. let target_block = self.cfg.start_new_block(); - let mut schedule_drops = true; + let mut schedule_drops = ScheduleDrops::Yes; let arm = arm_match_scope.unzip().0; // We keep a stack of all of the bindings and type ascriptions // from the parent candidates that we visit, that also need to @@ -576,7 +588,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { emit_storage_live, ); if arm.is_none() { - schedule_drops = false; + schedule_drops = ScheduleDrops::No; } self.cfg.goto(binding_end, outer_source_info, target_block); }, @@ -602,8 +614,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match irrefutable_pat.kind { // Optimize the case of `let x = ...` to write directly into `x` PatKind::Binding { mode: BindingMode(ByRef::No, _), var, subpattern: None, .. } => { - let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); + let place = self.storage_live_binding( + block, + var, + irrefutable_pat.span, + OutsideGuard, + ScheduleDrops::Yes, + ); unpack!(block = self.expr_into_dest(place, block, initializer_id)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -636,8 +653,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, ascription: thir::Ascription { ref annotation, variance: _ }, } => { - let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); + let place = self.storage_live_binding( + block, + var, + irrefutable_pat.span, + OutsideGuard, + ScheduleDrops::Yes, + ); unpack!(block = self.expr_into_dest(place, block, initializer_id)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -827,7 +849,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var: LocalVarId, span: Span, for_guard: ForGuard, - schedule_drop: bool, + schedule_drop: ScheduleDrops, ) -> Place<'tcx> { let local_id = self.var_local_id(var, for_guard); let source_info = self.source_info(span); @@ -835,7 +857,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Although there is almost always scope for given variable in corner cases // like #92893 we might get variable with no scope. if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) - && schedule_drop + && matches!(schedule_drop, ScheduleDrops::Yes) { self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } @@ -2112,7 +2134,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrows: &[(Place<'tcx>, Local, FakeBorrowKind)], scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, - schedule_drops: bool, + schedule_drops: ScheduleDrops, emit_storage_live: EmitStorageLive, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -2323,10 +2345,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause = FakeReadCause::ForGuardBinding; self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id)); } - assert!(schedule_drops, "patterns with guards must schedule drops"); + assert_matches!( + schedule_drops, + ScheduleDrops::Yes, + "patterns with guards must schedule drops" + ); self.bind_matched_candidate_for_arm_body( post_guard_block, - true, + ScheduleDrops::Yes, by_value_bindings, emit_storage_live, ); @@ -2376,7 +2402,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_guard<'b>( &mut self, block: BasicBlock, - schedule_drops: bool, + schedule_drops: ScheduleDrops, bindings: impl IntoIterator>, ) where 'tcx: 'b, @@ -2429,7 +2455,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_arm_body<'b>( &mut self, block: BasicBlock, - schedule_drops: bool, + schedule_drops: ScheduleDrops, bindings: impl IntoIterator>, emit_storage_live: EmitStorageLive, ) where @@ -2454,7 +2480,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { schedule_drops, ), }; - if schedule_drops { + if matches!(schedule_drops, ScheduleDrops::Yes) { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); } let rvalue = match binding.binding_mode.0 { From 6c3314905574651fa2e004173187bd5d202f0df1 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 30 Jun 2024 18:20:45 +1000 Subject: [PATCH 194/217] coverage: Avoid getting extra unexpansion info when we don't need it These particular callers don't actually use the returned macro information, so they can use a simpler span-unexpansion function that doesn't return it. --- .../src/coverage/mappings.rs | 9 +++--- .../src/coverage/unexpand.rs | 28 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index e003de4e1fd71..235992ac5470d 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -10,7 +10,7 @@ use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; use crate::coverage::spans::extract_refined_covspans; -use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; +use crate::coverage::unexpand::unexpand_into_body_span; use crate::coverage::ExtractedHirInfo; /// Associates an ordinary executable code span with its corresponding BCB. @@ -201,8 +201,7 @@ pub(super) fn extract_branch_pairs( if !raw_span.ctxt().outer_expn_data().is_root() { return None; } - let (span, _) = - unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?; + let span = unexpand_into_body_span(raw_span, hir_info.body_span)?; let bcb_from_marker = |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); @@ -237,7 +236,7 @@ pub(super) fn extract_mcdc_mappings( if !raw_span.ctxt().outer_expn_data().is_root() { return None; } - let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?; + let span = unexpand_into_body_span(raw_span, body_span)?; let true_bcb = bcb_from_marker(true_marker)?; let false_bcb = bcb_from_marker(false_marker)?; @@ -260,7 +259,7 @@ pub(super) fn extract_mcdc_mappings( mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map( |decision: &mir::coverage::MCDCDecisionSpan| { - let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?; + let span = unexpand_into_body_span(decision.span, body_span)?; let end_bcbs = decision .end_markers diff --git a/compiler/rustc_mir_transform/src/coverage/unexpand.rs b/compiler/rustc_mir_transform/src/coverage/unexpand.rs index 18532b8ee4581..8cde291b9073e 100644 --- a/compiler/rustc_mir_transform/src/coverage/unexpand.rs +++ b/compiler/rustc_mir_transform/src/coverage/unexpand.rs @@ -1,12 +1,18 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; -/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range -/// within the function's body source. This span is guaranteed to be contained -/// within, or equal to, the `body_span`. If the extrapolated span is not -/// contained within the `body_span`, `None` is returned. +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [syntax context] as `body_span`. +pub(crate) fn unexpand_into_body_span(original_span: Span, body_span: Span) -> Option { + // Because we don't need to return any extra ancestor information, + // we can just delegate directly to `find_ancestor_inside_same_ctxt`. + original_span.find_ancestor_inside_same_ctxt(body_span) +} + +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [syntax context] as `body_span`. /// -/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, -/// etc.). +/// If the returned span represents a bang-macro invocation (e.g. `foo!(..)`), +/// the returned symbol will be the name of that macro (e.g. `foo`). pub(crate) fn unexpand_into_body_span_with_visible_macro( original_span: Span, body_span: Span, @@ -24,15 +30,15 @@ pub(crate) fn unexpand_into_body_span_with_visible_macro( } /// Walks through the expansion ancestors of `original_span` to find a span that -/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. +/// is contained in `body_span` and has the same [syntax context] as `body_span`. /// The ancestor that was traversed just before the matching span (if any) is /// also returned. /// -/// For example, a return value of `Some((ancestor, Some(prev))` means that: +/// For example, a return value of `Some((ancestor, Some(prev)))` means that: /// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` -/// - `ancestor == prev.parent_callsite()` +/// - `prev.parent_callsite() == ancestor` /// -/// [`SyntaxContext`]: rustc_span::SyntaxContext +/// [syntax context]: rustc_span::SyntaxContext fn unexpand_into_body_span_with_prev( original_span: Span, body_span: Span, @@ -45,7 +51,7 @@ fn unexpand_into_body_span_with_prev( curr = curr.parent_callsite()?; } - debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); + debug_assert_eq!(Some(curr), original_span.find_ancestor_inside_same_ctxt(body_span)); if let Some(prev) = prev { debug_assert_eq!(Some(curr), prev.parent_callsite()); } From 4b516f599b15c81a5ab26c0044b9fdf84cf5e3c3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 30 Jun 2024 12:40:24 +0200 Subject: [PATCH 195/217] Improve `run-make-support` library `args` API --- src/tools/run-make-support/src/lib.rs | 5 +++-- tests/run-make/arguments-non-c-like-enum/rmake.rs | 4 ++-- tests/run-make/c-link-to-rust-staticlib/rmake.rs | 2 +- tests/run-make/c-link-to-rust-va-list-fn/rmake.rs | 2 +- tests/run-make/glibc-staticlib-args/rmake.rs | 4 ++-- tests/run-make/print-check-cfg/rmake.rs | 8 ++------ tests/run-make/return-non-c-like-enum/rmake.rs | 4 ++-- tests/run-make/textrel-on-minimal-lib/rmake.rs | 4 ++-- 8 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 31b913810b665..df417722e024f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -525,11 +525,12 @@ macro_rules! impl_common_helpers { /// Generic command arguments provider. Prefer specific helper methods if possible. /// Note that for some executables, arguments might be platform specific. For C/C++ /// compilers, arguments might be platform *and* compiler specific. - pub fn args(&mut self, args: &[S]) -> &mut Self + pub fn args(&mut self, args: V) -> &mut Self where + V: AsRef<[S]>, S: AsRef<::std::ffi::OsStr>, { - self.cmd.args(args); + self.cmd.args(args.as_ref()); self } diff --git a/tests/run-make/arguments-non-c-like-enum/rmake.rs b/tests/run-make/arguments-non-c-like-enum/rmake.rs index 88f4d664aa626..036691e850931 100644 --- a/tests/run-make/arguments-non-c-like-enum/rmake.rs +++ b/tests/run-make/arguments-non-c-like-enum/rmake.rs @@ -10,8 +10,8 @@ pub fn main() { cc().input("test.c") .input(static_lib_name("nonclike")) .out_exe("test") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .inspect(|cmd| eprintln!("{cmd:?}")) .run(); run("test"); diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs index 2edd36b9ec0b7..d60b37524f43c 100644 --- a/tests/run-make/c-link-to-rust-staticlib/rmake.rs +++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs @@ -9,7 +9,7 @@ use std::fs; fn main() { rustc().input("foo.rs").run(); - cc().input("bar.c").input(static_lib_name("foo")).out_exe("bar").args(&extra_c_flags()).run(); + cc().input("bar.c").input(static_lib_name("foo")).out_exe("bar").args(extra_c_flags()).run(); run("bar"); remove_file(static_lib_name("foo")); run("bar"); diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs index a01e259bce010..63904bea6227b 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -12,7 +12,7 @@ fn main() { cc().input("test.c") .input(static_lib_name("checkrust")) .out_exe("test") - .args(&extra_c_flags()) + .args(extra_c_flags()) .run(); run("test"); } diff --git a/tests/run-make/glibc-staticlib-args/rmake.rs b/tests/run-make/glibc-staticlib-args/rmake.rs index 8ab10419ab9d3..fc13be538123b 100644 --- a/tests/run-make/glibc-staticlib-args/rmake.rs +++ b/tests/run-make/glibc-staticlib-args/rmake.rs @@ -11,8 +11,8 @@ fn main() { cc().input("program.c") .arg(static_lib_name("library")) .out_exe("program") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); run(&bin_name("program")); } diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index f4b02b5e265be..4a79910c8e05e 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -86,12 +86,8 @@ fn main() { } fn check(CheckCfg { args, contains }: CheckCfg) { - let output = rustc() - .input("lib.rs") - .arg("-Zunstable-options") - .arg("--print=check-cfg") - .args(&*args) - .run(); + let output = + rustc().input("lib.rs").arg("-Zunstable-options").arg("--print=check-cfg").args(args).run(); let stdout = output.stdout_utf8(); diff --git a/tests/run-make/return-non-c-like-enum/rmake.rs b/tests/run-make/return-non-c-like-enum/rmake.rs index e698790b43c06..ecdfbd8889941 100644 --- a/tests/run-make/return-non-c-like-enum/rmake.rs +++ b/tests/run-make/return-non-c-like-enum/rmake.rs @@ -11,8 +11,8 @@ fn main() { cc().input("test.c") .arg(&static_lib_name("nonclike")) .out_exe("test") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); run("test"); } diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs index eba664479f112..625ded70ad624 100644 --- a/tests/run-make/textrel-on-minimal-lib/rmake.rs +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -20,8 +20,8 @@ fn main() { .out_exe(&dynamic_lib_name("bar")) .arg("-fPIC") .arg("-shared") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); llvm_readobj() .input(dynamic_lib_name("bar")) From 8a0e1ab565346491f932612508e57c225ddbb34c Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sun, 30 Jun 2024 07:12:26 -0400 Subject: [PATCH 196/217] Add a regression test for #123630 compiler should not suggest nonsensical signatures, original suggestion was error[E0308]: mismatched types --> src/lib.rs:3:31 | 3 | fn select(filter: F) -> Select { | ------ ^^^^^^^^^^^^ expected `Select`, found `()` | | | implicitly returns `()` as its body has no tail or `return` expression | = note: expected struct `Select` found unit type `()` error[E0282]: type annotations needed for `Select<{closure@src/lib.rs:8:22: 8:25}, I>` --> src/lib.rs:8:9 | 8 | let lit = select(|x| match x { | ^^^ | help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 8 | let lit: Select<{closure@src/lib.rs:8:22: 8:25}, I> = select(|x| match x { | ++++++++++++++++++++++++++++++++++++++++++++ Some errors have detailed explanations: E0282, E0308. For more information about an error, try `rustc --explain E0282`. --- .../types/dont-suggest-path-names.rs | 17 ++++++++++++ .../types/dont-suggest-path-names.stderr | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/suggestions/types/dont-suggest-path-names.rs create mode 100644 tests/ui/suggestions/types/dont-suggest-path-names.stderr diff --git a/tests/ui/suggestions/types/dont-suggest-path-names.rs b/tests/ui/suggestions/types/dont-suggest-path-names.rs new file mode 100644 index 0000000000000..d160e49cd0358 --- /dev/null +++ b/tests/ui/suggestions/types/dont-suggest-path-names.rs @@ -0,0 +1,17 @@ +// This is a regression test for #123630 +// +// Prior to #123703 this was resulting in compiler suggesting add a type signature +// for `lit` containing path to a file containing `Select` - something obviously invalid. + +struct Select(F, I); +fn select(filter: F) -> Select {} +//~^ 7:31: 7:43: mismatched types [E0308] + +fn parser1() { + let lit = select(|x| match x { + //~^ 11:23: 11:24: type annotations needed [E0282] + _ => (), + }); +} + +fn main() {} diff --git a/tests/ui/suggestions/types/dont-suggest-path-names.stderr b/tests/ui/suggestions/types/dont-suggest-path-names.stderr new file mode 100644 index 0000000000000..5c71e350f81a3 --- /dev/null +++ b/tests/ui/suggestions/types/dont-suggest-path-names.stderr @@ -0,0 +1,26 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-path-names.rs:7:31 + | +LL | fn select(filter: F) -> Select {} + | ------ ^^^^^^^^^^^^ expected `Select`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected struct `Select` + found unit type `()` + +error[E0282]: type annotations needed + --> $DIR/dont-suggest-path-names.rs:11:23 + | +LL | let lit = select(|x| match x { + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | let lit = select(|x: /* Type */| match x { + | ++++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. From 49cd5dd454d0115cfbe9e39102a8b3ba4616aa40 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:20:49 +0000 Subject: [PATCH 197/217] Rustup to rustc 1.81.0-nightly (ba1d7f4a0 2024-06-29) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 85d73cb414f17..cfa91744a0e8d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-26" +channel = "nightly-2024-06-30" components = ["rust-src", "rustc-dev", "llvm-tools"] From f79bf19a7a9dc9bbdab3d1c274bd267b0e86a66e Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 30 Jun 2024 15:15:05 +0100 Subject: [PATCH 198/217] Update test comment --- .../repeat_expr_hack_gives_right_generics.rs | 22 +++++++++++-------- ...peat_expr_hack_gives_right_generics.stderr | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs index 899db191ae7d7..e7ae2ea1d5a6a 100644 --- a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs @@ -1,14 +1,18 @@ -// Given an anon const `a`: `{ N }` and some anon const `b` which references the -// first anon const: `{ [1; a] }`. `b` should not have any generics as it is not -// a simple `N` argument nor is it a repeat expr count. +// Given a const argument `a`: `{ N }` and some const argument `b` which references the +// first anon const like so: `{ [1; a] }`. The `b` anon const should not be allowed to use +// any generic parameters as: +// - The anon const is not a simple bare parameter, e.g. `N` +// - The anon const is not the *length* of an array repeat expression, e.g. the `N` in `[1; N]`. // -// On the other hand `b` *is* a repeat expr count and so it should inherit its -// parents generics as part of the `const_evaluatable_unchecked` fcw (#76200). +// On the other hand `a` *is* a const argument for the length of a repeat expression and +// so it *should* inherit the generics declared on its parent definition. (This hack is +// introduced for backwards compatibility and is tracked in #76200) // -// In this specific case however `b`'s parent should be `a` and so it should wind -// up not having any generics after all. If `a` were to inherit its generics from -// the enclosing item then the reference to `a` from `b` would contain generic -// parameters not usable by `b` which would cause us to ICE. +// In this specific case `a`'s parent should be `b` which does not have any generics. +// This means that even though `a` inherits generics from `b`, it still winds up not having +// access to any generic parameters. If `a` were to inherit its generics from the surrounding +// function `foo` then the reference to `a` from `b` would contain generic parameters not usable +// by `b` which would cause us to ICE. fn bar() {} diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr index 64548cc5a301e..72a6e6977f583 100644 --- a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/repeat_expr_hack_gives_right_generics.rs:16:17 + --> $DIR/repeat_expr_hack_gives_right_generics.rs:20:17 | LL | bar::<{ [1; N] }>(); | ^ cannot perform const operation using `N` From 34ae56de35d4c8b61f51758113debea2ec7c21e7 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 30 Jun 2024 17:08:10 +0000 Subject: [PATCH 199/217] Make `feature(effects)` require `-Znext-solver` --- compiler/rustc_hir_analysis/messages.ftl | 4 ++++ compiler/rustc_hir_analysis/src/errors.rs | 6 ++++++ compiler/rustc_hir_analysis/src/lib.rs | 6 ++++++ .../effects/with-without-next-solver.coherence.stderr | 7 +++++++ .../effects/with-without-next-solver.rs | 10 ++++++++++ .../effects/with-without-next-solver.stock.stderr | 7 +++++++ 6 files changed, 40 insertions(+) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 7ed32fb9d9f37..064d9c077b0a6 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -120,6 +120,10 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice .label = parameter captured again here +hir_analysis_effects_without_next_solver = using `#![feature(effects)]` without enabling next trait solver globally + .note = the next trait solver must be enabled globally for the effects feature to work correctly + .help = use `-Znext-solver` to enable + hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 44025c3cd61c1..3ffb51fa9926a 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1699,3 +1699,9 @@ pub struct InvalidReceiverTy<'tcx> { pub span: Span, pub receiver_ty: Ty<'tcx>, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_effects_without_next_solver)] +#[note] +#[help] +pub struct EffectsWithoutNextSolver; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0428abcdf24e8..cf41f51f74814 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -151,6 +151,12 @@ pub fn provide(providers: &mut Providers) { pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); + // FIXME(effects): remove once effects is implemented in old trait solver + // or if the next solver is stabilized. + if tcx.features().effects && !tcx.next_trait_solver_globally() { + tcx.dcx().emit_err(errors::EffectsWithoutNextSolver); + } + tcx.sess.time("coherence_checking", || { tcx.hir().par_for_each_module(|module| { let _ = tcx.ensure().check_mod_type_wf(module); diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr new file mode 100644 index 0000000000000..20448f51de22c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr @@ -0,0 +1,7 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs new file mode 100644 index 0000000000000..f022af05c50e7 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs @@ -0,0 +1,10 @@ +// test that we error correctly when effects is used without the next-solver flag. +//@ revisions: stock coherence full +//@[coherence] compile-flags: -Znext-solver=coherence +//@[full] compile-flags: -Znext-solver +//@[full] check-pass + +#![feature(effects)] +#![allow(incomplete_features)] + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr new file mode 100644 index 0000000000000..20448f51de22c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr @@ -0,0 +1,7 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 1 previous error + From daff015314b9ffeb2f65fa45659a1c3008149534 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 30 Jun 2024 17:08:45 +0000 Subject: [PATCH 200/217] Migrate tests to use `-Znext-solver` --- tests/crashes/119924-6.rs | 1 + .../auxiliary/const-effect-param.rs | 2 ++ .../unify-op-with-fn-call.rs | 2 +- .../unify-op-with-fn-call.stderr | 32 +++++++++++++------ tests/ui/const-generics/issues/issue-88119.rs | 4 +-- .../const-generics/issues/issue-88119.stderr | 27 ++++++++++++++++ .../auxiliary/closure-in-foreign-crate.rs | 4 ++- tests/ui/consts/const-float-classify.rs | 2 +- tests/ui/consts/const-try.stderr | 7 +++- tests/ui/consts/const_cmp_type_id.rs | 21 +++++++----- tests/ui/consts/const_cmp_type_id.stderr | 25 --------------- ...constifconst-call-in-const-position.stderr | 7 +++- tests/ui/consts/rustc-impl-const-stability.rs | 5 +-- .../consts/rustc-impl-const-stability.stderr | 13 ++------ .../generic-const-items/const-trait-impl.rs | 2 +- .../impls-nested-within-fns-semantic-1.rs | 4 ++- .../impls-nested-within-fns-semantic-1.stderr | 11 ------- .../assoc-type-const-bound-usage-0.stderr | 7 +++- .../assoc-type-const-bound-usage-1.stderr | 7 +++- .../assoc-type.stderr | 7 +++- .../auxiliary/cross-crate.rs | 1 + .../auxiliary/staged-api.rs | 4 ++- .../call-const-trait-method-fail.stderr | 7 +++- .../call-generic-method-chain.stderr | 7 +++- .../call-generic-method-dup-bound.stderr | 7 +++- .../call-generic-method-fail.rs | 5 +-- .../call-generic-method-fail.stderr | 11 ------- .../call-generic-method-nonconst.stderr | 7 +++- .../call-generic-method-pass.stderr | 7 +++- .../ui/rfcs/rfc-2632-const-trait-impl/call.rs | 2 +- ...st-bound-on-not-const-associated-fn.stderr | 7 +++- .../const-bounds-non-const-trait.stderr | 7 +++- .../const-check-fns-in-const-impl.stderr | 7 +++- .../const-default-method-bodies.stderr | 7 +++- .../const-impl-requires-const-trait.stderr | 7 +++- .../const-impl-trait.stderr | 7 +++- .../const-trait-bounds.rs | 5 +-- .../const-trait-bounds.stderr | 30 +++++++++++++++++ .../derive-const-non-const-type.stderr | 7 +++- .../const_derives/derive-const-use.stderr | 7 +++- .../derive-const-with-params.stderr | 7 +++- ...ross-crate-default-method-body-is-const.rs | 5 +-- ...-crate-default-method-body-is-const.stderr | 11 ------- .../cross-crate.gated.stderr | 11 ------- .../cross-crate.gatednc.stderr | 20 +++--------- .../rfc-2632-const-trait-impl/cross-crate.rs | 3 +- .../cross-crate.stock.stderr | 2 +- .../cross-crate.stocknc.stderr | 4 +-- ...-method-body-is-const-same-trait-ck.stderr | 7 +++- .../do-not-const-check-override.rs | 4 ++- .../do-not-const-check-override.stderr | 11 ------- .../effects/auxiliary/cross-crate.rs | 4 ++- ...nst_closure-const_trait_impl-ice-113381.rs | 1 + .../effects/effect-param-infer.rs | 5 +-- .../effects/effect-param-infer.stderr | 11 ------- .../effects/fallback.rs | 5 +-- .../effects/fallback.stderr | 11 ------- .../effects/helloworld.rs | 6 ++-- .../effects/helloworld.stderr | 11 ------- .../ice-112822-expected-type-for-param.stderr | 7 +++- ...ice-113375-index-out-of-bounds-generics.rs | 2 +- .../effects/infer-fallback.rs | 4 ++- .../effects/infer-fallback.stderr | 11 ------- ...o-explicit-const-params-cross-crate.stderr | 8 ++--- .../effects/no-explicit-const-params.stderr | 7 +++- .../effects/project.rs | 2 +- .../effects/span-bug-issue-121418.stderr | 7 +++- .../effects/spec-effectvar-ice.stderr | 7 +++- .../effects/trait-fn-const.stderr | 7 +++- .../hir-const-check.stderr | 7 +++- .../ice-119717-constant-lifetime.stderr | 7 +++- .../ice-120503-async-const-method.stderr | 7 +++- .../ice-121536-const-method.stderr | 7 +++- .../ice-123664-unexpected-bound-var.stderr | 7 +++- ...857-combine-effect-const-infer-vars.stderr | 7 +++- .../ice-126148-failed-to-normalize.stderr | 7 +++- .../impl-with-default-fn-fail.stderr | 7 +++- .../impl-with-default-fn-pass.rs | 1 + .../issue-100222.nn.stderr | 9 ++++++ .../issue-100222.ny.stderr | 9 ++++++ .../rfc-2632-const-trait-impl/issue-100222.rs | 3 +- .../issue-100222.yn.stderr | 9 ++++++ .../issue-100222.yy.stderr | 9 ++++++ .../rfc-2632-const-trait-impl/issue-79450.rs | 4 ++- .../issue-79450.stderr | 13 ++------ ...ult-impl-non-const-specialized-impl.stderr | 7 +++- .../specializing-constness.stderr | 7 +++- .../rfc-2632-const-trait-impl/staged-api.rs | 4 ++- .../staged-api.stable.stderr | 21 ++++-------- .../staged-api.unstable.stderr | 21 ++++-------- .../super-traits-fail-2.nn.stderr | 21 ++++-------- .../super-traits-fail-2.ny.stderr | 17 +++------- .../super-traits-fail-2.rs | 4 ++- .../super-traits-fail-2.yn.stderr | 19 +++-------- .../super-traits-fail-2.yy.stderr | 15 ++------- .../super-traits-fail-3.nn.stderr | 12 +++---- .../super-traits-fail-3.ny.stderr | 6 ++-- .../super-traits-fail-3.rs | 1 + .../super-traits-fail-3.yn.stderr | 10 +++--- .../super-traits-fail-3.yy.stderr | 4 +-- .../tilde-const-and-const-params.stderr | 7 +++- .../tilde-const-assoc-fn-in-trait-impl.rs | 5 +-- .../tilde-const-assoc-fn-in-trait-impl.stderr | 11 ------- .../tilde-const-inherent-assoc-const-fn.rs | 4 ++- ...tilde-const-inherent-assoc-const-fn.stderr | 11 ------- .../tilde-const-trait-assoc-tys.rs | 4 ++- .../tilde-const-trait-assoc-tys.stderr | 11 ------- .../trait-default-body-stability.rs | 3 +- .../trait-default-body-stability.stderr | 15 ++------- .../trait-where-clause-const.rs | 1 + .../trait-where-clause-const.stderr | 12 +++---- .../trait-where-clause-self-referential.rs | 5 +-- ...trait-where-clause-self-referential.stderr | 11 ------- .../missing-const-stability.rs | 1 + .../missing-const-stability.stderr | 8 ++--- 115 files changed, 503 insertions(+), 428 deletions(-) create mode 100644 tests/ui/const-generics/issues/issue-88119.stderr delete mode 100644 tests/ui/consts/const_cmp_type_id.stderr delete mode 100644 tests/ui/parser/impls-nested-within-fns-semantic-1.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr diff --git a/tests/crashes/119924-6.rs b/tests/crashes/119924-6.rs index 01c4f43e8fd43..f1cc9d2915915 100644 --- a/tests/crashes/119924-6.rs +++ b/tests/crashes/119924-6.rs @@ -1,4 +1,5 @@ //@ known-bug: #119924 +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] struct S; diff --git a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs index b0c21ffaeb997..161d0c9d54e11 100644 --- a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs +++ b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs @@ -1,4 +1,6 @@ +//@ compile-flags: -Znext-solver #![feature(effects, const_trait_impl)] +#![allow(incomplete_features)] #[const_trait] pub trait Resource {} diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index bd9c08e5ad895..818b5d6ca93ae 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,5 +1,5 @@ //@ known-bug: #110395 - +//@ compile-flags: -Znext-solver #![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index cf03bb9ad7612..db93bcca60fb3 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -19,6 +19,12 @@ LL + #[derive(ConstParamTy)] LL | struct Foo(u8); | +error[E0284]: type annotations needed: cannot normalize `foo::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:20:25 + | +LL | fn foo(a: Evaluatable<{ N + N }>) { + | ^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo::{constant#0}` + error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/unify-op-with-fn-call.rs:20:17 | @@ -43,17 +49,25 @@ LL + #[derive(ConstParamTy)] LL | struct Foo(u8); | -error: unconstrained generic constant - --> $DIR/unify-op-with-fn-call.rs:30:12 +error[E0284]: type annotations needed: cannot normalize `foo2::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:29:28 | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo2(a: Evaluatable2<{ N + N }>) { + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2::{constant#0}` + +error[E0284]: type annotations needed: cannot normalize `foo::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:21:11 | -help: try adding a `where` bound +LL | bar::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo::{constant#0}` + +error[E0284]: type annotations needed: cannot normalize `foo2::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:30:12 | -LL | fn foo2(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: { - | +++++++++++++++++++++++++++++++++++++++++ +LL | bar2::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2::{constant#0}` -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0741`. +Some errors have detailed explanations: E0284, E0741. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index 128e0b64a2bfa..12cb7ee7f55cc 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,5 +1,5 @@ -//@ check-pass - +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr new file mode 100644 index 0000000000000..c17a7d5d9fad0 --- /dev/null +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -0,0 +1,27 @@ +error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` + --> $DIR/issue-88119.rs:21:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | +note: required by a bound in `<&T as ConstName>` + --> $DIR/issue-88119.rs:21:10 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` + +error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` + --> $DIR/issue-88119.rs:28:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | +note: required by a bound in `<&mut T as ConstName>` + --> $DIR/issue-88119.rs:28:10 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs index eb58233d1b1f8..a4dd3ee2e7e96 100644 --- a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs +++ b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs @@ -1,5 +1,7 @@ +//@ compile-flags: -Znext-solver #![crate_type = "lib"] -#![feature(const_closures, const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_closures, const_trait_impl, effects)] +#![allow(incomplete_features)] pub const fn test() { let cl = const || {}; diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index acc8d00f83e60..c64d31a5c60ae 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zmir-opt-level=0 +//@ compile-flags: -Zmir-opt-level=0 -Znext-solver //@ known-bug: #110395 // FIXME(effects) run-pass diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 27eb1252d7b7d..8afdd4e0d61bf 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/const-try.rs:16:12 | @@ -16,5 +21,5 @@ LL | impl const Try for TryMe { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index f27271423232c..77482007be48a 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,12 +1,17 @@ -//@ known-bug: #110395 -#![feature(const_type_id)] -#![feature(const_trait_impl, effects)] +//@ check-pass +//@ compile-flags: -Znext-solver +#![feature(const_type_id, const_trait_impl, effects)] +#![allow(incomplete_features)] use std::any::TypeId; -const fn main() { - assert!(TypeId::of::() == TypeId::of::()); - assert!(TypeId::of::<()>() != TypeId::of::()); - const _A: bool = TypeId::of::() < TypeId::of::(); - // can't assert `_A` because it is not deterministic +fn main() { + const { + // FIXME(effects) this isn't supposed to pass (right now) but it did. + // revisit binops typeck please. + assert!(TypeId::of::() == TypeId::of::()); + assert!(TypeId::of::<()>() != TypeId::of::()); + let _a = TypeId::of::() < TypeId::of::(); + // can't assert `_a` because it is not deterministic + } } diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr deleted file mode 100644 index e0e673d5fbdcf..0000000000000 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ /dev/null @@ -1,25 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const_cmp_type_id.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/const_cmp_type_id.rs:7:14 - | -LL | const fn main() { - | ^ `main` cannot have generic parameters - -error[E0080]: evaluation of constant value failed - --> $DIR/const_cmp_type_id.rs:10:22 - | -LL | const _A: bool = TypeId::of::() < TypeId::of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `::lt` - -error: aborting due to 2 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0080, E0131. -For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 9096bd7868272..7de10f0287b4b 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/constifconst-call-in-const-position.rs:17:38 | @@ -16,6 +21,6 @@ LL | [0; T::a()] = note: expected constant `false` found constant `host` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index 98c5c89713804..af3262ca57534 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -1,8 +1,9 @@ +//@ compile-flags: -Znext-solver //@ known-bug: #110395 #![crate_type = "lib"] -#![feature(staged_api)] -#![feature(const_trait_impl, effects)] +#![feature(staged_api, const_trait_impl, effects)] +#![allow(incomplete_features)] #![stable(feature = "foo", since = "1.0.0")] #[stable(feature = "potato", since = "1.27.0")] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 84bd375ea406e..4a534b3ca1410 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/rustc-impl-const-stability.rs:5:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/rustc-impl-const-stability.rs:15:12 + --> $DIR/rustc-impl-const-stability.rs:16:12 | LL | impl const Default for Data { | ^^^^^^^ @@ -16,5 +7,5 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/generic-const-items/const-trait-impl.rs b/tests/ui/generic-const-items/const-trait-impl.rs index 34be9fe601400..51209121bd915 100644 --- a/tests/ui/generic-const-items/const-trait-impl.rs +++ b/tests/ui/generic-const-items/const-trait-impl.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // Test that we can call methods from const trait impls inside of generic const items. #![feature(generic_const_items, const_trait_impl, effects)] diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs index 0e95fc757f3e8..92823b05af840 100644 --- a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs +++ b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs @@ -1,7 +1,9 @@ // Regression test for part of issue #119924. //@ check-pass +//@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr b/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr deleted file mode 100644 index 6670b3772db12..0000000000000 --- a/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/impls-nested-within-fns-semantic-1.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr index 919b5b6cd913d..fb491453b379b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 | @@ -28,6 +33,6 @@ LL | #[const_trait] LL | fn func() -> i32; | ---- required by a bound in this associated function -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index 48855d64b58a1..392b310a4c99e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 | @@ -28,6 +33,6 @@ LL | #[const_trait] LL | fn func() -> i32; | ---- required by a bound in this associated function -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 1862339cddc5e..405212b52c7c7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type.rs:41:15 | @@ -18,6 +23,6 @@ help: consider further restricting the associated type LL | trait Baz where Add::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index 78e41ca6b7519..8f63cd1d521ed 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs index fd4e1ff803da6..986165ef91e6c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 336ee01dc8d73..73ea1422bf9d7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:5 | @@ -23,6 +28,6 @@ LL | pub trait Plus { LL | fn plus(self, rhs: Self) -> Self; | ---- required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 2e1feccd0f358..57d57dfd5b935 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-chain.rs:10:12 | @@ -28,5 +33,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index d3b009636865a..0088ed2eb13db 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-dup-bound.rs:8:12 | @@ -28,5 +33,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs index a9ed5a639d73a..86e0eae61c9ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] pub const fn equals_self(t: &T) -> bool { *t == *t diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr deleted file mode 100644 index 74b74052da079..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/call-generic-method-fail.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index d48ee9c95f593..b2a98041c1cdf 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: const Compat` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | @@ -22,6 +27,6 @@ note: required by a bound in `equals_self` LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^^ required by this bound in `equals_self` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index cab8d6d761195..4a6100c3c1aac 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-pass.rs:10:12 | @@ -22,5 +27,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs index 1150d7e1059f1..af2f7caf88c75 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver #![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr index 42964b9774e29..b5d9b1fff8a1c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr @@ -22,5 +22,10 @@ note: this function is not `const`, so it cannot have `~const` trait bounds LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^ -error: aborting due to 2 previous errors +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr index d04e5490b7639..e1a85fc54144b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-bounds-non-const-trait.rs:6:28 | @@ -19,5 +24,5 @@ error: `const` can only be applied to `#[const_trait]` traits LL | fn operate() {} | ^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr index d93327cea1b2c..49cd1725c8cf3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0015]: cannot call non-const fn `non_const` in constant functions --> $DIR/const-check-fns-in-const-impl.rs:12:16 | @@ -15,6 +20,6 @@ LL | fn foo() { non_const() } | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 32bc0093347c0..02f9dffba3239 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | @@ -23,6 +28,6 @@ LL | #[const_trait] LL | fn a(self) { | - required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index 7925cf53f42c4..2a030369093d6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `A` which is not marked with `#[const_trait]` --> $DIR/const-impl-requires-const-trait.rs:8:12 | @@ -19,5 +24,5 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr index af50a115c69f7..b59c6d1eed8da 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -4,6 +4,11 @@ error[E0635]: unknown feature `const_cmp` LL | const_cmp, | ^^^^^^^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:13:30 | @@ -238,7 +243,7 @@ LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Des | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 32 previous errors +error: aborting due to 33 previous errors Some errors have detailed explanations: E0493, E0635. For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs index cf452cf852687..3b4ba6a998f88 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs @@ -1,5 +1,6 @@ -//@ check-pass - +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver +// FIXME(effects): check-pass #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr new file mode 100644 index 0000000000000..4d543f6a1559a --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr @@ -0,0 +1,30 @@ +error[E0284]: type annotations needed: cannot normalize `process::{constant#0}` + --> $DIR/const-trait-bounds.rs:12:35 + | +LL | fn process(input: [(); T::make(2)]) -> [(); T::make(2)] { + | ^^^^^^^^^^^^^^^^ cannot normalize `process::{constant#0}` + +error[E0284]: type annotations needed: cannot satisfy `the constant `T::make(P)` can be evaluated` + --> $DIR/const-trait-bounds.rs:18:5 + | +LL | [u32; T::make(P)]:, + | ^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `T::make(P)` can be evaluated` + | +note: required by a bound in `Struct` + --> $DIR/const-trait-bounds.rs:18:11 + | +LL | struct Struct + | ------ required by a bound in this struct +LL | where +LL | [u32; T::make(P)]:, + | ^^^^^^^^^^ required by this bound in `Struct` + +error[E0284]: type annotations needed: cannot normalize `process::{constant#1}` + --> $DIR/const-trait-bounds.rs:13:5 + | +LL | input + | ^^^^^ cannot normalize `process::{constant#1}` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 78e5b70d41c38..777b3313da6b2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -7,6 +7,11 @@ LL | #![feature(derive_const, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-non-const-type.rs:10:16 | @@ -17,5 +22,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index da6b77f623cc1..ad727fc36cd76 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -19,6 +19,11 @@ error[E0635]: unknown feature `const_default_impls` LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)] | ^^^^^^^^^^^^^^^^^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:7:12 | @@ -79,7 +84,7 @@ LL | const _: () = assert!(S((), A) == S::default()); | ^^^^^^^^^^^^ = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted Some errors have detailed explanations: E0080, E0635. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index 102458450fbf7..addce8dcd6c75 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/derive-const-with-params.rs:7:16 | @@ -25,5 +30,5 @@ LL | #[derive_const(PartialEq)] | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs index d8be8b13d0822..9ee5254dbf8a8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs @@ -2,8 +2,9 @@ // be called from a const context when used across crates. // //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr deleted file mode 100644 index 2f1e1e6b8d2b9..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate-default-method-body-is-const.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr deleted file mode 100644 index 2ce29a74eaeb0..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate.rs:3:60 - | -LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index af042ecff953b..b7209827c22c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,21 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate.rs:3:60 - | -LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied - --> $DIR/cross-crate.rs:18:14 +error[E0277]: the trait bound `cross_crate::MyTrait::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); - | ^^^^ the trait `~const Compat` is not implemented for `Runtime` + | ^^^^ the trait `~const Compat` is not implemented for `cross_crate::MyTrait::{synthetic#0}` | - = help: the trait `Compat` is implemented for `Runtime` note: required by a bound in `func` - --> $DIR/auxiliary/cross-crate.rs:4:1 + --> $DIR/auxiliary/cross-crate.rs:5:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` @@ -23,6 +13,6 @@ LL | #[const_trait] LL | fn func(self); | ---- required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs index 04c101d0fc5fb..cfcada9c828d4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,7 +1,8 @@ //@ revisions: stock gated stocknc gatednc //@ [gated] check-pass +//@ compile-flags: -Znext-solver #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] -//[gated,gatednc]~^ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] //@ aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr index 3df875057f2c8..b481bdc470ce3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:21:11 + --> $DIR/cross-crate.rs:22:11 | LL | Const.func(); | ^^^^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr index e56a5e4165ce3..5c3e3b6ff4008 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:18:14 + --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); | ^^^^^^ @@ -11,7 +11,7 @@ LL + #![feature(const_trait_impl)] | error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:21:11 + --> $DIR/cross-crate.rs:22:11 | LL | Const.func(); | ^^^^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 8b422d62578a0..1b5aa9c91918c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | @@ -23,6 +28,6 @@ LL | pub trait Tr { LL | fn a(&self) {} | - required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs index be5e66478dfaf..71e6375283fd8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, rustc_attrs, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, rustc_attrs, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr deleted file mode 100644 index 4be1160b58cb2..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/do-not-const-check-override.rs:2:43 - | -LL | #![feature(const_trait_impl, rustc_attrs, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs index 5c32eee8737e8..779527e22d4ab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] pub const fn foo() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs index a1c0425b24e38..3debc22098afc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs @@ -1,5 +1,6 @@ //@ check-pass // FIXME(effects) this shouldn't pass +//@ compile-flags: -Znext-solver #![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs index b354591e0070f..958b9ac6d5773 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs @@ -2,8 +2,9 @@ // at the end of generic args when the generics have defaulted params. // //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr deleted file mode 100644 index 7ceb3669e5983..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/effect-param-infer.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs index d949e4b829fc4..4cfba00526b0b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(effects)] pub const fn owo() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr deleted file mode 100644 index f7d5de829b200..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/fallback.rs:3:12 - | -LL | #![feature(effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs index eed8cdc447c55..54f362b4413b9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs @@ -1,11 +1,11 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // gate-test-effects // ^ effects doesn't have a gate so we will trick tidy into thinking this is a gate test - +#![allow(incomplete_features)] #![feature( const_trait_impl, - effects, //~ WARN the feature `effects` is incomplete + effects, core_intrinsics, const_eval_select )] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr deleted file mode 100644 index 8719c5cbcef0f..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/helloworld.rs:8:5 - | -LL | effects, - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr index 3f0ed13d665f8..526746eec7346 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr @@ -17,6 +17,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/ice-112822-expected-type-for-param.rs:3:32 | @@ -40,7 +45,7 @@ LL | assert_eq!(first, &b'f'); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs index 53f8e3c56d761..06e3377c5eec1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // effects ice https://github.com/rust-lang/rust/issues/113375 index out of bounds #![allow(incomplete_features, unused)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs index ff3a27c3ee479..581c3949d3811 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] const fn a() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr deleted file mode 100644 index 49c7d3958466a..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/infer-fallback.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr index 34732ac4f2ef7..fa2e3da368bd8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr @@ -7,7 +7,7 @@ LL | foo::(); | expected 0 generic arguments | note: function defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:3:14 + --> $DIR/auxiliary/cross-crate.rs:5:14 | LL | pub const fn foo() {} | ^^^ @@ -19,7 +19,7 @@ LL | <() as Bar>::bar(); | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:6:11 + --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ @@ -37,7 +37,7 @@ LL | foo::(); | expected 0 generic arguments | note: function defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:3:14 + --> $DIR/auxiliary/cross-crate.rs:5:14 | LL | pub const fn foo() {} | ^^^ @@ -49,7 +49,7 @@ LL | <() as Bar>::bar(); | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:6:11 + --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr index c3ff30d2d797b..fbb96dfd85e1b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params.rs:22:5 | @@ -76,7 +81,7 @@ help: replace the generic bound with the associated type LL | <() as Bar< = true>>::bar(); | + -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted Some errors have detailed explanations: E0107, E0308. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs index 373a4393713c6..9f6ca1f294f01 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr index 313ba4fc9565e..5ff1c6c5b9f15 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr @@ -17,6 +17,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/span-bug-issue-121418.rs:9:27 | @@ -39,7 +44,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>` --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL = note: the return type of a function must have a statically known size -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr index 047549bca75a5..e97a9615ae1a0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -7,6 +7,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` --> $DIR/spec-effectvar-ice.rs:12:15 | @@ -55,5 +60,5 @@ error: cannot specialize on trait `Specialize` LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr index 33914cb306dc6..15cb84026e470 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr @@ -63,6 +63,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 4 previous errors; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr index 416ba248a5f31..598129d8694e0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr @@ -17,6 +17,11 @@ LL | Some(())?; = help: add `#![feature(const_try)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr index 9e22422ad3b94..50cdded8d5114 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/ice-119717-constant-lifetime.rs:6:15 | @@ -27,7 +32,7 @@ help: try replacing `_` with the type in the corresponding trait method signatur LL | fn from_residual(t: T) -> T { | ~ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0121, E0210. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr index 011232f30b8a6..1f309e1e85446 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr @@ -55,6 +55,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0425]: cannot find function `main8` in this scope --> $DIR/ice-120503-async-const-method.rs:13:9 | @@ -95,7 +100,7 @@ LL | async const fn bar(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted Some errors have detailed explanations: E0379, E0391, E0407, E0425. For more information about an error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr index 4fe88f263c81b..29187654c3cc7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr @@ -23,6 +23,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 1 previous error; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr index 19369e38964f4..c937430a1ca19 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -1,8 +1,13 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 | LL | const fn with_positive() {} | ^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr index 0b1f8b40898e3..284757c1a8977 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0119]: conflicting implementations of trait `Foo` for type `i32` --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 | @@ -7,6 +12,6 @@ LL | LL | impl const Foo for T where T: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr index e641b457ef9c8..e49436c8f0f78 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/ice-126148-failed-to-normalize.rs:8:12 | @@ -33,6 +38,6 @@ LL | impl const Try for TryMe { = help: implement the missing item: `fn from_output(_: ::Output) -> Self { todo!() }` = help: implement the missing item: `fn branch(self) -> ControlFlow<::Residual, ::Output> { todo!() }` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 0135296526f96..2ea203627f435 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0046]: not all trait items implemented, missing: `req` --> $DIR/impl-with-default-fn-fail.rs:13:1 | @@ -7,6 +12,6 @@ LL | fn req(&self); LL | impl const Tr for u16 { | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs index 0a1d2355a75bc..2c375036941c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr new file mode 100644 index 0000000000000..4a949e90d8554 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:34:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr new file mode 100644 index 0000000000000..1bfce48d26a2d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:25:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs index 10d7a3942e497..7949772a2b4e9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs @@ -1,5 +1,6 @@ //@ revisions: nn ny yn yy -//@ check-pass +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr new file mode 100644 index 0000000000000..4a949e90d8554 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:34:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr new file mode 100644 index 0000000000000..1bfce48d26a2d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:25:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs index 36c82dfe68485..b8b9e07b3bd60 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs @@ -1,5 +1,7 @@ +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(const_fmt_arguments_new)] -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr index 9da31486faaff..9e6348d37ed5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-79450.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0015]: cannot call non-const fn `_print` in constant functions - --> $DIR/issue-79450.rs:9:9 + --> $DIR/issue-79450.rs:11:9 | LL | println!("lul"); | ^^^^^^^^^^^^^^^ @@ -16,6 +7,6 @@ LL | println!("lul"); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr index 363fbee1f8bfb..c51d169dd3397 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr @@ -7,11 +7,16 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: cannot specialize on const impl with non-const impl --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1 | LL | impl Value for FortyTwo { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 272cb26ff42e5..90721af8e5aab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: cannot specialize on const impl with non-const impl --> $DIR/specializing-constness.rs:23:1 | @@ -25,5 +30,5 @@ error: cannot specialize on trait `Compat` LL | impl A for T { | ^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs index 460c2ef617438..f87e723472ad8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs @@ -1,7 +1,9 @@ //@ revisions: stable unstable +//@ compile-flags: -Znext-solver #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file. -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr index 0604b22ecbb3e..6c07a253f5b09 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/staged-api.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: trait implementations cannot be const stable yet - --> $DIR/staged-api.rs:19:1 + --> $DIR/staged-api.rs:21:1 | LL | / impl const MyTrait for Foo { LL | | @@ -19,7 +10,7 @@ LL | | } = note: see issue #67792 for more information error: function has missing const stability attribute - --> $DIR/staged-api.rs:41:1 + --> $DIR/staged-api.rs:43:1 | LL | / pub const fn const_context_not_const_stable() { LL | | @@ -31,7 +22,7 @@ LL | | } | |_^ error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:32:5 + --> $DIR/staged-api.rs:34:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -39,7 +30,7 @@ LL | Unstable::func(); = help: add `#![feature(unstable)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:43:5 + --> $DIR/staged-api.rs:45:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -47,12 +38,12 @@ LL | Unstable::func(); = help: add `#![feature(unstable)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:53:5 + --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr index b53e7b6f6acec..1c772f13dd511 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/staged-api.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:34:5 + --> $DIR/staged-api.rs:36:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -16,7 +7,7 @@ LL | Foo::func(); = help: add `#![feature(foo)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:45:5 + --> $DIR/staged-api.rs:47:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -24,7 +15,7 @@ LL | Foo::func(); = help: add `#![feature(foo)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:53:5 + --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -32,7 +23,7 @@ LL | Unstable::func(); = help: const-stable functions can only call other const-stable functions error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:55:5 + --> $DIR/staged-api.rs:57:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -40,12 +31,12 @@ LL | Foo::func(); = help: const-stable functions can only call other const-stable functions error: `const_context_not_const_stable` is not yet stable as a const fn - --> $DIR/staged-api.rs:57:5 + --> $DIR/staged-api.rs:59:5 | LL | const_context_not_const_stable() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index 3a36a5b750932..48bb1907be2eb 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:10:12 + --> $DIR/super-traits-fail-2.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:10:1 + --> $DIR/super-traits-fail-2.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -34,12 +25,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index beb931570cb85..029c3b4bde3ec 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -22,12 +13,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index ba20a79a4df74..0d659744e700e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ revisions: yy yn ny nn #[cfg_attr(any(yy, yn), const_trait)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index a4f1c94bca0bc..d4064e01ef10c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:10:12 + --> $DIR/super-traits-fail-2.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:10:1 + --> $DIR/super-traits-fail-2.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-2.rs:17:7 + --> $DIR/super-traits-fail-2.rs:19:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:4:25 + --> $DIR/super-traits-fail-2.rs:6:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` @@ -38,6 +29,6 @@ help: consider further restricting the associated type LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index 4e27ebc5e9ec7..9f9f96c6b486b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-2.rs:17:7 + --> $DIR/super-traits-fail-2.rs:19:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:4:25 + --> $DIR/super-traits-fail-2.rs:6:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` @@ -26,6 +17,6 @@ help: consider further restricting the associated type LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index a9bf2687cb88f..f40583f0ca57f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:14:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:14:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -25,7 +25,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -33,7 +33,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:19:24 + --> $DIR/super-traits-fail-3.rs:20:24 | LL | const fn foo(x: &T) { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index c3811623c1c86..3f6dfa7b00896 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,11 +1,11 @@ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -13,7 +13,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index 24661f078b017..6694351265007 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index 34a60329eb5e2..0b48633a10e20 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,29 +1,29 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:14:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:14:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:19:24 + --> $DIR/super-traits-fail-3.rs:20:24 | LL | const fn foo(x: &T) { | ^^^ error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-3.rs:21:7 + --> $DIR/super-traits-fail-3.rs:22:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:7:25 + --> $DIR/super-traits-fail-3.rs:8:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr index 8ac20b3e06852..ea0e6c690b72b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-3.rs:21:7 + --> $DIR/super-traits-fail-3.rs:22:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:7:25 + --> $DIR/super-traits-fail-3.rs:8:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr index b479793814cb9..73526a26e081e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr @@ -22,6 +22,11 @@ note: this function is not `const`, so it cannot have `~const` trait bounds LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/tilde-const-and-const-params.rs:27:61 | @@ -40,6 +45,6 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { = note: expected constant `false` found constant `true` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs index 86a2bbe35ed7d..8e7202ecaa1ff 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs @@ -1,7 +1,8 @@ // Regression test for issue #119700. //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Main { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr deleted file mode 100644 index 70019ce57f29e..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-assoc-fn-in-trait-impl.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs index 0f5729e3daf62..71c5d8366b2f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr deleted file mode 100644 index 4ec8dac1f0d3a..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-inherent-assoc-const-fn.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs index c2d3b2036c638..254cf2200d853 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr deleted file mode 100644 index 1ead23d5c2c1d..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-trait-assoc-tys.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs index f41e70c99ff8a..b36e9535ca113 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -1,5 +1,6 @@ //@ known-bug: #110395 - +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(staged_api)] #![feature(const_trait_impl, effects)] #![feature(const_t_try)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index d0c2f88005d7a..49fbef9aaa29f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-default-body-stability.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:18:12 + --> $DIR/trait-default-body-stability.rs:19:12 | LL | impl const Try for T { | ^^^ @@ -17,7 +8,7 @@ LL | impl const Try for T { = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:33:12 + --> $DIR/trait-default-body-stability.rs:34:12 | LL | impl const FromResidual for T { | ^^^^^^^^^^^^ @@ -25,5 +16,5 @@ LL | impl const FromResidual for T { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index dd5de62aff529..8ca9b7cc7aa0a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver // Like trait-where-clause.rs, but we are calling from a const context. // Checking the validity of traits' where clauses happen at a later stage. // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 877152472c16e..979f1e798e0a7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied - --> $DIR/trait-where-clause-const.rs:21:5 + --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:12:1 + --> $DIR/trait-where-clause-const.rs:13:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` @@ -18,7 +18,7 @@ LL | const fn test1() where Foo::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:21:5 + --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); | ^^^^^^ expected `host`, found `true` @@ -27,13 +27,13 @@ LL | T::b(); found constant `true` error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied - --> $DIR/trait-where-clause-const.rs:24:5 + --> $DIR/trait-where-clause-const.rs:25:5 | LL | T::c::(); | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:12:1 + --> $DIR/trait-where-clause-const.rs:13:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` @@ -46,7 +46,7 @@ LL | const fn test1() where Foo::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:24:5 + --> $DIR/trait-where-clause-const.rs:25:5 | LL | T::c::(); | ^^^^^^^^^^^ expected `host`, found `true` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs index 59ddc2f748ede..cb5cc924bfd34 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr deleted file mode 100644 index 6e9e948e45cd3..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-self-referential.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 62bb0239168e0..82da18cc9ac2c 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![feature(staged_api)] #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete #![stable(feature = "stable", since = "1.0.0")] diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr index 4e488124fe394..adf60c3861140 100644 --- a/tests/ui/stability-attribute/missing-const-stability.stderr +++ b/tests/ui/stability-attribute/missing-const-stability.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing-const-stability.rs:2:30 + --> $DIR/missing-const-stability.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -8,13 +8,13 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error: function has missing const stability attribute - --> $DIR/missing-const-stability.rs:6:1 + --> $DIR/missing-const-stability.rs:7:1 | LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ error: implementation has missing const stability attribute - --> $DIR/missing-const-stability.rs:28:1 + --> $DIR/missing-const-stability.rs:29:1 | LL | / impl const Bar for Foo { LL | | @@ -23,7 +23,7 @@ LL | | } | |_^ error: associated function has missing const stability attribute - --> $DIR/missing-const-stability.rs:15:5 + --> $DIR/missing-const-stability.rs:16:5 | LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ From f6942112eb44cb292463d457c603016cc16f4bc6 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Jun 2024 11:30:22 -0700 Subject: [PATCH 201/217] Add a GVN test for 127089 that doesn't optimize to a constant --- ...ust_change_both_sides.GVN.panic-abort.diff | 16 +++++++++++++++ ...st_change_both_sides.GVN.panic-unwind.diff | 16 +++++++++++++++ tests/mir-opt/gvn.rs | 20 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff diff --git a/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff new file mode 100644 index 0000000000000..8b4bfb70401b3 --- /dev/null +++ b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff @@ -0,0 +1,16 @@ +- // MIR for `remove_casts_must_change_both_sides` before GVN ++ // MIR for `remove_casts_must_change_both_sides` after GVN + + fn remove_casts_must_change_both_sides(_1: &*mut u8, _2: *mut u8) -> bool { + let mut _0: bool; + let mut _3: *const u8; + let mut _4: *const u8; + + bb0: { + _3 = (*_1) as *const u8 (PtrToPtr); + _4 = _2 as *const u8 (PtrToPtr); + _0 = Eq(_3, _4); + return; + } + } + diff --git a/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..8b4bfb70401b3 --- /dev/null +++ b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff @@ -0,0 +1,16 @@ +- // MIR for `remove_casts_must_change_both_sides` before GVN ++ // MIR for `remove_casts_must_change_both_sides` after GVN + + fn remove_casts_must_change_both_sides(_1: &*mut u8, _2: *mut u8) -> bool { + let mut _0: bool; + let mut _3: *const u8; + let mut _4: *const u8; + + bb0: { + _3 = (*_1) as *const u8 (PtrToPtr); + _4 = _2 as *const u8 (PtrToPtr); + _0 = Eq(_3, _4); + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 86f42d23f3835..c7fae0bd08108 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -926,6 +926,25 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) { let fat_addr: usize = std::intrinsics::transmute(fat as *const ()); } +#[custom_mir(dialect = "analysis")] +fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool { + // CHECK-LABEL: fn remove_casts_must_change_both_sides( + mir! { + // We'd like to remove these casts, but we can't change *both* of them + // to be locals, so make sure we don't change one without the other, as + // that would be a type error. + { + // CHECK: [[A:_.+]] = (*_1) as *const u8 (PtrToPtr); + let a = *mut_a as *const u8; + // CHECK: [[B:_.+]] = _2 as *const u8 (PtrToPtr); + let b = mut_b as *const u8; + // CHECK: _0 = Eq([[A]], [[B]]); + RET = a == b; + Return() + } + } +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -995,3 +1014,4 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.generic_cast_metadata.GVN.diff // EMIT_MIR gvn.cast_pointer_eq.GVN.diff // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff +// EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff From 552794410a9237a26aded88990dbe8be26c72dfc Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 30 Jun 2024 19:31:15 +0100 Subject: [PATCH 202/217] add `rustc_dump_def_parents` attribute --- compiler/rustc_feature/src/builtin_attrs.rs | 4 + .../rustc_hir_analysis/src/collect/dump.rs | 50 ++++++- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/attributes/dump_def_parents.rs | 34 +++++ tests/ui/attributes/dump_def_parents.stderr | 128 ++++++++++++++++++ 6 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 tests/ui/attributes/dump_def_parents.rs create mode 100644 tests/ui/attributes/dump_def_parents.stderr diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a4245f0908e33..910402d5499fd 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1117,6 +1117,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ TEST, rustc_dump_predicates, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No ), + rustc_attr!( + TEST, rustc_dump_def_parents, Normal, template!(Word), + WarnFollowing, EncodeCrossCrate::No + ), rustc_attr!( TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 85e1c600d6da4..c73d3a5390d93 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,5 +1,7 @@ use rustc_hir::def::DefKind; -use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::intravisit; +use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::ty::TyCtxt; use rustc_span::sym; @@ -41,3 +43,49 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } } } + +pub(crate) fn def_parents(tcx: TyCtxt<'_>) { + for did in tcx.hir().body_owners() { + if tcx.has_attr(did, sym::rustc_dump_def_parents) { + struct AnonConstFinder<'tcx> { + tcx: TyCtxt<'tcx>, + anon_consts: Vec, + } + + impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + + fn visit_anon_const(&mut self, c: &'tcx rustc_hir::AnonConst) { + self.anon_consts.push(c.def_id); + intravisit::walk_anon_const(self, c) + } + } + + // Look for any anon consts inside of this body owner as there is no way to apply + // the `rustc_dump_def_parents` attribute to the anon const so it would not be possible + // to see what its def parent is. + let mut anon_ct_finder = AnonConstFinder { tcx, anon_consts: vec![] }; + intravisit::walk_expr(&mut anon_ct_finder, tcx.hir().body_owned_by(did).value); + + for did in [did].into_iter().chain(anon_ct_finder.anon_consts) { + let span = tcx.def_span(did); + + let mut diag = tcx.dcx().struct_span_err( + span, + format!("{}: {did:?}", sym::rustc_dump_def_parents.as_str()), + ); + + let mut current_did = did.to_def_id(); + while let Some(parent_did) = tcx.opt_parent(current_did) { + current_did = parent_did; + diag.span_note(tcx.def_span(parent_did), format!("{parent_did:?}")); + } + diag.emit(); + } + } + } +} diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0428abcdf24e8..dcf60edafe26e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -169,6 +169,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); collect::dump::opaque_hidden_types(tcx); collect::dump::predicates_and_item_bounds(tcx); + collect::dump::def_parents(tcx); } // Make sure we evaluate all static and (non-associated) const items, even if unused. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8b7a63f5eb9b6..7da9211bcbf74 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1614,6 +1614,7 @@ symbols! { rustc_do_not_const_check, rustc_doc_primitive, rustc_dummy, + rustc_dump_def_parents, rustc_dump_item_bounds, rustc_dump_predicates, rustc_dump_user_args, diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs new file mode 100644 index 0000000000000..af1c210d2cd18 --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.rs @@ -0,0 +1,34 @@ +//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +#![feature(rustc_attrs)] + +fn bar() { + fn foo() { + fn baz() { + #[rustc_dump_def_parents] + || { + //~^ ERROR: rustc_dump_def_parents: DefId + qux::< + { + //~^ ERROR: rustc_dump_def_parents: DefId + fn inhibits_dump() { + qux::< + { + "hi"; + 1 + }, + >(); + } + + qux::<{ 1 + 1 }>(); + //~^ ERROR: rustc_dump_def_parents: DefId + 1 + }, + >(); + }; + } + } +} + +const fn qux() {} + +fn main() {} diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr new file mode 100644 index 0000000000000..b2cc32d09b07e --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.stderr @@ -0,0 +1,128 @@ +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:22:31 + | +LL | qux::<{ 1 + 1 }>(); + | ^^^^^^^^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 3 previous errors + From af3d7f869b7a10ee5ccd7b7f8c6ce184be480d5e Mon Sep 17 00:00:00 2001 From: Daniel Huang Date: Sun, 30 Jun 2024 14:54:05 -0400 Subject: [PATCH 203/217] Update ip_addr.rs --- library/core/src/net/ip_addr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index b578756e46a66..c11a508a135b3 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -406,7 +406,7 @@ impl IpAddr { matches!(self, IpAddr::V6(_)) } - /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 addresses, otherwise it + /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 address, otherwise it /// returns `self` as-is. /// /// # Examples @@ -1879,7 +1879,7 @@ impl Ipv6Addr { } } - /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped addresses, otherwise it + /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped address, otherwise it /// returns self wrapped in an `IpAddr::V6`. /// /// # Examples From 4c919ac50b5fabe341b35d9440bc84dcc3388130 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 1 Jul 2024 00:24:56 +0100 Subject: [PATCH 204/217] Ensure `out_of_scope_macro_calls` lint is registered --- compiler/rustc_lint_defs/src/builtin.rs | 1 + tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 472e93d202d76..2ade6964ca89e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -74,6 +74,7 @@ declare_lint_pass! { NON_CONTIGUOUS_RANGE_ENDPOINTS, NON_EXHAUSTIVE_OMITTED_PATTERNS, ORDER_DEPENDENT_TRAIT_OBJECTS, + OUT_OF_SCOPE_MACRO_CALLS, OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, PRIVATE_BOUNDS, diff --git a/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs b/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs new file mode 100644 index 0000000000000..0736c373d576e --- /dev/null +++ b/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs @@ -0,0 +1,6 @@ +//@ check-pass + +#![deny(unknown_lints)] +#![allow(out_of_scope_macro_calls)] + +fn main() {} From 583b5fcad762d88dea0c1589e2aa6bff980848cd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 14:49:27 -0400 Subject: [PATCH 205/217] Use full expr span for return suggestion on type error/ambiguity --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 3 +- .../return/tail-expr-as-potential-return.rs | 36 ++++++++++++++----- .../tail-expr-as-potential-return.stderr | 33 +++++++++++++---- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 1138642c56d61..f4f3f24316716 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2042,7 +2042,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if block_num > 1 && found_semi { err.span_suggestion_verbose( - span.shrink_to_lo(), + // use the span of the *whole* expr + self.tcx.hir().span(binding_hir_id).shrink_to_lo(), "you might have meant to return this to infer its type parameters", "return ", Applicability::MaybeIncorrect, diff --git a/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs index 37dee1c19db8c..11ecddb049b57 100644 --- a/tests/ui/return/tail-expr-as-potential-return.rs +++ b/tests/ui/return/tail-expr-as-potential-return.rs @@ -1,3 +1,5 @@ +//@ edition:2018 + // > Suggest returning tail expressions that match return type // > // > Some newcomers are confused by the behavior of tail expressions, @@ -8,24 +10,24 @@ // // This test was amended to also serve as a regression test for #92308, where // this suggestion would not trigger with async functions. -// -//@ edition:2018 fn main() { } fn foo(x: bool) -> Result { if x { - Err(42) //~ ERROR mismatched types - //| HELP you might have meant to return this value + Err(42) + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(42.0) } async fn bar(x: bool) -> Result { if x { - Err(42) //~ ERROR mismatched types - //| HELP you might have meant to return this value + Err(42) + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(42.0) } @@ -40,8 +42,26 @@ impl Identity for T { async fn foo2() -> i32 { if true { - 1i32 //~ ERROR mismatched types - //| HELP you might have meant to return this value + 1i32 + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } 0 } + +struct Receiver; +impl Receiver { + fn generic(self) -> Option { + None + } +} +fn method() -> Option { + if true { + Receiver.generic(); + //~^ ERROR type annotations needed + //~| HELP consider specifying the generic argument + //~| HELP you might have meant to return this to infer its type parameters + } + + None +} diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index ccb208fc6c4ae..635a9e06633ff 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/tail-expr-as-potential-return.rs:27:9 + --> $DIR/tail-expr-as-potential-return.rs:28:9 | LL | / if x { LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -16,12 +17,13 @@ LL | return Err(42); | ++++++ + error[E0308]: mismatched types - --> $DIR/tail-expr-as-potential-return.rs:43:9 + --> $DIR/tail-expr-as-potential-return.rs:45:9 | LL | / if true { LL | | 1i32 | | ^^^^ expected `()`, found `i32` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -36,7 +38,8 @@ error[E0308]: mismatched types LL | / if x { LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -47,6 +50,22 @@ help: you might have meant to return this value LL | return Err(42); | ++++++ + -error: aborting due to 3 previous errors +error[E0282]: type annotations needed + --> $DIR/tail-expr-as-potential-return.rs:60:18 + | +LL | Receiver.generic(); + | ^^^^^^^ cannot infer type of the type parameter `T` declared on the method `generic` + | +help: consider specifying the generic argument + | +LL | Receiver.generic::(); + | +++++ +help: you might have meant to return this to infer its type parameters + | +LL | return Receiver.generic(); + | ++++++ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. From b5b97dccaeb764c7dc0e7877941808acabb1cc8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Jul 2024 10:45:55 +0200 Subject: [PATCH 206/217] Improve `run-make-support` API for `assert*` functions --- src/tools/run-make-support/src/command.rs | 8 ++++---- src/tools/run-make-support/src/lib.rs | 12 +++++++++--- tests/run-make/compressed-debuginfo/rmake.rs | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index 0a1bd9b0b34f5..ee651704c6fd0 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -185,14 +185,14 @@ impl CompletedProcess { /// Checks that `stdout` does not contain `unexpected`. #[track_caller] pub fn assert_stdout_not_contains>(&self, unexpected: S) -> &Self { - assert_not_contains(&self.stdout_utf8(), unexpected.as_ref()); + assert_not_contains(&self.stdout_utf8(), unexpected); self } /// Checks that `stdout` contains `expected`. #[track_caller] pub fn assert_stdout_contains>(&self, expected: S) -> &Self { - assert_contains(&self.stdout_utf8(), expected.as_ref()); + assert_contains(&self.stdout_utf8(), expected); self } @@ -206,14 +206,14 @@ impl CompletedProcess { /// Checks that `stderr` contains `expected`. #[track_caller] pub fn assert_stderr_contains>(&self, expected: S) -> &Self { - assert_contains(&self.stderr_utf8(), expected.as_ref()); + assert_contains(&self.stderr_utf8(), expected); self } /// Checks that `stderr` does not contain `unexpected`. #[track_caller] pub fn assert_stderr_not_contains>(&self, unexpected: S) -> &Self { - assert_not_contains(&self.stdout_utf8(), unexpected.as_ref()); + assert_not_contains(&self.stdout_utf8(), unexpected); self } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index df417722e024f..294dae109425f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -409,7 +409,9 @@ pub fn read_dir(dir: impl AsRef, mut callback: F) { /// Check that `actual` is equal to `expected`. Panic otherwise. #[track_caller] -pub fn assert_equals(actual: &str, expected: &str) { +pub fn assert_equals, S2: AsRef>(actual: S1, expected: S2) { + let actual = actual.as_ref(); + let expected = expected.as_ref(); if actual != expected { eprintln!("=== ACTUAL TEXT ==="); eprintln!("{}", actual); @@ -421,7 +423,9 @@ pub fn assert_equals(actual: &str, expected: &str) { /// Check that `haystack` contains `needle`. Panic otherwise. #[track_caller] -pub fn assert_contains(haystack: &str, needle: &str) { +pub fn assert_contains, S2: AsRef>(haystack: S1, needle: S2) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); if !haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); eprintln!("{}", haystack); @@ -433,7 +437,9 @@ pub fn assert_contains(haystack: &str, needle: &str) { /// Check that `haystack` does not contain `needle`. Panic otherwise. #[track_caller] -pub fn assert_not_contains(haystack: &str, needle: &str) { +pub fn assert_not_contains, S2: AsRef>(haystack: S1, needle: S2) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); if haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); eprintln!("{}", haystack); diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 9c6d50ab243cd..58eb2d6b1b39d 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -23,8 +23,8 @@ fn check_compression(compression: &str, to_find: &str) { cmd("readelf").arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); } else { assert_contains( - &stderr, - &format!("unknown debuginfo compression algorithm {compression}"), + stderr, + format!("unknown debuginfo compression algorithm {compression}"), ); } }); From fcfac05657acf387392f853904c917ac06c082c5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Jul 2024 10:55:43 +0200 Subject: [PATCH 207/217] Improve `target` method API in `run-make-support` --- src/tools/run-make-support/src/rustc.rs | 3 ++- src/tools/run-make-support/src/rustdoc.rs | 3 ++- tests/run-make/comment-section/rmake.rs | 2 +- tests/run-make/inaccessible-temp-dir/rmake.rs | 2 +- tests/run-make/static-pie/rmake.rs | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index df843d74fc927..3f23c1b8f9e76 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -201,7 +201,8 @@ impl Rustc { } /// Specify the target triple, or a path to a custom target json spec file. - pub fn target(&mut self, target: &str) -> &mut Self { + pub fn target>(&mut self, target: S) -> &mut Self { + let target = target.as_ref(); self.cmd.arg(format!("--target={target}")); self } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index fb00427b1c199..2be962ad88828 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -104,7 +104,8 @@ impl Rustdoc { } /// Specify the target triple, or a path to a custom target json spec file. - pub fn target(&mut self, target: &str) -> &mut Self { + pub fn target>(&mut self, target: S) -> &mut Self { + let target = target.as_ref(); self.cmd.arg(format!("--target={target}")); self } diff --git a/tests/run-make/comment-section/rmake.rs b/tests/run-make/comment-section/rmake.rs index 41df04da7a578..188c6dcb25d2e 100644 --- a/tests/run-make/comment-section/rmake.rs +++ b/tests/run-make/comment-section/rmake.rs @@ -21,7 +21,7 @@ fn main() { .stdin("fn main() {}") .emit("link,obj") .arg("-Csave-temps") - .target(&target) + .target(target) .run(); // Check linked output has a `.comment` section with the expected content. diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index c6bfae4cc01db..6b3e9e0b29e38 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -28,7 +28,7 @@ fn main() { // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, // so that it can't create `tmp`. rustc() - .target(&target()) + .target(target()) .input("program.rs") .arg("-Ztemps-dir=inaccessible/tmp") .run_fail() diff --git a/tests/run-make/static-pie/rmake.rs b/tests/run-make/static-pie/rmake.rs index 77c5e253bc03a..6a92f92328eec 100644 --- a/tests/run-make/static-pie/rmake.rs +++ b/tests/run-make/static-pie/rmake.rs @@ -51,7 +51,7 @@ fn test(compiler: &str) { rustc() .input("test-aslr.rs") - .target(&target()) + .target(target()) .linker(compiler) .arg("-Clinker-flavor=gcc") .arg("-Ctarget-feature=+crt-static") From fe6f3fa107389f3b46235b97aa7330e54ad241e6 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 30 Jun 2024 23:52:28 +0300 Subject: [PATCH 208/217] improve the way bootstrap handles rustlib components When CI rustc is enabled, bootstrap tries to symlink the rust source (project root) into target sysroot right before copying it from the CI rustc's sysroot. This becomes a problem in CI builders (which we currently don't see because they don't use CI rustc) because the copying part will fail as they run on read-only mode. This change fixes the problem by copying `rustc-src` from the CI rustc sysroot and only symlinking `rustc-src` from the rust source when download-rustc is not enabled. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a6172589dbb0f..6893ea883b11a 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -161,9 +161,10 @@ impl Step for Std { // This check is specific to testing std itself; see `test::Std` for more details. && !self.force_recompile { + let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); cp_rustc_component_to_ci_sysroot( builder, - compiler, + &sysroot, builder.config.ci_rust_std_contents(), ); return; @@ -797,12 +798,7 @@ impl Step for StartupObjects { } } -fn cp_rustc_component_to_ci_sysroot( - builder: &Builder<'_>, - compiler: Compiler, - contents: Vec, -) { - let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); +fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, contents: Vec) { let ci_rustc_dir = builder.config.ci_rustc_dir(); for file in contents { @@ -881,13 +877,7 @@ impl Step for Rustc { // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, // so its artifacts can't be reused. if builder.download_rustc() && compiler.stage != 0 { - // Copy the existing artifacts instead of rebuilding them. - // NOTE: this path is only taken for tools linking to rustc-dev (including ui-fulldeps tests). - cp_rustc_component_to_ci_sysroot( - builder, - compiler, - builder.config.ci_rustc_dev_contents(), - ); + builder.ensure(Sysroot { compiler, force_recompile: false }); return compiler.stage; } @@ -1646,19 +1636,29 @@ impl Step for Sysroot { ); } } - // Same for the rustc-src component. - let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src"); - t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc)); - let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust"); - if let Err(e) = - symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) - { - eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", - sysroot_lib_rustlib_rustcsrc_rust.display(), - builder.src.display(), - e, + + // Unlike rust-src component, we have to handle rustc-src a bit differently. + // When using CI rustc, we copy rustc-src component from its sysroot, + // otherwise we handle it in a similar way what we do for rust-src above. + if builder.download_rustc() { + cp_rustc_component_to_ci_sysroot( + builder, + &sysroot, + builder.config.ci_rustc_dev_contents(), ); + } else { + let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src"); + t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc)); + let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust"); + if let Err(e) = + symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) + { + eprintln!( + "WARNING: creating symbolic link `{}` to `{}` failed with {}", + sysroot_lib_rustlib_rustcsrc_rust.display(), + builder.src.display(), + e, + ); } sysroot From 97415ce6e792fecf5bfa5be20745c0f0f377dc51 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 1 Jul 2024 11:47:32 +0300 Subject: [PATCH 209/217] fail on component linking errors Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6893ea883b11a..de3b938e42731 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1624,17 +1624,18 @@ impl Step for Sysroot { let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust"); if let Err(e) = symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_src_rust) { eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", + "ERROR: creating symbolic link `{}` to `{}` failed with {}", sysroot_lib_rustlib_src_rust.display(), builder.src.display(), e, ); if builder.config.rust_remap_debuginfo { eprintln!( - "WARNING: some `tests/ui` tests will fail when lacking `{}`", + "ERROR: some `tests/ui` tests will fail when lacking `{}`", sysroot_lib_rustlib_src_rust.display(), ); } + build_helper::exit!(1); } // Unlike rust-src component, we have to handle rustc-src a bit differently. @@ -1654,11 +1655,13 @@ impl Step for Sysroot { symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) { eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", + "ERROR: creating symbolic link `{}` to `{}` failed with {}", sysroot_lib_rustlib_rustcsrc_rust.display(), builder.src.display(), e, ); + build_helper::exit!(1); + } } sysroot From af31c338fc19c51d61b9dabe7b8e4bc854558907 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 Jan 2024 19:35:55 +0300 Subject: [PATCH 210/217] linker: Refactor interface for passing arguments to linker --- compiler/rustc_codegen_ssa/src/back/link.rs | 70 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 617 ++++++++---------- 2 files changed, 314 insertions(+), 373 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index d509e4ce56d5b..da7ffdc49116f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -45,7 +45,7 @@ use tempfile::Builder as TempFileBuilder; use itertools::Itertools; use std::collections::BTreeSet; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::fs::{read, File, OpenOptions}; use std::io::{BufWriter, Write}; use std::ops::Deref; @@ -1306,12 +1306,12 @@ fn link_sanitizer_runtime( let filename = format!("rustc{channel}_rt.{name}"); let path = find_sanitizer_runtime(sess, &filename); let rpath = path.to_str().expect("non-utf8 component in path"); - linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); + linker.cc_args(&["-Wl,-rpath", "-Xlinker", rpath]); linker.link_dylib_by_name(&filename, false, true); } else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" { // MSVC provides the `/INFERASANLIBS` argument to automatically find the // compatible ASAN library. - linker.arg("/INFERASANLIBS"); + linker.link_arg("/INFERASANLIBS"); } else { let filename = format!("librustc{channel}_rt.{name}.a"); let path = find_sanitizer_runtime(sess, &filename).join(&filename); @@ -1888,9 +1888,9 @@ fn add_post_link_objects( /// FIXME: Determine where exactly these args need to be inserted. fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.pre_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } - cmd.args(&sess.opts.unstable_opts.pre_link_args); + cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args); } /// Add a link script embedded in the target, if applicable. @@ -1908,8 +1908,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty sess.dcx().emit_fatal(errors::LinkScriptWriteFailure { path, error }); } - cmd.arg("--script"); - cmd.arg(path); + cmd.link_arg("--script").link_arg(path); } _ => {} } @@ -1918,7 +1917,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty /// Add arbitrary "user defined" args defined from command line. /// FIXME: Determine where exactly these args need to be inserted. fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) { - cmd.args(&sess.opts.cg.link_args); + cmd.verbatim_args(&sess.opts.cg.link_args); } /// Add arbitrary "late link" args defined by the target spec. @@ -1936,15 +1935,15 @@ fn add_late_link_args( }); if any_dynamic_crate { if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } else { if let Some(args) = sess.target.late_link_args_static.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } if let Some(args) = sess.target.late_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } @@ -1952,7 +1951,7 @@ fn add_late_link_args( /// FIXME: Determine where exactly these args need to be inserted. fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.post_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } @@ -2119,7 +2118,7 @@ fn add_rpath_args( is_like_osx: sess.target.is_like_osx, linker_is_gnu: sess.target.linker_flavor.is_gnu(), }; - cmd.args(&rpath::get_rpath_flags(&rpath_config)); + cmd.cc_args(&rpath::get_rpath_flags(&rpath_config)); } } @@ -2378,7 +2377,7 @@ fn add_order_independent_options( } else { "" }; - cmd.arg(format!("--dynamic-linker={prefix}ld.so.1")); + cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1")); } if sess.target.eh_frame_header { @@ -2393,8 +2392,7 @@ fn add_order_independent_options( } if sess.target.os == "emscripten" { - cmd.arg("-s"); - cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort { + cmd.cc_arg("-s").cc_arg(if sess.panic_strategy() == PanicStrategy::Abort { "DISABLE_EXCEPTION_CATCHING=1" } else { "DISABLE_EXCEPTION_CATCHING=0" @@ -2402,22 +2400,21 @@ fn add_order_independent_options( } if flavor == LinkerFlavor::Llbc { - cmd.arg("--target"); - cmd.arg(sess.target.llvm_target.as_ref()); - cmd.arg("--target-cpu"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&[ + "--target", + sess.target.llvm_target.as_ref(), + "--target-cpu", + &codegen_results.crate_info.target_cpu, + ]); } else if flavor == LinkerFlavor::Ptx { - cmd.arg("--fallback-arch"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { - cmd.arg("--cpu"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]); if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features] .into_iter() .find(|feat| !feat.is_empty()) { - cmd.arg("--cpu-features"); - cmd.arg(feat); + cmd.link_args(&["--cpu-features", feat]); } } @@ -2618,7 +2615,11 @@ fn add_native_libs_from_crate( NativeLibKind::WasmImportModule => {} NativeLibKind::LinkArg => { if link_static { - cmd.linker_arg(OsStr::new(name), verbatim); + if verbatim { + cmd.verbatim_arg(name); + } else { + cmd.link_arg(name); + } } } } @@ -3012,10 +3013,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // This is admittedly a bit strange, as on most targets // `-isysroot` only applies to include header files, but on Apple // targets this also applies to libraries and frameworks. - cmd.args(&["-isysroot", &sdk_root]); + cmd.cc_args(&["-isysroot", &sdk_root]); } LinkerFlavor::Darwin(Cc::No, _) => { - cmd.args(&["-syslibroot", &sdk_root]); + cmd.link_args(&["-syslibroot", &sdk_root]); } _ => unreachable!(), } @@ -3026,8 +3027,9 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // search path. // The flags are called `-L` and `-F` both in Clang, ld64 and ldd. - cmd.arg(format!("-L{sdk_root}/System/iOSSupport/usr/lib")); - cmd.arg(format!("-F{sdk_root}/System/iOSSupport/System/Library/Frameworks")); + let sdk_root = Path::new(&sdk_root); + cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib")); + cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks")); } } @@ -3142,7 +3144,7 @@ fn add_lld_args( for path in sess.get_tools_search_paths(false) { let linker_path = path.join("gcc-ld"); linker_path_exists |= linker_path.exists(); - cmd.arg({ + cmd.cc_arg({ let mut arg = OsString::from("-B"); arg.push(linker_path); arg @@ -3162,7 +3164,7 @@ fn add_lld_args( // is to use LLD but the `wasm32-wasip2` target relies on a wrapper around // this, `wasm-component-ld`, which is overridden if this option is passed. if !sess.target.is_like_wasm { - cmd.arg("-fuse-ld=lld"); + cmd.cc_arg("-fuse-ld=lld"); } if !flavor.is_gnu() { @@ -3186,7 +3188,7 @@ fn add_lld_args( // targeting a different linker flavor on macOS, and that's also always // the case when targeting WASM. if sess.target.linker_flavor != sess.host.linker_flavor { - cmd.arg(format!("--target={}", sess.target.llvm_target)); + cmd.cc_arg(format!("--target={}", sess.target.llvm_target)); } } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index a82478900b17f..0f75ece9729cd 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -8,7 +8,7 @@ use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; -use std::{env, mem, str}; +use std::{env, iter, mem, str}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; @@ -159,6 +159,102 @@ pub fn get_linker<'a>( } } +// Note: Ideally neither these helper function, nor the macro-generated inherent methods below +// would exist, and these functions would live in `trait Linker`. +// Unfortunately, adding these functions to `trait Linker` make it `dyn`-incompatible. +// If the methods are added to the trait with `where Self: Sized` bounds, then even a separate +// implementation of them for `dyn Linker {}` wouldn't work due to a conflict with those +// uncallable methods in the trait. + +/// Just pass the arguments to the linker as is. +/// It is assumed that they are correctly prepared in advance. +fn verbatim_args( + l: &mut L, + args: impl IntoIterator>, +) -> &mut L { + for arg in args { + l.cmd().arg(arg); + } + l +} +/// Arguments for the underlying linker. +/// Add options to pass them through cc wrapper if `Linker` is a cc wrapper. +fn link_args( + l: &mut L, + args: impl IntoIterator, IntoIter: ExactSizeIterator>, +) -> &mut L { + let args = args.into_iter(); + if !l.is_cc() { + verbatim_args(l, args); + } else if args.len() != 0 { + // FIXME: Support arguments with commas, see `rpaths_to_flags` for the example. + let mut combined_arg = OsString::from("-Wl"); + for arg in args { + combined_arg.push(","); + combined_arg.push(arg); + } + l.cmd().arg(combined_arg); + } + l +} +/// Arguments for the cc wrapper specifically. +/// Check that it's indeed a cc wrapper and pass verbatim. +fn cc_args(l: &mut L, args: impl IntoIterator>) -> &mut L { + assert!(l.is_cc()); + verbatim_args(l, args) +} +/// Arguments supported by both underlying linker and cc wrapper, pass verbatim. +fn link_or_cc_args( + l: &mut L, + args: impl IntoIterator>, +) -> &mut L { + verbatim_args(l, args) +} + +macro_rules! generate_arg_methods { + ($($ty:ty)*) => { $( + impl $ty { + pub fn verbatim_args(&mut self, args: impl IntoIterator>) -> &mut Self { + verbatim_args(self, args) + } + pub fn verbatim_arg(&mut self, arg: impl AsRef) -> &mut Self { + verbatim_args(self, iter::once(arg)) + } + pub fn link_args(&mut self, args: impl IntoIterator, IntoIter: ExactSizeIterator>) -> &mut Self { + link_args(self, args) + } + pub fn link_arg(&mut self, arg: impl AsRef) -> &mut Self { + link_args(self, iter::once(arg)) + } + pub fn cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + cc_args(self, args) + } + pub fn cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + cc_args(self, iter::once(arg)) + } + pub fn link_or_cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + link_or_cc_args(self, args) + } + pub fn link_or_cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + link_or_cc_args(self, iter::once(arg)) + } + } + )* } +} + +generate_arg_methods! { + GccLinker<'_> + MsvcLinker<'_> + EmLinker<'_> + WasmLd<'_> + L4Bender<'_> + AixLinker<'_> + LlbcLinker<'_> + PtxLinker<'_> + BpfLinker<'_> + dyn Linker + '_ +} + /// Linker abstraction used by `back::link` to build up the command to invoke a /// linker. /// @@ -168,6 +264,9 @@ pub fn get_linker<'a>( /// MSVC linker (e.g., `link.exe`) is being used. pub trait Linker { fn cmd(&mut self) -> &mut Command; + fn is_cc(&self) -> bool { + false + } fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path); fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool); fn link_framework_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { @@ -175,10 +274,18 @@ pub trait Linker { } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool); fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool); - fn include_path(&mut self, path: &Path); - fn framework_path(&mut self, path: &Path); - fn output_filename(&mut self, path: &Path); - fn add_object(&mut self, path: &Path); + fn include_path(&mut self, path: &Path) { + link_or_cc_args(link_or_cc_args(self, &["-L"]), &[path]); + } + fn framework_path(&mut self, _path: &Path) { + bug!("framework path set with unsupported linker") + } + fn output_filename(&mut self, path: &Path) { + link_or_cc_args(link_or_cc_args(self, &["-o"]), &[path]); + } + fn add_object(&mut self, path: &Path) { + link_or_cc_args(self, &[path]); + } fn gc_sections(&mut self, keep_metadata: bool); fn no_gc_sections(&mut self); fn full_relro(&mut self); @@ -198,25 +305,9 @@ pub trait Linker { fn add_no_exec(&mut self) {} fn add_as_needed(&mut self) {} fn reset_per_library_state(&mut self) {} - fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) { - self.linker_args(&[arg], verbatim); - } - fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) { - args.into_iter().for_each(|a| { - self.cmd().arg(a); - }); - } } impl dyn Linker + '_ { - pub fn arg(&mut self, arg: impl AsRef) { - self.cmd().arg(arg); - } - - pub fn args(&mut self, args: impl IntoIterator>) { - self.cmd().args(args); - } - pub fn take_cmd(&mut self) -> Command { mem::replace(self.cmd(), Command::new("")) } @@ -233,14 +324,6 @@ pub struct GccLinker<'a> { } impl<'a> GccLinker<'a> { - fn linker_arg(&mut self, arg: impl AsRef) { - Linker::linker_arg(self, arg.as_ref(), false); - } - fn linker_args(&mut self, args: &[impl AsRef]) { - let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect(); - Linker::linker_args(self, &args_vec, false); - } - fn takes_hints(&self) -> bool { // Really this function only returns true if the underlying linker // configured for a compiler is binutils `ld.bfd` and `ld.gold`. We @@ -262,7 +345,7 @@ impl<'a> GccLinker<'a> { return; } if self.hinted_static != Some(true) { - self.linker_arg("-Bstatic"); + self.link_arg("-Bstatic"); self.hinted_static = Some(true); } } @@ -272,7 +355,7 @@ impl<'a> GccLinker<'a> { return; } if self.hinted_static != Some(false) { - self.linker_arg("-Bdynamic"); + self.link_arg("-Bdynamic"); self.hinted_static = Some(false); } } @@ -281,7 +364,7 @@ impl<'a> GccLinker<'a> { if let Some(plugin_path) = plugin_path { let mut arg = OsString::from("-plugin="); arg.push(plugin_path); - self.linker_arg(&arg); + self.link_arg(&arg); } let opt_level = match self.sess.opts.optimize { @@ -292,9 +375,9 @@ impl<'a> GccLinker<'a> { }; if let Some(path) = &self.sess.opts.unstable_opts.profile_sample_use { - self.linker_arg(&format!("-plugin-opt=sample-profile={}", path.display())); + self.link_arg(&format!("-plugin-opt=sample-profile={}", path.display())); }; - self.linker_args(&[ + self.link_args(&[ &format!("-plugin-opt={opt_level}"), &format!("-plugin-opt=mcpu={}", self.target_cpu), ]); @@ -304,10 +387,10 @@ impl<'a> GccLinker<'a> { // On mac we need to tell the linker to let this library be rpathed if self.sess.target.is_like_osx { if !self.is_ld { - self.cmd.arg("-dynamiclib"); + self.cc_arg("-dynamiclib"); } - self.linker_arg("-dylib"); + self.link_arg("-dylib"); // Note that the `osx_rpath_install_name` option here is a hack // purely to support rustbuild right now, we should get a more @@ -316,10 +399,10 @@ impl<'a> GccLinker<'a> { if self.sess.opts.cg.rpath || self.sess.opts.unstable_opts.osx_rpath_install_name { let mut rpath = OsString::from("@rpath/"); rpath.push(out_filename.file_name().unwrap()); - self.linker_args(&[OsString::from("-install_name"), rpath]); + self.link_arg("-install_name").link_arg(rpath); } } else { - self.cmd.arg("-shared"); + self.link_or_cc_arg("-shared"); if self.sess.target.is_like_windows { // The output filename already contains `dll_suffix` so // the resulting import library will have a name in the @@ -336,7 +419,7 @@ impl<'a> GccLinker<'a> { if let Some(implib_name) = implib_name { let implib = out_filename.parent().map(|dir| dir.join(&implib_name)); if let Some(implib) = implib { - self.linker_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); + self.link_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); } } } @@ -345,76 +428,56 @@ impl<'a> GccLinker<'a> { } impl<'a> Linker for GccLinker<'a> { - /// Passes a series of arguments directly to the linker. - /// - /// When the linker is ld-like, the arguments are simply appended to the command. When the - /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by - /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a - /// single argument is appended to the command to ensure that the order of the arguments is - /// preserved by the compiler. - fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) { - if self.is_ld || verbatim { - args.into_iter().for_each(|a| { - self.cmd.arg(a); - }); - } else { - if !args.is_empty() { - let mut s = OsString::from("-Wl"); - for a in args { - s.push(","); - s.push(a); - } - self.cmd.arg(s); - } - } - } - fn cmd(&mut self) -> &mut Command { &mut self.cmd } + fn is_cc(&self) -> bool { + !self.is_ld + } + fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { match output_kind { LinkOutputKind::DynamicNoPicExe => { if !self.is_ld && self.is_gnu { - self.cmd.arg("-no-pie"); + self.cc_arg("-no-pie"); } } LinkOutputKind::DynamicPicExe => { // noop on windows w/ gcc & ld, error w/ lld if !self.sess.target.is_like_windows { // `-pie` works for both gcc wrapper and ld. - self.cmd.arg("-pie"); + self.link_or_cc_arg("-pie"); } } LinkOutputKind::StaticNoPicExe => { // `-static` works for both gcc wrapper and ld. - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); if !self.is_ld && self.is_gnu { - self.cmd.arg("-no-pie"); + self.cc_arg("-no-pie"); } } LinkOutputKind::StaticPicExe => { if !self.is_ld { // Note that combination `-static -pie` doesn't work as expected // for the gcc wrapper, `-static` in that case suppresses `-pie`. - self.cmd.arg("-static-pie"); + self.cc_arg("-static-pie"); } else { // `--no-dynamic-linker` and `-z text` are not strictly necessary for producing // a static pie, but currently passed because gcc and clang pass them. // The former suppresses the `INTERP` ELF header specifying dynamic linker, // which is otherwise implicitly injected by ld (but not lld). // The latter doesn't change anything, only ensures that everything is pic. - self.cmd.args(&["-static", "-pie", "--no-dynamic-linker", "-z", "text"]); + self.link_args(&["-static", "-pie", "--no-dynamic-linker", "-z", "text"]); } } LinkOutputKind::DynamicDylib => self.build_dylib(out_filename), LinkOutputKind::StaticDylib => { - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); self.build_dylib(out_filename); } LinkOutputKind::WasiReactorExe => { - self.linker_args(&["--entry", "_initialize"]); + self.link_args(&["--entry", "_initialize"]); } } // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, @@ -430,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> { | LinkOutputKind::StaticDylib ) { - self.cmd.arg("--static-crt"); + self.cc_arg("--static-crt"); } } @@ -450,18 +513,18 @@ impl<'a> Linker for GccLinker<'a> { // but we have no way to detect that here. self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } else if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--no-as-needed"); + self.link_arg("--no-as-needed"); } else { self.sess.dcx().emit_warn(errors::LinkerUnsupportedModifier); } } self.hint_dynamic(); - self.cmd.arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },)); + self.link_or_cc_arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },)); if !as_needed { if self.sess.target.is_like_osx { // See above FIXME comment } else if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--as-needed"); + self.link_arg("--as-needed"); } } } @@ -471,63 +534,51 @@ impl<'a> Linker for GccLinker<'a> { if !as_needed { // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework // flag but we have no way to detect that here. - // self.cmd.arg("-needed_framework").arg(name); + // self.link_or_cc_arg("-needed_framework").link_or_cc_arg(name); self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } - self.cmd.arg("-framework").arg(name); + self.link_or_cc_args(&["-framework", name]); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); let colon = if verbatim && self.is_gnu { ":" } else { "" }; if !whole_archive { - self.cmd.arg(format!("-l{colon}{name}")); + self.link_or_cc_arg(format!("-l{colon}{name}")); } else if self.sess.target.is_like_osx { // -force_load is the macOS equivalent of --whole-archive, but it // involves passing the full path to the library to link. - self.linker_arg("-force_load"); - self.linker_arg(find_native_static_library(name, verbatim, self.sess)); + self.link_arg("-force_load"); + self.link_arg(find_native_static_library(name, verbatim, self.sess)); } else { - self.linker_arg("--whole-archive"); - self.cmd.arg(format!("-l{colon}{name}")); - self.linker_arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_arg(format!("-l{colon}{name}")) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else if self.sess.target.is_like_osx { - self.linker_arg("-force_load"); - self.linker_arg(path); + self.link_arg("-force_load").link_arg(path); } else { - self.linker_arg("--whole-archive"); - self.linker_arg(path); - self.linker_arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } fn framework_path(&mut self, path: &Path) { - self.cmd.arg("-F").arg(path); - } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_or_cc_arg("-F").link_or_cc_arg(path); } fn full_relro(&mut self) { - self.linker_args(&["-z", "relro", "-z", "now"]); + self.link_args(&["-z", "relro", "-z", "now"]); } fn partial_relro(&mut self) { - self.linker_args(&["-z", "relro"]); + self.link_args(&["-z", "relro"]); } fn no_relro(&mut self) { - self.linker_args(&["-z", "norelro"]); + self.link_args(&["-z", "norelro"]); } fn gc_sections(&mut self, keep_metadata: bool) { @@ -546,7 +597,7 @@ impl<'a> Linker for GccLinker<'a> { // for partial linking when using multiple codegen units (-r). So we // insert it here. if self.sess.target.is_like_osx { - self.linker_arg("-dead_strip"); + self.link_arg("-dead_strip"); // If we're building a dylib, we don't use --gc-sections because LLVM // has already done the best it can do, and we also don't want to @@ -554,13 +605,13 @@ impl<'a> Linker for GccLinker<'a> { // --gc-sections drops the size of hello world from 1.8MB to 597K, a 67% // reduction. } else if (self.is_gnu || self.sess.target.is_like_wasm) && !keep_metadata { - self.linker_arg("--gc-sections"); + self.link_arg("--gc-sections"); } } fn no_gc_sections(&mut self) { if self.is_gnu || self.sess.target.is_like_wasm { - self.linker_arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } } @@ -574,7 +625,7 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.opts.optimize == config::OptLevel::Default || self.sess.opts.optimize == config::OptLevel::Aggressive { - self.linker_arg("-O1"); + self.link_arg("-O1"); } } @@ -594,8 +645,7 @@ impl<'a> Linker for GccLinker<'a> { // // Though it may be worth to try to revert those changes upstream, since // the overhead of the initialization should be minor. - self.cmd.arg("-u"); - self.cmd.arg("__llvm_profile_runtime"); + self.link_or_cc_args(&["-u", "__llvm_profile_runtime"]); } fn control_flow_guard(&mut self) {} @@ -616,33 +666,33 @@ impl<'a> Linker for GccLinker<'a> { // The --strip-debug case is handled by running an external // `strip` utility as a separate step after linking. if !self.sess.target.is_like_solaris { - self.linker_arg("--strip-debug"); + self.link_arg("--strip-debug"); } } Strip::Symbols => { - self.linker_arg("--strip-all"); + self.link_arg("--strip-all"); } } match self.sess.opts.unstable_opts.debuginfo_compression { config::DebugInfoCompression::None => {} config::DebugInfoCompression::Zlib => { - self.linker_arg("--compress-debug-sections=zlib"); + self.link_arg("--compress-debug-sections=zlib"); } config::DebugInfoCompression::Zstd => { - self.linker_arg("--compress-debug-sections=zstd"); + self.link_arg("--compress-debug-sections=zstd"); } } } fn no_crt_objects(&mut self) { if !self.is_ld { - self.cmd.arg("-nostartfiles"); + self.cc_arg("-nostartfiles"); } } fn no_default_libraries(&mut self) { if !self.is_ld { - self.cmd.arg("-nodefaultlibs"); + self.cc_arg("-nodefaultlibs"); } } @@ -718,24 +768,22 @@ impl<'a> Linker for GccLinker<'a> { } if self.sess.target.is_like_osx { - self.linker_args(&[OsString::from("-exported_symbols_list"), path.into()]); + self.link_arg("-exported_symbols_list").link_arg(path); } else if self.sess.target.is_like_solaris { - self.linker_args(&[OsString::from("-M"), path.into()]); + self.link_arg("-M").link_arg(path); } else { if is_windows { - self.linker_arg(path); + self.link_arg(path); } else { let mut arg = OsString::from("--version-script="); arg.push(path); - self.linker_arg(arg); - self.linker_arg("--no-undefined-version"); + self.link_arg(arg).link_arg("--no-undefined-version"); } } } fn subsystem(&mut self, subsystem: &str) { - self.linker_arg("--subsystem"); - self.linker_arg(&subsystem); + self.link_args(&["--subsystem", subsystem]); } fn reset_per_library_state(&mut self) { @@ -760,23 +808,23 @@ impl<'a> Linker for GccLinker<'a> { // Some versions of `gcc` add it implicitly, some (e.g. `musl-gcc`) don't, // so we just always add it. fn add_eh_frame_header(&mut self) { - self.linker_arg("--eh-frame-hdr"); + self.link_arg("--eh-frame-hdr"); } fn add_no_exec(&mut self) { if self.sess.target.is_like_windows { - self.linker_arg("--nxcompat"); + self.link_arg("--nxcompat"); } else if self.is_gnu { - self.linker_args(&["-z", "noexecstack"]); + self.link_args(&["-z", "noexecstack"]); } } fn add_as_needed(&mut self) { if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--as-needed"); + self.link_arg("--as-needed"); } else if self.sess.target.is_like_solaris { // -z ignore is the Solaris equivalent to the GNU ld --as-needed option - self.linker_args(&["-z", "ignore"]); + self.link_args(&["-z", "ignore"]); } } } @@ -798,10 +846,10 @@ impl<'a> Linker for MsvcLinker<'a> { | LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { - self.cmd.arg("/DLL"); + self.link_arg("/DLL"); let mut arg: OsString = "/IMPLIB:".into(); arg.push(out_filename.with_extension("dll.lib")); - self.cmd.arg(arg); + self.link_arg(arg); } LinkOutputKind::WasiReactorExe => { panic!("can't link as reactor on non-wasi target"); @@ -810,44 +858,40 @@ impl<'a> Linker for MsvcLinker<'a> { } fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) { - self.cmd.arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); + self.link_arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" }; let suffix = if verbatim { "" } else { ".lib" }; - self.cmd.arg(format!("{prefix}{name}{suffix}")); + self.link_arg(format!("{prefix}{name}{suffix}")); } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { if !whole_archive { - self.cmd.arg(path); + self.link_arg(path); } else { let mut arg = OsString::from("/WHOLEARCHIVE:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn gc_sections(&mut self, _keep_metadata: bool) { // MSVC's ICF (Identical COMDAT Folding) link optimization is // slow for Rust and thus we disable it by default when not in // optimization build. if self.sess.opts.optimize != config::OptLevel::No { - self.cmd.arg("/OPT:REF,ICF"); + self.link_arg("/OPT:REF,ICF"); } else { // It is necessary to specify NOICF here, because /OPT:REF // implies ICF by default. - self.cmd.arg("/OPT:REF,NOICF"); + self.link_arg("/OPT:REF,NOICF"); } } fn no_gc_sections(&mut self) { - self.cmd.arg("/OPT:NOREF,NOICF"); + self.link_arg("/OPT:NOREF,NOICF"); } fn full_relro(&mut self) { @@ -867,23 +911,19 @@ impl<'a> Linker for MsvcLinker<'a> { } fn no_default_libraries(&mut self) { - self.cmd.arg("/NODEFAULTLIB"); + self.link_arg("/NODEFAULTLIB"); } fn include_path(&mut self, path: &Path) { let mut arg = OsString::from("/LIBPATH:"); arg.push(path); - self.cmd.arg(&arg); + self.link_arg(&arg); } fn output_filename(&mut self, path: &Path) { let mut arg = OsString::from("/OUT:"); arg.push(path); - self.cmd.arg(&arg); - } - - fn framework_path(&mut self, _path: &Path) { - bug!("frameworks are not supported on windows") + self.link_arg(&arg); } fn optimize(&mut self) { @@ -895,19 +935,19 @@ impl<'a> Linker for MsvcLinker<'a> { } fn control_flow_guard(&mut self) { - self.cmd.arg("/guard:cf"); + self.link_arg("/guard:cf"); } fn ehcont_guard(&mut self) { if self.sess.target.pointer_width == 64 { - self.cmd.arg("/guard:ehcont"); + self.link_arg("/guard:ehcont"); } } fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { // This will cause the Microsoft linker to generate a PDB file // from the CodeView line tables in the object files. - self.cmd.arg("/DEBUG"); + self.link_arg("/DEBUG"); // Default to emitting only the file name of the PDB file into // the binary instead of the full path. Emitting the full path @@ -916,7 +956,7 @@ impl<'a> Linker for MsvcLinker<'a> { // // This default behavior can be overridden by explicitly passing // `-Clink-arg=/PDBALTPATH:...` to rustc. - self.cmd.arg("/PDBALTPATH:%_PDB%"); + self.link_arg("/PDBALTPATH:%_PDB%"); // This will cause the Microsoft linker to embed .natvis info into the PDB file let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc"); @@ -928,7 +968,7 @@ impl<'a> Linker for MsvcLinker<'a> { if path.extension() == Some("natvis".as_ref()) { let mut arg = OsString::from("/NATVIS:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } Err(error) => { @@ -942,7 +982,7 @@ impl<'a> Linker for MsvcLinker<'a> { for path in natvis_debugger_visualizers { let mut arg = OsString::from("/NATVIS:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } @@ -986,13 +1026,13 @@ impl<'a> Linker for MsvcLinker<'a> { } let mut arg = OsString::from("/DEF:"); arg.push(path); - self.cmd.arg(&arg); + self.link_arg(&arg); } fn subsystem(&mut self, subsystem: &str) { // Note that previous passes of the compiler validated this subsystem, // so we just blindly pass it to the linker. - self.cmd.arg(&format!("/SUBSYSTEM:{subsystem}")); + self.link_arg(&format!("/SUBSYSTEM:{subsystem}")); // Windows has two subsystems we're interested in right now, the console // and windows subsystems. These both implicitly have different entry @@ -1009,7 +1049,7 @@ impl<'a> Linker for MsvcLinker<'a> { // // For more information see RFC #1665 if subsystem == "windows" { - self.cmd.arg("/ENTRY:mainCRTStartup"); + self.link_arg("/ENTRY:mainCRTStartup"); } } @@ -1018,7 +1058,7 @@ impl<'a> Linker for MsvcLinker<'a> { } fn add_no_exec(&mut self) { - self.cmd.arg("/NXCOMPAT"); + self.link_arg("/NXCOMPAT"); } } @@ -1032,31 +1072,23 @@ impl<'a> Linker for EmLinker<'a> { &mut self.cmd } + fn is_cc(&self) -> bool { + true + } + fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { // Emscripten always links statically - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, _whole_archive: bool) { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_or_cc_arg(path); } fn full_relro(&mut self) { @@ -1071,10 +1103,6 @@ impl<'a> Linker for EmLinker<'a> { // noop } - fn framework_path(&mut self, _path: &Path) { - bug!("frameworks are not supported on Emscripten") - } - fn gc_sections(&mut self, _keep_metadata: bool) { // noop } @@ -1085,7 +1113,7 @@ impl<'a> Linker for EmLinker<'a> { fn optimize(&mut self) { // Emscripten performs own optimizations - self.cmd.arg(match self.sess.opts.optimize { + self.cc_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1106,7 +1134,7 @@ impl<'a> Linker for EmLinker<'a> { fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { // Preserve names or generate source maps depending on debug info // For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g - self.cmd.arg(match self.sess.opts.debuginfo { + self.cc_arg(match self.sess.opts.debuginfo { DebugInfo::None => "-g0", DebugInfo::Limited | DebugInfo::LineTablesOnly | DebugInfo::LineDirectivesOnly => { "--profiling-funcs" @@ -1118,13 +1146,13 @@ impl<'a> Linker for EmLinker<'a> { fn no_crt_objects(&mut self) {} fn no_default_libraries(&mut self) { - self.cmd.arg("-nodefaultlibs"); + self.cc_arg("-nodefaultlibs"); } fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { debug!("EXPORTED SYMBOLS:"); - self.cmd.arg("-s"); + self.cc_arg("-s"); let mut arg = OsString::from("EXPORTED_FUNCTIONS="); let encoded = serde_json::to_string( @@ -1135,7 +1163,7 @@ impl<'a> Linker for EmLinker<'a> { arg.push(encoded); - self.cmd.arg(arg); + self.cc_arg(arg); } fn subsystem(&mut self, _subsystem: &str) { @@ -1153,7 +1181,7 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(mut cmd: Command, sess: &'a Session) -> WasmLd<'a> { + fn new(cmd: Command, sess: &'a Session) -> WasmLd<'a> { // If the atomics feature is enabled for wasm then we need a whole bunch // of flags: // @@ -1172,18 +1200,19 @@ impl<'a> WasmLd<'a> { // On wasm32-unknown-unknown, we also export symbols for glue code to use: // * `--export=*tls*` - when `#[thread_local]` symbols are used these // symbols are how the TLS segments are initialized and configured. + let mut wasm_ld = WasmLd { cmd, sess }; if sess.target_features.contains(&sym::atomics) { - cmd.arg("--shared-memory"); - cmd.arg("--max-memory=1073741824"); - cmd.arg("--import-memory"); + wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]); if sess.target.os == "unknown" { - cmd.arg("--export=__wasm_init_tls"); - cmd.arg("--export=__tls_size"); - cmd.arg("--export=__tls_align"); - cmd.arg("--export=__tls_base"); + wasm_ld.link_args(&[ + "--export=__wasm_init_tls", + "--export=__tls_size", + "--export=__tls_align", + "--export=__tls_base", + ]); } } - WasmLd { cmd, sess } + wasm_ld } } @@ -1199,51 +1228,36 @@ impl<'a> Linker for WasmLd<'a> { | LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { - self.cmd.arg("--no-entry"); + self.link_arg("--no-entry"); } LinkOutputKind::WasiReactorExe => { - self.cmd.arg("--entry"); - self.cmd.arg("_initialize"); + self.link_args(&["--entry", "_initialize"]); } } } fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { if !whole_archive { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } else { - self.cmd.arg("--whole-archive").arg("-l").arg(name).arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_args(&["-l", name]) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { - self.cmd.arg("--whole-archive").arg(path).arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_or_cc_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1251,17 +1265,17 @@ impl<'a> Linker for WasmLd<'a> { fn no_relro(&mut self) {} fn gc_sections(&mut self, _keep_metadata: bool) { - self.cmd.arg("--gc-sections"); + self.link_arg("--gc-sections"); } fn no_gc_sections(&mut self) { - self.cmd.arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } fn optimize(&mut self) { // The -O flag is, as of late 2023, only used for merging of strings and debuginfo, and // only differentiates -O0 and -O1. It does not apply to LTO. - self.cmd.arg(match self.sess.opts.optimize { + self.link_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1279,10 +1293,10 @@ impl<'a> Linker for WasmLd<'a> { match strip { Strip::None => {} Strip::Debuginfo => { - self.cmd.arg("--strip-debug"); + self.link_arg("--strip-debug"); } Strip::Symbols => { - self.cmd.arg("--strip-all"); + self.link_arg("--strip-all"); } } } @@ -1297,7 +1311,7 @@ impl<'a> Linker for WasmLd<'a> { fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { for sym in symbols { - self.cmd.arg("--export").arg(&sym); + self.link_args(&["--export", sym]); } // LLD will hide these otherwise-internal symbols since it only exports @@ -1305,8 +1319,7 @@ impl<'a> Linker for WasmLd<'a> { // others. Various bits and pieces of wasm32-unknown-unknown tooling use // this, so be sure these symbols make their way out of the linker as well. if self.sess.target.os == "unknown" { - self.cmd.arg("--export=__heap_base"); - self.cmd.arg("--export=__data_end"); + self.link_args(&["--export=__heap_base", "--export=__data_end"]); } } @@ -1337,7 +1350,7 @@ impl<'a> WasmLd<'a> { // wasm-ld only handles integer LTO opt levels. Use O2 config::OptLevel::Size | config::OptLevel::SizeMin => "O2", }; - self.cmd.arg(&format!("--lto-{opt_level}")); + self.link_arg(&format!("--lto-{opt_level}")); } } @@ -1362,56 +1375,43 @@ impl<'a> Linker for L4Bender<'a> { fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(format!("-PC{name}")); + self.link_arg(format!("-PC{name}")); } else { - self.cmd.arg("--whole-archive").arg(format!("-l{name}")).arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_arg(format!("-l{name}")) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { - self.cmd.arg("--whole-archive").arg(path).arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_or_cc_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - fn framework_path(&mut self, _: &Path) { - bug!("frameworks are not supported on L4Re"); - } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) { - self.cmd.arg("-z").arg("relro"); - self.cmd.arg("-z").arg("now"); + self.link_args(&["-z", "relro", "-z", "now"]); } fn partial_relro(&mut self) { - self.cmd.arg("-z").arg("relro"); + self.link_args(&["-z", "relro"]); } fn no_relro(&mut self) { - self.cmd.arg("-z").arg("norelro"); + self.link_args(&["-z", "norelro"]); } fn gc_sections(&mut self, keep_metadata: bool) { if !keep_metadata { - self.cmd.arg("--gc-sections"); + self.link_arg("--gc-sections"); } } fn no_gc_sections(&mut self) { - self.cmd.arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } fn optimize(&mut self) { @@ -1420,7 +1420,7 @@ impl<'a> Linker for L4Bender<'a> { if self.sess.opts.optimize == config::OptLevel::Default || self.sess.opts.optimize == config::OptLevel::Aggressive { - self.cmd.arg("-O1"); + self.link_arg("-O1"); } } @@ -1430,16 +1430,16 @@ impl<'a> Linker for L4Bender<'a> { match strip { Strip::None => {} Strip::Debuginfo => { - self.cmd().arg("--strip-debug"); + self.link_arg("--strip-debug"); } Strip::Symbols => { - self.cmd().arg("--strip-all"); + self.link_arg("--strip-all"); } } } fn no_default_libraries(&mut self) { - self.cmd.arg("-nostdlib"); + self.cc_arg("-nostdlib"); } fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { @@ -1449,7 +1449,7 @@ impl<'a> Linker for L4Bender<'a> { } fn subsystem(&mut self, subsystem: &str) { - self.cmd.arg(&format!("--subsystem {subsystem}")); + self.link_arg(&format!("--subsystem {subsystem}")); } fn reset_per_library_state(&mut self) { @@ -1467,12 +1467,12 @@ impl<'a> Linker for L4Bender<'a> { impl<'a> L4Bender<'a> { pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> { - L4Bender { cmd: cmd, sess: sess, hinted_static: false } + L4Bender { cmd, sess: sess, hinted_static: false } } fn hint_static(&mut self) { if !self.hinted_static { - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); self.hinted_static = true; } } @@ -1487,29 +1487,28 @@ pub struct AixLinker<'a> { impl<'a> AixLinker<'a> { pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> { - AixLinker { cmd: cmd, sess: sess, hinted_static: None } + AixLinker { cmd, sess: sess, hinted_static: None } } fn hint_static(&mut self) { if self.hinted_static != Some(true) { - self.cmd.arg("-bstatic"); + self.link_arg("-bstatic"); self.hinted_static = Some(true); } } fn hint_dynamic(&mut self) { if self.hinted_static != Some(false) { - self.cmd.arg("-bdynamic"); + self.link_arg("-bdynamic"); self.hinted_static = Some(false); } } fn build_dylib(&mut self, _out_filename: &Path) { - self.cmd.arg("-bM:SRE"); - self.cmd.arg("-bnoentry"); + self.link_args(&["-bM:SRE", "-bnoentry"]); // FIXME: Use CreateExportList utility to create export list // and remove -bexpfull. - self.cmd.arg("-bexpfull"); + self.link_arg("-bexpfull"); } } @@ -1534,47 +1533,31 @@ impl<'a> Linker for AixLinker<'a> { fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { self.hint_dynamic(); - self.cmd.arg(format!("-l{name}")); + self.link_or_cc_arg(format!("-l{name}")); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(format!("-l{name}")); + self.link_or_cc_arg(format!("-l{name}")); } else { let mut arg = OsString::from("-bkeepfile:"); arg.push(find_native_static_library(name, verbatim, self.sess)); - self.cmd.arg(arg); + self.link_or_cc_arg(arg); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { let mut arg = OsString::from("-bkeepfile:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn framework_path(&mut self, _: &Path) { - bug!("frameworks are not supported on AIX"); - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1582,17 +1565,17 @@ impl<'a> Linker for AixLinker<'a> { fn no_relro(&mut self) {} fn gc_sections(&mut self, _keep_metadata: bool) { - self.cmd.arg("-bgc"); + self.link_arg("-bgc"); } fn no_gc_sections(&mut self) { - self.cmd.arg("-bnogc"); + self.link_arg("-bnogc"); } fn optimize(&mut self) {} fn pgo_gen(&mut self) { - self.cmd.arg("-bdbg:namedsects:ss"); + self.link_arg("-bdbg:namedsects:ss"); } fn control_flow_guard(&mut self) {} @@ -1618,7 +1601,7 @@ impl<'a> Linker for AixLinker<'a> { if let Err(e) = res { self.sess.dcx().fatal(format!("failed to write export file: {e}")); } - self.cmd.arg(format!("-bE:{}", path.to_str().unwrap())); + self.link_arg(format!("-bE:{}", path.to_str().unwrap())); } fn subsystem(&mut self, _subsystem: &str) {} @@ -1747,39 +1730,27 @@ impl<'a> Linker for PtxLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg("--rlib").arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_arg("--rlib").link_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); + self.link_arg("--debug"); } fn add_object(&mut self, path: &Path) { - self.cmd.arg("--bitcode").arg(path); + self.link_arg("--bitcode").link_arg(path); } fn optimize(&mut self) { match self.sess.lto() { Lto::Thin | Lto::Fat | Lto::ThinLocal => { - self.cmd.arg("-Olto"); + self.link_arg("-Olto"); } Lto::No => {} } } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1829,19 +1800,11 @@ impl<'a> Linker for LlbcLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_or_cc_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_arg("--debug"); } fn optimize(&mut self) { @@ -1855,14 +1818,6 @@ impl<'a> Linker for LlbcLinker<'a> { }; } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1887,7 +1842,7 @@ impl<'a> Linker for LlbcLinker<'a> { match _crate_type { CrateType::Cdylib => { for sym in symbols { - self.cmd.arg("--export-symbol").arg(sym); + self.link_args(&["--export-symbol", sym]); } } _ => (), @@ -1920,23 +1875,15 @@ impl<'a> Linker for BpfLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_or_cc_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_arg("--debug"); } fn optimize(&mut self) { - self.cmd.arg(match self.sess.opts.optimize { + self.link_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1946,14 +1893,6 @@ impl<'a> Linker for BpfLinker<'a> { }); } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1985,7 +1924,7 @@ impl<'a> Linker for BpfLinker<'a> { if let Err(error) = res { self.sess.dcx().emit_fatal(errors::SymbolFileWriteFailure { error }); } else { - self.cmd.arg("--export-symbols").arg(&path); + self.link_arg("--export-symbols").link_arg(&path); } } From 5f9a0d3844e5a00f2c821c9b1e7d17679b758036 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 1 Jul 2024 13:06:20 +0300 Subject: [PATCH 211/217] linker: Bail out of rpath logic early if the target doesn't support rpath --- compiler/rustc_codegen_ssa/src/back/link.rs | 5 ++++- compiler/rustc_codegen_ssa/src/back/rpath.rs | 6 ------ compiler/rustc_codegen_ssa/src/back/rpath/tests.rs | 3 --- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index da7ffdc49116f..da4fa41e2aafc 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2096,6 +2096,10 @@ fn add_rpath_args( codegen_results: &CodegenResults, out_filename: &Path, ) { + if !sess.target.has_rpath { + return; + } + // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // add_lib_search_paths @@ -2114,7 +2118,6 @@ fn add_rpath_args( let rpath_config = RPathConfig { libs: &*libs, out_filename: out_filename.to_path_buf(), - has_rpath: sess.target.has_rpath, is_like_osx: sess.target.is_like_osx, linker_is_gnu: sess.target.linker_flavor.is_gnu(), }; diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs index f499bbcf85339..82070d4453b28 100644 --- a/compiler/rustc_codegen_ssa/src/back/rpath.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs @@ -9,16 +9,10 @@ pub struct RPathConfig<'a> { pub libs: &'a [&'a Path], pub out_filename: PathBuf, pub is_like_osx: bool, - pub has_rpath: bool, pub linker_is_gnu: bool, } pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec { - // No rpath on windows - if !config.has_rpath { - return Vec::new(); - } - debug!("preparing the RPATH!"); let rpaths = get_rpaths(config); diff --git a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs index 0de90a1036ec5..c620e92db1f08 100644 --- a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs @@ -37,7 +37,6 @@ fn test_rpath_relative() { if cfg!(target_os = "macos") { let config = &mut RPathConfig { libs: &[], - has_rpath: true, is_like_osx: true, linker_is_gnu: false, out_filename: PathBuf::from("bin/rustc"), @@ -48,7 +47,6 @@ fn test_rpath_relative() { let config = &mut RPathConfig { libs: &[], out_filename: PathBuf::from("bin/rustc"), - has_rpath: true, is_like_osx: false, linker_is_gnu: true, }; @@ -62,7 +60,6 @@ fn test_rpath_relative_issue_119571() { let config = &mut RPathConfig { libs: &[], out_filename: PathBuf::from("rustc"), - has_rpath: true, is_like_osx: false, linker_is_gnu: true, }; From 23c8ed14c938ab28873e88321ac0ad75842fa2c1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 29 Jun 2024 00:48:23 -0700 Subject: [PATCH 212/217] Avoid MIR bloat in inlining In 126578 we ended up with more binary size increases than expected. This change attempts to avoid inlining large things into small things, to avoid that kind of increase, in cases when top-down inlining will still be able to do that inlining later. --- .../rustc_mir_transform/src/cost_checker.rs | 31 +++ compiler/rustc_mir_transform/src/inline.rs | 50 +++- compiler/rustc_session/src/options.rs | 2 + library/alloc/src/raw_vec.rs | 17 ++ library/alloc/src/vec/mod.rs | 1 + .../drop_in_place_intrinsic.rs | 1 + ...inline_direct.Inline.after.panic-abort.mir | 22 ++ ...nline_direct.Inline.after.panic-unwind.mir | 22 ++ ...line_indirect.Inline.after.panic-abort.mir | 27 ++ ...ine_indirect.Inline.after.panic-unwind.mir | 27 ++ ...ic_not_inline.Inline.after.panic-abort.mir | 34 +++ ...c_not_inline.Inline.after.panic-unwind.mir | 34 +++ .../inline/inline_more_in_non_inline.rs | 46 ++++ .../inline_shims.drop.Inline.panic-abort.diff | 58 +---- ...erse_loop.PreCodegen.after.panic-abort.mir | 231 +++-------------- ...rse_loop.PreCodegen.after.panic-unwind.mir | 237 +++--------------- ...next_back.PreCodegen.after.panic-abort.mir | 195 +------------- ...ext_back.PreCodegen.after.panic-unwind.mir | 195 +------------- 18 files changed, 385 insertions(+), 845 deletions(-) create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.rs diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 7e401b5482f3d..3333bebff3a6e 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -31,6 +31,37 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> { CostChecker { tcx, param_env, callee_body, instance, penalty: 0, bonus: 0 } } + /// Add function-level costs not well-represented by the block-level costs. + /// + /// Needed because the `CostChecker` is used sometimes for just blocks, + /// and even the full `Inline` doesn't call `visit_body`, so there's nowhere + /// to put this logic in the visitor. + pub fn add_function_level_costs(&mut self) { + fn is_call_like(bbd: &BasicBlockData<'_>) -> bool { + use TerminatorKind::*; + match bbd.terminator().kind { + Call { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true, + + Goto { .. } + | SwitchInt { .. } + | UnwindResume + | UnwindTerminate(_) + | Return + | Unreachable => false, + + Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => { + unreachable!() + } + } + } + + // If the only has one Call (or similar), inlining isn't increasing the total + // number of calls, so give extra encouragement to inlining that. + if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd)).count() == 1 { + self.bonus += CALL_PENALTY; + } + } + pub fn cost(&self) -> usize { usize::saturating_sub(self.penalty, self.bonus) } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 07482d0571a2f..6fa31c1174d0b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -85,13 +85,18 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { } let param_env = tcx.param_env_reveal_all_normalized(def_id); + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); let mut this = Inliner { tcx, param_env, - codegen_fn_attrs: tcx.codegen_fn_attrs(def_id), + codegen_fn_attrs, history: Vec::new(), changed: false, + caller_is_inline_forwarder: matches!( + codegen_fn_attrs.inline, + InlineAttr::Hint | InlineAttr::Always + ) && body_is_forwarder(body), }; let blocks = START_BLOCK..body.basic_blocks.next_index(); this.process_blocks(body, blocks); @@ -111,6 +116,9 @@ struct Inliner<'tcx> { history: Vec, /// Indicates that the caller body has been modified. changed: bool, + /// Indicates that the caller is #[inline] and just calls another function, + /// and thus we can inline less into it as it'll be inlined itself. + caller_is_inline_forwarder: bool, } impl<'tcx> Inliner<'tcx> { @@ -485,7 +493,9 @@ impl<'tcx> Inliner<'tcx> { ) -> Result<(), &'static str> { let tcx = self.tcx; - let mut threshold = if cross_crate_inlinable { + let mut threshold = if self.caller_is_inline_forwarder { + self.tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30) + } else if cross_crate_inlinable { self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100) } else { self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50) @@ -504,6 +514,8 @@ impl<'tcx> Inliner<'tcx> { let mut checker = CostChecker::new(self.tcx, self.param_env, Some(callsite.callee), callee_body); + checker.add_function_level_costs(); + // Traverse the MIR manually so we can account for the effects of inlining on the CFG. let mut work_list = vec![START_BLOCK]; let mut visited = BitSet::new_empty(callee_body.basic_blocks.len()); @@ -1091,3 +1103,37 @@ fn try_instance_mir<'tcx>( } Ok(tcx.instance_mir(instance)) } + +fn body_is_forwarder(body: &Body<'_>) -> bool { + let TerminatorKind::Call { target, .. } = body.basic_blocks[START_BLOCK].terminator().kind + else { + return false; + }; + if let Some(target) = target { + let TerminatorKind::Return = body.basic_blocks[target].terminator().kind else { + return false; + }; + } + + let max_blocks = if !body.is_polymorphic { + 2 + } else if target.is_none() { + 3 + } else { + 4 + }; + if body.basic_blocks.len() > max_blocks { + return false; + } + + body.basic_blocks.iter_enumerated().all(|(bb, bb_data)| { + bb == START_BLOCK + || matches!( + bb_data.terminator().kind, + TerminatorKind::Return + | TerminatorKind::Drop { .. } + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + ) + }) +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 80f7ca544f3c5..2e4421d50e313 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1766,6 +1766,8 @@ options! { "enable LLVM inlining (default: yes)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], "enable MIR inlining (default: no)"), + inline_mir_forwarder_threshold: Option = (None, parse_opt_number, [TRACKED], + "inlining threshold when the caller is a simple forwarding function (default: 30)"), inline_mir_hint_threshold: Option = (None, parse_opt_number, [TRACKED], "inlining threshold for functions with inline hint (default: 100)"), inline_mir_preserve_debug: Option = (None, parse_opt_bool, [TRACKED], diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 1134c7f833e2b..7b7dae5a057f0 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -429,6 +429,7 @@ impl RawVec { /// /// Aborts on OOM. #[cfg(not(no_global_oom_handling))] + #[inline] pub fn shrink_to_fit(&mut self, cap: usize) { if let Err(err) = self.shrink(cap) { handle_error(err); @@ -511,9 +512,25 @@ impl RawVec { } #[cfg(not(no_global_oom_handling))] + #[inline] fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> { assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity"); + // SAFETY: Just checked this isn't trying to grow + unsafe { self.shrink_unchecked(cap) } + } + /// `shrink`, but without the capacity check. + /// + /// This is split out so that `shrink` can inline the check, since it + /// optimizes out in things like `shrink_to_fit`, without needing to + /// also inline all this code, as doing that ends up failing the + /// `vec-shrink-panic` codegen test when `shrink_to_fit` ends up being too + /// big for LLVM to be willing to inline. + /// + /// # Safety + /// `cap <= self.capacity()` + #[cfg(not(no_global_oom_handling))] + unsafe fn shrink_unchecked(&mut self, cap: usize) -> Result<(), TryReserveError> { let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; // See current_memory() why this assert is here const { assert!(mem::size_of::() % mem::align_of::() == 0) }; diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 743429d26dbfb..f1706e31bb80a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1101,6 +1101,7 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn shrink_to_fit(&mut self) { // The capacity is never less than the length, and there's nothing to do when // they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit` diff --git a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs index 947faa165a9cb..d87ad41e70d58 100644 --- a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -1,6 +1,7 @@ // //@ compile-flags:-Zprint-mono-items=eager //@ compile-flags:-Zinline-in-all-cgus +//@ compile-flags:-Zinline-mir=no #![feature(start)] diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..522f772c6f48e --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir @@ -0,0 +1,22 @@ +// MIR for `marked_inline_direct` after Inline + +fn marked_inline_direct(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + _2 = call_twice(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..722b02eeba806 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir @@ -0,0 +1,22 @@ +// MIR for `marked_inline_direct` after Inline + +fn marked_inline_direct(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + _2 = call_twice(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..63b91cbce2d60 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir @@ -0,0 +1,27 @@ +// MIR for `marked_inline_indirect` after Inline + +fn marked_inline_indirect(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined marked_inline_direct) { + let _4: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + _4 = call_twice(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..7c84e98dd516c --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir @@ -0,0 +1,27 @@ +// MIR for `marked_inline_indirect` after Inline + +fn marked_inline_indirect(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined marked_inline_direct) { + let _4: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + _4 = call_twice(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..989014b8b476d --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir @@ -0,0 +1,34 @@ +// MIR for `monomorphic_not_inline` after Inline + +fn monomorphic_not_inline(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined call_twice) { + let _4: (); + let _5: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + StorageLive(_5); + _4 = other_thing(_3) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + + bb2: { + _5 = other_thing(move _3) -> [return: bb1, unwind unreachable]; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..bd200719bbbe9 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir @@ -0,0 +1,34 @@ +// MIR for `monomorphic_not_inline` after Inline + +fn monomorphic_not_inline(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined call_twice) { + let _4: (); + let _5: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + StorageLive(_5); + _4 = other_thing(_3) -> [return: bb2, unwind continue]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + + bb2: { + _5 = other_thing(move _3) -> [return: bb1, unwind continue]; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.rs b/tests/mir-opt/inline/inline_more_in_non_inline.rs new file mode 100644 index 0000000000000..5968b97047096 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.rs @@ -0,0 +1,46 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -O --crate-type lib + +// To avoid MIR blow-up, don't inline large callees into simple shim callers, +// but *do* inline other trivial things. + +extern "Rust" { + fn other_thing(x: i32); +} + +#[inline] +unsafe fn call_twice(x: i32) { + unsafe { + other_thing(x); + other_thing(x); + } +} + +// EMIT_MIR inline_more_in_non_inline.monomorphic_not_inline.Inline.after.mir +#[no_mangle] +pub unsafe fn monomorphic_not_inline(x: i32) { + // CHECK-LABEL: monomorphic_not_inline + // CHECK: other_thing + // CHECK: other_thing + unsafe { call_twice(x) }; +} + +// EMIT_MIR inline_more_in_non_inline.marked_inline_direct.Inline.after.mir +#[inline] +pub unsafe fn marked_inline_direct(x: i32) { + // CHECK-LABEL: marked_inline_direct + // CHECK-NOT: other_thing + // CHECK: call_twice + // CHECK-NOT: other_thing + unsafe { call_twice(x) }; +} + +// EMIT_MIR inline_more_in_non_inline.marked_inline_indirect.Inline.after.mir +#[inline] +pub unsafe fn marked_inline_indirect(x: i32) { + // CHECK-LABEL: marked_inline_indirect + // CHECK-NOT: other_thing + // CHECK: call_twice + // CHECK-NOT: other_thing + unsafe { marked_inline_direct(x) }; +} diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index 45ce933a55ad2..2a36ccaab110a 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -11,30 +11,10 @@ + scope 1 (inlined std::ptr::drop_in_place::> - shim(Some(Vec))) { + let mut _6: &mut std::vec::Vec; + let mut _7: (); -+ scope 2 (inlined as Drop>::drop) { -+ let mut _8: *mut [A]; -+ let mut _9: *mut A; -+ let mut _10: usize; -+ scope 3 (inlined Vec::::as_mut_ptr) { -+ let mut _11: &alloc::raw_vec::RawVec; -+ scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { -+ let mut _13: std::ptr::NonNull; -+ scope 5 (inlined Unique::::as_ptr) { -+ scope 6 (inlined NonNull::::as_ptr) { -+ let mut _12: *const A; -+ } -+ } -+ } -+ } -+ scope 7 (inlined slice_from_raw_parts_mut::) { -+ scope 8 (inlined std::ptr::from_raw_parts_mut::<[A], A>) { -+ } -+ } -+ } + } -+ scope 9 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { -+ let mut _14: isize; -+ let mut _15: isize; ++ scope 2 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { ++ let mut _8: isize; ++ let mut _9: isize; + } bb0: { @@ -45,24 +25,7 @@ + StorageLive(_6); + StorageLive(_7); + _6 = &mut (*_4); -+ StorageLive(_8); -+ StorageLive(_9); -+ StorageLive(_11); -+ _11 = &((*_6).0: alloc::raw_vec::RawVec); -+ StorageLive(_13); -+ _13 = ((((*_6).0: alloc::raw_vec::RawVec).0: std::ptr::Unique).0: std::ptr::NonNull); -+ StorageLive(_12); -+ _12 = (_13.0: *const A); -+ _9 = move _12 as *mut A (PtrToPtr); -+ StorageDead(_12); -+ StorageDead(_13); -+ StorageDead(_11); -+ StorageLive(_10); -+ _10 = ((*_6).1: usize); -+ _8 = *mut [A] from (_9, _10); -+ StorageDead(_10); -+ StorageDead(_9); -+ _7 = std::ptr::drop_in_place::<[A]>(move _8) -> [return: bb2, unwind unreachable]; ++ _7 = as Drop>::drop(move _6) -> [return: bb2, unwind unreachable]; } bb1: { @@ -73,20 +36,19 @@ StorageLive(_5); _5 = _2; - _0 = std::ptr::drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; -+ StorageLive(_14); -+ StorageLive(_15); -+ _14 = discriminant((*_5)); -+ switchInt(move _14) -> [0: bb3, otherwise: bb4]; ++ StorageLive(_8); ++ StorageLive(_9); ++ _8 = discriminant((*_5)); ++ switchInt(move _8) -> [0: bb3, otherwise: bb4]; } bb2: { -+ StorageDead(_8); + drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; + } + + bb3: { -+ StorageDead(_15); -+ StorageDead(_14); ++ StorageDead(_9); ++ StorageDead(_8); StorageDead(_5); return; + } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 79c5bcfe9cd5c..fbb887fe76a59 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -7,90 +7,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _37: std::option::Option<&T>; - let mut _39: &impl Fn(&T); - let mut _40: (&T,); - let _41: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { debug iter => _13; - let _38: &T; + let _17: &T; scope 2 { - debug x => _38; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - scope 18 (inlined as DoubleEndedIterator>::next_back) { - let mut _14: *const *const T; - let mut _15: *const std::ptr::NonNull; - let mut _20: bool; - let mut _21: *const T; - let _36: &T; - scope 19 { - let _16: std::ptr::NonNull; - let _22: usize; - scope 20 { - } - scope 21 { - scope 25 (inlined as PartialEq>::eq) { - let mut _17: std::ptr::NonNull; - scope 26 (inlined NonNull::::as_ptr) { - let mut _18: *const T; - } - scope 27 (inlined NonNull::::as_ptr) { - let mut _19: *const T; - } - } - } - scope 22 (inlined std::ptr::const_ptr::::addr) { - scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 24 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { - let _29: std::ptr::NonNull; - scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { - let mut _23: *mut *const T; - let mut _24: *mut std::ptr::NonNull; - let mut _25: std::ptr::NonNull; - let mut _28: std::ptr::NonNull; - let mut _30: *mut *const T; - let mut _31: *mut usize; - let mut _32: usize; - let mut _33: usize; - scope 30 { - scope 31 { - } - scope 32 { - scope 35 (inlined NonNull::::sub) { - scope 36 (inlined core::num::::unchecked_neg) { - scope 37 (inlined core::ub_checks::check_language_ub) { - scope 38 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 39 (inlined NonNull::::offset) { - let mut _26: *const T; - let mut _27: *const T; - } - } - } - scope 33 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 34 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 40 (inlined NonNull::::as_ref::<'_>) { - let mut _34: std::ptr::NonNull; - scope 41 (inlined NonNull::::as_ptr) { - let mut _35: *const T; - } - scope 42 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -178,147 +107,45 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_37); - StorageLive(_22); - StorageLive(_21); - StorageLive(_16); - StorageLive(_36); - StorageLive(_20); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageLive(_15); - StorageLive(_14); - _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = (*_15); - StorageDead(_15); - StorageLive(_18); - StorageLive(_19); - StorageLive(_17); - _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - _18 = (_17.0: *const T); - StorageDead(_17); - _19 = (_16.0: *const T); - _20 = Eq(_18, _19); - StorageDead(_19); - StorageDead(_18); - goto -> bb7; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _22 = _21 as usize (Transmute); - _20 = Eq(_22, const 0_usize); - goto -> bb7; + StorageDead(_15); + StorageDead(_13); + drop(_2) -> [return: bb7, unwind unreachable]; } bb7: { - switchInt(move _20) -> [0: bb8, otherwise: bb16]; + return; } bb8: { - StorageLive(_35); - StorageLive(_29); - StorageLive(_31); - StorageLive(_24); - switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { - StorageLive(_23); - _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_23); - StorageLive(_28); - _25 = (*_24); - switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; - } - - bb10: { - StorageLive(_27); - StorageLive(_26); - _26 = (_25.0: *const T); - _27 = Offset(move _26, const -1_isize); - StorageDead(_26); - _28 = NonNull:: { pointer: move _27 }; - StorageDead(_27); - goto -> bb12; - } - - bb11: { - _28 = _25; - goto -> bb12; - } - - bb12: { - (*_24) = move _28; - StorageDead(_28); - _29 = (*_24); - goto -> bb14; - } - - bb13: { - StorageLive(_30); - _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _31 = _30 as *mut usize (PtrToPtr); - StorageDead(_30); - StorageLive(_33); - StorageLive(_32); - _32 = (*_31); - _33 = SubUnchecked(move _32, const 1_usize); - StorageDead(_32); - (*_31) = move _33; - StorageDead(_33); - _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - goto -> bb14; - } - - bb14: { - StorageDead(_24); - StorageDead(_31); - StorageLive(_34); - _34 = _29; - _35 = (_34.0: *const T); - StorageDead(_34); - _36 = &(*_35); - StorageDead(_29); - StorageDead(_35); - _37 = Option::<&T>::Some(_36); - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - _38 = ((_37 as Some).0: &T); - StorageLive(_39); - _39 = &_2; - StorageLive(_40); - _40 = (_38,); - _41 = >::call(move _39, move _40) -> [return: bb15, unwind unreachable]; - } - - bb15: { - StorageDead(_40); - StorageDead(_39); - StorageDead(_37); + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } - bb16: { - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - StorageDead(_37); - StorageDead(_13); - drop(_2) -> [return: bb17, unwind unreachable]; - } - - bb17: { - return; + bb10: { + unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 7c107a23f9e0b..db9409f72ab1a 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -7,90 +7,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _37: std::option::Option<&T>; - let mut _39: &impl Fn(&T); - let mut _40: (&T,); - let _41: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { debug iter => _13; - let _38: &T; + let _17: &T; scope 2 { - debug x => _38; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - scope 18 (inlined as DoubleEndedIterator>::next_back) { - let mut _14: *const *const T; - let mut _15: *const std::ptr::NonNull; - let mut _20: bool; - let mut _21: *const T; - let _36: &T; - scope 19 { - let _16: std::ptr::NonNull; - let _22: usize; - scope 20 { - } - scope 21 { - scope 25 (inlined as PartialEq>::eq) { - let mut _17: std::ptr::NonNull; - scope 26 (inlined NonNull::::as_ptr) { - let mut _18: *const T; - } - scope 27 (inlined NonNull::::as_ptr) { - let mut _19: *const T; - } - } - } - scope 22 (inlined std::ptr::const_ptr::::addr) { - scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 24 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { - let _29: std::ptr::NonNull; - scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { - let mut _23: *mut *const T; - let mut _24: *mut std::ptr::NonNull; - let mut _25: std::ptr::NonNull; - let mut _28: std::ptr::NonNull; - let mut _30: *mut *const T; - let mut _31: *mut usize; - let mut _32: usize; - let mut _33: usize; - scope 30 { - scope 31 { - } - scope 32 { - scope 35 (inlined NonNull::::sub) { - scope 36 (inlined core::num::::unchecked_neg) { - scope 37 (inlined core::ub_checks::check_language_ub) { - scope 38 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 39 (inlined NonNull::::offset) { - let mut _26: *const T; - let mut _27: *const T; - } - } - } - scope 33 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 34 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 40 (inlined NonNull::::as_ref::<'_>) { - let mut _34: std::ptr::NonNull; - scope 41 (inlined NonNull::::as_ptr) { - let mut _35: *const T; - } - scope 42 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -178,155 +107,53 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_37); - StorageLive(_22); - StorageLive(_21); - StorageLive(_16); - StorageLive(_36); - StorageLive(_20); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageLive(_15); - StorageLive(_14); - _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = (*_15); - StorageDead(_15); - StorageLive(_18); - StorageLive(_19); - StorageLive(_17); - _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - _18 = (_17.0: *const T); - StorageDead(_17); - _19 = (_16.0: *const T); - _20 = Eq(_18, _19); - StorageDead(_19); - StorageDead(_18); - goto -> bb7; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _22 = _21 as usize (Transmute); - _20 = Eq(_22, const 0_usize); - goto -> bb7; + StorageDead(_15); + StorageDead(_13); + drop(_2) -> [return: bb7, unwind continue]; } bb7: { - switchInt(move _20) -> [0: bb8, otherwise: bb18]; + return; } bb8: { - StorageLive(_35); - StorageLive(_29); - StorageLive(_31); - StorageLive(_24); - switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageLive(_23); - _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_23); - StorageLive(_28); - _25 = (*_24); - switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); + goto -> bb4; } bb10: { - StorageLive(_27); - StorageLive(_26); - _26 = (_25.0: *const T); - _27 = Offset(move _26, const -1_isize); - StorageDead(_26); - _28 = NonNull:: { pointer: move _27 }; - StorageDead(_27); - goto -> bb12; - } - - bb11: { - _28 = _25; - goto -> bb12; - } - - bb12: { - (*_24) = move _28; - StorageDead(_28); - _29 = (*_24); - goto -> bb14; - } - - bb13: { - StorageLive(_30); - _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _31 = _30 as *mut usize (PtrToPtr); - StorageDead(_30); - StorageLive(_33); - StorageLive(_32); - _32 = (*_31); - _33 = SubUnchecked(move _32, const 1_usize); - StorageDead(_32); - (*_31) = move _33; - StorageDead(_33); - _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - goto -> bb14; + unreachable; } - bb14: { - StorageDead(_24); - StorageDead(_31); - StorageLive(_34); - _34 = _29; - _35 = (_34.0: *const T); - StorageDead(_34); - _36 = &(*_35); - StorageDead(_29); - StorageDead(_35); - _37 = Option::<&T>::Some(_36); - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - _38 = ((_37 as Some).0: &T); - StorageLive(_39); - _39 = &_2; - StorageLive(_40); - _40 = (_38,); - _41 = >::call(move _39, move _40) -> [return: bb15, unwind: bb16]; + bb11 (cleanup): { + drop(_2) -> [return: bb12, unwind terminate(cleanup)]; } - bb15: { - StorageDead(_40); - StorageDead(_39); - StorageDead(_37); - goto -> bb4; - } - - bb16 (cleanup): { - drop(_2) -> [return: bb17, unwind terminate(cleanup)]; - } - - bb17 (cleanup): { + bb12 (cleanup): { resume; } - - bb18: { - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - StorageDead(_37); - StorageDead(_13); - drop(_2) -> [return: bb19, unwind continue]; - } - - bb19: { - return; - } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir index 2df346c081c8e..78f96bf419559 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -3,205 +3,12 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; - scope 1 (inlined as DoubleEndedIterator>::next_back) { - let mut _2: *const *mut T; - let mut _3: *const std::ptr::NonNull; - let mut _8: bool; - let mut _9: *mut T; - let mut _25: &mut T; - scope 2 { - let _4: std::ptr::NonNull; - let _10: usize; - scope 3 { - } - scope 4 { - scope 8 (inlined as PartialEq>::eq) { - let mut _5: std::ptr::NonNull; - scope 9 (inlined NonNull::::as_ptr) { - let mut _6: *const T; - } - scope 10 (inlined NonNull::::as_ptr) { - let mut _7: *const T; - } - } - } - scope 5 (inlined std::ptr::mut_ptr::::addr) { - scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { - } - } - scope 7 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { - let mut _17: std::ptr::NonNull; - scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { - let mut _11: *mut *mut T; - let mut _12: *mut std::ptr::NonNull; - let mut _13: std::ptr::NonNull; - let mut _16: std::ptr::NonNull; - let mut _18: *mut *mut T; - let mut _19: *mut usize; - let mut _20: usize; - let mut _21: usize; - scope 13 { - scope 14 { - } - scope 15 { - scope 18 (inlined NonNull::::sub) { - scope 19 (inlined core::num::::unchecked_neg) { - scope 20 (inlined core::ub_checks::check_language_ub) { - scope 21 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 22 (inlined NonNull::::offset) { - let mut _14: *const T; - let mut _15: *const T; - } - } - } - scope 16 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 17 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 23 (inlined NonNull::::as_mut::<'_>) { - let mut _22: std::ptr::NonNull; - let mut _24: *mut T; - scope 24 (inlined NonNull::::as_ptr) { - let mut _23: *const T; - } - } - } - } bb0: { - StorageLive(_10); - StorageLive(_9); - StorageLive(_4); - StorageLive(_25); - StorageLive(_8); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_3); - StorageLive(_2); - _2 = &raw const ((*_1).1: *mut T); - _3 = _2 as *const std::ptr::NonNull (PtrToPtr); - StorageDead(_2); - _4 = (*_3); - StorageDead(_3); - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); - _5 = ((*_1).0: std::ptr::NonNull); - _6 = (_5.0: *const T); - StorageDead(_5); - _7 = (_4.0: *const T); - _8 = Eq(_6, _7); - StorageDead(_7); - StorageDead(_6); - goto -> bb3; - } - - bb2: { - _9 = ((*_1).1: *mut T); - _10 = _9 as usize (Transmute); - _8 = Eq(_10, const 0_usize); - goto -> bb3; - } - - bb3: { - switchInt(move _8) -> [0: bb4, otherwise: bb11]; - } - - bb4: { - StorageLive(_24); - StorageLive(_17); - StorageLive(_19); - StorageLive(_12); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; - } - - bb5: { - StorageLive(_11); - _11 = &raw mut ((*_1).1: *mut T); - _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_11); - StorageLive(_16); - _13 = (*_12); - switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; - } - - bb6: { - StorageLive(_15); - StorageLive(_14); - _14 = (_13.0: *const T); - _15 = Offset(move _14, const -1_isize); - StorageDead(_14); - _16 = NonNull:: { pointer: move _15 }; - StorageDead(_15); - goto -> bb8; - } - - bb7: { - _16 = _13; - goto -> bb8; - } - - bb8: { - (*_12) = move _16; - StorageDead(_16); - _17 = (*_12); - goto -> bb10; - } - - bb9: { - StorageLive(_18); - _18 = &raw mut ((*_1).1: *mut T); - _19 = _18 as *mut usize (PtrToPtr); - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - _20 = (*_19); - _21 = SubUnchecked(move _20, const 1_usize); - StorageDead(_20); - (*_19) = move _21; - StorageDead(_21); - _17 = ((*_1).0: std::ptr::NonNull); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_19); - StorageLive(_22); - _22 = _17; - StorageLive(_23); - _23 = (_22.0: *const T); - _24 = move _23 as *mut T (PtrToPtr); - StorageDead(_23); - StorageDead(_22); - _25 = &mut (*_24); - StorageDead(_17); - StorageDead(_24); - _0 = Option::<&mut T>::Some(_25); - goto -> bb12; - } - - bb11: { - _0 = const {transmute(0x0000000000000000): Option<&mut T>}; - goto -> bb12; - } - - bb12: { - StorageDead(_8); - StorageDead(_25); - StorageDead(_4); - StorageDead(_9); - StorageDead(_10); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index 2df346c081c8e..dfe5e206fadaf 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -3,205 +3,12 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; - scope 1 (inlined as DoubleEndedIterator>::next_back) { - let mut _2: *const *mut T; - let mut _3: *const std::ptr::NonNull; - let mut _8: bool; - let mut _9: *mut T; - let mut _25: &mut T; - scope 2 { - let _4: std::ptr::NonNull; - let _10: usize; - scope 3 { - } - scope 4 { - scope 8 (inlined as PartialEq>::eq) { - let mut _5: std::ptr::NonNull; - scope 9 (inlined NonNull::::as_ptr) { - let mut _6: *const T; - } - scope 10 (inlined NonNull::::as_ptr) { - let mut _7: *const T; - } - } - } - scope 5 (inlined std::ptr::mut_ptr::::addr) { - scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { - } - } - scope 7 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { - let mut _17: std::ptr::NonNull; - scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { - let mut _11: *mut *mut T; - let mut _12: *mut std::ptr::NonNull; - let mut _13: std::ptr::NonNull; - let mut _16: std::ptr::NonNull; - let mut _18: *mut *mut T; - let mut _19: *mut usize; - let mut _20: usize; - let mut _21: usize; - scope 13 { - scope 14 { - } - scope 15 { - scope 18 (inlined NonNull::::sub) { - scope 19 (inlined core::num::::unchecked_neg) { - scope 20 (inlined core::ub_checks::check_language_ub) { - scope 21 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 22 (inlined NonNull::::offset) { - let mut _14: *const T; - let mut _15: *const T; - } - } - } - scope 16 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 17 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 23 (inlined NonNull::::as_mut::<'_>) { - let mut _22: std::ptr::NonNull; - let mut _24: *mut T; - scope 24 (inlined NonNull::::as_ptr) { - let mut _23: *const T; - } - } - } - } bb0: { - StorageLive(_10); - StorageLive(_9); - StorageLive(_4); - StorageLive(_25); - StorageLive(_8); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_3); - StorageLive(_2); - _2 = &raw const ((*_1).1: *mut T); - _3 = _2 as *const std::ptr::NonNull (PtrToPtr); - StorageDead(_2); - _4 = (*_3); - StorageDead(_3); - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); - _5 = ((*_1).0: std::ptr::NonNull); - _6 = (_5.0: *const T); - StorageDead(_5); - _7 = (_4.0: *const T); - _8 = Eq(_6, _7); - StorageDead(_7); - StorageDead(_6); - goto -> bb3; - } - - bb2: { - _9 = ((*_1).1: *mut T); - _10 = _9 as usize (Transmute); - _8 = Eq(_10, const 0_usize); - goto -> bb3; - } - - bb3: { - switchInt(move _8) -> [0: bb4, otherwise: bb11]; - } - - bb4: { - StorageLive(_24); - StorageLive(_17); - StorageLive(_19); - StorageLive(_12); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; - } - - bb5: { - StorageLive(_11); - _11 = &raw mut ((*_1).1: *mut T); - _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_11); - StorageLive(_16); - _13 = (*_12); - switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; - } - - bb6: { - StorageLive(_15); - StorageLive(_14); - _14 = (_13.0: *const T); - _15 = Offset(move _14, const -1_isize); - StorageDead(_14); - _16 = NonNull:: { pointer: move _15 }; - StorageDead(_15); - goto -> bb8; - } - - bb7: { - _16 = _13; - goto -> bb8; - } - - bb8: { - (*_12) = move _16; - StorageDead(_16); - _17 = (*_12); - goto -> bb10; - } - - bb9: { - StorageLive(_18); - _18 = &raw mut ((*_1).1: *mut T); - _19 = _18 as *mut usize (PtrToPtr); - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - _20 = (*_19); - _21 = SubUnchecked(move _20, const 1_usize); - StorageDead(_20); - (*_19) = move _21; - StorageDead(_21); - _17 = ((*_1).0: std::ptr::NonNull); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_19); - StorageLive(_22); - _22 = _17; - StorageLive(_23); - _23 = (_22.0: *const T); - _24 = move _23 as *mut T (PtrToPtr); - StorageDead(_23); - StorageDead(_22); - _25 = &mut (*_24); - StorageDead(_17); - StorageDead(_24); - _0 = Option::<&mut T>::Some(_25); - goto -> bb12; - } - - bb11: { - _0 = const {transmute(0x0000000000000000): Option<&mut T>}; - goto -> bb12; - } - - bb12: { - StorageDead(_8); - StorageDead(_25); - StorageDead(_4); - StorageDead(_9); - StorageDead(_10); return; } } From fc8b6c6657962002af58f9a4cf5796031ebbf665 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 25 Jun 2024 12:39:04 +0200 Subject: [PATCH 213/217] Add `input_file` method on `LlvmFileCheck` --- src/tools/run-make-support/src/llvm.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs index 7f42223bf7f5a..4c9e9a5323025 100644 --- a/src/tools/run-make-support/src/llvm.rs +++ b/src/tools/run-make-support/src/llvm.rs @@ -180,6 +180,13 @@ impl LlvmFilecheck { self.cmd.arg(path.as_ref()); self } + + /// `--input-file` option. + pub fn input_file>(&mut self, input_file: P) -> &mut Self { + self.cmd.arg("--input-file"); + self.cmd.arg(input_file.as_ref()); + self + } } impl LlvmObjdump { From 7276499dc962a2fe5e6d7517ffdf1f866f046ed8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 25 Jun 2024 12:39:19 +0200 Subject: [PATCH 214/217] Migrate `run-make/llvm-ident` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/llvm-ident/Makefile | 19 --------- tests/run-make/llvm-ident/rmake.rs | 41 +++++++++++++++++++ 3 files changed, 41 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/llvm-ident/Makefile create mode 100644 tests/run-make/llvm-ident/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 741bb46d1a713..5a8480e408d39 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -85,7 +85,6 @@ run-make/link-cfg/Makefile run-make/link-framework/Makefile run-make/link-path-order/Makefile run-make/linkage-attr-on-static/Makefile -run-make/llvm-ident/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile run-make/longjmp-across-rust/Makefile diff --git a/tests/run-make/llvm-ident/Makefile b/tests/run-make/llvm-ident/Makefile deleted file mode 100644 index e583e6018e0bf..0000000000000 --- a/tests/run-make/llvm-ident/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../tools.mk - -# only-linux - -all: - # `-Ccodegen-units=16 -Copt-level=2` is used here to trigger thin LTO - # across codegen units to test deduplication of the named metadata - # (see `LLVMRustPrepareThinLTOImport` for details). - echo 'fn main(){}' | $(RUSTC) - --emit=link,obj -Csave-temps -Ccodegen-units=16 -Copt-level=2 --target=$(TARGET) - - # `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR - # for temporary outputs. - "$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/*.bc - - # Check LLVM IR files (including temporary outputs) have `!llvm.ident` - # named metadata, reusing the related codegen test. - set -e; for f in $(TMPDIR)/*.ll; do \ - $(LLVM_FILECHECK) --input-file $$f ../../codegen/llvm-ident.rs; \ - done diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs new file mode 100644 index 0000000000000..f460829288e8c --- /dev/null +++ b/tests/run-make/llvm-ident/rmake.rs @@ -0,0 +1,41 @@ +//@ only-linux +//@ ignore-cross-compile + +use run_make_support::llvm::llvm_bin_dir; +use run_make_support::{cmd, env_var, llvm_filecheck, read_dir, rustc, source_root}; + +use std::ffi::OsStr; + +fn main() { + // `-Ccodegen-units=16 -Copt-level=2` is used here to trigger thin LTO + // across codegen units to test deduplication of the named metadata + // (see `LLVMRustPrepareThinLTOImport` for details). + rustc() + .emit("link,obj") + .arg("-") + .arg("-Csave-temps") + .codegen_units(16) + .opt_level("2") + .target(&env_var("TARGET")) + .stdin("fn main(){}") + .run(); + + // `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR + // for temporary outputs. + let mut files = Vec::new(); + read_dir(".", |path| { + if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("bc")) { + files.push(path.to_path_buf()); + } + }); + cmd(llvm_bin_dir().join("llvm-dis")).args(&files).run(); + + // Check LLVM IR files (including temporary outputs) have `!llvm.ident` + // named metadata, reusing the related codegen test. + let llvm_ident_path = source_root().join("tests/codegen/llvm-ident.rs"); + read_dir(".", |path| { + if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) { + llvm_filecheck().input_file(path).arg(&llvm_ident_path).run(); + } + }); +} From b998cff5582b819910cc8e0f092c15151b930d02 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 2 Jul 2024 06:04:23 +0000 Subject: [PATCH 215/217] Use `cfg!(windows)` --- src/bootstrap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 6d00ff9982d96..f5941e31e251f 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1678,7 +1678,7 @@ impl Build { return; } if let Err(e) = fs::remove_file(dst) { - if e.kind() != io::ErrorKind::NotFound { + if cfg!(windows) && e.kind() != io::ErrorKind::NotFound { // workaround for https://github.com/rust-lang/rust/issues/127126 // if removing the file fails, attempt to rename it instead. let now = t!(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)); From 42ac903f4fe4e9894f8c6e97538696bdbae848dc Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 2 Jul 2024 01:51:55 -0400 Subject: [PATCH 216/217] Change to the NetBSD archive URL rather than the CDN The CDN has been down for a few hours. Switch to an alternative for the time being so we can unblock CI. It appears that the CDN is quite a bit faster, so we will likely want to switch back when available. --- .../build-netbsd-toolchain.sh | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh index e0c008b76fa8b..4a42f5da29fcc 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ignore-tidy-linelength -set -ex +set -eux hide_output() { set +x @@ -20,6 +20,22 @@ exit 1 set -x } +# Download, verify SHA512, and remove the downloaded file +# Usage: +download() { + fname="$1" + shift + url="$1" + shift + sha="$1" + shift + + curl "$url" -o "$fname" + echo "$sha $fname" | shasum -a 512 --check || exit 1 + "$@" + rm "$fname" +} + mkdir netbsd cd netbsd @@ -27,17 +43,31 @@ mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot # URL=https://ci-mirrors.rust-lang.org/rustc -SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets -curl $SOURCE_URL/src.tgz | tar xzf - -curl $SOURCE_URL/gnusrc.tgz | tar xzf - -curl $SOURCE_URL/sharesrc.tgz | tar xzf - -curl $SOURCE_URL/syssrc.tgz | tar xzf - - -BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets -curl $BINARY_URL/base.tar.xz | \ - tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib -curl $BINARY_URL/comp.tar.xz | \ - tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib +# Hashes come from https://cdn.netbsd.org/pub/NetBSD/security/hashes/NetBSD-9.0_hashes.asc +SRC_SHA=2c791ae009a6929c6fc893ec5df7e62910ee8207e0b2159d6937309c03efe175b6ae1e445829a13d041b6851334ad35c521f2fa03c97675d4a05f1fafe58ede0 +GNUSRC_SHA=3710085a73feecf6a843415271ec794c90146b03f6bbd30f07c9e0c79febf8995d557e40194f1e05db655e4f5ef2fae97563f8456fceaae65d4ea98857a83b1c +SHARESRC_SHA=f080776ed82c3ac5d6272dee39746f87897d8e6984996caf5bf6d87bf11d9c9e0c1ad5c437c21258bd278bb6fd76974946e878f548517885f71c556096231369 +SYSSRC_SHA=60b9ddf4cc6402256473e2e1eefeabd9001aa4e205208715ecc6d6fc3f5b400e469944580077271b8e80562a4c2f601249e69e07a504f46744e0c50335f1cbf1 +BASE_SHA=b5926b107cebf40c3c19b4f6cd039b610987dd7f819e7cdde3bd1e5230a856906e7930b15ab242d52ced9f0bda01d574be59488b8dbb95fa5df2987d0a70995f +COMP_SHA=38ea54f30d5fc2afea87e5096f06873e00182789e8ad9cec0cb3e9f7c538c1aa4779e63fd401a36ba02676158e83fa5c95e8e87898db59c1914fb206aecd82d2 + +# FIXME: the archive URL is being used temporarily while the CDN is down. +# We should serve this from our own CDN +# SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets +SOURCE_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/source/sets +download src.tgz "$SOURCE_URL/src.tgz" "$SRC_SHA" tar xzf src.tgz +download gnusrc.tgz "$SOURCE_URL/gnusrc.tgz" "$GNUSRC_SHA" tar xzf gnusrc.tgz +download sharesrc.tgz "$SOURCE_URL/sharesrc.tgz" "$SHARESRC_SHA" tar xzf sharesrc.tgz +download syssrc.tgz "$SOURCE_URL/syssrc.tgz" "$SYSSRC_SHA" tar xzf syssrc.tgz + +# FIXME: the archive URL is being used temporarily while the CDN is down. +# We should serve this from our own CDN +# BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets +BINARY_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/amd64/binary/sets +download base.tar.xz "$BINARY_URL/base.tar.xz" "$BASE_SHA" \ + tar xJf base.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib +download comp.tar.xz "$BINARY_URL/comp.tar.xz" "$COMP_SHA" \ + tar xJf comp.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib cd usr/src From 9f32459c988dec799458f304bbc49ed5dc6ef772 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 3 Jul 2024 06:15:17 +0800 Subject: [PATCH 217/217] Fix incorrect suggestion for extra argument with a type error --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 26 ++++ .../suggest-better-removing-issue-126246.rs | 21 +++ ...uggest-better-removing-issue-126246.stderr | 124 ++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs create mode 100644 tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 63148ab517c5d..c6d72700b3fce 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -951,6 +951,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return err.emit(); } + // Special case, we found an extra argument is provided, which is very common in practice. + // but there is a obviously better removing suggestion compared to the current one, + // try to find the argument with Error type, if we removed it all the types will become good, + // then we will replace the current suggestion. + if let [Error::Extra(provided_idx)] = &errors[..] { + let remove_idx_is_perfect = |idx: usize| -> bool { + let removed_arg_tys = provided_arg_tys + .iter() + .enumerate() + .filter_map(|(j, arg)| if idx == j { None } else { Some(arg) }) + .collect::>(); + std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all( + |((expected_ty, _), (provided_ty, _))| { + !provided_ty.references_error() + && self.can_coerce(*provided_ty, *expected_ty) + }, + ) + }; + + if !remove_idx_is_perfect(provided_idx.as_usize()) { + if let Some(i) = (0..provided_args.len()).find(|&i| remove_idx_is_perfect(i)) { + errors = vec![Error::Extra(ProvidedIdx::from_usize(i))]; + } + } + } + let mut err = if formal_and_expected_inputs.len() == provided_args.len() { struct_span_code_err!( self.dcx(), diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs new file mode 100644 index 0000000000000..fa1802283c39c --- /dev/null +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs @@ -0,0 +1,21 @@ +fn add_one(x: i32) -> i32 { + x + 1 +} + +fn add_two(x: i32, y: i32) -> i32 { + x + y +} + +fn main() { + add_one(2, 2); //~ ERROR this function takes 1 argument but 2 arguments were supplied + add_one(no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 1 argument but 2 arguments were supplied + add_one(10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 1 argument but 2 arguments were supplied + add_two(10, no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied + add_two(no_such_local, 10, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied + add_two(10, 10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied +} diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr new file mode 100644 index 0000000000000..7c4daa3ffe95b --- /dev/null +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -0,0 +1,124 @@ +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:11:13 + | +LL | add_one(no_such_local, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:13:17 + | +LL | add_one(10, no_such_local); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:15:17 + | +LL | add_two(10, no_such_local, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:17:13 + | +LL | add_two(no_such_local, 10, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:19:21 + | +LL | add_two(10, 10, no_such_local); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:10:5 + | +LL | add_one(2, 2); + | ^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:11:5 + | +LL | add_one(no_such_local, 10); + | ^^^^^^^ --------------- + | | + | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:13:5 + | +LL | add_one(10, no_such_local); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:15:5 + | +LL | add_two(10, no_such_local, 10); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:17:5 + | +LL | add_two(no_such_local, 10, 10); + | ^^^^^^^ --------------- + | | + | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:19:5 + | +LL | add_two(10, 10, no_such_local); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0061, E0425. +For more information about an error, try `rustc --explain E0061`.