From 32605d8b606def024d84af5bf7ae2141f30951ac Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 5 Jun 2025 20:41:41 +0530 Subject: [PATCH 001/525] Implement `simd_round_ties_even` for miri, cg_clif and cg_gcc --- src/intrinsics/simd.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 46a441488fa6..f928ad8bc021 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -495,7 +495,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( | sym::simd_flog | sym::simd_flog10 | sym::simd_flog2 - | sym::simd_round => { + | sym::simd_round + | sym::simd_round_ties_even => { intrinsic_args!(fx, args => (a); intrinsic); if !a.layout().ty.is_simd() { @@ -526,6 +527,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( (sym::simd_flog2, types::F64) => "log2", (sym::simd_round, types::F32) => "roundf", (sym::simd_round, types::F64) => "round", + (sym::simd_round_ties_even, types::F32) => "rintf", + (sym::simd_round_ties_even, types::F64) => "rint", _ => unreachable!("{:?}", intrinsic), }; fx.lib_call( From aaea8ebdba45344e1f012b396d2e26b457261c1b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 09:00:20 +0000 Subject: [PATCH 002/525] Fix normalization in linker-warning Ensure rustc_codegen_cranelift doesn't get normalized to rustc. And handle -Cpanic=abort. --- scripts/test_rustc_tests.sh | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 32c71f433b0f..7e356b4b462b 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -151,20 +151,6 @@ rm tests/ui/process/process-panic-after-fork.rs # same cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist cat < Date: Tue, 24 Jun 2025 11:32:02 +0000 Subject: [PATCH 003/525] Merge commit '8c848e0604b5d26fad120914f822f564fe05c52a' into sync_cg_clif-2025-06-24 --- Cargo.lock | 84 +++++++++++-------- Cargo.toml | 24 +++--- build_system/abi_cafe.rs | 8 +- .../0002-abi-cafe-Disable-broken-tests.patch | 69 --------------- rust-toolchain | 2 +- scripts/abi-cafe-rules.toml | 17 ++++ src/constant.rs | 2 +- src/intrinsics/llvm_x86.rs | 7 +- src/intrinsics/simd.rs | 7 +- 9 files changed, 95 insertions(+), 125 deletions(-) delete mode 100644 patches/0002-abi-cafe-Disable-broken-tests.patch create mode 100644 scripts/abi-cafe-rules.toml diff --git a/Cargo.lock b/Cargo.lock index a906bec8b7e2..b893a2be9a2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-assembler-x64" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff8e35182c7372df00447cb90a04e584e032c42b9b9b6e8c50ddaaf0d7900d5" +checksum = "f6f53499803b1607b6ee0ba0de4ba036e6da700c2e489fe8f9d0f683d0b84d31" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14220f9c2698015c3b94dc6b84ae045c1c45509ddc406e43c6139252757fdb7a" +checksum = "1aadaa5bc8430d0e7bb999459369bedd0e5816ad4a82a0e20748341c4e333eda" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d372ef2777ceefd75829e1390211ac240e9196bc60699218f7ea2419038288ee" +checksum = "2005fda2fc52a2dbce58229b4fb4483b70cbc806ba8ecc11b3f050c1a2d26cac" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56323783e423818fa89ce8078e90a3913d2a6e0810399bfce8ebd7ee87baa81f" +checksum = "56935e02452ca1249d39ad5c45a96304d0b4300a158a391fd113451e0cd4483d" [[package]] name = "cranelift-codegen" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ffb780aab6186c6e9ba26519654b1ac55a09c0a866f6088a4efbbd84da68ed" +checksum = "62612786bf00e10999f50217d6f455d02b31591155881a45a903d1a95d1a4043" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -97,13 +97,14 @@ dependencies = [ "serde", "smallvec", "target-lexicon", + "wasmtime-math", ] [[package]] name = "cranelift-codegen-meta" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c23ef13814d3b39c869650d5961128cbbecad83fbdff4e6836a03ecf6862d7ed" +checksum = "07bae789df91ef236079733af9df11d852256c64af196f0bc6471ea0f5f301be" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -112,33 +113,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f623300657679f847803ce80811454bfff89cea4f6bf684be5c468d4a73631" +checksum = "1be319616d36527782558a8312508757815f64deb19b094c7b8f4337229a9bc6" [[package]] name = "cranelift-control" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4168af69989aa6b91fab46799ed4df6096f3209f4a6c8fb4358f49c60188f" +checksum = "8810ee1ab5e9bd5cff4c0c8d240e2009cb5c2b79888fde1d5256d605712314b7" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6fa9bae1c8de26d71ac2162f069447610fd91e7780cb480ee0d76ac81eabb8" +checksum = "086452c97cfbe116bf17dbe622dc5fdf2ea97299c7d4ce42460f284387c9928a" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8219205608aa0b0e6769b580284a7e055c7e0c323c1041cde7ca078add3e412" +checksum = "4c27947010ab759330f252610c17a8cd64d123358be4f33164233d04fcd77b80" dependencies = [ "cranelift-codegen", "log", @@ -148,15 +149,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588d0c5964f10860b04043e55aab26d7f7a206b0fd4f10c5260e8aa5773832bd" +checksum = "ec67bfb8bd55b1e9760eb9f5186dca8d81bd4d86110f8d5af01154a044c91802" [[package]] name = "cranelift-jit" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56bd917ddc524f84f4066f954062875bdfc0dffea068ee94e906d98de5ac7c33" +checksum = "d67cdfc447f2abdb46bb30a6582cce189539c3c051c1d5330692376e1400edff" dependencies = [ "anyhow", "cranelift-codegen", @@ -174,9 +175,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a03c057d8a992e06596c871341e446af43ff9224f941e5b8adea39137a5391" +checksum = "e4597eaa52bca1ed111986c7a7f70cdbe192f83d271d627201365078e37b7e84" dependencies = [ "anyhow", "cranelift-codegen", @@ -185,9 +186,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed3c94cb97b14f92b6a94a1d45ef8c851f6a2ad9114e5d91d233f7da638fed" +checksum = "75a9b63edea46e013fce459c46e500462cb03a0490fdd9c18fe42b1dd7b93aa1" dependencies = [ "cranelift-codegen", "libc", @@ -196,9 +197,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64dacef362a69375a604f6636e5e9a174fb96dba3b273646fcd9fa85c1d0997" +checksum = "ce706f0166d5b7f31693dff521e87cb9858e12adf22ffcde93c4a2826f8f04a9" dependencies = [ "anyhow", "cranelift-codegen", @@ -211,9 +212,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.120.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85256fac1519a7d25a040c1d850fba67478f3f021ad5fdf738ba4425ee862dbf" +checksum = "7d5870e266df8237b56cc98b04f5739c228565c92dd629ec6c66efa87271a158" [[package]] name = "crc32fast" @@ -288,6 +289,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "log" version = "0.4.22" @@ -446,9 +453,9 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "wasmtime-jit-icache-coherence" -version = "33.0.0" +version = "34.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175e924dbc944c185808466d1e90b5a7feb610f3b9abdfe26f8ee25fd1086d1c" +checksum = "2eedc0324e37cf39b049f4dca0c30997eaab49f09006d5f4c1994e64e7b7dba8" dependencies = [ "anyhow", "cfg-if", @@ -456,6 +463,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "wasmtime-math" +version = "34.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd35fae4cf51d2b4a9bd2ef04b0eb309fa1849cab6a6ab5ac27cbd054ea284d" +dependencies = [ + "libm", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 94fcbd0a5023..9066e4dbbb52 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.120.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.120.0" } -cranelift-module = { version = "0.120.0" } -cranelift-native = { version = "0.120.0" } -cranelift-jit = { version = "0.120.0", optional = true } -cranelift-object = { version = "0.120.0" } +cranelift-codegen = { version = "0.121.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.121.0" } +cranelift-module = { version = "0.121.0" } +cranelift-native = { version = "0.121.0" } +cranelift-jit = { version = "0.121.0", optional = true } +cranelift-object = { version = "0.121.0" } target-lexicon = "0.13" gimli = { version = "0.31", default-features = false, features = ["write"] } object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-33.0.0", version = "0.120.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 674acfbd3097..43025137bc6b 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -6,8 +6,8 @@ use crate::{CodegenBackend, SysrootKind, build_sysroot}; static ABI_CAFE_REPO: GitRepo = GitRepo::github( "Gankra", "abi-cafe", - "f1220cfd13b57f5c0082c26529163865ee25e115", - "fe93a9acd461425d", + "94d38030419eb00a1ba80e5e2b4d763dcee58db4", + "6efb4457893c8670", "abi-cafe", ); @@ -46,6 +46,10 @@ pub(crate) fn run( let mut cmd = ABI_CAFE.run(bootstrap_host_compiler, dirs); cmd.arg("--"); + cmd.arg("--debug"); + + cmd.arg("--rules").arg(dirs.source_dir.join("scripts/abi-cafe-rules.toml")); + // stdcall, vectorcall and such don't work yet cmd.arg("--conventions").arg("c").arg("--conventions").arg("rust"); diff --git a/patches/0002-abi-cafe-Disable-broken-tests.patch b/patches/0002-abi-cafe-Disable-broken-tests.patch deleted file mode 100644 index 01b6a990b720..000000000000 --- a/patches/0002-abi-cafe-Disable-broken-tests.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 236df390f3bc4ed69c26f4d51d584bea246da886 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Tue, 9 Jul 2024 11:25:14 +0000 -Subject: [PATCH] Disable broken tests - ---- - src/report.rs | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/src/toolchains/rust.rs b/src/toolchains/rust.rs -index 0c50f7a..bfde2b1 100644 ---- a/src/toolchains/rust.rs -+++ b/src/toolchains/rust.rs -@@ -83,6 +83,7 @@ impl Toolchain for RustcToolchain { - .arg(out_dir) - .arg("--target") - .arg(built_info::TARGET) -+ .arg("-g") - .arg(format!("-Cmetadata={lib_name}")) - .arg(src_path); - if let Some(codegen_backend) = &self.codegen_backend { -diff --git a/src/report.rs b/src/report.rs -index 958ab43..dcf1044 100644 ---- a/src/report.rs -+++ b/src/report.rs -@@ -48,6 +48,40 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn Toolchain, callee: &dyn Toolc - // - // THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES - -+ if cfg!(all(target_arch = "aarch64", target_os = "linux")) { -+ if test.test == "F32Array" && test.options.convention == CallingConvention::C { -+ result.check = Busted(Check); -+ } -+ } -+ -+ if cfg!(all(target_arch = "aarch64", target_os = "macos")) { -+ if test.test == "SingleVariantUnion" && test.options.convention == CallingConvention::C && test.options.repr == LangRepr::C { -+ result.check = Busted(Check); -+ } -+ -+ if test.test == "OptionU128" && test.caller == "rustc" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C { -+ result.check = Busted(Run); -+ } -+ -+ if test.test == "OptionU128" && test.caller == "cgclif" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C { -+ result.check = Busted(Check); -+ } -+ } -+ -+ if cfg!(all(target_arch = "x86_64", windows)) { -+ if test.test == "simple" && test.options.convention == CallingConvention::Rust { -+ result.check = Busted(Check); -+ } -+ -+ if test.test == "simple" && test.options.convention == CallingConvention::Rust && test.caller == "rustc" { -+ result.check = Busted(Run); -+ } -+ } -+ -+ if test.test == "f16" || test.test == "f128" { -+ result.run = Skip; -+ } -+ - // END OF VENDOR RESERVED AREA - // - // --- -2.34.1 - diff --git a/rust-toolchain b/rust-toolchain index af4bd6dc6b85..150bb562f74a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-05-25" +channel = "nightly-2025-06-24" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" diff --git a/scripts/abi-cafe-rules.toml b/scripts/abi-cafe-rules.toml new file mode 100644 index 000000000000..54f9445c8e52 --- /dev/null +++ b/scripts/abi-cafe-rules.toml @@ -0,0 +1,17 @@ +[target.'cfg(all(target_arch = "aarch64", target_os = "linux"))'] +'F32Array::conv_c'.busted = "check" + +[target.'cfg(all(target_arch = "aarch64", target_os = "macos"))'] +'SingleVariantUnion::conv_c::repr_c'.busted = "check" +'OptionU128::conv_rust::repr_c::rustc_caller'.busted = "run" +'OptionU128::conv_rust::repr_c::cgclif_caller'.busted = "check" + +[target.'cfg(all(target_arch = "x86_64", windows))'] +'simple::conv_rust'.busted = "check" +'simple::conv_rust::rustc_caller'.busted = "run" + +[target.'*'.'f16'] +run = "skip" + +[target.'*'.'f128'] +run = "skip" diff --git a/src/constant.rs b/src/constant.rs index c8527c3a57df..3a62cd52a9d9 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -228,7 +228,7 @@ fn pointer_for_allocation<'tcx>( crate::pointer::Pointer::new(global_ptr) } -pub(crate) fn data_id_for_alloc_id( +fn data_id_for_alloc_id( cx: &mut ConstantCx, module: &mut dyn Module, alloc_id: AllocId, diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 615f6c47d902..37fbe4be1b0f 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -202,9 +202,10 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( }; let x = codegen_operand(fx, &x.node); let y = codegen_operand(fx, &y.node); - let kind = match &kind.node { - Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0, - Operand::Copy(_) | Operand::Move(_) => unreachable!("{kind:?}"), + let kind = if let Some(const_) = kind.node.constant() { + crate::constant::eval_mir_constant(fx, const_).0 + } else { + unreachable!("{kind:?}") }; let flt_cc = match kind diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 46a441488fa6..68ff0b622c8f 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -205,9 +205,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( // Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead. let indexes = { use rustc_middle::mir::interpret::*; - let idx_const = match &idx.node { - Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0, - Operand::Copy(_) | Operand::Move(_) => unreachable!("{idx:?}"), + let idx_const = if let Some(const_) = idx.node.constant() { + crate::constant::eval_mir_constant(fx, const_).0 + } else { + unreachable!("{idx:?}") }; let idx_bytes = match idx_const { From d0ee10d2f8603c847ea0be0fbb186af281e9714d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:16:27 +0000 Subject: [PATCH 004/525] Rustup to rustc 1.90.0-nightly (0fa4ec6cd 2025-06-25) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 150bb562f74a..57b45c7706b1 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-06-24" +channel = "nightly-2025-06-26" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8bf928a2e56b3d1a930973d5c97b031ea9e7803c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:00:26 +0200 Subject: [PATCH 005/525] Move inline_asm_index from CodegenCx to FunctionCx --- src/base.rs | 1 + src/common.rs | 2 ++ src/inline_asm.rs | 14 ++++++++------ src/lib.rs | 2 -- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/base.rs b/src/base.rs index 0b641ba64b7a..c6352ba6112f 100644 --- a/src/base.rs +++ b/src/base.rs @@ -104,6 +104,7 @@ pub(crate) fn codegen_fn<'tcx>( clif_comments, next_ssa_var: 0, + inline_asm_index: 0, }; tcx.prof.generic_activity("codegen clif ir").run(|| codegen_fn_body(&mut fx, start_block)); diff --git a/src/common.rs b/src/common.rs index 2f11b2d2dcc1..5a342a3fe989 100644 --- a/src/common.rs +++ b/src/common.rs @@ -292,6 +292,8 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { /// This should only be accessed by `CPlace::new_var`. pub(crate) next_ssa_var: u32, + + pub(crate) inline_asm_index: u32, } impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 120d6ff9e38e..b4aa0651a6b8 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -103,11 +103,12 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( // be exported from the main codegen unit and may thus be unreachable from the // object file created by an external assembler. let wrapper_name = format!( - "__inline_asm_{}_wrapper_n{}", + "{}__inline_asm_{}_wrapper_n{}", + fx.symbol_name, fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let sig = get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); @@ -166,11 +167,12 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( asm_gen.allocate_stack_slots(); let asm_name = format!( - "__inline_asm_{}_n{}", + "{}__inline_asm_{}_n{}", + fx.symbol_name, fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let generated_asm = asm_gen.generate_asm_wrapper(&asm_name); fx.cx.global_asm.push_str(&generated_asm); diff --git a/src/lib.rs b/src/lib.rs index 8e34436fb5e0..d3aa9c532243 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,7 +129,6 @@ struct CodegenCx { invocation_temp: Option, should_write_ir: bool, global_asm: String, - inline_asm_index: usize, debug_context: Option, cgu_name: Symbol, } @@ -148,7 +147,6 @@ impl CodegenCx { invocation_temp: tcx.sess.invocation_temp.clone(), should_write_ir: crate::pretty_clif::should_write_ir(tcx), global_asm: String::new(), - inline_asm_index: 0, debug_context, cgu_name, } From 9ead1c10aac15e748fb3ae30111fc54cdadac460 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:02:11 +0200 Subject: [PATCH 006/525] Move invocation_temp out of CodegenCx --- src/driver/aot.rs | 5 +++-- src/lib.rs | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 442151fe32de..b3f91fc84b0e 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -593,6 +593,7 @@ fn module_codegen( let producer = crate::debuginfo::producer(tcx.sess); let profiler = tcx.prof.clone(); + let invocation_temp = tcx.sess.invocation_temp.clone(); OngoingModuleCodegen::Async(std::thread::spawn(move || { profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { @@ -618,7 +619,7 @@ fn module_codegen( &global_asm_config, &cgu_name, &cx.global_asm, - cx.invocation_temp.as_deref(), + invocation_temp.as_deref(), ) })?; @@ -626,7 +627,7 @@ fn module_codegen( profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| { emit_cgu( &global_asm_config.output_filenames, - cx.invocation_temp.as_deref(), + invocation_temp.as_deref(), &profiler, cgu_name, module, diff --git a/src/lib.rs b/src/lib.rs index d3aa9c532243..39bfeb1bf303 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,6 @@ impl String> Drop for PrintOnPanic { /// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). struct CodegenCx { output_filenames: Arc, - invocation_temp: Option, should_write_ir: bool, global_asm: String, debug_context: Option, @@ -144,7 +143,6 @@ impl CodegenCx { }; CodegenCx { output_filenames: tcx.output_filenames(()).clone(), - invocation_temp: tcx.sess.invocation_temp.clone(), should_write_ir: crate::pretty_clif::should_write_ir(tcx), global_asm: String::new(), debug_context, From 23110bdf763142b1c3ecd688ce95bf819f2da461 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:13:53 +0200 Subject: [PATCH 007/525] Remove output_filenames from CodegenCx --- src/base.rs | 6 ++++-- src/driver/aot.rs | 2 ++ src/driver/jit.rs | 13 ++++++++++++- src/lib.rs | 2 -- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/base.rs b/src/base.rs index c6352ba6112f..57009b4ff8eb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -12,6 +12,7 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_session::config::OutputFilenames; use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; @@ -138,6 +139,7 @@ pub(crate) fn codegen_fn<'tcx>( pub(crate) fn compile_fn( cx: &mut crate::CodegenCx, profiler: &SelfProfilerRef, + output_filenames: &OutputFilenames, cached_context: &mut Context, module: &mut dyn Module, codegened_func: CodegenedFunction, @@ -215,7 +217,7 @@ pub(crate) fn compile_fn( if cx.should_write_ir { // Write optimized function to file for debugging crate::pretty_clif::write_clif_file( - &cx.output_filenames, + output_filenames, &codegened_func.symbol_name, "opt", module.isa(), @@ -225,7 +227,7 @@ pub(crate) fn compile_fn( if let Some(disasm) = &context.compiled_code().unwrap().vcode { crate::pretty_clif::write_ir_file( - &cx.output_filenames, + output_filenames, &format!("{}.vcode", codegened_func.symbol_name), |file| file.write_all(disasm.as_bytes()), ) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index b3f91fc84b0e..d2337c0059b8 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -594,6 +594,7 @@ fn module_codegen( let profiler = tcx.prof.clone(); let invocation_temp = tcx.sess.invocation_temp.clone(); + let output_filenames = tcx.output_filenames(()).clone(); OngoingModuleCodegen::Async(std::thread::spawn(move || { profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { @@ -606,6 +607,7 @@ fn module_codegen( crate::base::compile_fn( &mut cx, &profiler, + &output_filenames, &mut cached_context, &mut module, codegened_func, diff --git a/src/driver/jit.rs b/src/driver/jit.rs index b1f185b551c3..52551d7c0767 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -9,6 +9,7 @@ use rustc_codegen_ssa::CrateInfo; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::MonoItem; use rustc_session::Session; +use rustc_session::config::OutputFilenames; use rustc_span::sym; use crate::CodegenCx; @@ -41,6 +42,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { tcx.dcx().fatal("can't jit non-executable crate"); } + let output_filenames = tcx.output_filenames(()); let (mut jit_module, mut cx) = create_jit_module(tcx); let mut cached_context = Context::new(); @@ -60,6 +62,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { MonoItem::Fn(inst) => { codegen_and_compile_fn( tcx, + &output_filenames, &mut cx, &mut cached_context, &mut jit_module, @@ -122,6 +125,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { fn codegen_and_compile_fn<'tcx>( tcx: TyCtxt<'tcx>, + output_filenames: &OutputFilenames, cx: &mut crate::CodegenCx, cached_context: &mut Context, module: &mut dyn Module, @@ -149,7 +153,14 @@ fn codegen_and_compile_fn<'tcx>( module, instance, ); - crate::base::compile_fn(cx, &tcx.prof, cached_context, module, codegened_func); + crate::base::compile_fn( + cx, + &tcx.prof, + output_filenames, + cached_context, + module, + codegened_func, + ); }); } diff --git a/src/lib.rs b/src/lib.rs index 39bfeb1bf303..3e4351f660bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,7 +125,6 @@ impl String> Drop for PrintOnPanic { /// The codegen context holds any information shared between the codegen of individual functions /// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). struct CodegenCx { - output_filenames: Arc, should_write_ir: bool, global_asm: String, debug_context: Option, @@ -142,7 +141,6 @@ impl CodegenCx { None }; CodegenCx { - output_filenames: tcx.output_filenames(()).clone(), should_write_ir: crate::pretty_clif::should_write_ir(tcx), global_asm: String::new(), debug_context, From 4042f4026617ed7bc5dffdb999a34848d409f3d6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:28:08 +0200 Subject: [PATCH 008/525] Remove global_asm from CodegenCx --- src/base.rs | 7 ++++++- src/common.rs | 1 + src/driver/aot.rs | 15 +++++++++------ src/driver/jit.rs | 10 ++++++---- src/global_asm.rs | 2 +- src/inline_asm.rs | 2 +- src/lib.rs | 2 -- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/base.rs b/src/base.rs index 57009b4ff8eb..7f799b5730b4 100644 --- a/src/base.rs +++ b/src/base.rs @@ -26,6 +26,7 @@ pub(crate) struct CodegenedFunction { func: Function, clif_comments: CommentWriter, func_debug_cx: Option, + inline_asm: String, } pub(crate) fn codegen_fn<'tcx>( @@ -105,6 +106,7 @@ pub(crate) fn codegen_fn<'tcx>( clif_comments, next_ssa_var: 0, + inline_asm: String::new(), inline_asm_index: 0, }; @@ -116,6 +118,7 @@ pub(crate) fn codegen_fn<'tcx>( let symbol_name = fx.symbol_name; let clif_comments = fx.clif_comments; let func_debug_cx = fx.func_debug_cx; + let inline_asm = fx.inline_asm; fx.constants_cx.finalize(fx.tcx, &mut *fx.module); @@ -133,7 +136,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 } + CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx, inline_asm } } pub(crate) fn compile_fn( @@ -142,12 +145,14 @@ pub(crate) fn compile_fn( output_filenames: &OutputFilenames, cached_context: &mut Context, module: &mut dyn Module, + global_asm: &mut String, codegened_func: CodegenedFunction, ) { let _timer = profiler.generic_activity_with_arg("compile function", &*codegened_func.symbol_name); let clif_comments = codegened_func.clif_comments; + global_asm.push_str(&codegened_func.inline_asm); // Store function in context let context = cached_context; diff --git a/src/common.rs b/src/common.rs index 5a342a3fe989..b47b2a4ee4a5 100644 --- a/src/common.rs +++ b/src/common.rs @@ -293,6 +293,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { /// This should only be accessed by `CPlace::new_var`. pub(crate) next_ssa_var: u32, + pub(crate) inline_asm: String, pub(crate) inline_asm_index: u32, } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index d2337c0059b8..9e793fc52545 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -512,7 +512,7 @@ fn codegen_cgu_content( tcx: TyCtxt<'_>, module: &mut dyn Module, cgu_name: rustc_span::Symbol, -) -> (CodegenCx, Vec) { +) -> (CodegenCx, Vec, String) { let _timer = tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str()); let cgu = tcx.codegen_unit(cgu_name); @@ -524,6 +524,7 @@ fn codegen_cgu_content( tcx.sess.opts.debuginfo != DebugInfo::None, cgu_name, ); + let mut global_asm = String::new(); let mut type_dbg = TypeDebugContext::default(); super::predefine_mono_items(tcx, module, &mono_items); let mut codegened_functions = vec![]; @@ -533,7 +534,7 @@ fn codegen_cgu_content( if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { rustc_codegen_ssa::mir::naked_asm::codegen_naked_asm( - &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, + &mut GlobalAsmContext { tcx, global_asm: &mut global_asm }, instance, MonoItemData { linkage: RLinkage::External, @@ -565,7 +566,7 @@ fn codegen_cgu_content( } MonoItem::GlobalAsm(item_id) => { rustc_codegen_ssa::base::codegen_global_asm( - &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, + &mut GlobalAsmContext { tcx, global_asm: &mut global_asm }, item_id, ); } @@ -573,7 +574,7 @@ fn codegen_cgu_content( } crate::main_shim::maybe_create_entry_wrapper(tcx, module, false, cgu.is_primary()); - (cx, codegened_functions) + (cx, codegened_functions, global_asm) } fn module_codegen( @@ -586,7 +587,8 @@ fn module_codegen( ) -> OngoingModuleCodegen { let mut module = make_module(tcx.sess, cgu_name.as_str().to_string()); - let (mut cx, codegened_functions) = codegen_cgu_content(tcx, &mut module, cgu_name); + let (mut cx, codegened_functions, mut global_asm) = + codegen_cgu_content(tcx, &mut module, cgu_name); let cgu_name = cgu_name.as_str().to_owned(); @@ -610,6 +612,7 @@ fn module_codegen( &output_filenames, &mut cached_context, &mut module, + &mut global_asm, codegened_func, ); } @@ -620,7 +623,7 @@ fn module_codegen( crate::global_asm::compile_global_asm( &global_asm_config, &cgu_name, - &cx.global_asm, + global_asm, invocation_temp.as_deref(), ) })?; diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 52551d7c0767..ab1544e62b0a 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -80,10 +80,6 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { } }); - if !cx.global_asm.is_empty() { - tcx.dcx().fatal("Inline asm is not supported in JIT mode"); - } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, true, true); tcx.dcx().abort_if_errors(); @@ -153,14 +149,20 @@ fn codegen_and_compile_fn<'tcx>( module, instance, ); + + let mut global_asm = String::new(); crate::base::compile_fn( cx, &tcx.prof, output_filenames, cached_context, module, + &mut global_asm, codegened_func, ); + if !global_asm.is_empty() { + tcx.dcx().fatal("Inline asm is not supported in JIT mode"); + } }); } diff --git a/src/global_asm.rs b/src/global_asm.rs index 203b443269fa..db40d84be0aa 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -168,7 +168,7 @@ impl GlobalAsmConfig { pub(crate) fn compile_global_asm( config: &GlobalAsmConfig, cgu_name: &str, - global_asm: &str, + global_asm: String, invocation_temp: Option<&str>, ) -> Result, String> { if global_asm.is_empty() { diff --git a/src/inline_asm.rs b/src/inline_asm.rs index b4aa0651a6b8..832f24b38bce 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -175,7 +175,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( fx.inline_asm_index += 1; let generated_asm = asm_gen.generate_asm_wrapper(&asm_name); - fx.cx.global_asm.push_str(&generated_asm); + fx.inline_asm.push_str(&generated_asm); let mut inputs = Vec::new(); let mut outputs = Vec::new(); diff --git a/src/lib.rs b/src/lib.rs index 3e4351f660bb..a5ec796c1c2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,6 @@ impl String> Drop for PrintOnPanic { /// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). struct CodegenCx { should_write_ir: bool, - global_asm: String, debug_context: Option, cgu_name: Symbol, } @@ -142,7 +141,6 @@ impl CodegenCx { }; CodegenCx { should_write_ir: crate::pretty_clif::should_write_ir(tcx), - global_asm: String::new(), debug_context, cgu_name, } From b2cafc96ec61a2bfa43caf1ef68be0cc348e9140 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:47:17 +0200 Subject: [PATCH 009/525] Use ConstantCx for defining anonymous strings As opposed to directly defining them in the module. --- src/base.rs | 2 +- src/common.rs | 15 --------------- src/constant.rs | 18 ++++++++++-------- src/lib.rs | 1 + 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/base.rs b/src/base.rs index 7f799b5730b4..d79cf5aa5842 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1084,7 +1084,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>( msg_str: &str, span: Span, ) { - let msg_ptr = fx.anonymous_str(msg_str); + let msg_ptr = crate::constant::pointer_for_anonymous_str(fx, msg_str); let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); let args = [msg_ptr, msg_len]; diff --git a/src/common.rs b/src/common.rs index b47b2a4ee4a5..80b1f0881347 100644 --- a/src/common.rs +++ b/src/common.rs @@ -420,21 +420,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty()) }) } - - pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value { - let mut data = DataDescription::new(); - data.define(msg.as_bytes().to_vec().into_boxed_slice()); - let msg_id = self.module.declare_anonymous_data(false, false).unwrap(); - - // Ignore DuplicateDefinition error, as the data will be the same - let _ = self.module.define_data(msg_id, &data); - - let local_msg_id = self.module.declare_data_in_func(msg_id, self.bcx.func); - if self.clif_comments.enabled() { - self.add_comment(local_msg_id, msg); - } - self.bcx.ins().global_value(self.pointer_type, local_msg_id) - } } pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); diff --git a/src/constant.rs b/src/constant.rs index 3a62cd52a9d9..ff2c0d577bb4 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -3,6 +3,7 @@ use std::cmp::Ordering; use cranelift_module::*; +use rustc_const_eval::interpret::CTFE_ALLOC_SALT; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint}; @@ -199,23 +200,20 @@ pub(crate) fn codegen_const_value<'tcx>( } }, ConstValue::Indirect { alloc_id, offset } => CValue::by_ref( - pointer_for_allocation(fx, alloc_id) + Pointer::new(pointer_for_allocation(fx, alloc_id)) .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), ConstValue::Slice { data, meta } => { let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); - let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx); + let ptr = pointer_for_allocation(fx, alloc_id); let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64); CValue::by_val_pair(ptr, len, layout) } } } -fn pointer_for_allocation<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - alloc_id: AllocId, -) -> crate::pointer::Pointer { +fn pointer_for_allocation<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, alloc_id: AllocId) -> Value { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); let data_id = data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); @@ -224,8 +222,7 @@ fn pointer_for_allocation<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } - let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); - crate::pointer::Pointer::new(global_ptr) + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } fn data_id_for_alloc_id( @@ -251,6 +248,11 @@ pub(crate) fn data_id_for_vtable<'tcx>( data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) } +pub(crate) fn pointer_for_anonymous_str(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) -> Value { + let alloc_id = fx.tcx.allocate_bytes_dedup(msg.as_bytes(), CTFE_ALLOC_SALT); + pointer_for_allocation(fx, alloc_id) +} + fn data_id_for_static( tcx: TyCtxt<'_>, module: &mut dyn Module, diff --git a/src/lib.rs b/src/lib.rs index a5ec796c1c2d..678580a23723 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,7 @@ extern crate rustc_middle; extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_codegen_ssa; +extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_fs_util; From ac8ce3e3be305fae748fa7e2c98b4bfaa3f1dd88 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Thu, 15 May 2025 19:09:13 +0000 Subject: [PATCH 010/525] Insert checks for enum discriminants when debug assertions are enabled Similar to the existing nullpointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following: ```rust let val: MyEnum = unsafe { std::mem::transmute(42) }; ``` An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++. This check is similar to Miri's capabilities of checking for valid construction of enum values. This PR is inspired by saethlin@'s PR https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments! I also pair-programmed large parts of this together with vabr-g@. --- src/base.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/base.rs b/src/base.rs index 0b641ba64b7a..1b68c6535da5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -407,6 +407,18 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { source_info.span, ) } + AssertKind::InvalidEnumConstruction(source) => { + let source = codegen_operand(fx, source).load_scalar(fx); + let location = fx.get_caller_location(source_info).load_scalar(fx); + + codegen_panic_inner( + fx, + rustc_hir::LangItem::PanicInvalidEnumConstruction, + &[source, location], + *unwind, + source_info.span, + ) + } _ => { let location = fx.get_caller_location(source_info).load_scalar(fx); From 0bd5a21843eea25a77fd191539caae3d20d67308 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 28 Jun 2025 15:20:33 +0200 Subject: [PATCH 011/525] give Pointer::into_parts a more scary name and offer a safer alternative --- src/constant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index 3a62cd52a9d9..ee43eb736e65 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -133,7 +133,7 @@ pub(crate) fn codegen_const_value<'tcx>( } } Scalar::Ptr(ptr, _size) => { - let (prov, offset) = ptr.into_parts(); // we know the `offset` is relative + let (prov, offset) = ptr.prov_and_relative_offset(); let alloc_id = prov.alloc_id(); let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { From 95281ed1c16a994d5d3f69c3dbbfd5203fb15b6f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 21 Jun 2025 11:26:27 +0000 Subject: [PATCH 012/525] Stop backends from needing to support nullary intrinsics --- example/mini_core.rs | 2 +- example/mini_core_hello_world.rs | 23 ++++++++++++++++++----- src/intrinsics/mod.rs | 15 --------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 524ebde1c743..2f53bbf8b793 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -660,7 +660,7 @@ pub mod intrinsics { #[rustc_intrinsic] pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] - pub fn needs_drop() -> bool; + pub const fn needs_drop() -> bool; #[rustc_intrinsic] pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 1499f948deb3..246bd3104ec4 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,4 +1,13 @@ -#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)] +#![feature( + no_core, + lang_items, + never_type, + linkage, + extern_types, + thread_local, + repr_simd, + rustc_private +)] #![no_core] #![allow(dead_code, non_camel_case_types, internal_features)] @@ -207,10 +216,14 @@ fn main() { assert_eq!(intrinsics::align_of::() as u8, 2); assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8); - assert!(!intrinsics::needs_drop::()); - assert!(!intrinsics::needs_drop::<[u8]>()); - assert!(intrinsics::needs_drop::()); - assert!(intrinsics::needs_drop::()); + let u8_needs_drop = const { intrinsics::needs_drop::() }; + assert!(!u8_needs_drop); + let slice_needs_drop = const { intrinsics::needs_drop::<[u8]>() }; + assert!(!slice_needs_drop); + let noisy_drop = const { intrinsics::needs_drop::() }; + assert!(noisy_drop); + let noisy_unsized_drop = const { intrinsics::needs_drop::() }; + assert!(noisy_unsized_drop); Unique { pointer: NonNull(1 as *mut &str), _marker: PhantomData } as Unique; diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index df5748c34d11..4ff5773a06cb 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -812,21 +812,6 @@ fn codegen_regular_intrinsic_call<'tcx>( dest.write_cvalue(fx, val); } - sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { - intrinsic_args!(fx, args => (); intrinsic); - - let const_val = fx - .tcx - .const_eval_instance( - ty::TypingEnv::fully_monomorphized(), - instance, - source_info.span, - ) - .unwrap(); - let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); - ret.write_cvalue(fx, val); - } - sym::ptr_offset_from | sym::ptr_offset_from_unsigned => { intrinsic_args!(fx, args => (ptr, base); intrinsic); let ptr = ptr.load_scalar(fx); From ede659174d95d1c2b65aa1d97fc1b907b6d82ba9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:35:35 +0000 Subject: [PATCH 013/525] Implement exception handling support --- src/abi/mod.rs | 179 +++++++++++++++++--- src/base.rs | 47 ++++-- src/common.rs | 5 +- src/debuginfo/gcc_except_table.rs | 272 ++++++++++++++++++++++++++++++ src/debuginfo/mod.rs | 3 +- src/debuginfo/unwind.rs | 160 +++++++++++++++++- src/inline_asm.rs | 1 + src/intrinsics/mod.rs | 66 +++++++- 8 files changed, 675 insertions(+), 58 deletions(-) create mode 100644 src/debuginfo/gcc_except_table.rs diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 4c6fd9078154..fea4e73b18e3 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -7,7 +7,7 @@ mod returning; use std::borrow::Cow; use std::mem; -use cranelift_codegen::ir::{ArgumentPurpose, SigRef}; +use cranelift_codegen::ir::{ArgumentPurpose, BlockArg, ExceptionTableData, ExceptionTag, SigRef}; use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_abi::{CanonAbi, ExternAbi, X86Call}; @@ -20,10 +20,12 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use self::pass_mode::*; pub(crate) use self::returning::codegen_return; +use crate::base::codegen_unwind_terminate; +use crate::debuginfo::EXCEPTION_HANDLER_CLEANUP; use crate::prelude::*; fn clif_sig_from_fn_abi<'tcx>( @@ -380,7 +382,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( args: &[Spanned>], destination: Place<'tcx>, target: Option, - _unwind: UnwindAction, + unwind: UnwindAction, ) { let func = codegen_operand(fx, func); let fn_sig = func.layout().ty.fn_sig(fx.tcx); @@ -515,12 +517,6 @@ 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), - } - let (func_ref, first_arg_override) = match instance { // Trait object call Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => { @@ -582,18 +578,12 @@ pub(crate) fn codegen_terminator_call<'tcx>( adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args); } - let call_inst = 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 fx.clif_comments.enabled() { - with_no_trimmed_paths!(fx.add_comment(call_inst, format!("abi: {:?}", fn_abi))); + let nop_inst = fx.bcx.ins().nop(); + with_no_trimmed_paths!(fx.add_post_comment(nop_inst, format!("abi: {:?}", fn_abi))); } - fx.bcx.func.dfg.inst_results(call_inst).iter().copied().collect::>() + codegen_call_with_unwind_action(fx, source_info.span, func_ref, unwind, &call_args, None) }); if let Some(dest) = target { @@ -703,7 +693,7 @@ pub(crate) fn codegen_drop<'tcx>( source_info: mir::SourceInfo, drop_place: CPlace<'tcx>, target: BasicBlock, - _unwind: UnwindAction, + unwind: UnwindAction, ) { let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty); @@ -749,9 +739,14 @@ pub(crate) fn codegen_drop<'tcx>( let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); let sig = fx.bcx.import_signature(sig); - // FIXME implement cleanup on exceptions - fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]); - fx.bcx.ins().jump(ret_block, &[]); + codegen_call_with_unwind_action( + fx, + source_info.span, + CallTarget::Indirect(sig, drop_fn), + unwind, + &[ptr], + Some(ret_block), + ); } ty::Dynamic(_, _, ty::DynStar) => { // IN THIS ARM, WE HAVE: @@ -794,9 +789,14 @@ pub(crate) fn codegen_drop<'tcx>( let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); let sig = fx.bcx.import_signature(sig); - fx.bcx.ins().call_indirect(sig, drop_fn, &[data]); - // FIXME implement cleanup on exceptions - fx.bcx.ins().jump(ret_block, &[]); + codegen_call_with_unwind_action( + fx, + source_info.span, + CallTarget::Indirect(sig, drop_fn), + unwind, + &[data], + Some(ret_block), + ); } _ => { assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); @@ -821,9 +821,132 @@ pub(crate) fn codegen_drop<'tcx>( } let func_ref = fx.get_function_ref(drop_instance); - fx.bcx.ins().call(func_ref, &call_args); - // FIXME implement cleanup on exceptions - fx.bcx.ins().jump(ret_block, &[]); + codegen_call_with_unwind_action( + fx, + source_info.span, + CallTarget::Direct(func_ref), + unwind, + &call_args, + Some(ret_block), + ); + } + } + } +} + +#[derive(Copy, Clone)] +pub(crate) enum CallTarget { + Direct(FuncRef), + Indirect(SigRef, Value), +} + +pub(crate) fn codegen_call_with_unwind_action( + fx: &mut FunctionCx<'_, '_, '_>, + span: Span, + func_ref: CallTarget, + unwind: UnwindAction, + call_args: &[Value], + target_block: Option, +) -> SmallVec<[Value; 2]> { + let sig_ref = match func_ref { + CallTarget::Direct(func_ref) => fx.bcx.func.dfg.ext_funcs[func_ref].signature, + CallTarget::Indirect(sig_ref, _func_ptr) => sig_ref, + }; + + if target_block.is_some() { + assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty()); + } + match unwind { + UnwindAction::Continue | UnwindAction::Unreachable => { + let call_inst = 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(target_block) = target_block { + fx.bcx.ins().jump(target_block, &[]); + smallvec![] + } else { + fx.bcx + .func + .dfg + .inst_results(call_inst) + .iter() + .copied() + .collect::>() + } + } + UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => { + let returns_types = fx.bcx.func.dfg.signatures[sig_ref] + .returns + .iter() + .map(|return_param| return_param.value_type) + .collect::>(); + + let fallthrough_block = fx.bcx.create_block(); + let fallthrough_block_call_args = returns_types + .iter() + .enumerate() + .map(|(i, _)| BlockArg::TryCallRet(i.try_into().unwrap())) + .collect::>(); + let fallthrough_block_call = fx.bcx.func.dfg.block_call( + target_block.unwrap_or(fallthrough_block), + &fallthrough_block_call_args, + ); + let pre_cleanup_block = fx.bcx.create_block(); + let pre_cleanup_block_call = + fx.bcx.func.dfg.block_call(pre_cleanup_block, &[BlockArg::TryCallExn(0)]); + let exception_table = fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( + sig_ref, + fallthrough_block_call, + [( + Some(ExceptionTag::with_number(EXCEPTION_HANDLER_CLEANUP).unwrap()), + pre_cleanup_block_call, + )], + )); + + match func_ref { + CallTarget::Direct(func_ref) => { + fx.bcx.ins().try_call(func_ref, &call_args, exception_table); + } + CallTarget::Indirect(_sig, func_ptr) => { + fx.bcx.ins().try_call_indirect(func_ptr, &call_args, exception_table); + } + } + + fx.bcx.seal_block(pre_cleanup_block); + fx.bcx.switch_to_block(pre_cleanup_block); + fx.bcx.set_cold_block(pre_cleanup_block); + match unwind { + UnwindAction::Continue | UnwindAction::Unreachable => unreachable!(), + UnwindAction::Cleanup(cleanup) => { + let exception_ptr = + fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type); + fx.bcx.def_var(fx.exception_slot, exception_ptr); + let cleanup_block = fx.get_block(cleanup); + fx.bcx.ins().jump(cleanup_block, &[]); + } + UnwindAction::Terminate(reason) => { + // FIXME dedup terminate blocks + fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type); + + codegen_unwind_terminate(fx, span, reason); + } + } + + if target_block.is_none() { + fx.bcx.seal_block(fallthrough_block); + fx.bcx.switch_to_block(fallthrough_block); + let returns = returns_types + .into_iter() + .map(|ty| fx.bcx.append_block_param(fallthrough_block, ty)) + .collect(); + fx.bcx.ins().nop(); + returns + } else { + smallvec![] } } } diff --git a/src/base.rs b/src/base.rs index d79cf5aa5842..ddc1013c25ad 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,7 +2,7 @@ use cranelift_codegen::CodegenError; use cranelift_codegen::ir::UserFuncName; -use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; @@ -85,6 +85,9 @@ pub(crate) fn codegen_fn<'tcx>( None }; + let exception_slot = Variable::from_u32(0); + bcx.declare_var(exception_slot, pointer_type); + let mut fx = FunctionCx { cx, module, @@ -103,9 +106,10 @@ pub(crate) fn codegen_fn<'tcx>( block_map, local_map: IndexVec::with_capacity(mir.local_decls.len()), caller_location: None, // set by `codegen_fn_prelude` + exception_slot, clif_comments, - next_ssa_var: 0, + next_ssa_var: 1, // var0 is used for the exception slot inline_asm: String::new(), inline_asm_index: 0, }; @@ -304,11 +308,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } if bb_data.is_cleanup { - // Unwinding after panicking is not supported - continue; - - // FIXME Once unwinding is supported and Cranelift supports marking blocks as cold, do - // so for cleanup blocks. + fx.bcx.set_cold_block(block); } fx.bcx.ins().nop(); @@ -542,7 +542,13 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { codegen_unwind_terminate(fx, source_info.span, *reason); } TerminatorKind::UnwindResume => { - // FIXME implement unwinding + let exception_ptr = fx.bcx.use_var(fx.exception_slot); + fx.lib_call( + "_Unwind_Resume", + vec![AbiParam::new(fx.pointer_type)], + vec![], + &[exception_ptr], + ); fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } TerminatorKind::Unreachable => { @@ -1109,7 +1115,7 @@ fn codegen_panic_inner<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, lang_item: rustc_hir::LangItem, args: &[Value], - _unwind: UnwindAction, + unwind: UnwindAction, span: Span, ) { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); @@ -1125,14 +1131,23 @@ fn codegen_panic_inner<'tcx>( let symbol_name = fx.tcx.symbol_name(instance).name; - // FIXME implement cleanup on exceptions + let sig = Signature { + params: args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(), + returns: vec![], + call_conv: fx.target_config.default_call_conv, + }; + let func_id = fx.module.declare_function(symbol_name, Linkage::Import, &sig).unwrap(); + let func_ref = fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(func_ref, format!("{:?}", symbol_name)); + } - fx.lib_call( - symbol_name, - args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(), - vec![], - args, - ); + let nop_inst = fx.bcx.ins().nop(); + if fx.clif_comments.enabled() { + fx.add_comment(nop_inst, format!("panic {}", symbol_name)); + } + + codegen_call_with_unwind_action(fx, span, CallTarget::Direct(func_ref), unwind, &args, None); fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } diff --git a/src/common.rs b/src/common.rs index 80b1f0881347..6596b27fb1ff 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,5 +1,5 @@ use cranelift_codegen::isa::TargetFrontendConfig; -use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use rustc_abi::{Float, Integer, Primitive}; use rustc_index::IndexVec; use rustc_middle::ty::TypeFoldable; @@ -288,6 +288,9 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { /// When `#[track_caller]` is used, the implicit caller location is stored in this variable. pub(crate) caller_location: Option>, + /// During cleanup the exception pointer will be stored in this variable. + pub(crate) exception_slot: Variable, + pub(crate) clif_comments: crate::pretty_clif::CommentWriter, /// This should only be accessed by `CPlace::new_var`. diff --git a/src/debuginfo/gcc_except_table.rs b/src/debuginfo/gcc_except_table.rs new file mode 100644 index 000000000000..b8e602c76a8c --- /dev/null +++ b/src/debuginfo/gcc_except_table.rs @@ -0,0 +1,272 @@ +use gimli::write::{Address, Writer}; +use gimli::{DW_EH_PE_omit, DW_EH_PE_uleb128, Encoding, LittleEndian}; + +pub(super) struct GccExceptTable { + pub call_sites: CallSiteTable, + pub actions: ActionTable, + pub type_info: TypeInfoTable, +} + +impl GccExceptTable { + pub(super) fn write( + &self, + w: &mut W, + encoding: Encoding, + ) -> gimli::write::Result<()> { + // lpStartEncoding + w.write_u8(DW_EH_PE_omit.0)?; + // lpStart (omitted) + let type_info_padding = if self.type_info.type_info.is_empty() { + // ttypeEncoding + w.write_u8(DW_EH_PE_omit.0)?; + None + } else { + // ttypeEncoding + w.write_u8(self.type_info.ttype_encoding.0)?; + + // classInfoOffset + let class_info_offset_field_offset = w.len() as u64; + + // Note: The offset in classInfoOffset is relative to position right after classInfoOffset + // itself. + let class_info_offset_no_padding = self.call_sites.encoded_size() + + self.actions.encoded_size() + + self.type_info.encoded_size(encoding); + + let type_info_is_aligned = |type_info_padding: u64| { + (class_info_offset_field_offset + + gimli::leb128::write::uleb128_size( + class_info_offset_no_padding + type_info_padding, + ) as u64 + + self.call_sites.encoded_size() + + self.actions.encoded_size() + + type_info_padding) + % 4 + == 0 + }; + + let mut type_info_padding = 0; + while !type_info_is_aligned(type_info_padding) { + type_info_padding += 1; + } + + w.write_uleb128(class_info_offset_no_padding + type_info_padding)?; + + Some(type_info_padding) + }; + + // call site table + self.call_sites.write(w)?; + + // action table + self.actions.write(w)?; + + // align to 4 bytes + if let Some(type_info_padding) = type_info_padding { + for _ in 0..type_info_padding { + w.write_u8(0)?; + } + // In this case we calculated the expected padding amount and used it to write the + // classInfoOffset field. Assert that the expected value matched the actual value to catch + // any inconsistency. + assert!(w.len() % 4 == 0, "type_info must be aligned to 4 bytes"); + } else { + while w.len() % 4 != 0 { + w.write_u8(0)?; + } + } + + // type_info + self.type_info.write(w, encoding)?; + + // exception specs (unused for rust) + + // align to 4 bytes + while w.len() % 4 != 0 { + w.write_u8(0)?; + } + + Ok(()) + } +} + +pub(super) struct CallSiteTable(pub Vec); + +impl CallSiteTable { + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + let callsite_table_length = self.0.iter().map(|call_site| call_site.encoded_size()).sum(); + + // callsiteEncoding + w.write_u8(DW_EH_PE_uleb128.0)?; + // callsiteTableLength + w.write_uleb128(callsite_table_length)?; + + for call_site in &self.0 { + call_site.write(w)?; + } + + Ok(()) + } +} + +pub(super) struct CallSite { + pub start: u64, + pub length: u64, + pub landing_pad: u64, + pub action_entry: Option, +} + +impl CallSite { + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + w.write_uleb128(self.start)?; + w.write_uleb128(self.length)?; + w.write_uleb128(self.landing_pad)?; + w.write_uleb128(match self.action_entry { + Some(action_offset) => action_offset.0 + 1, + None => 0, + })?; + Ok(()) + } +} + +pub(super) struct ActionTable { + actions: Vec, + encoded_length: u64, +} + +impl ActionTable { + pub(super) fn new() -> ActionTable { + ActionTable { actions: vec![], encoded_length: 0 } + } + + pub(super) fn add(&mut self, action: Action) -> ActionOffset { + let id = ActionOffset(self.encoded_length); + self.encoded_length += action.encoded_size(self.encoded_length); + self.actions.push(action); + id + } + + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + let action_table_start = w.len() as u64; + for action in &self.actions { + action.write(w, w.len() as u64 - action_table_start)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) struct ActionOffset(u64); + +pub(super) struct Action { + pub(super) kind: ActionKind, + pub(super) next_action: Option, +} + +impl Action { + fn encoded_size(&self, action_table_offset: u64) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len, action_table_offset).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W, action_table_offset: u64) -> gimli::write::Result<()> { + // ttypeIndex + let ttype_index = match self.kind { + ActionKind::Catch(type_info_id) => type_info_id.0 as i64 + 1, + }; + w.write_sleb128(ttype_index)?; + // actionOffset + let action_offset_field_offset = + action_table_offset + gimli::leb128::write::sleb128_size(ttype_index) as u64; + w.write_sleb128(match self.next_action { + Some(next_action_offset) => { + next_action_offset.0 as i64 - action_offset_field_offset as i64 + } + None => 0, + })?; + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) enum ActionKind { + Catch(TypeInfoId), +} + +pub(super) struct TypeInfoTable { + ttype_encoding: gimli::DwEhPe, + type_info: Vec
, +} + +impl TypeInfoTable { + pub(super) fn new(ttype_encoding: gimli::DwEhPe) -> TypeInfoTable { + TypeInfoTable { ttype_encoding, type_info: vec![] } + } + + pub(super) fn add(&mut self, type_info: Address) -> TypeInfoId { + let id = TypeInfoId(self.type_info.len() as u64); + self.type_info.push(type_info); + id + } + + fn encoded_size(&self, encoding: Encoding) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len, encoding).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W, encoding: Encoding) -> gimli::write::Result<()> { + for &type_info in self.type_info.iter().rev() { + w.write_eh_pointer(type_info, self.ttype_encoding, encoding.address_size)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) struct TypeInfoId(u64); + +struct LenWriter(usize); + +impl Writer for LenWriter { + type Endian = LittleEndian; + + fn endian(&self) -> LittleEndian { + LittleEndian + } + + fn len(&self) -> usize { + self.0 + } + + fn write(&mut self, bytes: &[u8]) -> gimli::write::Result<()> { + self.0 += bytes.len(); + Ok(()) + } + + fn write_at(&mut self, offset: usize, bytes: &[u8]) -> gimli::write::Result<()> { + assert!(offset + bytes.len() < self.0); + Ok(()) + } +} diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 286e02b986b3..35f92609982e 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -1,6 +1,7 @@ //! Handling of everything related to debuginfo. mod emit; +mod gcc_except_table; mod line_info; mod object; mod types; @@ -24,7 +25,7 @@ use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::types::TypeDebugContext; -pub(crate) use self::unwind::UnwindContext; +pub(crate) use self::unwind::{EXCEPTION_HANDLER_CATCH, EXCEPTION_HANDLER_CLEANUP, UnwindContext}; use crate::debuginfo::emit::{address_for_data, address_for_func}; use crate::prelude::*; diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 74b82a7139ab..fb93648332b8 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -2,14 +2,21 @@ use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::unwind::UnwindInfo; +use cranelift_module::DataId; use cranelift_object::ObjectProduct; -use gimli::RunTimeEndian; -use gimli::write::{CieId, EhFrame, FrameTable, Section}; +use gimli::write::{Address, CieId, EhFrame, FrameTable, Section}; +use gimli::{Encoding, Format, RunTimeEndian}; -use super::emit::address_for_func; +use super::emit::{DebugRelocName, address_for_data, address_for_func}; +use super::gcc_except_table::{ + Action, ActionKind, ActionTable, CallSite, CallSiteTable, GccExceptTable, TypeInfoTable, +}; use super::object::WriteDebugInfo; use crate::prelude::*; +pub(crate) const EXCEPTION_HANDLER_CLEANUP: u32 = 0; +pub(crate) const EXCEPTION_HANDLER_CATCH: u32 = 1; + pub(crate) struct UnwindContext { endian: RunTimeEndian, frame_table: FrameTable, @@ -28,7 +35,68 @@ impl UnwindContext { if pic_eh_frame { cie.fde_address_encoding = gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0); + cie.lsda_encoding = + Some(gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0)); + } else { + cie.fde_address_encoding = gimli::DW_EH_PE_absptr; + cie.lsda_encoding = Some(gimli::DW_EH_PE_absptr); } + // FIXME use eh_personality lang item instead + let personality = module + .declare_function( + "rust_eh_personality", + Linkage::Import, + &Signature { + params: vec![ + AbiParam::new(types::I32), + AbiParam::new(types::I32), + AbiParam::new(types::I64), + AbiParam::new(module.target_config().pointer_type()), + AbiParam::new(module.target_config().pointer_type()), + ], + returns: vec![AbiParam::new(types::I32)], + call_conv: module.target_config().default_call_conv, + }, + ) + .unwrap(); + + // Use indirection here to support PIC the case where rust_eh_personality is defined in + // another DSO. + let personality_ref = module + .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false) + .unwrap(); + + let mut personality_ref_data = DataDescription::new(); + // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss + // section. + let pointer_bytes = usize::from(module.target_config().pointer_bytes()); + personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice()); + let personality_func_ref = + module.declare_func_in_data(personality, &mut personality_ref_data); + personality_ref_data.write_function_addr(0, personality_func_ref); + + module.define_data(personality_ref, &personality_ref_data).unwrap(); + + cie.personality = Some(( + if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata4.0, + ) + } else if let target_lexicon::Architecture::Aarch64(_) = + module.isa().triple().architecture + { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata8.0, + ) + } else { + todo!() + }, + address_for_data(personality_ref), + )); Some(frame_table.add_cie(cie)) } else { None @@ -63,8 +131,90 @@ impl UnwindContext { match unwind_info { UnwindInfo::SystemV(unwind_info) => { - self.frame_table - .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id))); + let mut fde = unwind_info.to_fde(address_for_func(func_id)); + // FIXME use unique symbol name derived from function name + let lsda = module.declare_anonymous_data(false, false).unwrap(); + + let encoding = Encoding { + format: Format::Dwarf32, + version: 1, + address_size: module.isa().frontend_config().pointer_bytes(), + }; + + let mut gcc_except_table_data = GccExceptTable { + call_sites: CallSiteTable(vec![]), + actions: ActionTable::new(), + type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4), + }; + + let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0)); + let catch_action = gcc_except_table_data + .actions + .add(Action { kind: ActionKind::Catch(catch_type), next_action: None }); + + for call_site in context.compiled_code().unwrap().buffer.call_sites() { + if call_site.exception_handlers.is_empty() { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: 0, + action_entry: None, + }); + } + for &(tag, landingpad) in call_site.exception_handlers { + match tag.expand().unwrap().as_u32() { + EXCEPTION_HANDLER_CLEANUP => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: None, + }) + } + EXCEPTION_HANDLER_CATCH => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: Some(catch_action), + }) + } + _ => unreachable!(), + } + } + } + + let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian); + + gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap(); + + let mut data = DataDescription::new(); + data.define(gcc_except_table.writer.into_vec().into_boxed_slice()); + data.set_segment_section("", ".gcc_except_table"); + + for reloc in &gcc_except_table.relocs { + match reloc.name { + DebugRelocName::Section(_id) => unreachable!(), + DebugRelocName::Symbol(id) => { + let id = id.try_into().unwrap(); + if id & 1 << 31 == 0 { + let func_ref = + module.declare_func_in_data(FuncId::from_u32(id), &mut data); + data.write_function_addr(reloc.offset, func_ref); + } else { + let gv = module.declare_data_in_data( + DataId::from_u32(id & !(1 << 31)), + &mut data, + ); + data.write_data_addr(reloc.offset, gv, 0); + } + } + }; + } + + module.define_data(lsda, &data).unwrap(); + fde.lsda = Some(address_for_data(lsda)); + self.frame_table.add_fde(self.cie_id.unwrap(), fde); } UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => { // Windows does not have debug info for its unwind info. diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 832f24b38bce..5f4956c801be 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -829,6 +829,7 @@ fn call_inline_asm<'tcx>( } let stack_slot_addr = stack_slot.get_addr(fx); + // FIXME use try_call once unwinding inline assembly is supported fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]); for (offset, place) in outputs { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index df5748c34d11..da740cb88e41 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -17,17 +17,19 @@ mod llvm_aarch64; mod llvm_x86; mod simd; -use cranelift_codegen::ir::AtomicRmwOp; +use cranelift_codegen::ir::{AtomicRmwOp, BlockArg, ExceptionTableData, ExceptionTag}; use rustc_middle::ty; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_span::source_map::Spanned; use rustc_span::{Symbol, sym}; +use rustc_target::spec::PanicStrategy; pub(crate) use self::llvm::codegen_llvm_intrinsic_call; use crate::cast::clif_intcast; use crate::codegen_f16_f128; +use crate::debuginfo::EXCEPTION_HANDLER_CATCH; use crate::prelude::*; fn bug_on_incorrect_arg_count(intrinsic: impl std::fmt::Display) -> ! { @@ -1352,23 +1354,73 @@ fn codegen_regular_intrinsic_call<'tcx>( } sym::catch_unwind => { + let ret_block = fx.get_block(destination.unwrap()); + intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic); let f = f.load_scalar(fx); let data = data.load_scalar(fx); - let _catch_fn = catch_fn.load_scalar(fx); + let catch_fn = catch_fn.load_scalar(fx); - // FIXME once unwinding is supported, change this to actually catch panics let f_sig = fx.bcx.func.import_signature(Signature { call_conv: fx.target_config.default_call_conv, params: vec![AbiParam::new(pointer_ty(fx.tcx))], returns: vec![], }); - fx.bcx.ins().call_indirect(f_sig, f, &[data]); + if fx.tcx.sess.panic_strategy() == PanicStrategy::Abort { + fx.bcx.ins().call_indirect(f_sig, f, &[data]); - let layout = fx.layout_of(fx.tcx.types.i32); - let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); - ret.write_cvalue(fx, ret_val); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + + fx.bcx.ins().jump(ret_block, &[]); + } else { + let catch_fn_sig = fx.bcx.func.import_signature(Signature { + call_conv: fx.target_config.default_call_conv, + params: vec![ + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + returns: vec![], + }); + + let fallthrough_block = fx.bcx.create_block(); + let fallthrough_block_call = fx.bcx.func.dfg.block_call(fallthrough_block, &[]); + let catch_block = fx.bcx.create_block(); + let catch_block_call = + fx.bcx.func.dfg.block_call(catch_block, &[BlockArg::TryCallExn(0)]); + let exception_table = + fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( + f_sig, + fallthrough_block_call, + [( + Some(ExceptionTag::with_number(EXCEPTION_HANDLER_CATCH).unwrap()), + catch_block_call, + )], + )); + + fx.bcx.ins().try_call_indirect(f, &[data], exception_table); + + fx.bcx.seal_block(fallthrough_block); + fx.bcx.switch_to_block(fallthrough_block); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + + fx.bcx.seal_block(catch_block); + fx.bcx.switch_to_block(catch_block); + fx.bcx.set_cold_block(catch_block); + let exception = fx.bcx.append_block_param(catch_block, pointer_ty(fx.tcx)); + fx.bcx.ins().call_indirect(catch_fn_sig, catch_fn, &[data, exception]); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 1), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + } + + return Ok(()); } sym::fadd_fast From 0c7e953885ad3754538f0fce150ecf5247878e82 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 7 May 2025 13:08:21 +0000 Subject: [PATCH 014/525] Fix panic=unwind for JIT --- src/debuginfo/unwind.rs | 58 +++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index fb93648332b8..940075e250e0 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -32,15 +32,36 @@ impl UnwindContext { let mut frame_table = FrameTable::default(); let cie_id = if let Some(mut cie) = module.isa().create_systemv_cie() { - if pic_eh_frame { - cie.fde_address_encoding = - gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0); - cie.lsda_encoding = - Some(gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0)); + let ptr_encoding = if pic_eh_frame { + gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0) } else { - cie.fde_address_encoding = gimli::DW_EH_PE_absptr; - cie.lsda_encoding = Some(gimli::DW_EH_PE_absptr); - } + gimli::DW_EH_PE_absptr + }; + let code_ptr_encoding = if pic_eh_frame { + if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata4.0, + ) + } else if let target_lexicon::Architecture::Aarch64(_) = + module.isa().triple().architecture + { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata8.0, + ) + } else { + todo!() + } + } else { + gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0) + }; + + cie.fde_address_encoding = ptr_encoding; + cie.lsda_encoding = Some(ptr_encoding); + // FIXME use eh_personality lang item instead let personality = module .declare_function( @@ -77,26 +98,7 @@ impl UnwindContext { module.define_data(personality_ref, &personality_ref_data).unwrap(); - cie.personality = Some(( - if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { - gimli::DwEhPe( - gimli::DW_EH_PE_indirect.0 - | gimli::DW_EH_PE_pcrel.0 - | gimli::DW_EH_PE_sdata4.0, - ) - } else if let target_lexicon::Architecture::Aarch64(_) = - module.isa().triple().architecture - { - gimli::DwEhPe( - gimli::DW_EH_PE_indirect.0 - | gimli::DW_EH_PE_pcrel.0 - | gimli::DW_EH_PE_sdata8.0, - ) - } else { - todo!() - }, - address_for_data(personality_ref), - )); + cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref))); Some(frame_table.add_cie(cie)) } else { None From e0ea4b016a8137f7953ee4f2ec765eec78574c94 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 7 May 2025 13:34:29 +0000 Subject: [PATCH 015/525] Put unwinding support behind a cargo feature --- Cargo.toml | 1 + build_system/abi_cafe.rs | 2 + build_system/build_backend.rs | 5 + build_system/build_sysroot.rs | 17 ++- build_system/main.rs | 7 + build_system/tests.rs | 21 ++- build_system/usage.txt | 4 + scripts/cargo-clif.rs | 6 +- scripts/rustc-clif.rs | 6 +- scripts/rustdoc-clif.rs | 6 +- src/abi/mod.rs | 7 +- src/base.rs | 20 ++- src/debuginfo/unwind.rs | 275 ++++++++++++++++++---------------- src/intrinsics/mod.rs | 4 +- 14 files changed, 231 insertions(+), 150 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9066e4dbbb52..51bb5d9db0ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ smallvec = "1.8.1" unstable-features = ["jit", "inline_asm_sym"] jit = ["cranelift-jit", "libloading"] inline_asm_sym = [] +unwinding = [] # Not yet included in unstable-features for performance reasons [package.metadata.rust-analyzer] rustc_private = true diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 43025137bc6b..5a393a217c27 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -19,6 +19,7 @@ pub(crate) fn run( cg_clif_dylib: &CodegenBackend, rustup_toolchain_name: Option<&str>, bootstrap_host_compiler: &Compiler, + panic_unwind_support: bool, ) { std::fs::create_dir_all(&dirs.download_dir).unwrap(); ABI_CAFE_REPO.fetch(dirs); @@ -32,6 +33,7 @@ pub(crate) fn run( bootstrap_host_compiler, rustup_toolchain_name, bootstrap_host_compiler.triple.clone(), + panic_unwind_support, ); eprintln!("Running abi-cafe"); diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index bf7cf1c0a346..a1f19a1afd09 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -12,6 +12,7 @@ pub(crate) fn build_backend( dirs: &Dirs, bootstrap_host_compiler: &Compiler, use_unstable_features: bool, + panic_unwind_support: bool, ) -> PathBuf { let _group = LogGroup::guard("Build backend"); @@ -31,6 +32,10 @@ pub(crate) fn build_backend( cmd.arg("--features").arg("unstable-features"); } + if panic_unwind_support { + cmd.arg("--features").arg("unwinding"); + } + cmd.arg("--release"); eprintln!("[BUILD] rustc_codegen_cranelift"); diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 00955998e703..fec6ff241550 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -17,6 +17,7 @@ pub(crate) fn build_sysroot( bootstrap_host_compiler: &Compiler, rustup_toolchain_name: Option<&str>, target_triple: String, + panic_unwind_support: bool, ) -> Compiler { let _guard = LogGroup::guard("Build sysroot"); @@ -52,6 +53,9 @@ pub(crate) fn build_sysroot( .arg("-o") .arg(&wrapper_path) .arg("-Cstrip=debuginfo"); + if panic_unwind_support { + build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind"); + } if let Some(rustup_toolchain_name) = &rustup_toolchain_name { build_cargo_wrapper_cmd .env("TOOLCHAIN_NAME", rustup_toolchain_name) @@ -77,6 +81,7 @@ pub(crate) fn build_sysroot( bootstrap_host_compiler.clone(), &cg_clif_dylib_path, sysroot_kind, + panic_unwind_support, ); host.install_into_sysroot(dist_dir); @@ -91,6 +96,7 @@ pub(crate) fn build_sysroot( }, &cg_clif_dylib_path, sysroot_kind, + panic_unwind_support, ) .install_into_sysroot(dist_dir); } @@ -141,12 +147,15 @@ fn build_sysroot_for_triple( compiler: Compiler, cg_clif_dylib_path: &CodegenBackend, sysroot_kind: SysrootKind, + panic_unwind_support: bool, ) -> SysrootTarget { match sysroot_kind { SysrootKind::None => build_rtstartup(dirs, &compiler) .unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }), SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler), - SysrootKind::Clif => build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path), + SysrootKind::Clif => { + build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support) + } } } @@ -188,6 +197,7 @@ fn build_clif_sysroot_for_triple( dirs: &Dirs, mut compiler: Compiler, cg_clif_dylib_path: &CodegenBackend, + panic_unwind_support: bool, ) -> SysrootTarget { let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] }; @@ -206,7 +216,10 @@ fn build_clif_sysroot_for_triple( } // Build sysroot - let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()]; + let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned()]; + if !panic_unwind_support { + rustflags.push("-Cpanic=abort".to_owned()); + } match cg_clif_dylib_path { CodegenBackend::Local(path) => { rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap())); diff --git a/build_system/main.rs b/build_system/main.rs index 3ff9751a3ef2..fc0093128300 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -83,6 +83,7 @@ fn main() { let mut download_dir = None; let mut sysroot_kind = SysrootKind::Clif; let mut use_unstable_features = true; + let mut panic_unwind_support = false; let mut frozen = false; let mut skip_tests = vec![]; let mut use_backend = None; @@ -108,6 +109,7 @@ fn main() { } } "--no-unstable-features" => use_unstable_features = false, + "--panic-unwind-support" => panic_unwind_support = true, "--frozen" => frozen = true, "--skip-test" => { // FIXME check that all passed in tests actually exist @@ -201,6 +203,7 @@ fn main() { &dirs, &bootstrap_host_compiler, use_unstable_features, + panic_unwind_support, )) }; match command { @@ -212,6 +215,7 @@ fn main() { &dirs, sysroot_kind, use_unstable_features, + panic_unwind_support, &skip_tests.iter().map(|test| &**test).collect::>(), &cg_clif_dylib, &bootstrap_host_compiler, @@ -230,6 +234,7 @@ fn main() { &cg_clif_dylib, rustup_toolchain_name.as_deref(), &bootstrap_host_compiler, + panic_unwind_support, ); } Command::Build => { @@ -240,6 +245,7 @@ fn main() { &bootstrap_host_compiler, rustup_toolchain_name.as_deref(), target_triple, + panic_unwind_support, ); } Command::Bench => { @@ -250,6 +256,7 @@ fn main() { &bootstrap_host_compiler, rustup_toolchain_name.as_deref(), target_triple, + panic_unwind_support, ); bench::benchmark(&dirs, &compiler); } diff --git a/build_system/tests.rs b/build_system/tests.rs index eec89c026b26..8cd84a79f9f7 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -233,6 +233,7 @@ pub(crate) fn run_tests( dirs: &Dirs, sysroot_kind: SysrootKind, use_unstable_features: bool, + panic_unwind_support: bool, skip_tests: &[&str], cg_clif_dylib: &CodegenBackend, bootstrap_host_compiler: &Compiler, @@ -251,12 +252,14 @@ pub(crate) fn run_tests( bootstrap_host_compiler, rustup_toolchain_name, target_triple.clone(), + panic_unwind_support, ); let runner = TestRunner::new( dirs.clone(), target_compiler, use_unstable_features, + panic_unwind_support, skip_tests, bootstrap_host_compiler.triple == target_triple, stdlib_source.clone(), @@ -283,12 +286,14 @@ pub(crate) fn run_tests( bootstrap_host_compiler, rustup_toolchain_name, target_triple.clone(), + panic_unwind_support, ); let mut runner = TestRunner::new( dirs.clone(), target_compiler, use_unstable_features, + panic_unwind_support, skip_tests, bootstrap_host_compiler.triple == target_triple, stdlib_source, @@ -314,6 +319,7 @@ pub(crate) fn run_tests( struct TestRunner<'a> { is_native: bool, jit_supported: bool, + panic_unwind_support: bool, skip_tests: &'a [&'a str], dirs: Dirs, target_compiler: Compiler, @@ -325,6 +331,7 @@ impl<'a> TestRunner<'a> { dirs: Dirs, mut target_compiler: Compiler, use_unstable_features: bool, + panic_unwind_support: bool, skip_tests: &'a [&'a str], is_native: bool, stdlib_source: PathBuf, @@ -335,7 +342,15 @@ impl<'a> TestRunner<'a> { let jit_supported = use_unstable_features && is_native && !target_compiler.triple.contains("windows"); - Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source } + Self { + is_native, + jit_supported, + panic_unwind_support, + skip_tests, + dirs, + target_compiler, + stdlib_source, + } } fn run_testsuite(&self, tests: &[TestCase]) { @@ -404,7 +419,9 @@ impl<'a> TestRunner<'a> { cmd.arg("-Cdebuginfo=2"); cmd.arg("--target"); cmd.arg(&self.target_compiler.triple); - cmd.arg("-Cpanic=abort"); + if !self.panic_unwind_support { + cmd.arg("-Cpanic=abort"); + } cmd.arg("--check-cfg=cfg(jit)"); cmd.args(args); cmd diff --git a/build_system/usage.txt b/build_system/usage.txt index 5c333fe2db59..6c98087e5239 100644 --- a/build_system/usage.txt +++ b/build_system/usage.txt @@ -25,6 +25,10 @@ OPTIONS: Some features are not yet ready for production usage. This option will disable these features. This includes the JIT mode and inline assembly support. + --panic-unwind-support + Enable support for unwinding when -Cpanic=unwind is used. This currently regresses build + performance. + --frozen Require Cargo.lock and cache are up to date diff --git a/scripts/cargo-clif.rs b/scripts/cargo-clif.rs index e6c63bf5e650..e391cc7f75a9 100644 --- a/scripts/cargo-clif.rs +++ b/scripts/cargo-clif.rs @@ -12,7 +12,11 @@ fn main() { sysroot = sysroot.parent().unwrap(); } - let mut rustflags = vec!["-Cpanic=abort".to_owned(), "-Zpanic-abort-tests".to_owned()]; + let mut rustflags = vec![]; + if !cfg!(support_panic_unwind) { + rustflags.push("-Cpanic=abort".to_owned()); + rustflags.push("-Zpanic-abort-tests".to_owned()); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { rustflags.push(format!("-Zcodegen-backend={name}")); } else { diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs index 528031af82a8..15d929d0f5a5 100644 --- a/scripts/rustc-clif.rs +++ b/scripts/rustc-clif.rs @@ -17,8 +17,10 @@ fn main() { let passed_args = std::env::args_os().skip(1).collect::>(); let mut args = vec![]; - args.push(OsString::from("-Cpanic=abort")); - args.push(OsString::from("-Zpanic-abort-tests")); + if !cfg!(support_panic_unwind) { + args.push(OsString::from("-Cpanic=abort")); + args.push(OsString::from("-Zpanic-abort-tests")); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { args.push(OsString::from(format!("-Zcodegen-backend={name}"))) } else { diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index 6ebe060d8bbd..dc5bef18cda8 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -17,8 +17,10 @@ fn main() { let passed_args = std::env::args_os().skip(1).collect::>(); let mut args = vec![]; - args.push(OsString::from("-Cpanic=abort")); - args.push(OsString::from("-Zpanic-abort-tests")); + if !cfg!(support_panic_unwind) { + args.push(OsString::from("-Cpanic=abort")); + args.push(OsString::from("-Zpanic-abort-tests")); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { args.push(OsString::from(format!("-Zcodegen-backend={name}"))) } else { diff --git a/src/abi/mod.rs b/src/abi/mod.rs index fea4e73b18e3..23fe0c32895d 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -844,7 +844,7 @@ pub(crate) fn codegen_call_with_unwind_action( fx: &mut FunctionCx<'_, '_, '_>, span: Span, func_ref: CallTarget, - unwind: UnwindAction, + mut unwind: UnwindAction, call_args: &[Value], target_block: Option, ) -> SmallVec<[Value; 2]> { @@ -856,6 +856,11 @@ pub(crate) fn codegen_call_with_unwind_action( if target_block.is_some() { assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty()); } + + if cfg!(not(feature = "unwinding")) { + unwind = UnwindAction::Unreachable; + } + match unwind { UnwindAction::Continue | UnwindAction::Unreachable => { let call_inst = match func_ref { diff --git a/src/base.rs b/src/base.rs index ddc1013c25ad..9a5a575f79e3 100644 --- a/src/base.rs +++ b/src/base.rs @@ -308,6 +308,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } if bb_data.is_cleanup { + if cfg!(not(feature = "unwinding")) { + continue; + } + fx.bcx.set_cold_block(block); } @@ -542,13 +546,15 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { codegen_unwind_terminate(fx, source_info.span, *reason); } TerminatorKind::UnwindResume => { - let exception_ptr = fx.bcx.use_var(fx.exception_slot); - fx.lib_call( - "_Unwind_Resume", - vec![AbiParam::new(fx.pointer_type)], - vec![], - &[exception_ptr], - ); + if cfg!(feature = "unwinding") { + let exception_ptr = fx.bcx.use_var(fx.exception_slot); + fx.lib_call( + "_Unwind_Resume", + vec![AbiParam::new(fx.pointer_type)], + vec![], + &[exception_ptr], + ); + } fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } TerminatorKind::Unreachable => { diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 940075e250e0..ff114811975e 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -37,68 +37,74 @@ impl UnwindContext { } else { gimli::DW_EH_PE_absptr }; - let code_ptr_encoding = if pic_eh_frame { - if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { - gimli::DwEhPe( - gimli::DW_EH_PE_indirect.0 - | gimli::DW_EH_PE_pcrel.0 - | gimli::DW_EH_PE_sdata4.0, - ) - } else if let target_lexicon::Architecture::Aarch64(_) = - module.isa().triple().architecture - { - gimli::DwEhPe( - gimli::DW_EH_PE_indirect.0 - | gimli::DW_EH_PE_pcrel.0 - | gimli::DW_EH_PE_sdata8.0, - ) - } else { - todo!() - } - } else { - gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0) - }; cie.fde_address_encoding = ptr_encoding; - cie.lsda_encoding = Some(ptr_encoding); - // FIXME use eh_personality lang item instead - let personality = module - .declare_function( - "rust_eh_personality", - Linkage::Import, - &Signature { - params: vec![ - AbiParam::new(types::I32), - AbiParam::new(types::I32), - AbiParam::new(types::I64), - AbiParam::new(module.target_config().pointer_type()), - AbiParam::new(module.target_config().pointer_type()), - ], - returns: vec![AbiParam::new(types::I32)], - call_conv: module.target_config().default_call_conv, - }, - ) - .unwrap(); + // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204 + if cfg!(feature = "unwinding") { + let code_ptr_encoding = if pic_eh_frame { + if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata4.0, + ) + } else if let target_lexicon::Architecture::Aarch64(_) = + module.isa().triple().architecture + { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata8.0, + ) + } else { + todo!() + } + } else { + gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0) + }; - // Use indirection here to support PIC the case where rust_eh_personality is defined in - // another DSO. - let personality_ref = module - .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false) - .unwrap(); + cie.lsda_encoding = Some(ptr_encoding); - let mut personality_ref_data = DataDescription::new(); - // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss - // section. - let pointer_bytes = usize::from(module.target_config().pointer_bytes()); - personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice()); - let personality_func_ref = - module.declare_func_in_data(personality, &mut personality_ref_data); - personality_ref_data.write_function_addr(0, personality_func_ref); + // FIXME use eh_personality lang item instead + let personality = module + .declare_function( + "rust_eh_personality", + Linkage::Import, + &Signature { + params: vec![ + AbiParam::new(types::I32), + AbiParam::new(types::I32), + AbiParam::new(types::I64), + AbiParam::new(module.target_config().pointer_type()), + AbiParam::new(module.target_config().pointer_type()), + ], + returns: vec![AbiParam::new(types::I32)], + call_conv: module.target_config().default_call_conv, + }, + ) + .unwrap(); - module.define_data(personality_ref, &personality_ref_data).unwrap(); + // Use indirection here to support PIC the case where rust_eh_personality is defined in + // another DSO. + let personality_ref = module + .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false) + .unwrap(); + + let mut personality_ref_data = DataDescription::new(); + // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss + // section. + let pointer_bytes = usize::from(module.target_config().pointer_bytes()); + personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice()); + let personality_func_ref = + module.declare_func_in_data(personality, &mut personality_ref_data); + personality_ref_data.write_function_addr(0, personality_func_ref); + + module.define_data(personality_ref, &personality_ref_data).unwrap(); + + cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref))); + } - cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref))); Some(frame_table.add_cie(cie)) } else { None @@ -134,88 +140,93 @@ impl UnwindContext { match unwind_info { UnwindInfo::SystemV(unwind_info) => { let mut fde = unwind_info.to_fde(address_for_func(func_id)); - // FIXME use unique symbol name derived from function name - let lsda = module.declare_anonymous_data(false, false).unwrap(); - let encoding = Encoding { - format: Format::Dwarf32, - version: 1, - address_size: module.isa().frontend_config().pointer_bytes(), - }; + // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204 + if cfg!(feature = "unwinding") { + // FIXME use unique symbol name derived from function name + let lsda = module.declare_anonymous_data(false, false).unwrap(); - let mut gcc_except_table_data = GccExceptTable { - call_sites: CallSiteTable(vec![]), - actions: ActionTable::new(), - type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4), - }; - - let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0)); - let catch_action = gcc_except_table_data - .actions - .add(Action { kind: ActionKind::Catch(catch_type), next_action: None }); - - for call_site in context.compiled_code().unwrap().buffer.call_sites() { - if call_site.exception_handlers.is_empty() { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: 0, - action_entry: None, - }); - } - for &(tag, landingpad) in call_site.exception_handlers { - match tag.expand().unwrap().as_u32() { - EXCEPTION_HANDLER_CLEANUP => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: None, - }) - } - EXCEPTION_HANDLER_CATCH => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: Some(catch_action), - }) - } - _ => unreachable!(), - } - } - } - - let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian); - - gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap(); - - let mut data = DataDescription::new(); - data.define(gcc_except_table.writer.into_vec().into_boxed_slice()); - data.set_segment_section("", ".gcc_except_table"); - - for reloc in &gcc_except_table.relocs { - match reloc.name { - DebugRelocName::Section(_id) => unreachable!(), - DebugRelocName::Symbol(id) => { - let id = id.try_into().unwrap(); - if id & 1 << 31 == 0 { - let func_ref = - module.declare_func_in_data(FuncId::from_u32(id), &mut data); - data.write_function_addr(reloc.offset, func_ref); - } else { - let gv = module.declare_data_in_data( - DataId::from_u32(id & !(1 << 31)), - &mut data, - ); - data.write_data_addr(reloc.offset, gv, 0); - } - } + let encoding = Encoding { + format: Format::Dwarf32, + version: 1, + address_size: module.isa().frontend_config().pointer_bytes(), }; + + let mut gcc_except_table_data = GccExceptTable { + call_sites: CallSiteTable(vec![]), + actions: ActionTable::new(), + type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4), + }; + + let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0)); + let catch_action = gcc_except_table_data + .actions + .add(Action { kind: ActionKind::Catch(catch_type), next_action: None }); + + for call_site in context.compiled_code().unwrap().buffer.call_sites() { + if call_site.exception_handlers.is_empty() { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: 0, + action_entry: None, + }); + } + for &(tag, landingpad) in call_site.exception_handlers { + match tag.expand().unwrap().as_u32() { + EXCEPTION_HANDLER_CLEANUP => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: None, + }) + } + EXCEPTION_HANDLER_CATCH => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: Some(catch_action), + }) + } + _ => unreachable!(), + } + } + } + + let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian); + + gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap(); + + let mut data = DataDescription::new(); + data.define(gcc_except_table.writer.into_vec().into_boxed_slice()); + data.set_segment_section("", ".gcc_except_table"); + + for reloc in &gcc_except_table.relocs { + match reloc.name { + DebugRelocName::Section(_id) => unreachable!(), + DebugRelocName::Symbol(id) => { + let id = id.try_into().unwrap(); + if id & 1 << 31 == 0 { + let func_ref = module + .declare_func_in_data(FuncId::from_u32(id), &mut data); + data.write_function_addr(reloc.offset, func_ref); + } else { + let gv = module.declare_data_in_data( + DataId::from_u32(id & !(1 << 31)), + &mut data, + ); + data.write_data_addr(reloc.offset, gv, 0); + } + } + }; + } + + module.define_data(lsda, &data).unwrap(); + fde.lsda = Some(address_for_data(lsda)); } - module.define_data(lsda, &data).unwrap(); - fde.lsda = Some(address_for_data(lsda)); self.frame_table.add_fde(self.cie_id.unwrap(), fde); } UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index da740cb88e41..1fcd5871476c 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -1367,7 +1367,9 @@ fn codegen_regular_intrinsic_call<'tcx>( returns: vec![], }); - if fx.tcx.sess.panic_strategy() == PanicStrategy::Abort { + if cfg!(not(feature = "unwinding")) + || fx.tcx.sess.panic_strategy() == PanicStrategy::Abort + { fx.bcx.ins().call_indirect(f_sig, f, &[data]); let layout = fx.layout_of(fx.tcx.types.i32); From c02a509168352da21fb065f8d8bc392350730c21 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 26 May 2025 09:51:17 +0000 Subject: [PATCH 016/525] Update readme --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 4d1e4d843ffe..9989cc7e7eaf 100644 --- a/Readme.md +++ b/Readme.md @@ -104,7 +104,7 @@ See [rustc_testing.md](docs/rustc_testing.md). ## Not yet supported * SIMD ([tracked here](https://github.com/rust-lang/rustc_codegen_cranelift/issues/171), `std::simd` fully works, `std::arch` is partially supported) -* Unwinding on panics ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1677), `-Cpanic=abort` is enabled by default) +* Unwinding on panics ([experimental and not supported on Windows and macOS](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1567), `-Cpanic=abort` is enabled by default) ## License From b3eb17c1151f1666f9f36afb603ea75cdc3ac9e0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:59:41 +0000 Subject: [PATCH 017/525] Rustup to rustc 1.90.0-nightly (f26e58023 2025-06-30) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 57b45c7706b1..78dfd8d1f9fc 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-06-26" +channel = "nightly-2025-07-01" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 2eccb7a5f8e08d551c3b09deaa318609f1e3497b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:21:45 +0000 Subject: [PATCH 018/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 7e356b4b462b..f9a3fc85de45 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -34,6 +34,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs # vendor intrinsics rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps +rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr} # exotic linkages rm tests/incremental/hashes/function_interfaces.rs @@ -58,6 +59,7 @@ rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo +rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet # requires LTO rm -r tests/run-make/cdylib From c2d7ac4717d85087caa409f7e786a366c6bbe4e2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:22:44 +0000 Subject: [PATCH 019/525] Revert enabling rustc_private for mini_core_hello_world --- example/mini_core_hello_world.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 246bd3104ec4..66ecc9ec034a 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,13 +1,4 @@ -#![feature( - no_core, - lang_items, - never_type, - linkage, - extern_types, - thread_local, - repr_simd, - rustc_private -)] +#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)] #![no_core] #![allow(dead_code, non_camel_case_types, internal_features)] From c4743bd2b9b2831320e758c9f74a84c32325b24c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:57:02 +0000 Subject: [PATCH 020/525] Move to the 2024 edition --- Cargo.toml | 2 +- src/abi/mod.rs | 4 ++-- src/base.rs | 6 +++--- src/compiler_builtins.rs | 2 +- src/constant.rs | 2 +- src/debuginfo/emit.rs | 2 +- src/debuginfo/unwind.rs | 6 +++--- src/lib.rs | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 51bb5d9db0ea..a1f406df8c25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_cranelift" version = "0.1.0" -edition = "2021" +edition = "2024" [lib] crate-type = ["dylib"] diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 23fe0c32895d..73f1485c90cd 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -268,7 +268,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ // individual function arguments. let tupled_arg_tys = match arg_ty.kind() { - ty::Tuple(ref tys) => tys, + ty::Tuple(tys) => tys, _ => bug!("spread argument isn't a tuple?! but {:?}", arg_ty), }; @@ -491,7 +491,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; let tupled_arguments = match pack_arg.value.layout().ty.kind() { - ty::Tuple(ref tupled_arguments) => tupled_arguments, + ty::Tuple(tupled_arguments) => tupled_arguments, _ => bug!("argument to function with \"rust-call\" ABI is not a tuple"), }; diff --git a/src/base.rs b/src/base.rs index 5f7c49f5d749..72b17623b785 100644 --- a/src/base.rs +++ b/src/base.rs @@ -382,7 +382,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fx.bcx.ins().nop(); match &**msg { - AssertKind::BoundsCheck { ref len, ref index } => { + AssertKind::BoundsCheck { len, index } => { let len = codegen_operand(fx, len).load_scalar(fx); let index = codegen_operand(fx, index).load_scalar(fx); let location = fx.get_caller_location(source_info).load_scalar(fx); @@ -395,7 +395,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { source_info.span, ); } - AssertKind::MisalignedPointerDereference { ref required, ref found } => { + AssertKind::MisalignedPointerDereference { required, found } => { let required = codegen_operand(fx, required).load_scalar(fx); let found = codegen_operand(fx, found).load_scalar(fx); let location = fx.get_caller_location(source_info).load_scalar(fx); @@ -977,7 +977,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: | StatementKind::AscribeUserType(..) => {} StatementKind::Coverage { .. } => unreachable!(), - StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic { + StatementKind::Intrinsic(intrinsic) => match &**intrinsic { // We ignore `assume` intrinsics, they are only useful for optimizations NonDivergingIntrinsic::Assume(_) => {} NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index 6eea19211fa1..d3784f8e56ac 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -18,7 +18,7 @@ macro_rules! builtin_functions { ) => { #[cfg(feature = "jit")] #[allow(improper_ctypes)] - extern "C" { + unsafe extern "C" { $( $(#[$attr])? fn $name($($arg_name: $arg_ty),*) -> $ret_ty; diff --git a/src/constant.rs b/src/constant.rs index ff2c0d577bb4..389c6546aaba 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -576,7 +576,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( { return None; } - StatementKind::Intrinsic(ref intrinsic) => match **intrinsic { + StatementKind::Intrinsic(intrinsic) => match **intrinsic { NonDivergingIntrinsic::CopyNonOverlapping(..) => return None, NonDivergingIntrinsic::Assume(..) => {} }, diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 0f4696b9337e..53b513ded9c4 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -96,7 +96,7 @@ impl WriterRelocate { if jit_module.declarations().get_function_decl(func_id).name.as_deref() == Some("rust_eh_personality") { - extern "C" { + unsafe extern "C" { fn rust_eh_personality() -> !; } rust_eh_personality as *const u8 diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index ff114811975e..02f6b1d39bc2 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -279,7 +279,7 @@ impl UnwindContext { // Everything after this line up to the end of the file is loosely based on // https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs #[cfg(target_os = "macos")] - { + unsafe { // On macOS, `__register_frame` takes a pointer to a single FDE let start = eh_frame.as_ptr(); let end = start.add(eh_frame.len()); @@ -301,12 +301,12 @@ impl UnwindContext { #[cfg(not(target_os = "macos"))] { // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0 - __register_frame(eh_frame.as_ptr()); + unsafe { __register_frame(eh_frame.as_ptr()) }; } } } -extern "C" { +unsafe extern "C" { // libunwind import fn __register_frame(fde: *const u8); } diff --git a/src/lib.rs b/src/lib.rs index 678580a23723..62ba9974f726 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -382,7 +382,7 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { } /// This is the entrypoint for a hot plugged rustc_codegen_cranelift -#[no_mangle] +#[unsafe(no_mangle)] pub fn __rustc_codegen_backend() -> Box { Box::new(CraneliftCodegenBackend { config: None }) } From b87f756d4d5dfa3cdfd3c79d2ac6d1810fe3c948 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:57:27 +0000 Subject: [PATCH 021/525] Fix building std_detect on s390x --- src/inline_asm.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 5f4956c801be..95c249f5af1f 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -51,6 +51,26 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( return; } + if fx.tcx.sess.target.arch == "s390x" + && template.len() == 3 + && template[0] == InlineAsmTemplatePiece::String("stfle 0(".into()) + && let InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ } = + template[1] + && template[2] == InlineAsmTemplatePiece::String(")".into()) + { + // FIXME no inline asm support for s390x yet, but stdarch needs it for feature detection + match destination { + Some(destination) => { + let destination_block = fx.get_block(destination); + fx.bcx.ins().jump(destination_block, &[]); + } + None => { + fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); + } + } + return; + } + let operands = operands .iter() .map(|operand| match *operand { From ef78e985fbf350d1df42eadb3fc9a03155a4eb9e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Jun 2025 02:01:38 +0000 Subject: [PATCH 022/525] Remove support for dyn* --- src/abi/mod.rs | 45 ------------------------------------------ src/base.rs | 8 -------- src/unsize.rs | 33 ------------------------------- src/value_and_place.rs | 37 ---------------------------------- src/vtable.rs | 40 +++++++++++++------------------------ 5 files changed, 14 insertions(+), 149 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 4c6fd9078154..8965e4a944d4 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -753,51 +753,6 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]); fx.bcx.ins().jump(ret_block, &[]); } - ty::Dynamic(_, _, ty::DynStar) => { - // IN THIS ARM, WE HAVE: - // ty = *mut (dyn* Trait) - // which is: *mut exists (T, Vtable) - // - // args = [ * ] - // | - // v - // ( Data, Vtable ) - // | - // v - // /-------\ - // | ... | - // \-------/ - // - // - // WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING - // - // data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer) - // vtable = (*args[0]).1 // loads the vtable out - // (data, vtable) // an equivalent Rust `*mut dyn Trait` - // - // SO THEN WE CAN USE THE ABOVE CODE. - 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::InstanceKind::Virtual(drop_instance.def_id(), 0), - args: drop_instance.args, - }; - let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) - .fn_abi_of_instance(virtual_drop, ty::List::empty()); - - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); - let sig = fx.bcx.import_signature(sig); - fx.bcx.ins().call_indirect(sig, drop_fn, &[data]); - // FIXME implement cleanup on exceptions - fx.bcx.ins().jump(ret_block, &[]); - } _ => { assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); diff --git a/src/base.rs b/src/base.rs index 1b68c6535da5..bc0a0f034b23 100644 --- a/src/base.rs +++ b/src/base.rs @@ -790,14 +790,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::DynStar, _), - ref operand, - _, - ) => { - let operand = codegen_operand(fx, operand); - crate::unsize::coerce_dyn_star(fx, operand, lval); - } Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => { let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); diff --git a/src/unsize.rs b/src/unsize.rs index df60b05c4636..2aee0b2e9742 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -112,21 +112,6 @@ fn unsize_ptr<'tcx>( } } -/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type. -pub(crate) fn cast_to_dyn_star<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - src: Value, - src_ty_and_layout: TyAndLayout<'tcx>, - dst_ty: Ty<'tcx>, - old_info: Option, -) -> (Value, Value) { - assert!( - matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)), - "destination type must be a dyn*" - ); - (src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info)) -} - /// Coerce `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty` and store the result in `dst` pub(crate) fn coerce_unsized_into<'tcx>( @@ -174,24 +159,6 @@ pub(crate) fn coerce_unsized_into<'tcx>( } } -pub(crate) fn coerce_dyn_star<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - src: CValue<'tcx>, - dst: CPlace<'tcx>, -) { - let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() { - let (data, vtable) = src.load_scalar_pair(fx); - (data, Some(vtable)) - } else { - let data = src.load_scalar(fx); - (data, None) - }; - - let (data, vtable) = cast_to_dyn_star(fx, data, src.layout(), dst.layout().ty, extra); - - dst.write_cvalue(fx, CValue::by_val_pair(data, vtable, dst.layout())); -} - // Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs pub(crate) fn size_and_align_of<'tcx>( diff --git a/src/value_and_place.rs b/src/value_and_place.rs index cbfb215a892a..9d73f200afe2 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -121,43 +121,6 @@ impl<'tcx> CValue<'tcx> { } } - // FIXME remove - /// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the - /// vtable pointer. - pub(crate) fn dyn_star_force_data_on_stack( - self, - fx: &mut FunctionCx<'_, '_, 'tcx>, - ) -> (Value, Value) { - assert!(self.1.ty.is_dyn_star()); - - match self.0 { - CValueInner::ByRef(ptr, None) => { - let (a_scalar, b_scalar) = match self.1.backend_repr { - BackendRepr::ScalarPair(a, b) => (a, b), - _ => unreachable!("dyn_star_force_data_on_stack({:?})", self), - }; - let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); - let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar); - let mut flags = MemFlags::new(); - flags.set_notrap(); - let vtable = ptr.offset(fx, b_offset).load(fx, clif_ty2, flags); - (ptr.get_addr(fx), vtable) - } - CValueInner::ByValPair(data, vtable) => { - let data_ptr = fx.create_stack_slot( - u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(), - u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(), - ); - data_ptr.store(fx, data, MemFlags::trusted()); - - (data_ptr.get_addr(fx), vtable) - } - CValueInner::ByRef(_, Some(_)) | CValueInner::ByVal(_) => { - unreachable!("dyn_star_force_data_on_stack({:?})", self) - } - } - } - pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option)> { match self.0 { CValueInner::ByRef(ptr, meta) => Some((ptr, meta)), diff --git a/src/vtable.rs b/src/vtable.rs index 1fae56949bc0..423cc8d225be 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -46,34 +46,22 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( mut arg: CValue<'tcx>, idx: usize, ) -> (Pointer, Value) { - let (ptr, vtable) = 'block: { - if let BackendRepr::Scalar(_) = arg.layout().backend_repr { - while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() { - let (idx, _) = arg - .layout() - .non_1zst_field(fx) - .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); - arg = arg.value_field(fx, idx); - } + if let BackendRepr::Scalar(_) = arg.layout().backend_repr { + while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() { + let (idx, _) = arg + .layout() + .non_1zst_field(fx) + .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); + arg = arg.value_field(fx, idx); } + } - if let ty::Ref(_, ty, _) = arg.layout().ty.kind() { - if ty.is_dyn_star() { - let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap()); - let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); - let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr(); - let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx); - break 'block (ptr, vtable); - } - } - - if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr { - let (ptr, vtable) = arg.load_scalar_pair(fx); - (Pointer::new(ptr), vtable) - } else { - let (ptr, vtable) = arg.try_to_ptr().unwrap(); - (ptr, vtable.unwrap()) - } + let (ptr, vtable) = if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr { + let (ptr, vtable) = arg.load_scalar_pair(fx); + (Pointer::new(ptr), vtable) + } else { + let (ptr, vtable) = arg.try_to_ptr().unwrap(); + (ptr, vtable.unwrap()) }; let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes(); From 2f9af6b67401f5664e6c4033c9a9bc3f77bdea4c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:10:48 +0000 Subject: [PATCH 023/525] Rustup to rustc 1.90.0-nightly (71e4c005c 2025-07-01) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 78dfd8d1f9fc..2c6ecd32c7c8 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-01" +channel = "nightly-2025-07-02" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From a0c1a29f58acd1cb2cab3526a2ae924fddc2eada Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:55:34 +0000 Subject: [PATCH 024/525] Rustup to rustc 1.90.0-nightly (667787527 2025-07-02) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 2c6ecd32c7c8..56d1bda88ca6 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-02" +channel = "nightly-2025-07-03" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 588c630b79c9446ee0145eb7cd33408032f7a950 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:15:26 +0000 Subject: [PATCH 025/525] Escape { and } before passing to global_asm!() --- src/global_asm.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/global_asm.rs b/src/global_asm.rs index db40d84be0aa..cbb4c3131b2c 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -202,6 +202,9 @@ pub(crate) fn compile_global_asm( return Err(format!("Failed to assemble `{}`", global_asm)); } } else { + // Escape { and } + let global_asm = global_asm.replace('{', "{{").replace('}', "}}"); + let mut child = Command::new(std::env::current_exe().unwrap()) // Avoid a warning about the jobserver fd not being passed .env_remove("CARGO_MAKEFLAGS") From 868d953b7a13bbc1ebf1635ff6c5fddaed441050 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 3 Jul 2025 10:16:13 +0000 Subject: [PATCH 026/525] Avoid q modifier for user references to arm64 vector registers It should only be necessary for the clobber save/restore sequences. --- src/inline_asm.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 95c249f5af1f..eec8b08a1bcd 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -568,20 +568,6 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier) .unwrap(), }, - InlineAsmArch::AArch64 => match reg { - InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => { - // rustc emits v0 rather than q0 - reg.emit( - &mut generated_asm, - InlineAsmArch::AArch64, - Some(modifier.unwrap_or('q')), - ) - .unwrap() - } - _ => reg - .emit(&mut generated_asm, InlineAsmArch::AArch64, *modifier) - .unwrap(), - }, _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(), } } From de58bdc3db9ca033adafcf9c798e227ffd0f8559 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 3 Jul 2025 09:17:48 -0700 Subject: [PATCH 027/525] Make __rust_alloc_error_handler_should_panic a function --- src/allocator.rs | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index ffb932a3c38e..04f1129d87c1 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -84,19 +84,34 @@ fn codegen_inner( &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), ); - let data_id = module - .declare_data( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - false, - false, - ) - .unwrap(); - let mut data = DataDescription::new(); - data.set_align(1); - let val = oom_strategy.should_panic(); - data.define(Box::new([val])); - module.define_data(data_id, &data).unwrap(); + { + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: vec![], + returns: vec![AbiParam::new(types::I8)], + }; + let func_id = module + .declare_function( + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + Linkage::Export, + &sig, + ) + .unwrap(); + let mut ctx = Context::new(); + ctx.func.signature = sig; + { + let mut func_ctx = FunctionBuilderContext::new(); + let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + + let block = bcx.create_block(); + bcx.switch_to_block(block); + let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64); + bcx.ins().return_(&[value]); + bcx.seal_all_blocks(); + bcx.finalize(); + } + module.define_function(func_id, &mut ctx).unwrap(); + } { let sig = Signature { From d24852f515c98fb39b2fda3b52968400d27c55c7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:19:57 +0000 Subject: [PATCH 028/525] Migrate all tests to the 2024 edition --- .vscode/settings.json | 6 +-- build_system/tests.rs | 11 +--- example/example.rs | 16 +++--- example/mini_core.rs | 22 ++++---- example/mini_core_hello_world.rs | 91 +++++++++++++++++--------------- 5 files changed, 76 insertions(+), 70 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 68bd93aea890..2a3ec5e1c905 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,13 +20,13 @@ "crates": [ { "root_module": "./example/mini_core.rs", - "edition": "2015", + "edition": "2024", "deps": [], "cfg": [], }, { "root_module": "./example/mini_core_hello_world.rs", - "edition": "2015", + "edition": "2024", "deps": [ { "crate": 0, @@ -37,7 +37,7 @@ }, { "root_module": "./example/std_example.rs", - "edition": "2015", + "edition": "2024", "deps": [], "cfg": [], }, diff --git a/build_system/tests.rs b/build_system/tests.rs index 8cd84a79f9f7..3c22450a15f6 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -89,15 +89,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]), TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"), TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]), - TestCase::custom("aot.gen_block_iterate", &|runner| { - runner.run_rustc([ - "example/gen_block_iterate.rs", - "--edition", - "2024", - "-Zunstable-options", - ]); - runner.run_out_command("gen_block_iterate", &[]); - }), + TestCase::build_bin_and_run("aot.gen_block_iterate", "example/gen_block_iterate.rs", &[]), TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]), TestCase::custom("test.sysroot", &|runner| { apply_patches( @@ -423,6 +415,7 @@ impl<'a> TestRunner<'a> { cmd.arg("-Cpanic=abort"); } cmd.arg("--check-cfg=cfg(jit)"); + cmd.arg("--edition=2024"); cmd.args(args); cmd } diff --git a/example/example.rs b/example/example.rs index aeb38331edb0..e86bb8f59339 100644 --- a/example/example.rs +++ b/example/example.rs @@ -81,12 +81,16 @@ pub fn use_size_of() -> usize { } pub unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) { - intrinsics::copy::(src, dst, 1); + unsafe { + intrinsics::copy::(src, dst, 1); + } } pub unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) { - let copy2 = &intrinsics::copy::; - copy2(src, dst, 1); + unsafe { + let copy2 = &intrinsics::copy::; + copy2(src, dst, 1); + } } pub const ABC: u8 = 6 * 7; @@ -130,11 +134,11 @@ pub fn eq_char(a: char, b: char) -> bool { } pub unsafe fn transmute(c: char) -> u32 { - intrinsics::transmute(c) + unsafe { intrinsics::transmute(c) } } pub unsafe fn deref_str_ptr(s: *const str) -> &'static str { - &*s + unsafe { &*s } } pub fn use_array(arr: [u8; 3]) -> u8 { @@ -150,7 +154,7 @@ pub fn array_as_slice(arr: &[u8; 3]) -> &[u8] { } pub unsafe fn use_ctlz_nonzero(a: u16) -> u32 { - intrinsics::ctlz_nonzero(a) + unsafe { intrinsics::ctlz_nonzero(a) } } pub fn ptr_as_usize(ptr: *const u8) -> usize { diff --git a/example/mini_core.rs b/example/mini_core.rs index 2f53bbf8b793..3f846d393ba6 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -545,7 +545,7 @@ fn panic_in_cleanup() -> ! { #[cfg(all(unix, not(target_vendor = "apple")))] #[link(name = "gcc_s")] -extern "C" { +unsafe extern "C" { fn _Unwind_Resume(exc: *mut ()) -> !; } @@ -554,7 +554,9 @@ extern "C" { pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. - drop_in_place(to_drop); + unsafe { + drop_in_place(to_drop); + } } #[lang = "unpin"] @@ -621,7 +623,7 @@ impl Deref for Box { #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { - libc::malloc(size) + unsafe { libc::malloc(size) } } #[lang = "drop"] @@ -648,11 +650,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn size_of() -> usize; #[rustc_intrinsic] - pub unsafe fn size_of_val(val: *const T) -> usize; + pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub fn align_of() -> usize; #[rustc_intrinsic] - pub unsafe fn align_of_val(val: *const T) -> usize; + pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub unsafe fn copy(src: *const T, dst: *mut T, count: usize); #[rustc_intrinsic] @@ -660,7 +662,7 @@ pub mod intrinsics { #[rustc_intrinsic] pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] - pub const fn needs_drop() -> bool; + pub const fn needs_drop() -> bool; #[rustc_intrinsic] pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] @@ -677,13 +679,13 @@ pub mod libc { // symbols to link against. #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))] - extern "C" { + unsafe extern "C" { pub fn printf(format: *const i8, ...) -> i32; } #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "msvcrt"))] - extern "C" { + unsafe extern "C" { pub fn puts(s: *const i8) -> i32; pub fn malloc(size: usize) -> *mut u8; pub fn free(ptr: *mut u8); @@ -715,7 +717,7 @@ impl Index for [T] { } } -extern "C" { +unsafe extern "C" { type VaListImpl; } @@ -774,7 +776,7 @@ struct PanicLocation { column: u32, } -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(all(windows, target_env = "gnu")))] pub fn get_tls() -> u8 { #[thread_local] diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 66ecc9ec034a..3a5bcc55584f 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -115,9 +115,11 @@ static mut NUM: u8 = 6 * 7; static NUM_REF: &'static u8 = unsafe { &*&raw const NUM }; unsafe fn zeroed() -> T { - let mut uninit = MaybeUninit { uninit: () }; - intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1); - uninit.value.value + unsafe { + let mut uninit = MaybeUninit { uninit: () }; + intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1); + uninit.value.value + } } fn take_f32(_f: f32) {} @@ -228,7 +230,7 @@ fn main() { } unsafe fn uninitialized() -> T { - MaybeUninit { uninit: () }.value.value + unsafe { MaybeUninit { uninit: () }.value.value } } zeroed::<(u8, u8)>(); @@ -261,20 +263,20 @@ fn main() { let x = &[0u32, 42u32] as &[u32]; match x { [] => assert_eq!(0u32, 1), - [_, ref y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), + [_, y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), } assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); #[cfg(not(any(jit, target_vendor = "apple", windows)))] { - extern "C" { + unsafe extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } { - extern "C" { + unsafe extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } @@ -301,7 +303,7 @@ fn main() { check_niche_behavior(); - extern "C" { + unsafe extern "C" { type ExternType; } @@ -354,7 +356,7 @@ fn stack_val_align() { } #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] -extern "C" { +unsafe extern "C" { fn global_asm_test(); } @@ -402,7 +404,7 @@ struct pthread_attr_t { #[link(name = "pthread")] #[cfg(unix)] -extern "C" { +unsafe extern "C" { fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int; fn pthread_create( @@ -423,7 +425,7 @@ type HANDLE = *mut c_void; #[link(name = "msvcrt")] #[cfg(windows)] -extern "C" { +unsafe extern "C" { fn WaitForSingleObject(hHandle: LPVOID, dwMilliseconds: DWORD) -> DWORD; fn CreateThread( @@ -445,46 +447,51 @@ struct Thread { impl Thread { unsafe fn create(f: extern "C" fn(_: *mut c_void) -> *mut c_void) -> Self { - #[cfg(unix)] - { - let mut attr: pthread_attr_t = zeroed(); - let mut thread: pthread_t = 0; + unsafe { + #[cfg(unix)] + { + let mut attr: pthread_attr_t = zeroed(); + let mut thread: pthread_t = 0; - if pthread_attr_init(&mut attr) != 0 { - assert!(false); + if pthread_attr_init(&mut attr) != 0 { + assert!(false); + } + + if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 { + assert!(false); + } + + Thread { handle: thread } } - if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 { - assert!(false); + #[cfg(windows)] + { + let handle = + CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32); + + if (handle as u64) == 0 { + assert!(false); + } + + Thread { handle } } - - Thread { handle: thread } - } - - #[cfg(windows)] - { - let handle = CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32); - - if (handle as u64) == 0 { - assert!(false); - } - - Thread { handle } } } unsafe fn join(self) { - #[cfg(unix)] - { - let mut res = 0 as *mut c_void; - pthread_join(self.handle, &mut res); - } + unsafe { + #[cfg(unix)] + { + let mut res = 0 as *mut c_void; + pthread_join(self.handle, &mut res); + } - #[cfg(windows)] - { - // The INFINITE macro is used to signal operations that do not timeout. - let infinite = 0xffffffff; - assert!(WaitForSingleObject(self.handle, infinite) == 0); + #[cfg(windows)] + { + // The INFINITE macro is used to signal operations that do not timeout. + let infinite = 0xffffffff; + assert!(WaitForSingleObject(self.handle, infinite) == 0); + } } } } From f02793c37f5c0698b84de1e6f72b2ea4bff7d50a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:47:01 +0000 Subject: [PATCH 029/525] Fix std_example on x86 --- example/std_example.rs | 144 ++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 65 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index 5d83066cffb8..c569ef0ef829 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -230,51 +230,53 @@ unsafe fn test_crc32() { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { - assert!(is_x86_feature_detected!("sse2")); + unsafe { + assert!(is_x86_feature_detected!("sse2")); - let x = _mm_setzero_si128(); - let y = _mm_set1_epi16(7); - let or = _mm_or_si128(x, y); - let cmp_eq = _mm_cmpeq_epi8(y, y); - let cmp_lt = _mm_cmplt_epi8(y, y); + let x = _mm_setzero_si128(); + let y = _mm_set1_epi16(7); + let or = _mm_or_si128(x, y); + let cmp_eq = _mm_cmpeq_epi8(y, y); + let cmp_lt = _mm_cmplt_epi8(y, y); - let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x); - assert_eq!((zero0, zero1), (0, 0)); - assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); - assert_eq!( - std::mem::transmute::<_, [u16; 8]>(cmp_eq), - [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff] - ); - assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]); + let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x); + assert_eq!((zero0, zero1), (0, 0)); + assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); + assert_eq!( + std::mem::transmute::<_, [u16; 8]>(cmp_eq), + [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff] + ); + assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]); - test_mm_slli_si128(); - test_mm_movemask_epi8(); - test_mm256_movemask_epi8(); - 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_slli_si128(); + test_mm_movemask_epi8(); + test_mm256_movemask_epi8(); + 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(); - test_mm_insert_epi16(); - test_mm_shuffle_epi8(); + test_mm_extract_epi8(); + test_mm_insert_epi16(); + test_mm_shuffle_epi8(); - #[cfg(not(jit))] - test_mm_cmpestri(); + #[cfg(not(jit))] + test_mm_cmpestri(); - test_mm256_shuffle_epi8(); - test_mm256_permute2x128_si256(); - test_mm256_permutevar8x32_epi32(); + test_mm256_shuffle_epi8(); + test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); - #[rustfmt::skip] + #[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); + assert_eq!(mask1, 1); - #[cfg(not(jit))] - test_crc32(); + #[cfg(not(jit))] + test_crc32(); + } } #[cfg(target_arch = "x86_64")] @@ -361,7 +363,7 @@ fn assert_eq_m128i(x: std::arch::x86_64::__m128i, y: std::arch::x86_64::__m128i) #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] -pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { +pub fn assert_eq_m128d(a: __m128d, b: __m128d) { if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { panic!("{:?} != {:?}", a, b); } @@ -369,15 +371,19 @@ pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx")] -pub unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) { - assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b)) +pub fn assert_eq_m256i(a: __m256i, b: __m256i) { + unsafe { + assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b)) + } } #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_mm_cvtsi128_si64() { - let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0])); - assert_eq!(r, 5); + unsafe { + let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0])); + assert_eq!(r, 5); + } } #[cfg(target_arch = "x86_64")] @@ -445,20 +451,24 @@ unsafe fn test_mm_shuffle_epi8() { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse4.2")] unsafe fn str_to_m128i(s: &[u8]) -> __m128i { - assert!(s.len() <= 16); - let slice = &mut [0u8; 16]; - std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len()); - _mm_loadu_si128(slice.as_ptr() as *const _) + unsafe { + assert!(s.len() <= 16); + let slice = &mut [0u8; 16]; + std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len()); + _mm_loadu_si128(slice.as_ptr() as *const _) + } } #[cfg(not(jit))] #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse4.2")] unsafe fn test_mm_cmpestri() { - let a = str_to_m128i(b"bar - garbage"); - let b = str_to_m128i(b"foobar"); - let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6); - assert_eq!(3, i); + unsafe { + let a = str_to_m128i(b"bar - garbage"); + let b = str_to_m128i(b"foobar"); + let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6); + assert_eq!(3, i); + } } #[cfg(target_arch = "x86_64")] @@ -513,35 +523,39 @@ unsafe fn test_mm256_permutevar8x32_epi32() { #[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]; + unsafe { + 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 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); + 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]; + // 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); + 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]; + unsafe { + 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 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); + 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]; + // 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); + assert_eq!(ints, expected_ints); + } } fn test_checked_mul() { From cdf5236ee8fc1c4534c3e186e0f2584cca3ea108 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:55:07 +0000 Subject: [PATCH 030/525] Fix neon.rs --- example/neon.rs | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/example/neon.rs b/example/neon.rs index 704f866e2c4f..fb3e10a41c02 100644 --- a/example/neon.rs +++ b/example/neon.rs @@ -14,7 +14,7 @@ unsafe fn test_vpmin_s8() { let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = i8x8::from([-2, -4, 5, 7, 0, 2, 4, 6]); - let r: i8x8 = transmute(vpmin_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpmin_s8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -23,7 +23,7 @@ unsafe fn test_vpmin_s16() { let a = i16x4::from([1, 2, 3, -4]); let b = i16x4::from([0, 3, 2, 5]); let e = i16x4::from([1, -4, 0, 2]); - let r: i16x4 = transmute(vpmin_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpmin_s16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -32,7 +32,7 @@ unsafe fn test_vpmin_s32() { let a = i32x2::from([1, -2]); let b = i32x2::from([0, 3]); let e = i32x2::from([-2, 0]); - let r: i32x2 = transmute(vpmin_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpmin_s32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -41,7 +41,7 @@ unsafe fn test_vpmin_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = u8x8::from([1, 3, 5, 7, 0, 2, 4, 6]); - let r: u8x8 = transmute(vpmin_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpmin_u8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -50,7 +50,7 @@ unsafe fn test_vpmin_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([0, 3, 2, 5]); let e = u16x4::from([1, 3, 0, 2]); - let r: u16x4 = transmute(vpmin_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpmin_u16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -59,7 +59,7 @@ unsafe fn test_vpmin_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([0, 3]); let e = u32x2::from([1, 0]); - let r: u32x2 = transmute(vpmin_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpmin_u32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -68,7 +68,7 @@ unsafe fn test_vpmin_f32() { let a = f32x2::from([1., -2.]); let b = f32x2::from([0., 3.]); let e = f32x2::from([-2., 0.]); - let r: f32x2 = transmute(vpmin_f32(transmute(a), transmute(b))); + let r: f32x2 = unsafe { transmute(vpmin_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -77,7 +77,7 @@ unsafe fn test_vpmax_s8() { let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = i8x8::from([1, 3, 6, 8, 3, 5, 7, 9]); - let r: i8x8 = transmute(vpmax_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpmax_s8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -86,7 +86,7 @@ unsafe fn test_vpmax_s16() { let a = i16x4::from([1, 2, 3, -4]); let b = i16x4::from([0, 3, 2, 5]); let e = i16x4::from([2, 3, 3, 5]); - let r: i16x4 = transmute(vpmax_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpmax_s16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -95,7 +95,7 @@ unsafe fn test_vpmax_s32() { let a = i32x2::from([1, -2]); let b = i32x2::from([0, 3]); let e = i32x2::from([1, 3]); - let r: i32x2 = transmute(vpmax_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpmax_s32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -104,7 +104,7 @@ unsafe fn test_vpmax_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = u8x8::from([2, 4, 6, 8, 3, 5, 7, 9]); - let r: u8x8 = transmute(vpmax_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpmax_u8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -113,7 +113,7 @@ unsafe fn test_vpmax_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([0, 3, 2, 5]); let e = u16x4::from([2, 4, 3, 5]); - let r: u16x4 = transmute(vpmax_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpmax_u16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -122,7 +122,7 @@ unsafe fn test_vpmax_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([0, 3]); let e = u32x2::from([2, 3]); - let r: u32x2 = transmute(vpmax_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpmax_u32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -131,7 +131,7 @@ unsafe fn test_vpmax_f32() { let a = f32x2::from([1., -2.]); let b = f32x2::from([0., 3.]); let e = f32x2::from([1., 3.]); - let r: f32x2 = transmute(vpmax_f32(transmute(a), transmute(b))); + let r: f32x2 = unsafe { transmute(vpmax_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -139,7 +139,7 @@ unsafe fn test_vpmax_f32() { unsafe fn test_vpadd_s16() { let a = i16x4::from([1, 2, 3, 4]); let b = i16x4::from([0, -1, -2, -3]); - let r: i16x4 = transmute(vpadd_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpadd_s16(transmute(a), transmute(b))) }; let e = i16x4::from([3, 7, -1, -5]); assert_eq!(r, e); } @@ -147,7 +147,7 @@ unsafe fn test_vpadd_s16() { unsafe fn test_vpadd_s32() { let a = i32x2::from([1, 2]); let b = i32x2::from([0, -1]); - let r: i32x2 = transmute(vpadd_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpadd_s32(transmute(a), transmute(b))) }; let e = i32x2::from([3, -1]); assert_eq!(r, e); } @@ -155,7 +155,7 @@ unsafe fn test_vpadd_s32() { unsafe fn test_vpadd_s8() { let a = i8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = i8x8::from([0, -1, -2, -3, -4, -5, -6, -7]); - let r: i8x8 = transmute(vpadd_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpadd_s8(transmute(a), transmute(b))) }; let e = i8x8::from([3, 7, 11, 15, -1, -5, -9, -13]); assert_eq!(r, e); } @@ -163,7 +163,7 @@ unsafe fn test_vpadd_s8() { unsafe fn test_vpadd_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([30, 31, 32, 33]); - let r: u16x4 = transmute(vpadd_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpadd_u16(transmute(a), transmute(b))) }; let e = u16x4::from([3, 7, 61, 65]); assert_eq!(r, e); } @@ -171,7 +171,7 @@ unsafe fn test_vpadd_u16() { unsafe fn test_vpadd_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([30, 31]); - let r: u32x2 = transmute(vpadd_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpadd_u32(transmute(a), transmute(b))) }; let e = u32x2::from([3, 61]); assert_eq!(r, e); } @@ -179,7 +179,7 @@ unsafe fn test_vpadd_u32() { unsafe fn test_vpadd_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([30, 31, 32, 33, 34, 35, 36, 37]); - let r: u8x8 = transmute(vpadd_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpadd_u8(transmute(a), transmute(b))) }; let e = u8x8::from([3, 7, 11, 15, 61, 65, 69, 73]); assert_eq!(r, e); } @@ -188,7 +188,7 @@ unsafe fn test_vpadd_u8() { unsafe fn test_vqsub_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = transmute(vqsub_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vqsub_u8(transmute(a), transmute(b))) }; let e = u8x8::from([0, 1, 2, 3, 0, 0, 0, 218]); assert_eq!(r, e); } @@ -197,7 +197,7 @@ unsafe fn test_vqsub_u8() { unsafe fn test_vqadd_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = transmute(vqadd_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vqadd_u8(transmute(a), transmute(b))) }; let e = u8x8::from([31, 3, 4, 5, 39, 0xff, 43, 0xff]); assert_eq!(r, e); } @@ -208,7 +208,7 @@ unsafe fn test_vmaxq_f32() { let a = f32x4::from([0., -1., 2., -3.]); let b = f32x4::from([-4., 5., -6., 7.]); let e = f32x4::from([0., 5., 2., 7.]); - let r: f32x4 = transmute(vmaxq_f32(transmute(a), transmute(b))); + let r: f32x4 = unsafe { transmute(vmaxq_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -218,7 +218,7 @@ unsafe fn test_vminq_f32() { let a = f32x4::from([0., -1., 2., -3.]); let b = f32x4::from([-4., 5., -6., 7.]); let e = f32x4::from([-4., -1., -6., -3.]); - let r: f32x4 = transmute(vminq_f32(transmute(a), transmute(b))); + let r: f32x4 = unsafe { transmute(vminq_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -227,7 +227,7 @@ unsafe fn test_vaddvq_f32() { // AArch64 llvm intrinsic: llvm.aarch64.neon.faddv.f32.v4f32 let a = f32x4::from([0., 1., 2., 3.]); let e = 6f32; - let r = vaddvq_f32(transmute(a)); + let r = unsafe { vaddvq_f32(transmute(a)) }; assert_eq!(r, e); } @@ -236,7 +236,7 @@ unsafe fn test_vrndnq_f32() { // llvm intrinsic: llvm.roundeven.v4f32 let a = f32x4::from([0.1, -1.9, 4.5, 5.5]); let e = f32x4::from([0., -2., 4., 6.]); - let r: f32x4 = transmute(vrndnq_f32(transmute(a))); + let r: f32x4 = unsafe { transmute(vrndnq_f32(transmute(a))) }; assert_eq!(r, e); } From d117c77a0e0bb7468e25eef66c79f87989104810 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:55:39 +0000 Subject: [PATCH 031/525] Fix raw-dylib.rs --- example/raw-dylib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/raw-dylib.rs b/example/raw-dylib.rs index 4711884f76af..5f5bde7d4dc5 100644 --- a/example/raw-dylib.rs +++ b/example/raw-dylib.rs @@ -5,7 +5,7 @@ fn main() { #[cfg(windows)] { #[link(name = "kernel32", kind = "raw-dylib")] - extern "C" { + unsafe extern "C" { fn GetModuleFileNameA( module: *mut std::ffi::c_void, filename: *mut u8, From 989bb25293f6d53f89821ea56f4b5e3ce5db3421 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:32:41 +0000 Subject: [PATCH 032/525] Remove reference to deleted test --- config.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/config.txt b/config.txt index 6ae4767adfdf..85748a4f8a78 100644 --- a/config.txt +++ b/config.txt @@ -20,7 +20,6 @@ aot.mini_core_hello_world testsuite.base_sysroot aot.arbitrary_self_types_pointers_and_wrappers -aot.issue_91827_extern_types jit.std_example aot.std_example aot.dst_field_align From 805f843f194d57af5892a6775f0a6e3014542c11 Mon Sep 17 00:00:00 2001 From: Edoardo Marangoni Date: Sun, 29 Jun 2025 12:11:51 +0200 Subject: [PATCH 033/525] compiler: Parse `p-` specs in datalayout string, allow definition of custom default data address space --- src/abi/mod.rs | 2 +- src/abi/pass_mode.rs | 2 +- src/common.rs | 2 +- src/constant.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 8965e4a944d4..7d0731c77bdc 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -786,7 +786,7 @@ pub(crate) fn codegen_drop<'tcx>( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); - if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size.bits() { + if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { match (&*tcx.sess.target.arch, &*tcx.sess.target.vendor) { ("x86_64", _) | ("aarch64", "apple") => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index cd0afee0cfb2..2031842062d9 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -127,7 +127,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { attrs, meta_attrs: None, on_stack } => { if on_stack { // Abi requires aligning struct size to pointer size - let size = self.layout.size.align_to(tcx.data_layout.pointer_align.abi); + let size = self.layout.size.align_to(tcx.data_layout.pointer_align().abi); let size = u32::try_from(size.bytes()).unwrap(); smallvec![apply_attrs_to_abi_param( AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),), diff --git a/src/common.rs b/src/common.rs index 2f11b2d2dcc1..2fbe5c02802a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -15,7 +15,7 @@ use crate::debuginfo::FunctionDebugContext; use crate::prelude::*; pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type { - match tcx.data_layout.pointer_size.bits() { + match tcx.data_layout.pointer_size().bits() { 16 => types::I16, 32 => types::I32, 64 => types::I64, diff --git a/src/constant.rs b/src/constant.rs index ee43eb736e65..ed06423b260f 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -443,7 +443,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant let addend = { let endianness = tcx.data_layout.endian; let offset = offset.bytes() as usize; - let ptr_size = tcx.data_layout.pointer_size; + let ptr_size = tcx.data_layout.pointer_size(); let bytes = &alloc.inspect_with_uninit_and_ptr_outside_interpreter( offset..offset + ptr_size.bytes() as usize, ); From 9360f7c24465ae9fbb6df707332bfc268c05ae66 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:32:43 +0200 Subject: [PATCH 034/525] Don't call collect_debug_info when debuginfo is disabled --- src/base.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 9b0a59c0dfc7..fad747b9c274 100644 --- a/src/base.rs +++ b/src/base.rs @@ -63,7 +63,9 @@ pub(crate) fn codegen_fn<'tcx>( func.clear(); func.name = UserFuncName::user(0, func_id.as_u32()); func.signature = sig; - func.collect_debug_info(); + if cx.debug_context.is_some() { + func.collect_debug_info(); + } let mut bcx = FunctionBuilder::new(&mut func, &mut func_ctx); From 8dab8de9d204fe417eec467370142dd3824237a7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 4 Jul 2025 15:57:32 +0200 Subject: [PATCH 035/525] Get rid of CodegenCx --- src/base.rs | 22 +++++++++++++--------- src/common.rs | 6 ++++-- src/debuginfo/mod.rs | 19 ++++++++++++++++--- src/driver/aot.rs | 27 ++++++++++++--------------- src/driver/jit.rs | 20 ++++++++++++-------- src/inline_asm.rs | 4 ++-- src/lib.rs | 25 ------------------------- src/pretty_clif.rs | 7 ++++--- 8 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/base.rs b/src/base.rs index fad747b9c274..5c826b50e8d1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::config::OutputFilenames; +use rustc_span::Symbol; use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; @@ -31,7 +32,8 @@ pub(crate) struct CodegenedFunction { pub(crate) fn codegen_fn<'tcx>( tcx: TyCtxt<'tcx>, - cx: &mut crate::CodegenCx, + cgu_name: Symbol, + mut debug_context: Option<&mut DebugContext>, type_dbg: &mut TypeDebugContext<'tcx>, cached_func: Function, module: &mut dyn Module, @@ -63,7 +65,7 @@ pub(crate) fn codegen_fn<'tcx>( func.clear(); func.name = UserFuncName::user(0, func_id.as_u32()); func.signature = sig; - if cx.debug_context.is_some() { + if debug_context.is_some() { func.collect_debug_info(); } @@ -79,9 +81,10 @@ pub(crate) fn codegen_fn<'tcx>( // Make FunctionCx let target_config = module.target_config(); let pointer_type = target_config.pointer_type(); + assert_eq!(pointer_ty(tcx), pointer_type); let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance, fn_abi); - let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { + let func_debug_cx = if let Some(debug_context) = debug_context.as_deref_mut() { Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span)) } else { None @@ -91,14 +94,15 @@ pub(crate) fn codegen_fn<'tcx>( bcx.declare_var(exception_slot, pointer_type); let mut fx = FunctionCx { - cx, module, + debug_context, tcx, target_config, pointer_type, constants_cx: ConstantCx::new(), func_debug_cx, + cgu_name, instance, symbol_name, mir, @@ -128,7 +132,7 @@ pub(crate) fn codegen_fn<'tcx>( fx.constants_cx.finalize(fx.tcx, &mut *fx.module); - if cx.should_write_ir { + if crate::pretty_clif::should_write_ir(tcx.sess) { crate::pretty_clif::write_clif_file( tcx.output_filenames(()), &symbol_name, @@ -146,11 +150,12 @@ pub(crate) fn codegen_fn<'tcx>( } pub(crate) fn compile_fn( - cx: &mut crate::CodegenCx, profiler: &SelfProfilerRef, output_filenames: &OutputFilenames, + should_write_ir: bool, cached_context: &mut Context, module: &mut dyn Module, + debug_context: Option<&mut DebugContext>, global_asm: &mut String, codegened_func: CodegenedFunction, ) { @@ -195,7 +200,7 @@ pub(crate) fn compile_fn( // Define function profiler.generic_activity("define function").run(|| { - context.want_disasm = cx.should_write_ir; + context.want_disasm = should_write_ir; match module.define_function(codegened_func.func_id, context) { Ok(()) => {} Err(ModuleError::Compilation(CodegenError::ImplLimitExceeded)) => { @@ -225,7 +230,7 @@ pub(crate) fn compile_fn( } }); - if cx.should_write_ir { + if should_write_ir { // Write optimized function to file for debugging crate::pretty_clif::write_clif_file( output_filenames, @@ -246,7 +251,6 @@ pub(crate) fn compile_fn( } // Define debuginfo for function - let debug_context = &mut cx.debug_context; profiler.generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { codegened_func.func_debug_cx.unwrap().finalize( diff --git a/src/common.rs b/src/common.rs index 6596b27fb1ff..035643d2fa2b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -6,6 +6,7 @@ use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; +use rustc_span::Symbol; use rustc_span::source_map::Spanned; use rustc_target::callconv::FnAbi; use rustc_target::spec::{HasTargetSpec, Target}; @@ -268,14 +269,15 @@ pub(crate) fn create_wrapper_function( } pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { - pub(crate) cx: &'clif mut crate::CodegenCx, pub(crate) module: &'m mut dyn Module, + pub(crate) debug_context: Option<&'clif mut DebugContext>, pub(crate) tcx: TyCtxt<'tcx>, pub(crate) target_config: TargetFrontendConfig, // Cached from module pub(crate) pointer_type: Type, // Cached from module pub(crate) constants_cx: ConstantCx, pub(crate) func_debug_cx: Option, + pub(crate) cgu_name: Symbol, pub(crate) instance: Instance<'tcx>, pub(crate) symbol_name: String, pub(crate) mir: &'tcx Body<'tcx>, @@ -407,7 +409,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) { - if let Some(debug_context) = &mut self.cx.debug_context { + if let Some(debug_context) = &mut self.debug_context { let (file_id, line, column) = debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 35f92609982e..391ce5200847 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -20,6 +20,7 @@ use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; +use rustc_session::config::DebugInfo; use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; @@ -53,7 +54,19 @@ pub(crate) struct FunctionDebugContext { } impl DebugContext { - pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self { + pub(crate) fn new( + tcx: TyCtxt<'_>, + isa: &dyn TargetIsa, + force_disable_debuginfo: bool, + cgu_name: &str, + ) -> Option { + if tcx.sess.opts.debuginfo == DebugInfo::None + || force_disable_debuginfo + || tcx.sess.target.options.is_like_windows + { + return None; + } + let encoding = Encoding { format: Format::Dwarf32, // FIXME this should be configurable @@ -146,7 +159,7 @@ impl DebugContext { AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), ); - DebugContext { + Some(DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), @@ -155,7 +168,7 @@ impl DebugContext { namespace_map: DefIdMap::default(), array_size_type, filename_display_preference, - } + }) } fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId { diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 9e793fc52545..ea50af77c9f2 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -25,9 +25,8 @@ use rustc_middle::mir::mono::{ CodegenUnit, Linkage as RLinkage, MonoItem, MonoItemData, Visibility, }; use rustc_session::Session; -use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType}; +use rustc_session::config::{OutFileName, OutputFilenames, OutputType}; -use crate::CodegenCx; use crate::base::CodegenedFunction; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; use crate::debuginfo::TypeDebugContext; @@ -512,18 +511,13 @@ fn codegen_cgu_content( tcx: TyCtxt<'_>, module: &mut dyn Module, cgu_name: rustc_span::Symbol, -) -> (CodegenCx, Vec, String) { +) -> (Option, Vec, String) { let _timer = tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str()); let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); - let mut cx = crate::CodegenCx::new( - tcx, - module.isa(), - tcx.sess.opts.debuginfo != DebugInfo::None, - cgu_name, - ); + let mut debug_context = DebugContext::new(tcx, module.isa(), false, cgu_name.as_str()); let mut global_asm = String::new(); let mut type_dbg = TypeDebugContext::default(); super::predefine_mono_items(tcx, module, &mono_items); @@ -550,7 +544,8 @@ fn codegen_cgu_content( } let codegened_function = crate::base::codegen_fn( tcx, - &mut cx, + cgu_name, + debug_context.as_mut(), &mut type_dbg, Function::new(), module, @@ -560,7 +555,7 @@ fn codegen_cgu_content( } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, module, def_id); - if let Some(debug_context) = &mut cx.debug_context { + if let Some(debug_context) = debug_context.as_mut() { debug_context.define_static(tcx, &mut type_dbg, def_id, data_id); } } @@ -574,7 +569,7 @@ fn codegen_cgu_content( } crate::main_shim::maybe_create_entry_wrapper(tcx, module, false, cgu.is_primary()); - (cx, codegened_functions, global_asm) + (debug_context, codegened_functions, global_asm) } fn module_codegen( @@ -587,7 +582,7 @@ fn module_codegen( ) -> OngoingModuleCodegen { let mut module = make_module(tcx.sess, cgu_name.as_str().to_string()); - let (mut cx, codegened_functions, mut global_asm) = + let (mut debug_context, codegened_functions, mut global_asm) = codegen_cgu_content(tcx, &mut module, cgu_name); let cgu_name = cgu_name.as_str().to_owned(); @@ -597,6 +592,7 @@ fn module_codegen( let profiler = tcx.prof.clone(); let invocation_temp = tcx.sess.invocation_temp.clone(); let output_filenames = tcx.output_filenames(()).clone(); + let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); OngoingModuleCodegen::Async(std::thread::spawn(move || { profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { @@ -607,11 +603,12 @@ fn module_codegen( let mut cached_context = Context::new(); for codegened_func in codegened_functions { crate::base::compile_fn( - &mut cx, &profiler, &output_filenames, + should_write_ir, &mut cached_context, &mut module, + debug_context.as_mut(), &mut global_asm, codegened_func, ); @@ -636,7 +633,7 @@ fn module_codegen( &profiler, cgu_name, module, - cx.debug_context, + debug_context, global_asm_object_file, &producer, ) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index ab1544e62b0a..697deae15545 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -12,12 +12,11 @@ use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::sym; -use crate::CodegenCx; use crate::debuginfo::TypeDebugContext; use crate::prelude::*; use crate::unwind_module::UnwindModule; -fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { +fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option) { let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let isa = crate::build_isa(tcx.sess, true); @@ -26,7 +25,7 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); - let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name); + let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name"); crate::allocator::codegen(tcx, &mut jit_module); @@ -43,7 +42,8 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { } let output_filenames = tcx.output_filenames(()); - let (mut jit_module, mut cx) = create_jit_module(tcx); + let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); + let (mut jit_module, mut debug_context) = create_jit_module(tcx); let mut cached_context = Context::new(); let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; @@ -63,7 +63,8 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { codegen_and_compile_fn( tcx, &output_filenames, - &mut cx, + should_write_ir, + debug_context.as_mut(), &mut cached_context, &mut jit_module, inst, @@ -122,7 +123,8 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { fn codegen_and_compile_fn<'tcx>( tcx: TyCtxt<'tcx>, output_filenames: &OutputFilenames, - cx: &mut crate::CodegenCx, + should_write_ir: bool, + mut debug_context: Option<&mut DebugContext>, cached_context: &mut Context, module: &mut dyn Module, instance: Instance<'tcx>, @@ -143,7 +145,8 @@ fn codegen_and_compile_fn<'tcx>( let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); let codegened_func = crate::base::codegen_fn( tcx, - cx, + sym::dummy_cgu_name, + debug_context.as_deref_mut(), &mut TypeDebugContext::default(), cached_func, module, @@ -152,11 +155,12 @@ fn codegen_and_compile_fn<'tcx>( let mut global_asm = String::new(); crate::base::compile_fn( - cx, &tcx.prof, output_filenames, + should_write_ir, cached_context, module, + debug_context.as_deref_mut(), &mut global_asm, codegened_func, ); diff --git a/src/inline_asm.rs b/src/inline_asm.rs index eec8b08a1bcd..5a29961f7d71 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -125,7 +125,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( let wrapper_name = format!( "{}__inline_asm_{}_wrapper_n{}", fx.symbol_name, - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), fx.inline_asm_index, ); fx.inline_asm_index += 1; @@ -189,7 +189,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( let asm_name = format!( "{}__inline_asm_{}_n{}", fx.symbol_name, - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), fx.inline_asm_index, ); fx.inline_asm_index += 1; diff --git a/src/lib.rs b/src/lib.rs index 62ba9974f726..835fd9a4d72e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,31 +123,6 @@ impl String> Drop for PrintOnPanic { } } -/// The codegen context holds any information shared between the codegen of individual functions -/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). -struct CodegenCx { - should_write_ir: bool, - debug_context: Option, - cgu_name: Symbol, -} - -impl CodegenCx { - fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol) -> Self { - assert_eq!(pointer_ty(tcx), isa.pointer_type()); - - let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { - Some(DebugContext::new(tcx, isa, cgu_name.as_str())) - } else { - None - }; - CodegenCx { - should_write_ir: crate::pretty_clif::should_write_ir(tcx), - debug_context, - cgu_name, - } - } -} - pub struct CraneliftCodegenBackend { pub config: Option, } diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 9400ae9fcff0..3655faf598a7 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -64,6 +64,7 @@ use cranelift_codegen::ir::Fact; use cranelift_codegen::ir::entities::AnyEntity; use cranelift_codegen::write::{FuncWriter, PlainWriter}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_session::Session; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_target::callconv::FnAbi; @@ -83,7 +84,7 @@ impl CommentWriter { instance: Instance<'tcx>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, ) -> Self { - let enabled = should_write_ir(tcx); + let enabled = should_write_ir(tcx.sess); let global_comments = if enabled { with_no_trimmed_paths!({ vec![ @@ -247,8 +248,8 @@ impl FunctionCx<'_, '_, '_> { } } -pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { - tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) +pub(crate) fn should_write_ir(sess: &Session) -> bool { + sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } pub(crate) fn write_ir_file( From 5df82239b004c815570b74847ed39e3d9c5ef53f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 7 Jul 2025 12:42:37 +0000 Subject: [PATCH 036/525] Rustup to rustc 1.90.0-nightly (a84ab0ce6 2025-07-06) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 56d1bda88ca6..75a305809b1c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-03" +channel = "nightly-2025-07-07" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 87e71fe07529e2eac43bb6d14fa58fa4fdb4f669 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 7 Jul 2025 12:48:18 +0000 Subject: [PATCH 037/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index f9a3fc85de45..22822d121d2f 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -146,8 +146,7 @@ rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables -rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd -rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same +rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist From 3bd80454602a41cc4d7d1dc3fe6dce671d4fb033 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:31:31 +0000 Subject: [PATCH 038/525] Rustup to rustc 1.90.0-nightly (a2d45f73c 2025-07-07) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 75a305809b1c..e3e55123592e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-07" +channel = "nightly-2025-07-08" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 2f84e16016cd3f8039c5da77cb8a2696e8ff5a7f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:47:46 +0000 Subject: [PATCH 039/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 22822d121d2f..78582e4ecdce 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,6 +60,7 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet +rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported # requires LTO rm -r tests/run-make/cdylib From 08dac6fc6c1634ab60c0b30589b443e31a212e7a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Mar 2025 10:26:37 +0000 Subject: [PATCH 040/525] Add opaque TypeId handles for CTFE --- src/constant.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/constant.rs b/src/constant.rs index ed06423b260f..85adf0f3716b 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -175,6 +175,13 @@ pub(crate) fn codegen_const_value<'tcx>( fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } + GlobalAlloc::TypeId { .. } => { + return CValue::const_val( + fx, + layout, + ScalarInt::try_from_target_usize(offset.bytes(), fx.tcx).unwrap(), + ); + } GlobalAlloc::Static(def_id) => { assert!(fx.tcx.is_static(def_id)); let data_id = data_id_for_static( @@ -360,6 +367,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant GlobalAlloc::Memory(alloc) => alloc, GlobalAlloc::Function { .. } | GlobalAlloc::Static(_) + | GlobalAlloc::TypeId { .. } | GlobalAlloc::VTable(..) => { unreachable!() } @@ -471,6 +479,11 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant .principal() .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)), ), + GlobalAlloc::TypeId { .. } => { + // Nothing to do, the bytes/offset of this pointer have already been written together with all other bytes, + // so we just need to drop this provenance. + continue; + } GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { From fb6de82523a613a63f55fceeae1ef09d66c84d03 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:37:15 +0000 Subject: [PATCH 041/525] Rustup to rustc 1.90.0-nightly (e43d139a8 2025-07-09) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index e3e55123592e..9f547841f83c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-08" +channel = "nightly-2025-07-10" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 503612e92fa768cdef191c9cfb5c7108381f6e58 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 10 Jul 2025 13:12:51 +0000 Subject: [PATCH 042/525] Fix rustc testsuite --- 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 78582e4ecdce..d32fd17d2eae 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,6 +60,7 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet +rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported # requires LTO From 5d1bc9b8c4e98702c1643cff6d793e9113e4a5fd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 11 Jul 2025 10:29:10 +0000 Subject: [PATCH 043/525] Rustup to rustc 1.90.0-nightly (2a023bf80 2025-07-10) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9f547841f83c..61bcbc3373ed 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-10" +channel = "nightly-2025-07-11" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8e7174905ee670a76ec174294c5c2a238c1a256b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 12 Jul 2025 15:52:14 +0000 Subject: [PATCH 044/525] Fix rustc testsuite --- 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 d32fd17d2eae..87e6dc3696d5 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -96,7 +96,7 @@ rm -r tests/run-make/llvm-location-discriminator-limit-dummy-span # 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/ui/optimization-remark.rs # same +rm -r tests/ui/codegen/remark-flag-functionality.rs # same rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support From e0860f807c451f95d5ba68a10de38ea90fa237ef Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 13 Jul 2025 15:41:29 +0000 Subject: [PATCH 045/525] MinGW misses some f16/f128 intrinsics --- src/compiler_builtins.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index d3784f8e56ac..155bf866889a 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -85,6 +85,7 @@ builtin_functions! { fn __divtf3(a: f128, b: f128) -> f128; fn fmodf(a: f32, b: f32) -> f32; fn fmod(a: f64, b: f64) -> f64; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmodf128(a: f128, b: f128) -> f128; // float comparison fn __eqtf2(a: f128, b: f128) -> i32; @@ -93,7 +94,9 @@ builtin_functions! { fn __letf2(a: f128, b: f128) -> i32; fn __gttf2(a: f128, b: f128) -> i32; fn __getf2(a: f128, b: f128) -> i32; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fminimumf128(a: f128, b: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmaximumf128(a: f128, b: f128) -> f128; // Cranelift float libcalls fn fmaf(a: f32, b: f32, c: f32) -> f32; @@ -127,16 +130,27 @@ builtin_functions! { fn sin(f: f64) -> f64; fn cosf(f: f32) -> f32; fn cos(f: f64) -> f64; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmaf128(a: f128, b: f128, c: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn floorf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn floorf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn ceilf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn ceilf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn truncf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn truncf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn rintf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn rintf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn sqrtf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn sqrtf128(f: f128) -> f128; // FIXME(f16_f128): Add other float intrinsics as compiler-builtins gains support (meaning they // are available on all targets). From a3796c7147334828635674c2486ec82e8eb093d3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:05:29 +0000 Subject: [PATCH 046/525] Rustup to rustc 1.90.0-nightly (a00149764 2025-07-14) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 61bcbc3373ed..26bd5523957c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-11" +channel = "nightly-2025-07-15" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 46fa9ad1f0d0bcc173d44a9a6d721158e2af5ed1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:25:27 +0000 Subject: [PATCH 047/525] Directly use symbol_value and tls_value global_value gets legalized to either of the two. --- src/constant.rs | 17 +++++++++++++---- src/vtable.rs | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 023cd000b5de..3bd907b38cf6 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -153,7 +153,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } } GlobalAlloc::Function { instance, .. } => { @@ -174,7 +174,7 @@ pub(crate) fn codegen_const_value<'tcx>( ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } GlobalAlloc::TypeId { .. } => { return CValue::const_val( @@ -195,7 +195,16 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", def_id)); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + if fx + .tcx + .codegen_fn_attrs(def_id) + .flags + .contains(CodegenFnAttrFlags::THREAD_LOCAL) + { + fx.bcx.ins().tls_value(fx.pointer_type, local_data_id) + } else { + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) + } } }; let val = if offset.bytes() != 0 { @@ -229,7 +238,7 @@ fn pointer_for_allocation<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, alloc_id: All if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } fn data_id_for_alloc_id( diff --git a/src/vtable.rs b/src/vtable.rs index 423cc8d225be..b5d241d8f39f 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -84,5 +84,5 @@ pub(crate) fn get_vtable<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, "vtable"); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } From 5320b81d1ba23214981e9f55da6cab9ee9bc4e11 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 1 Jul 2025 20:02:31 +0200 Subject: [PATCH 048/525] fix `-Zsanitizer=kcfi` on `#[naked]` functions And more broadly only codegen `InstanceKind::Item` using the naked function codegen code. Other instance kinds should follow the normal path. --- src/driver/aot.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 442151fe32de..727f2760c0f9 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -530,8 +530,12 @@ fn codegen_cgu_content( for (mono_item, item_data) in mono_items { match mono_item { MonoItem::Fn(instance) => { - if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) - { + // Other `InstanceKind`s (e.g. `ReifyShim` generated by indirect calls) should be + // codegened like a normal function. + let is_item_instance = matches!(instance.def, InstanceKind::Item(_)); + + let flags = tcx.codegen_fn_attrs(instance.def_id()).flags; + if is_item_instance && flags.contains(CodegenFnAttrFlags::NAKED) { rustc_codegen_ssa::mir::naked_asm::codegen_naked_asm( &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, instance, From 70d199a6398570c1fe4b5efe1e85bc2227152f40 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 2 Jul 2025 10:46:15 +0200 Subject: [PATCH 049/525] add `codegen_instance_attrs` query and use it for naked functions --- src/driver/aot.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 727f2760c0f9..8ec3599b63d8 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -530,12 +530,8 @@ fn codegen_cgu_content( for (mono_item, item_data) in mono_items { match mono_item { MonoItem::Fn(instance) => { - // Other `InstanceKind`s (e.g. `ReifyShim` generated by indirect calls) should be - // codegened like a normal function. - let is_item_instance = matches!(instance.def, InstanceKind::Item(_)); - - let flags = tcx.codegen_fn_attrs(instance.def_id()).flags; - if is_item_instance && flags.contains(CodegenFnAttrFlags::NAKED) { + let flags = tcx.codegen_instance_attrs(instance.def).flags; + if flags.contains(CodegenFnAttrFlags::NAKED) { rustc_codegen_ssa::mir::naked_asm::codegen_naked_asm( &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, instance, From 8e5e64750c6339f4c77e596ac72d56ab17378e97 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 2 Jul 2025 11:12:54 +0200 Subject: [PATCH 050/525] use `codegen_instance_attrs` where an instance is (easily) available --- src/driver/jit.rs | 2 +- src/driver/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index b1f185b551c3..b3497503bf06 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -127,7 +127,7 @@ fn codegen_and_compile_fn<'tcx>( module: &mut dyn Module, instance: Instance<'tcx>, ) { - if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { + if tcx.codegen_instance_attrs(instance.def).flags.contains(CodegenFnAttrFlags::NAKED) { tcx.dcx() .span_fatal(tcx.def_span(instance.def_id()), "Naked asm is not supported in JIT mode"); } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index ffd47cace380..8f83c30b598d 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -35,7 +35,7 @@ fn predefine_mono_items<'tcx>( is_compiler_builtins, ); let is_naked = tcx - .codegen_fn_attrs(instance.def_id()) + .codegen_instance_attrs(instance.def) .flags .contains(CodegenFnAttrFlags::NAKED); module From 7fa842965ee7e655191a5a1a5ab72a55c2bc62c2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 12 Jul 2025 17:11:47 -0700 Subject: [PATCH 051/525] Update cranelift tests --- example/float-minmax-pass.rs | 22 ++++++++++++++-------- example/mini_core_hello_world.rs | 3 ++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/example/float-minmax-pass.rs b/example/float-minmax-pass.rs index ad46e18c11c0..b7491b7e522f 100644 --- a/example/float-minmax-pass.rs +++ b/example/float-minmax-pass.rs @@ -11,6 +11,12 @@ #[derive(Copy, Clone, PartialEq, Debug)] struct f32x4(pub [f32; 4]); +impl f32x4 { + fn into_array(self) -> [f32; 4] { + unsafe { std::mem::transmute(self) } + } +} + use std::intrinsics::simd::*; fn main() { @@ -29,22 +35,22 @@ fn main() { unsafe { let min0 = simd_fmin(x, y); let min1 = simd_fmin(y, x); - assert_eq!(min0, min1); + assert_eq!(min0.into_array(), min1.into_array()); let e = f32x4([1.0, 1.0, 3.0, 3.0]); - assert_eq!(min0, e); + assert_eq!(min0.into_array(), e.into_array()); let minn = simd_fmin(x, n); - assert_eq!(minn, x); + assert_eq!(minn.into_array(), x.into_array()); let minn = simd_fmin(y, n); - assert_eq!(minn, y); + assert_eq!(minn.into_array(), y.into_array()); let max0 = simd_fmax(x, y); let max1 = simd_fmax(y, x); - assert_eq!(max0, max1); + assert_eq!(max0.into_array(), max1.into_array()); let e = f32x4([2.0, 2.0, 4.0, 4.0]); - assert_eq!(max0, e); + assert_eq!(max0.into_array(), e.into_array()); let maxn = simd_fmax(x, n); - assert_eq!(maxn, x); + assert_eq!(maxn.into_array(), x.into_array()); let maxn = simd_fmax(y, n); - assert_eq!(maxn, y); + assert_eq!(maxn.into_array(), y.into_array()); } } diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 246bd3104ec4..86602c6b2a3f 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -348,7 +348,8 @@ fn main() { struct V([f64; 2]); let f = V([0.0, 1.0]); - let _a = f.0[0]; + let fp = (&raw const f) as *const [f64; 2]; + let _a = (unsafe { &*fp })[0]; stack_val_align(); } From 959755f22456445cf9696afad66e073280531f5c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 21 Jul 2025 08:44:33 +0000 Subject: [PATCH 052/525] Rustup to rustc 1.90.0-nightly (9982d6462 2025-07-20) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 26bd5523957c..b0c39f661ecf 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-15" +channel = "nightly-2025-07-21" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 87c661ebbcf115116c87674d7760a1e8fb1e87e8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 21 Jul 2025 08:55:47 +0000 Subject: [PATCH 053/525] Re-enable some rustc tests --- scripts/test_rustc_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 87e6dc3696d5..8cc70ffc9c82 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -10,7 +10,7 @@ pushd rust command -v rg >/dev/null 2>&1 || cargo install ripgrep -rm -r tests/ui/{unsized-locals/,lto/,linkage*} || true +rm -r tests/ui/{lto/,linkage*} || true for test in $(rg --files-with-matches "lto" tests/{codegen-units,ui,incremental}); do rm $test done @@ -39,7 +39,6 @@ rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funne # exotic linkages rm tests/incremental/hashes/function_interfaces.rs rm tests/incremental/hashes/statics.rs -rm -r tests/run-make/naked-symbol-visibility # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs From e7c7bf04a7fb8b563cd5c393936118ae487c3999 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:14:09 +0000 Subject: [PATCH 054/525] Fix rustc testsuite --- 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 8cc70ffc9c82..1cd592a09ca6 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -39,6 +39,7 @@ rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funne # exotic linkages rm tests/incremental/hashes/function_interfaces.rs rm tests/incremental/hashes/statics.rs +rm -r tests/run-make/naked-symbol-visibility # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs From 57fb209e76f5922e8bd5fdb264034ba20472535e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:56:39 +0000 Subject: [PATCH 055/525] Update dependencies --- Cargo.lock | 84 +++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b893a2be9a2c..4a599f8d76a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "arbitrary" @@ -28,18 +28,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" dependencies = [ "allocator-api2", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" @@ -218,18 +218,18 @@ checksum = "7d5870e266df8237b56cc98b04f5739c228565c92dd629ec6c66efa87271a158" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "fallible-iterator" @@ -239,9 +239,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" @@ -256,18 +256,18 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "foldhash", ] [[package]] name = "indexmap" -version = "2.7.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -275,9 +275,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" @@ -297,24 +297,24 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "object" @@ -330,18 +330,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -374,9 +374,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_codegen_cranelift" @@ -398,18 +398,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" @@ -430,9 +430,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.95" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -441,15 +441,15 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc12939a1c9b9d391e0b7135f72fd30508b73450753e28341fed159317582a77" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasmtime-jit-icache-coherence" From 66503c1a83c141bff7779c165d6dcdda86cfa755 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 19 Jul 2025 23:23:40 +0200 Subject: [PATCH 056/525] atomicrmw on pointers: move integer-pointer cast hacks into backend --- src/intrinsics/mod.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 4ff5773a06cb..ed40901ac9b8 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -969,7 +969,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = amount.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -982,7 +982,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Add, ptr, amount); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_xsub => { @@ -991,7 +991,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = amount.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -1004,7 +1004,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Sub, ptr, amount); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_and => { @@ -1013,7 +1013,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = src.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -1025,7 +1025,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::And, ptr, src); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_or => { @@ -1034,7 +1034,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = src.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -1046,7 +1046,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Or, ptr, src); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_xor => { @@ -1055,7 +1055,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = src.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -1067,7 +1067,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xor, ptr, src); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_nand => { @@ -1076,7 +1076,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let layout = src.layout(); match layout.ty.kind() { - ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} + ty::Uint(_) | ty::Int(_) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); return Ok(()); @@ -1088,7 +1088,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Nand, ptr, src); - let old = CValue::by_val(old, layout); + let old = CValue::by_val(old, ret.layout()); ret.write_cvalue(fx, old); } sym::atomic_max => { From 6098fb9e48e7358fa916329acd38a5e1889c2824 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 23 Jul 2025 14:42:01 +0000 Subject: [PATCH 057/525] Rustup to rustc 1.90.0-nightly (a7a1618e6 2025-07-22) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index b0c39f661ecf..b1a53d70b1ae 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-21" +channel = "nightly-2025-07-23" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 17f2c4db532d4ae643387797eca93b9628444ce3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:33:16 +0200 Subject: [PATCH 058/525] Update to Cranelift 0.122 --- Cargo.lock | 80 +++++++++++++++++++++--------------------- Cargo.toml | 24 ++++++------- src/base.rs | 6 ++-- src/common.rs | 3 -- src/value_and_place.rs | 13 ++----- 5 files changed, 57 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a599f8d76a1..0187e07a6bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f53499803b1607b6ee0ba0de4ba036e6da700c2e489fe8f9d0f683d0b84d31" +checksum = "0ae7b60ec3fd7162427d3b3801520a1908bef7c035b52983cd3ca11b8e7deb51" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aadaa5bc8430d0e7bb999459369bedd0e5816ad4a82a0e20748341c4e333eda" +checksum = "6511c200fed36452697b4b6b161eae57d917a2044e6333b1c1389ed63ccadeee" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2005fda2fc52a2dbce58229b4fb4483b70cbc806ba8ecc11b3f050c1a2d26cac" +checksum = "5f7086a645aa58bae979312f64e3029ac760ac1b577f5cd2417844842a2ca07f" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56935e02452ca1249d39ad5c45a96304d0b4300a158a391fd113451e0cd4483d" +checksum = "5225b4dec45f3f3dbf383f12560fac5ce8d780f399893607e21406e12e77f491" [[package]] name = "cranelift-codegen" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62612786bf00e10999f50217d6f455d02b31591155881a45a903d1a95d1a4043" +checksum = "858fb3331e53492a95979378d6df5208dd1d0d315f19c052be8115f4efc888e0" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -97,14 +97,14 @@ dependencies = [ "serde", "smallvec", "target-lexicon", - "wasmtime-math", + "wasmtime-internal-math", ] [[package]] name = "cranelift-codegen-meta" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bae789df91ef236079733af9df11d852256c64af196f0bc6471ea0f5f301be" +checksum = "456715b9d5f12398f156d5081096e7b5d039f01b9ecc49790a011c8e43e65b5f" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -113,33 +113,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be319616d36527782558a8312508757815f64deb19b094c7b8f4337229a9bc6" +checksum = "0306041099499833f167a0ddb707e1e54100f1a84eab5631bc3dad249708f482" [[package]] name = "cranelift-control" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8810ee1ab5e9bd5cff4c0c8d240e2009cb5c2b79888fde1d5256d605712314b7" +checksum = "1672945e1f9afc2297f49c92623f5eabc64398e2cb0d824f8f72a2db2df5af23" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086452c97cfbe116bf17dbe622dc5fdf2ea97299c7d4ce42460f284387c9928a" +checksum = "aa3cd55eb5f3825b9ae5de1530887907360a6334caccdc124c52f6d75246c98a" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c27947010ab759330f252610c17a8cd64d123358be4f33164233d04fcd77b80" +checksum = "781f9905f8139b8de22987b66b522b416fe63eb76d823f0b3a8c02c8fd9500c7" dependencies = [ "cranelift-codegen", "log", @@ -149,15 +149,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec67bfb8bd55b1e9760eb9f5186dca8d81bd4d86110f8d5af01154a044c91802" +checksum = "a05337a2b02c3df00b4dd9a263a027a07b3dff49f61f7da3b5d195c21eaa633d" [[package]] name = "cranelift-jit" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d67cdfc447f2abdb46bb30a6582cce189539c3c051c1d5330692376e1400edff" +checksum = "593f8ff2c1a1785d9ab61a4b112ec1c9e8a3b976d8857ed1e70a79d4a07dd5ba" dependencies = [ "anyhow", "cranelift-codegen", @@ -169,15 +169,15 @@ dependencies = [ "log", "region", "target-lexicon", - "wasmtime-jit-icache-coherence", + "wasmtime-internal-jit-icache-coherence", "windows-sys 0.59.0", ] [[package]] name = "cranelift-module" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4597eaa52bca1ed111986c7a7f70cdbe192f83d271d627201365078e37b7e84" +checksum = "f9f7a4b804066f3e62d8fc943e25adc135acbb39288aa6c68e67021a9f6a0c58" dependencies = [ "anyhow", "cranelift-codegen", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a9b63edea46e013fce459c46e500462cb03a0490fdd9c18fe42b1dd7b93aa1" +checksum = "2eee7a496dd66380082c9c5b6f2d5fa149cec0ec383feec5caf079ca2b3671c2" dependencies = [ "cranelift-codegen", "libc", @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce706f0166d5b7f31693dff521e87cb9858e12adf22ffcde93c4a2826f8f04a9" +checksum = "0dc322ace52184f0ece213f4194f49762e7e854fafdf27b9bfd9fc738ba67708" dependencies = [ "anyhow", "cranelift-codegen", @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5870e266df8237b56cc98b04f5739c228565c92dd629ec6c66efa87271a158" +checksum = "b530783809a55cb68d070e0de60cfbb3db0dc94c8850dd5725411422bedcf6bb" [[package]] name = "crc32fast" @@ -452,10 +452,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "wasmtime-jit-icache-coherence" -version = "34.0.0" +name = "wasmtime-internal-jit-icache-coherence" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eedc0324e37cf39b049f4dca0c30997eaab49f09006d5f4c1994e64e7b7dba8" +checksum = "4417e06b7f80baff87d9770852c757a39b8d7f11d78b2620ca992b8725f16f50" dependencies = [ "anyhow", "cfg-if", @@ -464,10 +464,10 @@ dependencies = [ ] [[package]] -name = "wasmtime-math" -version = "34.0.0" +name = "wasmtime-internal-math" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd35fae4cf51d2b4a9bd2ef04b0eb309fa1849cab6a6ab5ac27cbd054ea284d" +checksum = "7710d5c4ecdaa772927fd11e5dc30a9a62d1fc8fe933e11ad5576ad596ab6612" dependencies = [ "libm", ] diff --git a/Cargo.toml b/Cargo.toml index a1f406df8c25..274ea16ed9c7 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.121.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.121.0" } -cranelift-module = { version = "0.121.0" } -cranelift-native = { version = "0.121.0" } -cranelift-jit = { version = "0.121.0", optional = true } -cranelift-object = { version = "0.121.0" } +cranelift-codegen = { version = "0.122.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.122.0" } +cranelift-module = { version = "0.122.0" } +cranelift-native = { version = "0.122.0" } +cranelift-jit = { version = "0.122.0", optional = true } +cranelift-object = { version = "0.122.0" } target-lexicon = "0.13" gimli = { version = "0.31", default-features = false, features = ["write"] } object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/src/base.rs b/src/base.rs index 5c826b50e8d1..e4802e301bb2 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,7 +2,7 @@ use cranelift_codegen::CodegenError; use cranelift_codegen::ir::UserFuncName; -use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; @@ -90,8 +90,7 @@ pub(crate) fn codegen_fn<'tcx>( None }; - let exception_slot = Variable::from_u32(0); - bcx.declare_var(exception_slot, pointer_type); + let exception_slot = bcx.declare_var(pointer_type); let mut fx = FunctionCx { module, @@ -115,7 +114,6 @@ pub(crate) fn codegen_fn<'tcx>( exception_slot, clif_comments, - next_ssa_var: 1, // var0 is used for the exception slot inline_asm: String::new(), inline_asm_index: 0, }; diff --git a/src/common.rs b/src/common.rs index 2272075c71a6..91b28164b686 100644 --- a/src/common.rs +++ b/src/common.rs @@ -295,9 +295,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) clif_comments: crate::pretty_clif::CommentWriter, - /// This should only be accessed by `CPlace::new_var`. - pub(crate) next_ssa_var: u32, - pub(crate) inline_asm: String, pub(crate) inline_asm_index: u32, } diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 9d73f200afe2..269a35b95858 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -393,9 +393,7 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap()); + let var = fx.bcx.declare_var(fx.clif_type(layout.ty).unwrap()); CPlace { inner: CPlaceInner::Var(local, var), layout } } @@ -404,14 +402,9 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var1 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let var2 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap(); - fx.bcx.declare_var(var1, ty1); - fx.bcx.declare_var(var2, ty2); + let var1 = fx.bcx.declare_var(ty1); + let var2 = fx.bcx.declare_var(ty2); CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout } } From 8483461b090db76f0da9d9196fcacbb2baed1da5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Jul 2025 10:15:35 +0000 Subject: [PATCH 059/525] Support used(linker) --- src/constant.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 3bd907b38cf6..735bbb10b35f 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -372,6 +372,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant continue; } + let mut data = DataDescription::new(); + let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { @@ -390,7 +392,10 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant (data_id, alloc, None) } TodoItem::Static(def_id) => { - let section_name = tcx.codegen_fn_attrs(def_id).link_section; + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); + let section_name = codegen_fn_attrs.link_section; + + data.set_used(codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)); let alloc = tcx.eval_static_initializer(def_id).unwrap(); @@ -405,7 +410,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } }; - let mut data = DataDescription::new(); let alloc = alloc.inner(); data.set_align(alloc.align.bytes()); From ae8c473c9f9571f47c01416732facee7df8fb49c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 13 Oct 2023 20:20:57 +0000 Subject: [PATCH 060/525] Give an AllocId to ConstValue::Slice. --- src/constant.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 85adf0f3716b..a7e9d7c7bae5 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -210,8 +210,7 @@ pub(crate) fn codegen_const_value<'tcx>( .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), - ConstValue::Slice { data, meta } => { - let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); + ConstValue::Slice { alloc_id, meta, phantom: _ } => { let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx); let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64); CValue::by_val_pair(ptr, len, layout) From 83907452bffc4951d5e5a022c23fee097825e844 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 3 Jul 2025 18:41:12 +0000 Subject: [PATCH 061/525] Remove useless lifetime parameter. --- src/constant.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index a7e9d7c7bae5..a04cfa272376 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -74,7 +74,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( pub(crate) fn eval_mir_constant<'tcx>( fx: &FunctionCx<'_, '_, 'tcx>, constant: &ConstOperand<'tcx>, -) -> (ConstValue<'tcx>, Ty<'tcx>) { +) -> (ConstValue, Ty<'tcx>) { let cv = fx.monomorphize(constant.const_); // This cannot fail because we checked all required_consts in advance. let val = cv @@ -93,7 +93,7 @@ pub(crate) fn codegen_constant_operand<'tcx>( pub(crate) fn codegen_const_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - const_val: ConstValue<'tcx>, + const_val: ConstValue, ty: Ty<'tcx>, ) -> CValue<'tcx> { let layout = fx.layout_of(ty); @@ -210,7 +210,7 @@ pub(crate) fn codegen_const_value<'tcx>( .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), - ConstValue::Slice { alloc_id, meta, phantom: _ } => { + ConstValue::Slice { alloc_id, meta } => { let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx); let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64); CValue::by_val_pair(ptr, len, layout) From d47ae4a9b6db4a589850d7f35ac7abd8dd3b3612 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:00:22 +0000 Subject: [PATCH 062/525] Rustup to rustc 1.90.0-nightly (b56aaec52 2025-07-24) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index b1a53d70b1ae..307a0ad12cc8 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-23" +channel = "nightly-2025-07-25" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 812388a717cbc1311aa7ab3f321d6503b56ecd16 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:27:09 +0000 Subject: [PATCH 063/525] Remove unnecessary download-ci-llvm from setup_rust_fork.sh --- scripts/setup_rust_fork.sh | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 532702bb1a46..724912973569 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -25,9 +25,6 @@ git -c user.name=Dummy -c user.email=dummy@example.com -c commit.gpgSign=false \ cat > config.toml < Date: Tue, 1 Jul 2025 09:33:35 -0700 Subject: [PATCH 064/525] Remove `[T]::array_chunks(_mut)` --- patches/0027-sysroot_tests-128bit-atomic-operations.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/0027-sysroot_tests-128bit-atomic-operations.patch b/patches/0027-sysroot_tests-128bit-atomic-operations.patch index f6e6bbc2387c..f3d1d5c43ea1 100644 --- a/patches/0027-sysroot_tests-128bit-atomic-operations.patch +++ b/patches/0027-sysroot_tests-128bit-atomic-operations.patch @@ -19,7 +19,7 @@ index 1e336bf..35e6f54 100644 -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] #![feature(alloc_layout_extra)] - #![feature(array_chunks)] + #![feature(array_ptr_get)] diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs index b735957..ea728b6 100644 --- a/coretests/tests/atomic.rs From bfdb1c16426131d4d304bc457fbf043e841cd9be Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:19:28 +0000 Subject: [PATCH 065/525] Skip pre-defining naked functions --- src/driver/mod.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 8f83c30b598d..9f2b7b4b09f2 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -38,16 +38,12 @@ fn predefine_mono_items<'tcx>( .codegen_instance_attrs(instance.def) .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(); + if is_naked { + // Naked functions are defined in a separate object + // file, so they can be declared on the fly. + continue; + } + module.declare_function(name, linkage, &sig).unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } From 00fd153d0d4e3e4956bdbaa8ba2c65e1d0bc1ba6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:41:03 +0000 Subject: [PATCH 066/525] Rustup to rustc 1.90.0-nightly (498ae9fed 2025-07-28) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 307a0ad12cc8..5f9602e509e0 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-25" +channel = "nightly-2025-07-29" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 91afcca7c5977fa325a683184ab196f4e2ea811e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:55:10 +0000 Subject: [PATCH 067/525] Fix rustc testsuite --- 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 1cd592a09ca6..895088c869d1 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -62,6 +62,7 @@ rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported +rm -r tests/ui/c-variadic/same-program-multiple-abis.rs # variadics for calling conventions other than C unsupported # requires LTO rm -r tests/run-make/cdylib From 54db8a58d31bf4ac3f329222c0ea513f8286712c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:00:41 +0000 Subject: [PATCH 068/525] Revert "Remove unnecessary download-ci-llvm from setup_rust_fork.sh" It caused LLVM to be cloned on CI. This reverts commit 812388a717cbc1311aa7ab3f321d6503b56ecd16. --- scripts/setup_rust_fork.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 724912973569..532702bb1a46 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -25,6 +25,9 @@ git -c user.name=Dummy -c user.email=dummy@example.com -c commit.gpgSign=false \ cat > config.toml < Date: Wed, 30 Jul 2025 16:27:33 +0800 Subject: [PATCH 069/525] Update `codegen_{cranelift,gcc}` and `opt-dist` to use `build.compiletest-allow-stage0` --- scripts/setup_rust_fork.sh | 1 + scripts/test_rustc_tests.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 532702bb1a46..492f4dc44527 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -33,6 +33,7 @@ rustc = "$(pwd)/../dist/bin/rustc-clif" cargo = "$(rustup which cargo)" full-bootstrap = true local-rebuild = true +compiletest-allow-stage0 = true [rust] download-rustc = false diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 7e356b4b462b..52e02c857c7a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -166,5 +166,5 @@ index 073116933bd..c3e4578204d 100644 EOF echo "[TEST] rustc test suite" -COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 --test-args=--no-capture tests/{codegen-units,run-make,ui,incremental} +./x.py test --stage 0 --test-args=--no-capture tests/{codegen-units,run-make,ui,incremental} popd From 0ac38e3fca5d43ae9d31bacb31f3559ece9c1c88 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:31:58 +0000 Subject: [PATCH 070/525] Rustup to rustc 1.90.0-nightly (3048886e5 2025-07-30) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 5f9602e509e0..fc01f8c3ccc2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-29" +channel = "nightly-2025-07-31" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8b11468ac1116e5a50575c5bbd1a49f98a769d89 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:47:43 +0000 Subject: [PATCH 071/525] Workaround portable-simd examples compilation failure --- build_system/tests.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 3c22450a15f6..6dd9ebb84587 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -209,13 +209,15 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ PORTABLE_SIMD.clean(&runner.dirs); - let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs); - build_cmd.arg("--all-targets"); + let build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs); + // FIXME uncomment once examples work: https://github.com/rust-lang/portable-simd/issues/470 + //build_cmd.arg("--all-targets"); spawn_and_wait(build_cmd); if runner.is_native { let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs); - test_cmd.arg("-q"); + // FIXME remove --tests once examples work: https://github.com/rust-lang/portable-simd/issues/470 + test_cmd.arg("-q").arg("--tests"); spawn_and_wait(test_cmd); } }), From 0056e5638e3524edf61143c768bf28284891b1f9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 5 Aug 2025 08:25:06 +0000 Subject: [PATCH 072/525] Rustup to rustc 1.91.0-nightly (0060d5a2a 2025-08-04) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index fc01f8c3ccc2..7fac7e81e959 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-31" +channel = "nightly-2025-08-05" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 878f3198818e0d2cd9563d44287f028d5392cdff Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 5 Aug 2025 08:32:33 +0000 Subject: [PATCH 073/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index fa6b6bffe9ec..3feda057a4dd 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -63,6 +63,7 @@ rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/c-variadic/same-program-multiple-abis.rs # variadics for calling conventions other than C unsupported +rm -r tests/ui/explicit-tail-calls # tail calls # requires LTO rm -r tests/run-make/cdylib From f4fde2092b3ad19f7b39fda98f6763a22b69ff1c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 7 Aug 2025 13:13:04 +0000 Subject: [PATCH 074/525] Prevent name collisions with internal implementation details The implementation of the linkage attribute inside extern blocks defines symbols starting with _rust_extern_with_linkage_. If someone tries to also define this symbol you will get a symbol conflict or even an ICE. By adding an unpredictable component to the symbol name, this becomes less of an issue. --- src/constant.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index a04cfa272376..bec546badc9c 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -310,7 +310,10 @@ fn data_id_for_static( // `extern_with_linkage_foo` will instead be initialized to // zero. - let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name); + let ref_name = format!( + "_rust_extern_with_linkage_{:016x}_{symbol_name}", + tcx.stable_crate_id(LOCAL_CRATE) + ); let ref_data_id = module.declare_data(&ref_name, Linkage::Local, false, false).unwrap(); let mut data = DataDescription::new(); data.set_align(align); From 20cc800415b4b491033d6a53b7fb31b5895b97ce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:39:03 +0000 Subject: [PATCH 075/525] Rustup to rustc 1.91.0-nightly (8e62bfd31 2025-08-12) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 7fac7e81e959..603413f6a78f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-05" +channel = "nightly-2025-08-13" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From d962e00471936cbbefbca80666c4566dd5ac08d5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:46:55 +0000 Subject: [PATCH 076/525] Fix rustc test suite --- scripts/setup_rust_fork.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 492f4dc44527..84c7ad534561 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -50,23 +50,23 @@ EOF cat <( + ); } + +- if b && dwn_ctx.is_running_on_ci { +- // On CI, we must always rebuild LLVM if there were any modifications to it +- panic!( +- "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead." +- ); +- } +- + // If download-ci-llvm=true we also want to check that CI llvm is available + b && llvm::is_ci_llvm_available_for_target(&dwn_ctx.host_target, asserts) + } EOF popd From 69402da11eacde8945bbf3551a2d9db23965a982 Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Tue, 12 Aug 2025 20:22:45 +0200 Subject: [PATCH 077/525] Port the `#[linkage]` attribute to the new attribute system --- src/constant.rs | 8 ++++---- src/driver/aot.rs | 5 ++--- src/linkage.rs | 3 ++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index bec546badc9c..a56466750e75 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -281,8 +281,8 @@ fn data_id_for_static( .abi .bytes(); - let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak - || import_linkage == rustc_middle::mir::mono::Linkage::WeakAny + let linkage = if import_linkage == rustc_hir::attrs::Linkage::ExternalWeak + || import_linkage == rustc_hir::attrs::Linkage::WeakAny { Linkage::Preemptible } else { @@ -332,8 +332,8 @@ fn data_id_for_static( let linkage = if definition { crate::linkage::get_static_linkage(tcx, def_id) - } else if attrs.linkage == Some(rustc_middle::mir::mono::Linkage::ExternalWeak) - || attrs.linkage == Some(rustc_middle::mir::mono::Linkage::WeakAny) + } else if attrs.linkage == Some(rustc_hir::attrs::Linkage::ExternalWeak) + || attrs.linkage == Some(rustc_hir::attrs::Linkage::WeakAny) { Linkage::Preemptible } else { diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 8ec3599b63d8..7e77781dc2fc 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -18,12 +18,11 @@ use rustc_codegen_ssa::{ use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; +use rustc_hir::attrs::Linkage as RLinkage; use rustc_metadata::fs::copy_to_stdout; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::mono::{ - CodegenUnit, Linkage as RLinkage, MonoItem, MonoItemData, Visibility, -}; +use rustc_middle::mir::mono::{CodegenUnit, MonoItem, MonoItemData, Visibility}; use rustc_session::Session; use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType}; diff --git a/src/linkage.rs b/src/linkage.rs index ca853aac1589..d76ab9d0109f 100644 --- a/src/linkage.rs +++ b/src/linkage.rs @@ -1,4 +1,5 @@ -use rustc_middle::mir::mono::{Linkage as RLinkage, MonoItem, Visibility}; +use rustc_hir::attrs::Linkage as RLinkage; +use rustc_middle::mir::mono::{MonoItem, Visibility}; use crate::prelude::*; From 420235c0f87bd379e3bd318b401ebbf08d82c44d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Aug 2025 16:24:09 +0000 Subject: [PATCH 078/525] Rustup to rustc 1.91.0-nightly (425a9c0a0 2025-08-17) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 603413f6a78f..4cd356e94b78 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-13" +channel = "nightly-2025-08-18" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From f4383ffa732267b74a9e23ae30a092f9ea4c2071 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Aug 2025 16:43:49 +0000 Subject: [PATCH 079/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 3feda057a4dd..7257cf97a365 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -149,6 +149,7 @@ rm tests/ui/backtrace/synchronized-panic-handler.rs # missing needs-unwind annot rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables +rm -r tests/run-make/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same From 8cb157c17d01e7130cd177f3c327663c01035376 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 6 Aug 2025 10:57:09 +0000 Subject: [PATCH 080/525] Update to Cranelift 0.123 --- Cargo.lock | 188 ++++++++++++++++++++++++++++------------ Cargo.toml | 28 +++--- src/abi/mod.rs | 8 +- src/debuginfo/mod.rs | 1 + src/debuginfo/unwind.rs | 40 +++++---- src/intrinsics/mod.rs | 8 +- 6 files changed, 181 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0187e07a6bba..2f58bcc00b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae7b60ec3fd7162427d3b3801520a1908bef7c035b52983cd3ca11b8e7deb51" +checksum = "ed4b70d50ef7f5a1fe6acd4dd5fe1050abb96da29cfd9dbd816425468b077054" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6511c200fed36452697b4b6b161eae57d917a2044e6333b1c1389ed63ccadeee" +checksum = "e2a0508022f39d640b5830b831dd3cb98e4d5e2d35b46cf9fc2a098805234365" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7086a645aa58bae979312f64e3029ac760ac1b577f5cd2417844842a2ca07f" +checksum = "56f60341caf62338f84d8e1a6261d9b72b00932564094d37d12215028a3fae95" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5225b4dec45f3f3dbf383f12560fac5ce8d780f399893607e21406e12e77f491" +checksum = "9f01687e7f1cb4ec9394b4ba13c1e1835edbec012304cf2f854537deec901aeb" [[package]] name = "cranelift-codegen" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "858fb3331e53492a95979378d6df5208dd1d0d315f19c052be8115f4efc888e0" +checksum = "7c24d59006f532c84fae3c7bae9fadfc569d9912c5d0bf67ea8c20de289b5786" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,44 +102,45 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456715b9d5f12398f156d5081096e7b5d039f01b9ecc49790a011c8e43e65b5f" +checksum = "0b250ca6c45149339f3908f1137f28faa4dba0f12673f8b6c6201a733f6e012a" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", "cranelift-srcgen", + "heck", ] [[package]] name = "cranelift-codegen-shared" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306041099499833f167a0ddb707e1e54100f1a84eab5631bc3dad249708f482" +checksum = "4923507eb61e357184e4c5e11052dbca7abcee3a306dfaa62cd2f2bdd9851c51" [[package]] name = "cranelift-control" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1672945e1f9afc2297f49c92623f5eabc64398e2cb0d824f8f72a2db2df5af23" +checksum = "ed6bf355bddc171ac2d5a62e6cfa8f1eb1b37667924210e400cbc65e53870bf2" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa3cd55eb5f3825b9ae5de1530887907360a6334caccdc124c52f6d75246c98a" +checksum = "60f0c0e4057964aa3c6597606986ed5df32d465838ad389f226461bf562555c7" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781f9905f8139b8de22987b66b522b416fe63eb76d823f0b3a8c02c8fd9500c7" +checksum = "f39ca2f29e01050443d5d4d59fe674b7107641d79a9a847d5a01fded8264b9f2" dependencies = [ "cranelift-codegen", "log", @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a05337a2b02c3df00b4dd9a263a027a07b3dff49f61f7da3b5d195c21eaa633d" +checksum = "14633795ccf9b5f3ef8484dc6bfed943118330fc18a2172dc7aac661473558b1" [[package]] name = "cranelift-jit" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "593f8ff2c1a1785d9ab61a4b112ec1c9e8a3b976d8857ed1e70a79d4a07dd5ba" +checksum = "de5044e1a2211eaf40348f387334566f266531b7a6ae60fb7d0c944db0ad8731" dependencies = [ "anyhow", "cranelift-codegen", @@ -170,14 +171,14 @@ dependencies = [ "region", "target-lexicon", "wasmtime-internal-jit-icache-coherence", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "cranelift-module" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f7a4b804066f3e62d8fc943e25adc135acbb39288aa6c68e67021a9f6a0c58" +checksum = "625cb9020a5358a194da5a3a918d1ff29ee89f8191a3ccd7a485255364f32776" dependencies = [ "anyhow", "cranelift-codegen", @@ -186,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eee7a496dd66380082c9c5b6f2d5fa149cec0ec383feec5caf079ca2b3671c2" +checksum = "2a178fab381ece04958d895eff2bd5ddecb8537e08fb1af3eb92e45dd3e50301" dependencies = [ "cranelift-codegen", "libc", @@ -197,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc322ace52184f0ece213f4194f49762e7e854fafdf27b9bfd9fc738ba67708" +checksum = "11fc0edb2994ccc8802801c35c08572c443dca716e988110e63bfc9d81f0bbf1" dependencies = [ "anyhow", "cranelift-codegen", @@ -212,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b530783809a55cb68d070e0de60cfbb3db0dc94c8850dd5725411422bedcf6bb" +checksum = "07a6f374259f252ae78cbf9aad469091d6a51adda43cb91d23610532cf2b978e" [[package]] name = "crc32fast" @@ -245,9 +246,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" dependencies = [ "fallible-iterator", "indexmap", @@ -263,6 +264,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "indexmap" version = "2.10.0" @@ -286,7 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -318,9 +325,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", "hashbrown", @@ -453,41 +460,47 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "35.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4417e06b7f80baff87d9770852c757a39b8d7f11d78b2620ca992b8725f16f50" +checksum = "118c225f1c3c688c423de99d590b6e06fa811207090eeb9f4423b6a2d0113ff5" dependencies = [ "anyhow", "cfg-if", "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "wasmtime-internal-math" -version = "35.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7710d5c4ecdaa772927fd11e5dc30a9a62d1fc8fe933e11ad5576ad596ab6612" +checksum = "8b2378d723f821a5f24076bd9bed4ec849c24717c7af188d4f31fff1d7fc6cfe" dependencies = [ "libm", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets", + "windows-targets 0.53.3", ] [[package]] @@ -496,14 +509,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -512,44 +542,92 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" diff --git a/Cargo.toml b/Cargo.toml index 274ea16ed9c7..945854842f2d 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.122.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.122.0" } -cranelift-module = { version = "0.122.0" } -cranelift-native = { version = "0.122.0" } -cranelift-jit = { version = "0.122.0", optional = true } -cranelift-object = { version = "0.122.0" } +cranelift-codegen = { version = "0.123.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.123.0" } +cranelift-module = { version = "0.123.0" } +cranelift-native = { version = "0.123.0" } +cranelift-jit = { version = "0.123.0", optional = true } +cranelift-object = { version = "0.123.0" } target-lexicon = "0.13" -gimli = { version = "0.31", default-features = false, features = ["write"] } -object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +gimli = { version = "0.32", default-features = false, features = ["write"] } +object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.8.0", optional = true } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-35.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 52f1a946762f..075f2e2f5977 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -7,7 +7,9 @@ mod returning; use std::borrow::Cow; use std::mem; -use cranelift_codegen::ir::{ArgumentPurpose, BlockArg, ExceptionTableData, ExceptionTag, SigRef}; +use cranelift_codegen::ir::{ + ArgumentPurpose, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, SigRef, +}; use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_abi::{CanonAbi, ExternAbi, X86Call}; @@ -856,8 +858,8 @@ pub(crate) fn codegen_call_with_unwind_action( let exception_table = fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( sig_ref, fallthrough_block_call, - [( - Some(ExceptionTag::with_number(EXCEPTION_HANDLER_CLEANUP).unwrap()), + [ExceptionTableItem::Tag( + ExceptionTag::with_number(EXCEPTION_HANDLER_CLEANUP).unwrap(), pre_cleanup_block_call, )], )); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 391ce5200847..05b0253eff97 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -120,6 +120,7 @@ impl DebugContext { encoding, LineEncoding::default(), LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings), + None, LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings), file_info, ); diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 02f6b1d39bc2..ecaf88a26259 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -1,5 +1,6 @@ //! Unwind info generation (`.eh_frame`) +use cranelift_codegen::FinalizedMachExceptionHandler; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::unwind::UnwindInfo; use cranelift_module::DataId; @@ -172,23 +173,28 @@ impl UnwindContext { action_entry: None, }); } - for &(tag, landingpad) in call_site.exception_handlers { - match tag.expand().unwrap().as_u32() { - EXCEPTION_HANDLER_CLEANUP => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: None, - }) - } - EXCEPTION_HANDLER_CATCH => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: Some(catch_action), - }) + for &handler in call_site.exception_handlers { + match handler { + FinalizedMachExceptionHandler::Tag(tag, landingpad) => { + match tag.as_u32() { + EXCEPTION_HANDLER_CLEANUP => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: None, + }) + } + EXCEPTION_HANDLER_CATCH => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: Some(catch_action), + }) + } + _ => unreachable!(), + } } _ => unreachable!(), } diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index d240ff3b3dd3..eab1a506fd0e 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -17,7 +17,9 @@ mod llvm_aarch64; mod llvm_x86; mod simd; -use cranelift_codegen::ir::{AtomicRmwOp, BlockArg, ExceptionTableData, ExceptionTag}; +use cranelift_codegen::ir::{ + AtomicRmwOp, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, +}; use rustc_middle::ty; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::layout::ValidityRequirement; @@ -1381,8 +1383,8 @@ fn codegen_regular_intrinsic_call<'tcx>( fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( f_sig, fallthrough_block_call, - [( - Some(ExceptionTag::with_number(EXCEPTION_HANDLER_CATCH).unwrap()), + [ExceptionTableItem::Tag( + ExceptionTag::with_number(EXCEPTION_HANDLER_CATCH).unwrap(), catch_block_call, )], )); From 4a47066323a5d4b0068126101d6ac4fb81b3c463 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 13 Aug 2025 11:29:36 +0000 Subject: [PATCH 081/525] Update libloading This pulls in a newer version of windows-targets. The region crate still pulls in the older version though. --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f58bcc00b18..2c6acb600b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,12 +288,12 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.3", ] [[package]] From 69d5855ba3a100fadda5692eb4e1bc90e67528ac Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:19:08 +0000 Subject: [PATCH 082/525] Rustup to rustc 1.91.0-nightly (040a98af7 2025-08-20) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 4cd356e94b78..f017fe3c3024 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-18" +channel = "nightly-2025-08-21" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8c3a60c0879c03266c7f589e44450fc14af6b3e0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:25:12 +0000 Subject: [PATCH 083/525] Fix rustc test suite --- 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 7257cf97a365..0517b16acdf4 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -75,7 +75,6 @@ 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 From dbca51abe68f0fbc562cb7a0309bf8b7a337d60e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:37:30 +0000 Subject: [PATCH 084/525] Temporarily disable x86_64 macOS Upstream rustc broke it when turning it into a tier 2 target --- .github/workflows/abi-cafe.yml | 7 ++++--- .github/workflows/main.yml | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index 6ad041a796c9..75a506868a0f 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -28,9 +28,10 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 - env: - TARGET_TRIPLE: x86_64-apple-darwin + # FIXME(rust-lang/rust#145699) + #- os: macos-13 + # env: + # TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d92e0fdce99a..c7409fa63429 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,9 +56,10 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 - env: - TARGET_TRIPLE: x86_64-apple-darwin + # FIXME(rust-lang/rust#145699) + #- os: macos-13 + # env: + # TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin @@ -187,9 +188,10 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 - env: - TARGET_TRIPLE: x86_64-apple-darwin + # FIXME(rust-lang/rust#145699) + #- os: macos-13 + # env: + # TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin From cdab4cc90ead3845ac3c78a3c6a2a01299281684 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 24 Aug 2025 13:22:55 +0000 Subject: [PATCH 085/525] Rustup to rustc 1.91.0-nightly (69b76df90 2025-08-23) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index f017fe3c3024..53ef4a76f41a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-21" +channel = "nightly-2025-08-24" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 03505e815c9c3f159febcd57e7d6dca19b0cc605 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 24 Aug 2025 13:49:04 +0000 Subject: [PATCH 086/525] 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 0517b16acdf4..13951c0a70a8 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -62,7 +62,7 @@ rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported -rm -r tests/ui/c-variadic/same-program-multiple-abis.rs # variadics for calling conventions other than C unsupported +rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm -r tests/ui/explicit-tail-calls # tail calls # requires LTO From 2da17a63843f81f6f006f5116834bb8c0a827a5d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Aug 2025 09:45:53 +0000 Subject: [PATCH 087/525] Rustup to rustc 1.91.0-nightly (cdb45c87e 2025-08-27) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 53ef4a76f41a..6fe2ec48e606 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-24" +channel = "nightly-2025-08-28" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 42943a93cc6f9ba87213e212da7ee4c84a9bcf98 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:41:14 +0000 Subject: [PATCH 088/525] Re-enable x86_64 macOS CI builds --- .github/workflows/main.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c7409fa63429..d92e0fdce99a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,10 +56,9 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - # FIXME(rust-lang/rust#145699) - #- os: macos-13 - # env: - # TARGET_TRIPLE: x86_64-apple-darwin + - os: macos-13 + env: + TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin @@ -188,10 +187,9 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - # FIXME(rust-lang/rust#145699) - #- os: macos-13 - # env: - # TARGET_TRIPLE: x86_64-apple-darwin + - os: macos-13 + env: + TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin From 675ba3834574870c5bca4033578644b57b31dffd Mon Sep 17 00:00:00 2001 From: Oleksandr Babak Date: Sun, 31 Aug 2025 14:34:29 +0200 Subject: [PATCH 089/525] feat: add `from_fn_ptr` to `Waker` and `LocalWaker` --- library/core/src/task/wake.rs | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index bb7efe582f7a..178717fe42ea 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -584,6 +584,28 @@ impl Waker { pub fn vtable(&self) -> &'static RawWakerVTable { self.waker.vtable } + + /// Constructs a `Waker` from a function pointer. + #[inline] + #[must_use] + #[unstable(feature = "waker_from_fn_ptr", issue = "146055")] + pub const fn from_fn_ptr(f: fn()) -> Self { + // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it + // is sound to transmute it back to `fn()`. + static VTABLE: RawWakerVTable = unsafe { + RawWakerVTable::new( + |this| RawWaker::new(this, &VTABLE), + |this| transmute::<*const (), fn()>(this)(), + |this| transmute::<*const (), fn()>(this)(), + |_| {}, + ) + }; + let raw = RawWaker::new(f as *const (), &VTABLE); + + // SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and + // `wake_by_ref` just call the function pointer. + unsafe { Self::from_raw(raw) } + } } #[stable(feature = "futures_api", since = "1.36.0")] @@ -879,6 +901,28 @@ impl LocalWaker { pub fn vtable(&self) -> &'static RawWakerVTable { self.waker.vtable } + + /// Constructs a `LocalWaker` from a function pointer. + #[inline] + #[must_use] + #[unstable(feature = "waker_from_fn_ptr", issue = "146055")] + pub const fn from_fn_ptr(f: fn()) -> Self { + // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it + // is sound to transmute it back to `fn()`. + static VTABLE: RawWakerVTable = unsafe { + RawWakerVTable::new( + |this| RawWaker::new(this, &VTABLE), + |this| transmute::<*const (), fn()>(this)(), + |this| transmute::<*const (), fn()>(this)(), + |_| {}, + ) + }; + let raw = RawWaker::new(f as *const (), &VTABLE); + + // SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and + // `wake_by_ref` just call the function pointer. + unsafe { Self::from_raw(raw) } + } } #[unstable(feature = "local_waker", issue = "118959")] impl Clone for LocalWaker { From b494d3e73dd17318032fa406f3deb73cc7b659ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 Aug 2025 09:13:23 +1000 Subject: [PATCH 090/525] Avoid unnecessary `mut`-ness for various closures. --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index bc0a0f034b23..aefb9c9a1156 100644 --- a/src/base.rs +++ b/src/base.rs @@ -46,7 +46,7 @@ pub(crate) fn codegen_fn<'tcx>( with_no_trimmed_paths!({ use rustc_middle::mir::pretty; let options = pretty::PrettyPrintMirOptions::from_cli(tcx); - pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf, options).unwrap(); + pretty::write_mir_fn(tcx, mir, &|_, _| Ok(()), &mut buf, options).unwrap(); }); String::from_utf8_lossy(&buf).into_owned() }); From 3293a0b6b7973f816652c4a2380eb897b4f262ed Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 Aug 2025 14:38:17 +1000 Subject: [PATCH 091/525] Introduce `MirDumper` and `MirWriter`. MIR dumping is a mess. There are lots of functions and entry points, e.g. `dump_mir`, `dump_mir_with_options`, `dump_polonius_mir`, `dump_mir_to_writer`. Also, it's crucial that `create_dump_file` is never called without `dump_enabled` first being checked, but there is no mechanism for ensuring this and it's hard to tell if it is satisfied on all paths. (`dump_enabled` is checked twice on some paths, however!) This commit introduces `MirWriter`, which controls the MIR writing, and encapsulates the `extra_data` closure and `options`. Two existing functions are now methods of this type. It sets reasonable defaults, allowing the removal of many `|_, _| Ok(())` closures. The commit also introduces `MirDumper`, which is layered on top of `MirWriter`, and which manages the creation of the dump files, encapsulating pass names, disambiguators, etc. Four existing functions are now methods of this type. - `MirDumper::new` will only succeed if dumps are enabled, and will return `None` otherwise, which makes it impossible to dump when you shouldn't. - It also sets reasonable defaults for various things like disambiguators, which means you no longer need to specify them in many cases. When they do need to be specified, it's now done via setter methods. - It avoids some repetition. E.g. `dump_nll_mir` previously specifed the pass name `"nll"` four times and the disambiguator `&0` three times; now it specifies them just once, to put them in the `MirDumper`. - For Polonius, the `extra_data` closure can now be specified earlier, which avoids having to pass some arguments through some functions. --- src/base.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index aefb9c9a1156..3a28dd7e73cb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -44,9 +44,8 @@ pub(crate) fn codegen_fn<'tcx>( let _mir_guard = crate::PrintOnPanic(|| { let mut buf = Vec::new(); with_no_trimmed_paths!({ - use rustc_middle::mir::pretty; - let options = pretty::PrettyPrintMirOptions::from_cli(tcx); - pretty::write_mir_fn(tcx, mir, &|_, _| Ok(()), &mut buf, options).unwrap(); + let writer = pretty::MirWriter::new(tcx); + writer.write_mir_fn(mir, &mut buf).unwrap(); }); String::from_utf8_lossy(&buf).into_owned() }); From 9de73c86f373edec2381d17da180d9d533190519 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 2 Sep 2025 17:23:07 +0000 Subject: [PATCH 092/525] Rename the default branch to main --- scripts/rustup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 152c243aa6ad..fdfd03029b16 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -46,7 +46,7 @@ case $1 in git pull origin master branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" - "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git master + "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main git push -u my "$branch" # immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing From 3b311c32e59c2040c8c2d62762a01bb4a400fccd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 2 Sep 2025 20:03:41 +0000 Subject: [PATCH 093/525] Rustup to rustc 1.91.0-nightly (7aef4bec4 2025-09-01) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 6fe2ec48e606..ee94deedfe4c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-28" +channel = "nightly-2025-09-02" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8878a67f1bb5c90884cc60ea567e38f933b9e831 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Aug 2025 10:26:29 +0000 Subject: [PATCH 094/525] Special case allocator module submission to avoid special casing it elsewhere A lot of places had special handling just in case they would get an allocator module even though most of these places could never get one or would have a trivial implementation for the allocator module. Moving all handling of the allocator module to a single place simplifies things a fair bit. --- src/driver/aot.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 7e77781dc2fc..c3adb5e767e2 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -12,9 +12,7 @@ use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{ - CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors, -}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, errors as ssa_errors}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; @@ -363,7 +361,6 @@ fn emit_cgu( invocation_temp, prof, product.object, - ModuleKind::Regular, name.clone(), producer, )?; @@ -372,7 +369,6 @@ fn emit_cgu( module_regular, module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule { name: format!("{name}.asm"), - kind: ModuleKind::Regular, object: Some(global_asm_object_file), dwarf_object: None, bytecode: None, @@ -389,7 +385,6 @@ fn emit_module( invocation_temp: Option<&str>, prof: &SelfProfilerRef, mut object: cranelift_object::object::write::Object<'_>, - kind: ModuleKind, name: String, producer_str: &str, ) -> Result { @@ -430,7 +425,6 @@ fn emit_module( Ok(CompiledModule { name, - kind, object: Some(tmp_file), dwarf_object: None, bytecode: None, @@ -485,7 +479,6 @@ fn reuse_workproduct_for_cgu( Ok(ModuleCodegenResult { module_regular: CompiledModule { name: cgu.name().to_string(), - kind: ModuleKind::Regular, object: Some(obj_out_regular), dwarf_object: None, bytecode: None, @@ -495,7 +488,6 @@ fn reuse_workproduct_for_cgu( }, module_global_asm: source_file_global_asm.map(|source_file| CompiledModule { name: cgu.name().to_string(), - kind: ModuleKind::Regular, object: Some(obj_out_global_asm), dwarf_object: None, bytecode: None, @@ -651,7 +643,6 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option { tcx.sess.invocation_temp.as_deref(), &tcx.sess.prof, product.object, - ModuleKind::Allocator, "allocator_shim".to_owned(), &crate::debuginfo::producer(tcx.sess), ) { From 39d8f6a7a32e6322b526fd266fe32622ead219dc Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 5 Sep 2025 16:35:36 +0800 Subject: [PATCH 095/525] cg_clif: account for moved `tests/run-make-cargo/compiler-builtins` --- 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 52e02c857c7a..476a6f311bbf 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -121,7 +121,7 @@ rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift # ============================================================ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump rm -r tests/run-make/strip # same -rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source +rm -r tests/run-make-cargo/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source rm -r tests/run-make/translation # same rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features rm -r tests/run-make/const-trait-stable-toolchain # same From 719b14c3a73f84d1a1a64277bee37ce48f5bc929 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 5 Sep 2025 21:24:45 +0800 Subject: [PATCH 096/525] cg_clif: run `run-make-cargo` 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 476a6f311bbf..62f1cc6a8933 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -166,5 +166,5 @@ index 073116933bd..c3e4578204d 100644 EOF echo "[TEST] rustc test suite" -./x.py test --stage 0 --test-args=--no-capture tests/{codegen-units,run-make,ui,incremental} +./x.py test --stage 0 --test-args=--no-capture tests/{codegen-units,run-make,run-make-cargo,ui,incremental} popd From 877448730a206d8b773adf99b4fb162465c95528 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 5 Sep 2025 19:09:39 +0000 Subject: [PATCH 097/525] Ensure fat LTO doesn't merge everything into the allocator module --- src/driver/aot.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index c3adb5e767e2..7e77781dc2fc 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -12,7 +12,9 @@ use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, errors as ssa_errors}; +use rustc_codegen_ssa::{ + CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors, +}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; @@ -361,6 +363,7 @@ fn emit_cgu( invocation_temp, prof, product.object, + ModuleKind::Regular, name.clone(), producer, )?; @@ -369,6 +372,7 @@ fn emit_cgu( module_regular, module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule { name: format!("{name}.asm"), + kind: ModuleKind::Regular, object: Some(global_asm_object_file), dwarf_object: None, bytecode: None, @@ -385,6 +389,7 @@ fn emit_module( invocation_temp: Option<&str>, prof: &SelfProfilerRef, mut object: cranelift_object::object::write::Object<'_>, + kind: ModuleKind, name: String, producer_str: &str, ) -> Result { @@ -425,6 +430,7 @@ fn emit_module( Ok(CompiledModule { name, + kind, object: Some(tmp_file), dwarf_object: None, bytecode: None, @@ -479,6 +485,7 @@ fn reuse_workproduct_for_cgu( Ok(ModuleCodegenResult { module_regular: CompiledModule { name: cgu.name().to_string(), + kind: ModuleKind::Regular, object: Some(obj_out_regular), dwarf_object: None, bytecode: None, @@ -488,6 +495,7 @@ fn reuse_workproduct_for_cgu( }, module_global_asm: source_file_global_asm.map(|source_file| CompiledModule { name: cgu.name().to_string(), + kind: ModuleKind::Regular, object: Some(obj_out_global_asm), dwarf_object: None, bytecode: None, @@ -643,6 +651,7 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option { tcx.sess.invocation_temp.as_deref(), &tcx.sess.prof, product.object, + ModuleKind::Allocator, "allocator_shim".to_owned(), &crate::debuginfo::producer(tcx.sess), ) { From 39aa1ee936da62047dbb2652a2171c237e9e95f1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 7 Sep 2025 11:59:30 +0000 Subject: [PATCH 098/525] Rustup to rustc 1.91.0-nightly (1ed3cd703 2025-09-06) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index ee94deedfe4c..e20c05056ff7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-09-02" +channel = "nightly-2025-09-07" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From d077c1e30c18cb726b432b21dbce0c31a737c0c3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 7 Sep 2025 14:55:38 +0000 Subject: [PATCH 099/525] 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 b50580ba623e..75b614ff4bd4 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -148,7 +148,7 @@ rm tests/ui/backtrace/synchronized-panic-handler.rs # missing needs-unwind annot rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables -rm -r tests/run-make/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug +rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same From 8977078e1f71164ab9a1fb647d981130f5a41780 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:22:44 +0000 Subject: [PATCH 100/525] Rustup to rustc 1.91.0-nightly (5eda692e7 2025-09-11) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index e20c05056ff7..86cd3abad35a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-09-07" +channel = "nightly-2025-09-12" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 1d61b61f69d014802d9656db99286eca13e87ea3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:49:37 +0000 Subject: [PATCH 101/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 75b614ff4bd4..9c9dc2f58913 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -45,6 +45,7 @@ rm -r tests/run-make/naked-symbol-visibility 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/c-variadic/valid.rs # same rm tests/ui/delegation/fn-header.rs # misc unimplemented things From 7fdb85538d9d13c68bde46a26def632390b48a05 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:20:54 +0000 Subject: [PATCH 102/525] Rustup to rustc 1.92.0-nightly (52618eb33 2025-09-14) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 86cd3abad35a..d82f5180317d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-09-12" +channel = "nightly-2025-09-15" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 1988e68a35c70775d385d8a1253353eabe13ed70 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:03:03 +0000 Subject: [PATCH 103/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9c9dc2f58913..1a65d70205d8 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -46,6 +46,7 @@ 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/c-variadic/valid.rs # same +rm tests/ui/c-variadic/naked.rs # same rm tests/ui/delegation/fn-header.rs # misc unimplemented things From 78d8ce7301ef5dd562ea0e06e2b316f1a8d04bf2 Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Sat, 6 Sep 2025 01:14:31 -0400 Subject: [PATCH 104/525] add SliceIndex wrapper types Last and Clamp --- library/core/src/index.rs | 472 +++++++++++++++++++++++++++++++ library/core/src/lib.rs | 1 + library/core/src/range.rs | 12 + library/core/src/slice/index.rs | 5 + library/coretests/tests/index.rs | 83 ++++++ library/coretests/tests/lib.rs | 4 + 6 files changed, 577 insertions(+) create mode 100644 library/core/src/index.rs create mode 100644 library/coretests/tests/index.rs diff --git a/library/core/src/index.rs b/library/core/src/index.rs new file mode 100644 index 000000000000..3baefdf10cec --- /dev/null +++ b/library/core/src/index.rs @@ -0,0 +1,472 @@ +#![unstable(feature = "sliceindex_wrappers", issue = "146179")] + +//! Helper types for indexing slices. + +use crate::intrinsics::slice_get_unchecked; +use crate::slice::SliceIndex; +use crate::{cmp, ops, range}; + +/// Clamps an index, guaranteeing that it will only access valid elements of the slice. +/// +/// # Examples +/// +/// ``` +/// #![feature(sliceindex_wrappers)] +/// +/// use core::index::Clamp; +/// +/// let s: &[usize] = &[0, 1, 2, 3]; +/// +/// assert_eq!(&3, &s[Clamp(6)]); +/// assert_eq!(&[1, 2, 3], &s[Clamp(1..6)]); +/// assert_eq!(&[] as &[usize], &s[Clamp(5..6)]); +/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..6)]); +/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..=6)]); +/// assert_eq!(&[] as &[usize], &s[Clamp(6..)]); +/// ``` +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +#[derive(Debug)] +pub struct Clamp(pub Idx); + +/// Always accesses the last element of the slice. +/// +/// # Examples +/// +/// ``` +/// #![feature(sliceindex_wrappers)] +/// #![feature(slice_index_methods)] +/// +/// use core::index::Last; +/// use core::slice::SliceIndex; +/// +/// let s = &[0, 1, 2, 3]; +/// +/// assert_eq!(&3, &s[Last]); +/// assert_eq!(None, Last.get(&[] as &[usize])); +/// +/// ``` +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +#[derive(Debug)] +pub struct Last; + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp { + type Output = T; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + slice.get(cmp::min(self.0, slice.len() - 1)) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + slice.get_mut(cmp::min(self.0, slice.len() - 1)) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + &(*slice)[cmp::min(self.0, slice.len() - 1)] + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + &mut (*slice)[cmp::min(self.0, slice.len() - 1)] + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + // SAFETY: a range ending before len is always valid + unsafe { (start..end).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + // SAFETY: a range ending before len is always valid + unsafe { (start..end).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + // SAFETY: a range ending before len is always valid + unsafe { (start..end).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + // SAFETY: a range ending before len is always valid + unsafe { (start..end).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + let start = cmp::min(self.0.start, slice.len()); + let end = cmp::min(self.0.end, slice.len()); + (start..end).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + (start..=end).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + (start..=end).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (start..=end).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (start..=end).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + (start..=end).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.last, slice.len() - 1); + (start..=end).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + (start..=end).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + (start..=end).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (start..=end).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (start..=end).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + (start..=end).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + let start = cmp::min(self.0.start, slice.len() - 1); + let end = cmp::min(self.0.end, slice.len() - 1); + (start..=end).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (cmp::min(self.0.start, slice.len())..).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (cmp::min(self.0.start, slice.len())..).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: a range starting at len is valid + unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: a range starting at len is valid + unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (cmp::min(self.0.start, slice.len())..).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (cmp::min(self.0.start, slice.len())..).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (cmp::min(self.0.start, slice.len())..).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (cmp::min(self.0.start, slice.len())..).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: a range starting at len is valid + unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: a range starting at len is valid + unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (cmp::min(self.0.start, slice.len())..).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (cmp::min(self.0.start, slice.len())..).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (..cmp::min(self.0.end, slice.len())).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (..cmp::min(self.0.end, slice.len())).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: a range ending before len is always valid + unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: a range ending before len is always valid + unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (..cmp::min(self.0.end, slice.len())).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (..cmp::min(self.0.end, slice.len())).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (..=cmp::min(self.0.last, slice.len() - 1)).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (..=cmp::min(self.0.last, slice.len() - 1)).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (..=cmp::min(self.0.last, slice.len() - 1)).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (..=cmp::min(self.0.last, slice.len() - 1)).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (..=cmp::min(self.0.end, slice.len() - 1)).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (..=cmp::min(self.0.end, slice.len() - 1)).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (..=cmp::min(self.0.end, slice.len() - 1)).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (..=cmp::min(self.0.end, slice.len() - 1)).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Clamp { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + (..).get(slice) + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + (..).get_mut(slice) + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: RangeFull just returns `slice` here + unsafe { (..).get_unchecked(slice) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: RangeFull just returns `slice` here + unsafe { (..).get_unchecked_mut(slice) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + (..).index(slice) + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + (..).index_mut(slice) + } +} + +#[unstable(feature = "sliceindex_wrappers", issue = "146179")] +unsafe impl SliceIndex<[T]> for Last { + type Output = T; + + fn get(self, slice: &[T]) -> Option<&Self::Output> { + slice.last() + } + + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + slice.last_mut() + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { slice_get_unchecked(slice, slice.len() - 1) } + } + + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: the caller ensures that the slice isn't empty + unsafe { slice_get_unchecked(slice, slice.len() - 1) } + } + + fn index(self, slice: &[T]) -> &Self::Output { + // N.B., use intrinsic indexing + &(*slice)[slice.len() - 1] + } + + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + // N.B., use intrinsic indexing + &mut (*slice)[slice.len() - 1] + } +} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 86a68e18b0af..db059b86a8c8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -292,6 +292,7 @@ pub mod cmp; pub mod convert; pub mod default; pub mod error; +pub mod index; pub mod marker; pub mod ops; diff --git a/library/core/src/range.rs b/library/core/src/range.rs index a096a8ceafc8..ee8252c17765 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -629,6 +629,18 @@ impl> RangeToInclusive { } } +impl From> for RangeToInclusive { + fn from(value: legacy::RangeToInclusive) -> Self { + Self { last: value.end } + } +} + +impl From> for legacy::RangeToInclusive { + fn from(value: RangeToInclusive) -> Self { + Self { end: value.last } + } +} + // RangeToInclusive cannot impl From> // because underflow would be possible with (..0).into() diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index a8147d745f3a..40baff3f4465 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -134,6 +134,11 @@ mod private_slice_index { impl Sealed for range::RangeFrom {} impl Sealed for ops::IndexRange {} + + #[unstable(feature = "sliceindex_wrappers", issue = "146179")] + impl Sealed for crate::index::Last {} + #[unstable(feature = "sliceindex_wrappers", issue = "146179")] + impl Sealed for crate::index::Clamp where T: Sealed {} } /// A helper trait used for indexing operations. diff --git a/library/coretests/tests/index.rs b/library/coretests/tests/index.rs new file mode 100644 index 000000000000..68e4c841e322 --- /dev/null +++ b/library/coretests/tests/index.rs @@ -0,0 +1,83 @@ +use core::index::Clamp; +use core::range; +use core::slice::SliceIndex; + +macro_rules! test_clamp { + ($range:expr, $(($slice:expr, $other:expr)),+) => { + $( + assert_eq!(Clamp($range.clone()).get(&$slice as &[_]), $other.get(&$slice as &[_])); + assert_eq!(Clamp($range.clone()).get_mut(&mut $slice as &mut [_]), $other.get_mut(&mut $slice as &mut [_])); + unsafe { + assert_eq!(&*Clamp($range.clone()).get_unchecked(&$slice as &[_]), &*$other.get_unchecked(&$slice as &[_])); + assert_eq!(&*Clamp($range.clone()).get_unchecked_mut(&mut $slice as &mut [_]), &*$other.get_unchecked_mut(&mut $slice as &mut [_])); + } + assert_eq!(Clamp($range.clone()).index(&$slice as &[_]), $other.index(&$slice as &[_])); + assert_eq!(Clamp($range.clone()).index_mut(&mut $slice as &mut [_]), $other.index_mut(&mut $slice as &mut [_])); + )+ + }; +} + +#[test] +fn test_clamp_usize() { + test_clamp!(2, ([0, 1], 1), ([0, 1, 2], 2)); +} + +#[test] +fn test_clamp_range_range() { + test_clamp!(range::Range::from(1..4), ([0, 1], 1..2), ([0, 1, 2, 3, 4], 1..4), ([0], 1..1)); +} + +#[test] +fn test_clamp_ops_range() { + test_clamp!(1..4, ([0, 1], 1..2), ([0, 1, 2, 3, 4], 1..4), ([0], 1..1)); +} + +#[test] +fn test_clamp_range_range_inclusive() { + test_clamp!( + range::RangeInclusive::from(1..=3), + ([0, 1], 1..=1), + ([0, 1, 2, 3, 4], 1..=3), + ([0], 0..=0) + ); +} + +#[test] +fn test_clamp_ops_range_inclusive() { + test_clamp!(1..=3, ([0, 1], 1..=1), ([0, 1, 2, 3, 4], 1..=3), ([0], 0..=0)); +} + +#[test] +fn test_clamp_range_range_from() { + test_clamp!(range::RangeFrom::from(1..), ([0, 1], 1..), ([0, 1, 2, 3, 4], 1..), ([0], 1..)); +} + +#[test] +fn test_clamp_ops_range_from() { + test_clamp!(1.., ([0, 1], 1..), ([0, 1, 2, 3, 4], 1..), ([0], 1..)); +} + +#[test] +fn test_clamp_range_to() { + test_clamp!(..4, ([0, 1], ..2), ([0, 1, 2, 3, 4], ..4), ([0], ..1)); +} + +#[test] +fn test_clamp_range_range_to_inclusive() { + test_clamp!( + range::RangeToInclusive::from(..=4), + ([0, 1], ..=1), + ([0, 1, 2, 3, 4], ..=4), + ([0], ..=0) + ); +} + +#[test] +fn test_clamp_ops_range_to_inclusive() { + test_clamp!(..=4, ([0, 1], ..=1), ([0, 1, 2, 3, 4], ..=4), ([0], ..=0)); +} + +#[test] +fn test_clamp_range_full() { + test_clamp!(.., ([0, 1], ..), ([0, 1, 2, 3, 4], ..), ([0], ..)); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 5c519f3a499d..4d0a7780fe8d 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -81,6 +81,7 @@ #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(never_type)] +#![feature(new_range_api)] #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(numfmt)] @@ -93,9 +94,11 @@ #![feature(ptr_metadata)] #![feature(result_option_map_or_default)] #![feature(slice_from_ptr_range)] +#![feature(slice_index_methods)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(slice_split_once)] +#![feature(sliceindex_wrappers)] #![feature(split_array)] #![feature(split_as_slice)] #![feature(std_internals)] @@ -173,6 +176,7 @@ mod fmt; mod future; mod hash; mod hint; +mod index; mod intrinsics; mod io; mod iter; From 8b7d5f1a45653a218d39499e31b5ae6057b6e30c Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 14 Sep 2025 22:29:04 +0000 Subject: [PATCH 105/525] Remove Rvalue::Len. --- src/base.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/base.rs b/src/base.rs index 3a28dd7e73cb..41e11e1de616 100644 --- a/src/base.rs +++ b/src/base.rs @@ -834,12 +834,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fx.bcx.ins().nop(); } } - Rvalue::Len(place) => { - let place = codegen_place(fx, place); - let usize_layout = fx.layout_of(fx.tcx.types.usize); - let len = codegen_array_len(fx, place); - lval.write_cvalue(fx, CValue::by_val(len, usize_layout)); - } Rvalue::ShallowInitBox(ref operand, content_ty) => { let content_ty = fx.monomorphize(content_ty); let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty)); From e53af72d29dcb7e175bddba96583bcdd73b0ecc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 17 Sep 2025 04:16:47 +0200 Subject: [PATCH 106/525] Remove `DynKind` --- src/abi/mod.rs | 2 +- src/unsize.rs | 4 +--- src/value_and_place.rs | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 7d0731c77bdc..29ee46194de1 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -715,7 +715,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().jump(ret_block, &[]); } else { match ty.kind() { - ty::Dynamic(_, _, ty::Dyn) => { + ty::Dynamic(_, _) => { // IN THIS ARM, WE HAVE: // ty = *mut (dyn Trait) // which is: exists ( *mut T, Vtable ) diff --git a/src/unsize.rs b/src/unsize.rs index 2aee0b2e9742..643c7feb89a2 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -30,9 +30,7 @@ pub(crate) fn unsized_info<'tcx>( fx.pointer_type, len.try_to_target_usize(fx.tcx).expect("expected monomorphic const in codegen") as i64, ), - (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind)) - if src_dyn_kind == target_dyn_kind => - { + (&ty::Dynamic(data_a, _), &ty::Dynamic(data_b, _)) => { let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); let b_principal_def_id = data_b.principal_def_id(); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 9d73f200afe2..4519fa1a270e 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -909,8 +909,7 @@ pub(crate) fn assert_assignable<'tcx>( ); // fn(&T) -> for<'l> fn(&'l T) is allowed } - (&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => { - // FIXME(dyn-star): Do the right thing with DynKinds + (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => { for (from, to) in from_traits.iter().zip(to_traits) { let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from); let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to); From 73c3905de7b2a7cc14594080a72d4cd58391ebc7 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 18 Sep 2025 08:07:51 +0800 Subject: [PATCH 107/525] Add `is_ascii` function optimized for LoongArch64 for [u8] Similar to x86_64, on LoongArch64 we use the `vmskltz.b` instruction to test the high bit in a lane. For longer input cases, the performance improvement is significant. For unaligned cases close to 32 bytes in length, there's some regression, but it seems acceptable. | core benches (MB/s) | Before | After | % | |--------------------------------------------------------|--------|--------|---------| | ascii::is_ascii::short::case00_libcore | 1000 | 1000 | 0.00 | | ascii::is_ascii::medium::case00_libcore | 8000 | 8000 | 0.00 | | ascii::is_ascii::long::case00_libcore | 183947 | 436875 | +137.50 | | ascii::is_ascii::unaligned_head_medium::case00_libcore | 7750 | 2818 | -63.64 | | ascii::is_ascii::unaligned_head_long::case00_libcore | 317681 | 436812 | +37.50 | | ascii::is_ascii::unaligned_tail_medium::case00_libcore | 7750 | 3444 | -55.56 | | ascii::is_ascii::unaligned_tail_long::case00_libcore | 155311 | 436812 | +181.25 | | ascii::is_ascii::unaligned_both_medium::case00_libcore | 7500 | 3333 | -55.56 | | ascii::is_ascii::unaligned_both_long::case00_libcore | 174700 | 436750 | +150.00 | --- library/core/src/slice/ascii.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index e17a2e03d2dc..d02be440f5bf 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -3,7 +3,10 @@ use core::ascii::EscapeDefault; use crate::fmt::{self, Write}; -#[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] +#[cfg(not(any( + all(target_arch = "x86_64", target_feature = "sse2"), + all(target_arch = "loongarch64", target_feature = "lsx") +)))] use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; @@ -357,7 +360,10 @@ pub const fn is_ascii_simple(mut bytes: &[u8]) -> bool { /// /// If any of these loads produces something for which `contains_nonascii` /// (above) returns true, then we know the answer is false. -#[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] +#[cfg(not(any( + all(target_arch = "x86_64", target_feature = "sse2"), + all(target_arch = "loongarch64", target_feature = "lsx") +)))] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] // fallback impl has same behavior const fn is_ascii(s: &[u8]) -> bool { @@ -455,12 +461,15 @@ const fn is_ascii(s: &[u8]) -> bool { ) } -/// ASCII test optimized to use the `pmovmskb` instruction available on `x86-64` -/// platforms. +/// ASCII test optimized to use the `pmovmskb` instruction on `x86-64` and the +/// `vmskltz.b` instruction on `loongarch64`. /// /// Other platforms are not likely to benefit from this code structure, so they /// use SWAR techniques to test for ASCII in `usize`-sized chunks. -#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[cfg(any( + all(target_arch = "x86_64", target_feature = "sse2"), + all(target_arch = "loongarch64", target_feature = "lsx") +))] #[inline] const fn is_ascii(bytes: &[u8]) -> bool { // Process chunks of 32 bytes at a time in the fast path to enable From 0e9595e648f9982694e5b84b5f63830308a591ed Mon Sep 17 00:00:00 2001 From: Igor kehrazy Date: Sun, 21 Sep 2025 10:14:13 +0300 Subject: [PATCH 108/525] Support -Zembed-source in debuginfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - honour the session DWARF version, enabling v5 when embed-source is requested and plumb the flag through the debug context - attach embedded source bytes to line table FileInfo records alongside existing MD5 hashes - stop excluding rustc’s embed-source-dwarf run-make test so CG_CLIF exercises the feature --- scripts/test_rustc_tests.sh | 1 - src/debuginfo/line_info.rs | 48 +++++++++++++++++++++---------------- src/debuginfo/mod.rs | 28 ++++++++++++++-------- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 1a65d70205d8..5e54acb3a6b0 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,7 +60,6 @@ rm tests/ui/asm/global-asm-mono-sym-fn.rs # same rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes -rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index fa7b39c836f6..6fe22f5c6dd9 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -6,9 +6,7 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{ - FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, hygiene, -}; +use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -44,21 +42,27 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] { } } -const MD5_LEN: usize = 16; +fn make_file_info(source_file: &SourceFile, embed_source: bool) -> Option { + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + let has_source = embed_source && source_file.src.is_some(); -fn make_file_info(hash: SourceFileHash) -> Option { - if hash.kind == SourceFileHashAlgorithm::Md5 { - let mut buf = [0u8; MD5_LEN]; - buf.copy_from_slice(hash.hash_bytes()); - Some(FileInfo { - timestamp: 0, - size: 0, - md5: buf, - source: None, // FIXME implement -Zembed-source - }) - } else { - None + if !has_md5 && !has_source { + return None; } + + let mut info = FileInfo::default(); + + if has_md5 { + info.md5.copy_from_slice(source_file.src_hash.hash_bytes()); + } + + if embed_source { + if let Some(src) = &source_file.src { + info.source = Some(LineString::String(src.as_bytes().to_vec())); + } + } + + Some(info) } impl DebugContext { @@ -105,15 +109,19 @@ impl DebugContext { let file_name = LineString::new(file_name, line_program.encoding(), line_strings); - let info = make_file_info(source_file.src_hash); + let info = make_file_info(source_file, self.embed_source); - line_program.file_has_md5 &= info.is_some(); + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + line_program.file_has_md5 &= has_md5; line_program.add_file(file_name, dir_id, info) } filename => { - let dir_id = line_program.default_directory(); + // For anonymous sources, create an empty directory instead of using the default + let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); + let dir_id = line_program.add_directory(empty_dir); + let dummy_file_name = LineString::new( - filename.display(self.filename_display_preference).to_string().into_bytes(), + filename.prefer_remapped_unconditionally().to_string().into_bytes(), line_program.encoding(), line_strings, ); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 05b0253eff97..e552376e3452 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -45,6 +45,7 @@ pub(crate) struct DebugContext { array_size_type: UnitEntryId, filename_display_preference: FileNameDisplayPreference, + embed_source: bool, } pub(crate) struct FunctionDebugContext { @@ -67,21 +68,24 @@ impl DebugContext { return None; } + let mut requested_dwarf_version = tcx.sess.dwarf_version(); + if tcx.sess.target.is_like_darwin && requested_dwarf_version > 4 { + // Apple’s shipped debuggers still expect DWARF <= 4 by default. + // Stay on v4 unless the user explicitly opts into a feature that + // only works with v5 (e.g. -Zembed-source). + if !tcx.sess.opts.unstable_opts.embed_source { + requested_dwarf_version = 4; + } + } + let encoding = Encoding { format: Format::Dwarf32, - // FIXME this should be configurable - // macOS doesn't seem to support DWARF > 3 - // 5 version is required for md5 file hash - version: if tcx.sess.target.is_like_darwin { - 3 - } else { - // FIXME change to version 5 once the gdb and lldb shipping with the latest debian - // support it. - 4 - }, + version: requested_dwarf_version as u16, address_size: isa.frontend_config().pointer_bytes(), }; + let embed_source = tcx.sess.opts.unstable_opts.embed_source && encoding.version >= 5; + let endian = match isa.endianness() { Endianness::Little => RunTimeEndian::Little, Endianness::Big => RunTimeEndian::Big, @@ -125,6 +129,9 @@ impl DebugContext { file_info, ); line_program.file_has_md5 = file_has_md5; + if embed_source { + line_program.file_has_source = true; + } dwarf.unit.line_program = line_program; @@ -169,6 +176,7 @@ impl DebugContext { namespace_map: DefIdMap::default(), array_size_type, filename_display_preference, + embed_source, }) } From fd7ec3a2c4938fc00ac0e43c9a26cc16b17362b4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Sep 2025 09:00:27 +0000 Subject: [PATCH 109/525] Rustup to rustc 1.92.0-nightly (f6092f224 2025-09-22) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index d82f5180317d..8078c586edac 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-09-15" +channel = "nightly-2025-09-23" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 72d8b6c7d52a4d5e9fae77ac5476643ef9263723 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Sep 2025 09:22:47 +0000 Subject: [PATCH 110/525] Fix rustc test suite And re-enable a no longer failing test. --- scripts/setup_rust_fork.sh | 7 ++++--- scripts/test_rustc_tests.sh | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 84c7ad534561..c16cb4e538fe 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -53,12 +53,13 @@ diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/co index a656927b1f6..44fc5546fac 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs -@@ -2249,13 +2249,6 @@ pub fn parse_download_ci_llvm<'a>( +@@ -2249,14 +2249,6 @@ pub fn parse_download_ci_llvm<'a>( ); } -- if b && dwn_ctx.is_running_on_ci { -- // On CI, we must always rebuild LLVM if there were any modifications to it +- #[cfg(not(test))] +- if b && dwn_ctx.is_running_on_ci && CiEnv::is_rust_lang_managed_ci_job() { +- // On rust-lang CI, we must always rebuild LLVM if there were any modifications to it - panic!( - "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead." - ); diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 1a65d70205d8..91c855fe678a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -46,7 +46,9 @@ 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/c-variadic/valid.rs # same -rm tests/ui/c-variadic/naked.rs # same +rm tests/ui/c-variadic/trait-method.rs # same +rm tests/ui/c-variadic/inherent-method.rs # same +rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs # misc unimplemented things @@ -64,7 +66,6 @@ rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported -rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm -r tests/ui/explicit-tail-calls # tail calls # requires LTO From 64ec3592834b907c12f0316cd08c342fa474314a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Sep 2025 09:35:57 +0000 Subject: [PATCH 111/525] Ignore rustc test again that still fails --- 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 91c855fe678a..ebe3385d0b0a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -43,6 +43,7 @@ rm -r tests/run-make/naked-symbol-visibility # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs +rm tests/ui/c-variadic/naked.rs # same 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/c-variadic/valid.rs # same From 13748073d830211b7c57fec188ffe6cc379310d1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Sep 2025 08:47:03 +0000 Subject: [PATCH 112/525] Update to Cranelift 0.124.1 --- Cargo.lock | 76 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 24 ++++++++--------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c6acb600b77..a81f72e17fb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed4b70d50ef7f5a1fe6acd4dd5fe1050abb96da29cfd9dbd816425468b077054" +checksum = "d3e8ca189363907c025c5debe2bfe56c8c18503d4575d750f87e4ccbbfbd8681" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a0508022f39d640b5830b831dd3cb98e4d5e2d35b46cf9fc2a098805234365" +checksum = "e169461bfd463df68b01b196522f263c905eadc852f6e57fd4ce4c5d76115ead" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f60341caf62338f84d8e1a6261d9b72b00932564094d37d12215028a3fae95" +checksum = "2a98298338375075287834defe333d552847110f3a04db0ce19bd308b4c40fbb" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f01687e7f1cb4ec9394b4ba13c1e1835edbec012304cf2f854537deec901aeb" +checksum = "edf5f49a2e2ae284db75437a49cc13220a7fb394983d5545af1209ab0bbadee3" [[package]] name = "cranelift-codegen" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24d59006f532c84fae3c7bae9fadfc569d9912c5d0bf67ea8c20de289b5786" +checksum = "c354d6db9e344f647f38c88849c482c6014b79a295aca23fa82f73b62caeda2d" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b250ca6c45149339f3908f1137f28faa4dba0f12673f8b6c6201a733f6e012a" +checksum = "9bb8008396957de750e26d0b40a76bea6e5623d970a5bfe4266ef0a79ccb8341" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4923507eb61e357184e4c5e11052dbca7abcee3a306dfaa62cd2f2bdd9851c51" +checksum = "98ecb53eafe1ad1f7d7f7d0585ae5d42b2050978fa812216b0420d4752eb41cb" [[package]] name = "cranelift-control" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6bf355bddc171ac2d5a62e6cfa8f1eb1b37667924210e400cbc65e53870bf2" +checksum = "b9c43ac27fe178cadb17e7f4cf1320ba89b8875cc2bdee265cccfca49bc76c95" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f0c0e4057964aa3c6597606986ed5df32d465838ad389f226461bf562555c7" +checksum = "15513ee4bf648d366654c6a9864fe870ca64f1eed4acabf9139056e68b3d44dc" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f39ca2f29e01050443d5d4d59fe674b7107641d79a9a847d5a01fded8264b9f2" +checksum = "c5e4399d31f06b50fcb3fa0117ff4c393c22e521574eecf524cf932fc99cd78f" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14633795ccf9b5f3ef8484dc6bfed943118330fc18a2172dc7aac661473558b1" +checksum = "9a751ec2b7c2f281274a3798e37ba2344b55f60789e67aaa10d6bbea3f3f8a6b" [[package]] name = "cranelift-jit" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5044e1a2211eaf40348f387334566f266531b7a6ae60fb7d0c944db0ad8731" +checksum = "8b22769d71584df8b6a083e11a248da38c40c0b91b565c8c202b173b26cc861c" dependencies = [ "anyhow", "cranelift-codegen", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625cb9020a5358a194da5a3a918d1ff29ee89f8191a3ccd7a485255364f32776" +checksum = "4fb364ea65183c3961faf6cc5038bd88ceb957c3cd3480958bce28d02b194625" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a178fab381ece04958d895eff2bd5ddecb8537e08fb1af3eb92e45dd3e50301" +checksum = "546500d7cb424c423e118dfddc169aa61ed611c47fc1cf48783ed4e3f9800619" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11fc0edb2994ccc8802801c35c08572c443dca716e988110e63bfc9d81f0bbf1" +checksum = "c3aae694e5dd436c87ac90d1468a1032ff63d54faa33dcfece7e8fc7072fbe73" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.123.0" +version = "0.124.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07a6f374259f252ae78cbf9aad469091d6a51adda43cb91d23610532cf2b978e" +checksum = "edeb6b718b23108a123ad1c8eecf6fa34d21a6b5518fc340dda80ce5bdf42377" [[package]] name = "crc32fast" @@ -355,9 +355,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.12.2" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734" +checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98" dependencies = [ "allocator-api2", "bumpalo", @@ -460,9 +460,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "36.0.0" +version = "37.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "118c225f1c3c688c423de99d590b6e06fa811207090eeb9f4423b6a2d0113ff5" +checksum = "4aea2b284343796fbbe749c36db092b43809762f8b9e46626561a8be4003dd85" dependencies = [ "anyhow", "cfg-if", @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-math" -version = "36.0.0" +version = "37.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2378d723f821a5f24076bd9bed4ec849c24717c7af188d4f31fff1d7fc6cfe" +checksum = "5a058122e659373c3648a71de03436105f213037d8016bb68550c259d4b37931" dependencies = [ "libm", ] diff --git a/Cargo.toml b/Cargo.toml index 945854842f2d..3adf9f415c9a 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.123.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.123.0" } -cranelift-module = { version = "0.123.0" } -cranelift-native = { version = "0.123.0" } -cranelift-jit = { version = "0.123.0", optional = true } -cranelift-object = { version = "0.123.0" } +cranelift-codegen = { version = "0.124.1", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.124.1" } +cranelift-module = { version = "0.124.1" } +cranelift-native = { version = "0.124.1" } +cranelift-jit = { version = "0.124.1", optional = true } +cranelift-object = { version = "0.124.1" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-36.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } From b53c717e6ab8e093e18fb1df9b8a8f22197469e1 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 16 Sep 2025 02:23:24 -0400 Subject: [PATCH 113/525] Add an attribute to check the number of lanes in a SIMD vector after monomorphization Unify zero-length and oversized SIMD errors --- src/common.rs | 9 +++++++-- src/global_asm.rs | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common.rs b/src/common.rs index 2fbe5c02802a..81b1814605a1 100644 --- a/src/common.rs +++ b/src/common.rs @@ -439,7 +439,10 @@ pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::InvalidSimd { .. } + | LayoutError::ReferencesError(_) = err + { self.0.sess.dcx().span_fatal(span, err.to_string()) } else { self.0 @@ -458,7 +461,9 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { - if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { + if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) = + err + { self.0.sess.dcx().emit_fatal(Spanned { span, node: err }) } else { match fn_abi_request { diff --git a/src/global_asm.rs b/src/global_asm.rs index 203b443269fa..1306c6aa5179 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -42,7 +42,10 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> { impl<'tcx> LayoutOfHelpers<'tcx> for GlobalAsmContext<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::InvalidSimd { .. } + | LayoutError::ReferencesError(_) = err + { self.tcx.sess.dcx().span_fatal(span, err.to_string()) } else { self.tcx From 34eb0ce741af853d448d2feccf2c8220fdee9934 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:11:14 +0000 Subject: [PATCH 114/525] Use macos-15-intel runners for x86_64 --- .github/workflows/abi-cafe.yml | 7 +++---- .github/workflows/main.yml | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index 75a506868a0f..170c7126c296 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -28,10 +28,9 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - # FIXME(rust-lang/rust#145699) - #- os: macos-13 - # env: - # TARGET_TRIPLE: x86_64-apple-darwin + - os: macos-15-intel + env: + TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest env: TARGET_TRIPLE: aarch64-apple-darwin diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d92e0fdce99a..52a8eeee13d4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,7 +56,7 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 + - os: macos-15-intel env: TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest @@ -187,7 +187,7 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 + - os: macos-15-intel env: TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest From a7454d18803b44c7f22bcbbb7373ec43dd3619ef Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Thu, 25 Sep 2025 20:54:54 -0700 Subject: [PATCH 115/525] ProjectionElem::Subtype -> CastKind::Subtype --- src/base.rs | 4 ++-- src/value_and_place.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 41e11e1de616..a2f844642f85 100644 --- a/src/base.rs +++ b/src/base.rs @@ -789,7 +789,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => { + Rvalue::Cast(CastKind::Transmute | CastKind::Subtype, ref operand, _to_ty) => { let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); } @@ -996,7 +996,7 @@ pub(crate) fn codegen_place<'tcx>( cplace = cplace.place_deref(fx); } PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), - PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => { + PlaceElem::UnwrapUnsafeBinder(ty) => { cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)); } PlaceElem::Field(field, _ty) => { diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 4519fa1a270e..25bba48a9e3a 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -660,7 +660,7 @@ impl<'tcx> CPlace<'tcx> { } } - /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before + /// Used for `ProjectionElem::UnwrapUnsafeBinder`, `ty` has to be monomorphized before /// passed on. pub(crate) fn place_transmute_type( self, From f1ce0ecb4d0e281323627c14c7f0410b3cbf3f2c Mon Sep 17 00:00:00 2001 From: EriKWDev Date: Fri, 26 Sep 2025 11:26:52 +0200 Subject: [PATCH 116/525] Remove $ (#1595) Consider removing the redundant $:s that needs to be removed when copying commands --- Readme.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Readme.md b/Readme.md index 9989cc7e7eaf..48003ad270e6 100644 --- a/Readme.md +++ b/Readme.md @@ -11,7 +11,7 @@ The Cranelift codegen backend is distributed in nightly builds on Linux, macOS a install it using Rustup, you can do that by running: ```bash -$ rustup component add rustc-codegen-cranelift-preview --toolchain nightly +rustup component add rustc-codegen-cranelift-preview --toolchain nightly ``` Once it is installed, you can enable it with one of the following approaches: @@ -47,16 +47,16 @@ If you want to use `cargo clif build` instead of having to specify the full path If you want to build the backend manually, you can download it from GitHub and build it yourself: ```bash -$ git clone https://github.com/rust-lang/rustc_codegen_cranelift -$ cd rustc_codegen_cranelift -$ ./y.sh build +git clone https://github.com/rust-lang/rustc_codegen_cranelift +cd rustc_codegen_cranelift +./y.sh build ``` To run the test suite replace the last command with: ```bash -$ ./y.sh prepare # only needs to be run the first time -$ ./test.sh +./y.sh prepare # only needs to be run the first time +./test.sh ``` For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.sh`. @@ -90,7 +90,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo In the directory with your project (where you can do the usual `cargo build`), run: ```bash -$ $cg_clif_dir/dist/cargo-clif build +$cg_clif_dir/dist/cargo-clif build ``` This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. From 9b24d96173603d11dd36c6c98136c97ebf882d16 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:50:17 +0000 Subject: [PATCH 117/525] Re-enable Cirrus CI --- .cirrus.yml | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index ee5de8b42f46..1ec99eb3d17a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,21 +1,20 @@ -# FIXME re-enable once https://github.com/rust-lang/rust/issues/134863 is fixed. -# task: -# name: freebsd -# freebsd_instance: -# image: freebsd-13-2-release-amd64 -# setup_rust_script: -# - pkg install -y git-tiny binutils -# - curl https://sh.rustup.rs -sSf --output rustup.sh -# - sh rustup.sh --default-toolchain none -y --profile=minimal -# target_cache: -# folder: build/cg_clif -# prepare_script: -# - . $HOME/.cargo/env -# - ./y.sh prepare -# test_script: -# - . $HOME/.cargo/env -# # Disabling incr comp reduces cache size and incr comp doesn't save as much -# # on CI anyway. -# - export CARGO_BUILD_INCREMENTAL=false -# # Skip rand as it fails on FreeBSD due to rust-random/rand#1355 -# - ./y.sh test --skip-test test.rust-random/rand +task: + name: freebsd + freebsd_instance: + image: freebsd-13-2-release-amd64 + setup_rust_script: + - pkg install -y git-tiny binutils + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain none -y --profile=minimal + target_cache: + folder: build/cg_clif + prepare_script: + - . $HOME/.cargo/env + - ./y.sh prepare + test_script: + - . $HOME/.cargo/env + # Disabling incr comp reduces cache size and incr comp doesn't save as much + # on CI anyway. + - export CARGO_BUILD_INCREMENTAL=false + # Skip rand as it fails on FreeBSD due to rust-random/rand#1355 + - ./y.sh test --skip-test test.rust-random/rand From f2798d6233d21d95550a5fa1d762365aba383b09 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:56:59 +0000 Subject: [PATCH 118/525] Workaround for TLS issue on FreeBSD --- .cirrus.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.cirrus.yml b/.cirrus.yml index 1ec99eb3d17a..85527699530b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -16,5 +16,8 @@ task: # Disabling incr comp reduces cache size and incr comp doesn't save as much # on CI anyway. - export CARGO_BUILD_INCREMENTAL=false + # FIXME(rust-lang/rust#134863) necessary to avoid error when dlopening proc + # macros during compilation of cg_clif. + - export LD_STATIC_TLS_EXTRA=4096 # Skip rand as it fails on FreeBSD due to rust-random/rand#1355 - ./y.sh test --skip-test test.rust-random/rand From 3e563b840e50291a55b5e567162523ffb6a35f8b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:29:41 +0000 Subject: [PATCH 119/525] Improve ArgAbi left behind panic message --- src/abi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 1b21315046fa..9e9bc2e93b71 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -300,7 +300,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ Some(cvalue_for_param(fx, None, None, arg_abi, &mut block_params_iter).unwrap()); } - assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind"); + assert_eq!(arg_abis_iter.next(), None, "ArgAbi left behind for {:?}", fx.fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); self::comments::add_locals_header_comment(fx); From 5a3b82b64f4c2b8464f157d6ecc5380ade7b59fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Thu, 25 Sep 2025 15:15:41 +0200 Subject: [PATCH 120/525] Update memchr to 2.7.6 memchr 2.7.6 contains a bugfix for aarch64_be --- Cargo.lock | 4 ++-- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_lexer/Cargo.toml | 2 +- library/Cargo.lock | 4 ++-- src/bootstrap/Cargo.lock | 4 ++-- src/ci/citool/Cargo.lock | 4 ++-- src/tools/miri/miri-script/Cargo.lock | 4 ++-- src/tools/rustbook/Cargo.lock | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d4a1bf6a788..267118f155c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2319,9 +2319,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 155e14a3796e..34d90adf5cb3 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -memchr = "2.7.4" +memchr = "2.7.6" rustc-literal-escaper = "0.0.5" rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 343b81bd1717..6d524b9d8873 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -14,7 +14,7 @@ Rust lexer used by rustc. No stability guarantees are provided. # Note that this crate purposefully does not depend on other rustc crates [dependencies] -memchr = "2.7.4" +memchr = "2.7.6" unicode-properties = { version = "0.1.0", default-features = false, features = ["emoji"] } unicode-xid = "0.2.0" diff --git a/library/Cargo.lock b/library/Cargo.lock index 47fbf5169f49..dc4b7459d198 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" dependencies = [ "rustc-std-workspace-core", ] diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index fe832652d25c..cdd2b028cf7c 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -429,9 +429,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "normpath" diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 571f18e7cf18..ab5d2adc9dc5 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -609,9 +609,9 @@ checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miniz_oxide" diff --git a/src/tools/miri/miri-script/Cargo.lock b/src/tools/miri/miri-script/Cargo.lock index 044a678869e2..637137779c4a 100644 --- a/src/tools/miri/miri-script/Cargo.lock +++ b/src/tools/miri/miri-script/Cargo.lock @@ -197,9 +197,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miri-script" diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index cd7ee6fb4fea..191f9703750d 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -965,9 +965,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miniz_oxide" From 8537abbaf2548051eb4d7ddb44e3d926faf16e08 Mon Sep 17 00:00:00 2001 From: Noa Date: Wed, 27 Aug 2025 00:10:09 -0500 Subject: [PATCH 121/525] Stabilize `fmt::{from_fn, FromFn}` under feature `fmt_from_fn` --- library/alloc/src/fmt.rs | 2 +- library/core/src/fmt/builders.rs | 9 ++++----- library/core/src/fmt/mod.rs | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 82eaf7d87244..4d6fe220a09a 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -602,7 +602,7 @@ pub use core::fmt::{DebugAsHex, FormattingOptions, Sign}; pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Formatter, Result, Write}; -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] pub use core::fmt::{FromFn, from_fn}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{LowerExp, UpperExp}; diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 665b05b12ec0..dba54353e03f 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1216,7 +1216,6 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// # Examples /// /// ``` -/// #![feature(debug_closure_helpers)] /// use std::fmt; /// /// let value = 'a'; @@ -1227,7 +1226,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// assert_eq!(format!("{}", wrapped), "'a'"); /// assert_eq!(format!("{:?}", wrapped), "'a'"); /// ``` -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"] pub fn from_fn) -> fmt::Result>(f: F) -> FromFn { FromFn(f) @@ -1236,12 +1235,12 @@ pub fn from_fn) -> fmt::Result>(f: F) -> FromFn /// Implements [`fmt::Debug`] and [`fmt::Display`] using a function. /// /// Created with [`from_fn`]. -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] pub struct FromFn(F) where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, @@ -1251,7 +1250,7 @@ where } } -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] impl fmt::Display for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index fcd2e52101ff..1d592ab6800d 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -39,7 +39,7 @@ pub use num_buffer::{NumBuffer, NumBufferTrait}; #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; -#[unstable(feature = "debug_closure_helpers", issue = "117729")] +#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] pub use self::builders::{FromFn, from_fn}; /// The type returned by formatter methods. From f8d7b412045fa6cbeaacf765effa20f76273a777 Mon Sep 17 00:00:00 2001 From: Noa Date: Wed, 27 Aug 2025 00:11:46 -0500 Subject: [PATCH 122/525] Reword docs slightly --- library/core/src/fmt/builders.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index dba54353e03f..e97c1a8f77e4 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1210,8 +1210,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { } } -/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are provided with the function -/// `f`. +/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are +/// forwarded to the provided closure. /// /// # Examples /// @@ -1232,7 +1232,7 @@ pub fn from_fn) -> fmt::Result>(f: F) -> FromFn FromFn(f) } -/// Implements [`fmt::Debug`] and [`fmt::Display`] using a function. +/// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure. /// /// Created with [`from_fn`]. #[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] From 859ae05e938add34df930772557e5f2e795df96d Mon Sep 17 00:00:00 2001 From: Noa Date: Wed, 27 Aug 2025 00:32:49 -0500 Subject: [PATCH 123/525] Remove some feature(debug_closure_helpers) attributes --- compiler/rustc_hir/src/lib.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_target/src/lib.rs | 2 +- src/librustdoc/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index eb630fc80186..0d0a1f6b76a2 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -3,9 +3,9 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] -#![feature(debug_closure_helpers)] #![feature(exhaustive_patterns)] #![feature(never_type)] #![feature(variant_count)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 6659aff71110..56c0f4e7cee4 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,10 +59,10 @@ This API is completely unstable and subject to change. #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] -#![feature(debug_closure_helpers)] #![feature(gen_blocks)] #![feature(if_let_guard)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 8c6a77cba8ba..f664bbb874d6 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -9,9 +9,9 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(debug_closure_helpers)] #![feature(iter_intersperse)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c4f24e09ddbf..b6ddd5329a7a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/" @@ -7,7 +8,6 @@ #![feature(ascii_char_variants)] #![feature(assert_matches)] #![feature(box_patterns)] -#![feature(debug_closure_helpers)] #![feature(file_buffered)] #![feature(formatting_options)] #![feature(if_let_guard)] From 93c8bf13092e01603ff2bd4a5ce20eed79edfe35 Mon Sep 17 00:00:00 2001 From: Noa Date: Fri, 19 Sep 2025 13:27:11 -0500 Subject: [PATCH 124/525] Remove F: Fn bound from FromFn struct --- library/core/src/fmt/builders.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index e97c1a8f77e4..4ea6c6ba8fb9 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1236,9 +1236,7 @@ pub fn from_fn) -> fmt::Result>(f: F) -> FromFn /// /// Created with [`from_fn`]. #[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] -pub struct FromFn(F) -where - F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; +pub struct FromFn(F); #[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for FromFn From de53737f637054a32e8ea7536f077c96d9d2131c Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 28 Sep 2025 12:08:44 -0400 Subject: [PATCH 125/525] Add a leading dash to linker plugin arguments in the gcc codegen --- src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 8e34436fb5e0..5fd7c4d4f41b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,6 +165,10 @@ impl CodegenBackend for CraneliftCodegenBackend { "" } + fn name(&self) -> &'static str { + "cranelift" + } + fn init(&self, sess: &Session) { use rustc_session::config::{InstrumentCoverage, Lto}; match sess.lto() { From 5569e6b2053a6488c398d9bd8f8b48f2959a90bc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 28 Sep 2025 14:40:39 -0700 Subject: [PATCH 126/525] remove explicit deref of AbiAlign for most methods Much of the compiler calls functions on Align projected from AbiAlign. AbiAlign impls Deref to its inner Align, so we can simplify these away. Also, it will minimize disruption when AbiAlign is removed. For now, preserve usages that might resolve to PartialOrd or PartialEq, as those have odd inference. --- src/abi/comments.rs | 2 +- src/abi/pass_mode.rs | 2 +- src/base.rs | 2 +- src/debuginfo/mod.rs | 2 +- src/debuginfo/types.rs | 6 ++---- src/unsize.rs | 6 +++--- src/value_and_place.rs | 6 +++--- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/abi/comments.rs b/src/abi/comments.rs index c74efeb59f3f..d1b2b9a502ac 100644 --- a/src/abi/comments.rs +++ b/src/abi/comments.rs @@ -89,7 +89,7 @@ pub(super) fn add_local_place_comments<'tcx>( format!("{:?}", local), format!("{:?}", ty), size.bytes(), - align.abi.bytes(), + align.bytes(), if extra.is_empty() { "" } else { " " }, extra, )); diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 2031842062d9..7a909a740b05 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -233,7 +233,7 @@ pub(super) fn from_casted_value<'tcx>( // It may also be smaller for example when the type is a wrapper around an integer with a // larger alignment than the integer. std::cmp::max(abi_param_size, layout_size), - u32::try_from(layout.align.abi.bytes()).unwrap(), + u32::try_from(layout.align.bytes()).unwrap(), ); let mut block_params_iter = block_params.iter().copied(); for (offset, _) in abi_params { diff --git a/src/base.rs b/src/base.rs index 41e11e1de616..2cc5b82ddd34 100644 --- a/src/base.rs +++ b/src/base.rs @@ -846,7 +846,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { NullOp::SizeOf => layout.size.bytes(), - NullOp::AlignOf => layout.align.abi.bytes(), + NullOp::AlignOf => layout.align.bytes(), NullOp::OffsetOf(fields) => fx .tcx .offset_of_subfield( diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 286e02b986b3..4c438742f3d2 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -304,7 +304,7 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); - entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.abi.bytes())); + entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.bytes())); let mut expr = Expression::new(); expr.op_addr(address_for_data(data_id)); diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 25b922c8be4c..0d49f32373ca 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -166,7 +166,7 @@ impl DebugContext { let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id); tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); - tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.abi.bytes())); + tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.bytes())); for (i, (ty, dw_ty)) in components.into_iter().enumerate() { let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member); @@ -178,9 +178,7 @@ impl DebugContext { member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); member_entry.set( gimli::DW_AT_alignment, - AttributeValue::Udata( - FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.abi.bytes(), - ), + AttributeValue::Udata(FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.bytes()), ); member_entry.set( gimli::DW_AT_data_member_location, diff --git a/src/unsize.rs b/src/unsize.rs index 643c7feb89a2..d994f3e32ec3 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -167,7 +167,7 @@ pub(crate) fn size_and_align_of<'tcx>( if layout.is_sized() { return ( fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64), - fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, layout.align.bytes() as i64), ); } @@ -186,7 +186,7 @@ pub(crate) fn size_and_align_of<'tcx>( // times the unit size. ( fx.bcx.ins().imul_imm(info.unwrap(), unit.size.bytes() as i64), - fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, unit.align.bytes() as i64), ) } ty::Foreign(_) => { @@ -224,7 +224,7 @@ pub(crate) fn size_and_align_of<'tcx>( let unsized_offset_unadjusted = layout.fields.offset(i).bytes(); let unsized_offset_unadjusted = fx.bcx.ins().iconst(fx.pointer_type, unsized_offset_unadjusted as i64); - let sized_align = layout.align.abi.bytes(); + let sized_align = layout.align.bytes(); let sized_align = fx.bcx.ins().iconst(fx.pointer_type, sized_align as i64); // Recurse to get the size of the dynamically sized field (must be diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 4519fa1a270e..04e10cf17088 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -383,7 +383,7 @@ impl<'tcx> CPlace<'tcx> { let stack_slot = fx.create_stack_slot( u32::try_from(layout.size.bytes()).unwrap(), - u32::try_from(layout.align.abi.bytes()).unwrap(), + u32::try_from(layout.align.bytes()).unwrap(), ); CPlace { inner: CPlaceInner::Addr(stack_slot, None), layout } } @@ -641,8 +641,8 @@ impl<'tcx> CPlace<'tcx> { let size = dst_layout.size.bytes(); // `emit_small_memory_copy` uses `u8` for alignments, just use the maximum // alignment that fits in a `u8` if the actual alignment is larger. - let src_align = src_layout.align.abi.bytes().try_into().unwrap_or(128); - let dst_align = dst_layout.align.abi.bytes().try_into().unwrap_or(128); + let src_align = src_layout.align.bytes().try_into().unwrap_or(128); + let dst_align = dst_layout.align.bytes().try_into().unwrap_or(128); fx.bcx.emit_small_memory_copy( fx.target_config, to_addr, From a20daf79c016ef12d3b7687a34086754c8b9b7c2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 29 Sep 2025 15:17:11 +0200 Subject: [PATCH 127/525] arm-linux.md: various fixes/improvements --- .../rustc/src/platform-support/arm-linux.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/rustc/src/platform-support/arm-linux.md b/src/doc/rustc/src/platform-support/arm-linux.md index 5f40743f3d07..b620763fa6df 100644 --- a/src/doc/rustc/src/platform-support/arm-linux.md +++ b/src/doc/rustc/src/platform-support/arm-linux.md @@ -1,7 +1,7 @@ # Arm Linux support in Rust The Arm Architecture has been around since the mid-1980s, going through nine -major revisions, many minor revisions, and spanning both 32-bith and 64-bit +major revisions, many minor revisions, and spanning both 32-bit and 64-bit architectures. This page covers 32-bit Arm platforms that run some form of Linux (but not Android). Those targets are: @@ -49,7 +49,7 @@ The architecture component simply called `arm` corresponds to the Armv6 architecture - that is, version 6 of the Arm Architecture as defined in version 6 of the Arm Architecture Reference Manual (the Arm ARM). This was the last 'legacy' release of the Arm architecture, before they split into -Application, Real-Time and Microcontroller profiles (leading to Armv7-A, +Application, Real-Time, and Microcontroller profiles (leading to Armv7-A, Armv7-R and Armv7-M). Processors that implement the Armv6 architecture include the ARM1176JZF-S, as found in BCM2835 SoC that powers the Raspberry Pi Zero. Arm processors are generally fairly backwards compatible, especially for @@ -59,7 +59,7 @@ on newer ARMv7-A systems, or even 64/32-bit Armv8-A systems. The `armeb` architecture component specifies an Armv6 processor running in Big Endian mode (`eb` is for big-endian - the letters are backwards because engineers used to little-endian systems perceive big-endian numbers to be -written into memory backwards, and they thought it was funnier like that). +written into memory backwards, and they thought it was funny like that). Most Arm processors can operate in either little-endian or big-endian mode and little-endian mode is by far the most common. However, if for whatever reason you wish to store your Most Significant Bytes first, these targets are @@ -70,7 +70,7 @@ Targets that start with `armv4t` are for processors implementing the Armv4T architecture from 1994. These include the ARM7TDMI, as found in the Nokia 6110 brick-phone and the Game Boy Advance. The 'T' stands for *Thumb* and indicate that the processors can execute smaller 16-bit versions of some of the 32-bit -Arm instructions. Because a Thumb is like a small version of an Arm. +Arm instructions. A Thumb is like a small version of an Arm. Targets that start with `armv5te` are for processors implementing the Armv5TE architecture. These are mostly from the ARM9 family, like the ARM946E-S found @@ -111,11 +111,11 @@ The `gnueabi` ABI component indicates support for using the GNU C Library (glibc), and the Arm Embedded ABI (EABI). The EABI is a replacement for the original ABI (now called the Old ABI or OABI), and it is the standard ABI for 32-bit Arm systems. With this ABI, function parameters that are `f32` or `f64` -are passed as if they were integers, instead of being passed via in FPU -registers. Generally these targets also disable the use of the FPU entirely, +are passed as if they were integers, instead of being passed in FPU +registers. Generally, these targets also disable the use of the FPU entirely, although that isn't always true. -The `gnueabihf` ABI component is like `gnueabi`, except that it support the +The `gnueabihf` ABI component is like `gnueabi`, except that it supports the 'hard-float' of the EABI. That is, function parameters that are `f32` or `f64` are passed in FPU registers. Naturally, this makes the FPU mandatory. @@ -147,7 +147,7 @@ the Arm architecture, and more importantly, knows where to find a suitable C Library to link against. To do that, you can add the `linker` property to your `.cargo/config.toml`. -Typically you would refer to a suitable copy of GCC that has built as a +Typically, you would refer to a suitable copy of GCC that was built as a cross-compiler, alongside a C library. ```toml @@ -155,7 +155,7 @@ cross-compiler, alongside a C library. linker = "arm-linux-gnueabi-gcc" ``` -On Debian Linux, you could install such a cross-compilation toolchain with +On Debian, you could install such a cross-compilation toolchain with `apt install gcc-arm-linux-gnueabi`. For more exotic combinations, you might need to build a bespoke version of GCC using [crosstool-ng]. From 6b3ada06c3c7ee6148f2a1f91eb3d4bc30e8eb11 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 10:00:48 +0000 Subject: [PATCH 128/525] Use rustc --print host-tuple --- build_system/rustc_info.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs index 5b71504e90a4..61d56795efa3 100644 --- a/build_system/rustc_info.rs +++ b/build_system/rustc_info.rs @@ -2,19 +2,13 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; pub(crate) fn get_host_triple(rustc: &Path) -> String { - let version_info = - Command::new(rustc).stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout; - String::from_utf8(version_info) + let version_info = Command::new(rustc) + .stderr(Stdio::inherit()) + .args(&["--print", "host-tuple"]) + .output() .unwrap() - .lines() - .to_owned() - .find(|line| line.starts_with("host")) - .unwrap() - .split(":") - .nth(1) - .unwrap() - .trim() - .to_owned() + .stdout; + String::from_utf8(version_info).unwrap().trim().to_owned() } pub(crate) fn get_toolchain_name() -> String { From d923ff4f4bd787bfb59d2b7d3a8ecd229213816b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 10:17:28 +0000 Subject: [PATCH 129/525] Rustup to rustc 1.92.0-nightly (fa3155a64 2025-09-30) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 8078c586edac..2697f26e8e85 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-09-23" +channel = "nightly-2025-10-01" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 160c1091fbef7161372ac1d4e02949e1838621f1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 10:30:11 +0000 Subject: [PATCH 130/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 30e73d898ec1..3981a42eb119 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -67,6 +67,7 @@ rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/explicit-tail-calls # tail calls +rm -r tests/run-make/pointer-auth-link-with-c # pointer auth # requires LTO rm -r tests/run-make/cdylib @@ -131,6 +132,8 @@ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump rm -r tests/run-make/strip # same rm -r tests/run-make-cargo/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source rm -r tests/run-make/translation # same +rm -r tests/run-make-cargo/panic-immediate-abort-works # same +rm -r tests/run-make-cargo/panic-immediate-abort-codegen # same rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features rm -r tests/run-make/const-trait-stable-toolchain # same rm -r tests/run-make/print-request-help-stable-unstable # same From 099e5d2572f9920022b9286f9d330c3d5a562c11 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:50:21 +0000 Subject: [PATCH 131/525] Update Cirrus CI to FreeBSD 14.2 --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 85527699530b..3ed89beceb7f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ task: name: freebsd freebsd_instance: - image: freebsd-13-2-release-amd64 + image_family: freebsd-14-2 setup_rust_script: - pkg install -y git-tiny binutils - curl https://sh.rustup.rs -sSf --output rustup.sh From 992c2c6b01d2bdfaa0bbb4a736670fdce9d76a08 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:40:02 +0000 Subject: [PATCH 132/525] Use the correct return type for compiler-builtins float compares --- src/codegen_f16_f128.rs | 8 +++----- src/compiler_builtins.rs | 35 +++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index 1e202be1f185..c2406197f303 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -1,3 +1,4 @@ +use crate::compiler_builtins::CMP_RESULT_TY; use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { @@ -70,13 +71,10 @@ pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs let res = fx.lib_call( name, vec![AbiParam::new(types::F128), AbiParam::new(types::F128)], - // FIXME(rust-lang/compiler-builtins#919): This should be `I64` on non-AArch64 - // architectures, but switching it before compiler-builtins is fixed causes test - // failures. - vec![AbiParam::new(types::I32)], + vec![AbiParam::new(CMP_RESULT_TY)], &[lhs, rhs], )[0]; - let zero = fx.bcx.ins().iconst(types::I32, 0); + let zero = fx.bcx.ins().iconst(CMP_RESULT_TY, 0); let res = fx.bcx.ins().icmp(int_cc, res, zero); res } diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index 155bf866889a..ca9157daae58 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -3,11 +3,34 @@ use std::ffi::c_int; #[cfg(feature = "jit")] use std::ffi::c_void; +use cranelift_codegen::ir::{Type, types}; + // FIXME replace with core::ffi::c_size_t once stabilized #[allow(non_camel_case_types)] #[cfg(feature = "jit")] type size_t = usize; +// Needs to stay in sync with compiler-builtins + +// Aarch64 uses `int` rather than a pointer-sized value. +#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] +#[cfg(feature = "jit")] +type CmpResult = i32; +#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] +pub(crate) const CMP_RESULT_TY: Type = types::I32; + +// In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect, +// this means the return value is always pointer-sized. +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(feature = "jit")] +type CmpResult = isize; +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(target_pointer_width = "32")] +pub(crate) const CMP_RESULT_TY: Type = types::I32; +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(target_pointer_width = "64")] +pub(crate) const CMP_RESULT_TY: Type = types::I64; + macro_rules! builtin_functions { ( $register:ident; @@ -88,12 +111,12 @@ builtin_functions! { #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmodf128(a: f128, b: f128) -> f128; // float comparison - fn __eqtf2(a: f128, b: f128) -> i32; - fn __netf2(a: f128, b: f128) -> i32; - fn __lttf2(a: f128, b: f128) -> i32; - fn __letf2(a: f128, b: f128) -> i32; - fn __gttf2(a: f128, b: f128) -> i32; - fn __getf2(a: f128, b: f128) -> i32; + fn __eqtf2(a: f128, b: f128) -> CmpResult; + fn __netf2(a: f128, b: f128) -> CmpResult; + fn __lttf2(a: f128, b: f128) -> CmpResult; + fn __letf2(a: f128, b: f128) -> CmpResult; + fn __gttf2(a: f128, b: f128) -> CmpResult; + fn __getf2(a: f128, b: f128) -> CmpResult; #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fminimumf128(a: f128, b: f128) -> f128; #[cfg(not(all(target_os = "windows", target_env = "gnu")))] From ed6fbc28e3f0d74094e4d8f01272466c202c46c0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 13:17:17 +0000 Subject: [PATCH 133/525] Stop building rtstartup It is no longer used by rustc on 64bit MinGW and we don't support 32bit MinGW anyway. --- build_system/build_sysroot.rs | 54 +++++------------------------------ 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index fec6ff241550..c0ccf506262a 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -140,7 +140,6 @@ impl SysrootTarget { static STDLIB_SRC: RelPath = RelPath::build("stdlib"); static STANDARD_LIBRARY: CargoProject = CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target"); -static RTSTARTUP_SYSROOT: RelPath = RelPath::build("rtstartup"); fn build_sysroot_for_triple( dirs: &Dirs, @@ -150,8 +149,7 @@ fn build_sysroot_for_triple( panic_unwind_support: bool, ) -> SysrootTarget { match sysroot_kind { - SysrootKind::None => build_rtstartup(dirs, &compiler) - .unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }), + SysrootKind::None => SysrootTarget { triple: compiler.triple, libs: vec![] }, SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler), SysrootKind::Clif => { build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support) @@ -201,15 +199,14 @@ fn build_clif_sysroot_for_triple( ) -> SysrootTarget { let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] }; - if let Some(rtstartup_target_libs) = build_rtstartup(dirs, &compiler) { - rtstartup_target_libs.install_into_sysroot(&RTSTARTUP_SYSROOT.to_path(dirs)); - - target_libs.libs.extend(rtstartup_target_libs.libs); - } - let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join("release"); if !config::get_bool("keep_sysroot") { + let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust"); + assert!(sysroot_src_orig.exists()); + + apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs)); + // Cleanup the deps dir, but keep build scripts and the incremental cache for faster // recompilation as they are not affected by changes in cg_clif. ensure_empty_dir(&build_dir.join("deps")); @@ -228,9 +225,7 @@ fn build_clif_sysroot_for_triple( rustflags.push(format!("-Zcodegen-backend={name}")); } }; - // Necessary for MinGW to find rsbegin.o and rsend.o - rustflags.push("--sysroot".to_owned()); - rustflags.push(RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap().to_owned()); + rustflags.push("--sysroot=/dev/null".to_owned()); // Incremental compilation by default disables mir inlining. This leads to both a decent // compile perf and a significant runtime perf regression. As such forcefully enable mir @@ -271,38 +266,3 @@ fn build_clif_sysroot_for_triple( target_libs } - -fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { - if !config::get_bool("keep_sysroot") { - let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust"); - assert!(sysroot_src_orig.exists()); - - apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs)); - } - - if !compiler.triple.ends_with("windows-gnu") { - return None; - } - - let rtstartup_sysroot = RTSTARTUP_SYSROOT.to_path(dirs); - ensure_empty_dir(&rtstartup_sysroot); - - let rtstartup_src = STDLIB_SRC.to_path(dirs).join("library").join("rtstartup"); - let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] }; - - for file in ["rsbegin", "rsend"] { - let obj = rtstartup_sysroot.join(format!("{file}.o")); - let mut build_rtstartup_cmd = Command::new(&compiler.rustc); - build_rtstartup_cmd - .arg("--target") - .arg(&compiler.triple) - .arg("--emit=obj") - .arg("-o") - .arg(&obj) - .arg(rtstartup_src.join(format!("{file}.rs"))); - spawn_and_wait(build_rtstartup_cmd); - target_libs.libs.push(obj.clone()); - } - - Some(target_libs) -} From fdaf80466eb04bf28486fee2eda02a7a2029b250 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 13:37:35 +0000 Subject: [PATCH 134/525] Add note about FreeBSD TLS problems to Readme.md --- Readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 48003ad270e6..c5436cf67c80 100644 --- a/Readme.md +++ b/Readme.md @@ -66,7 +66,7 @@ For more docs on how to build and test see [build_system/usage.txt](build_system |OS \ architecture|x86\_64|AArch64|Riscv64|s390x (System-Z)| |---|---|---|---|---| |Linux|✅|✅|✅[^no-rustup]|✅[^no-rustup]| -|FreeBSD|✅[^no-rustup]|❓|❓|❓| +|FreeBSD|✅[^no-rustup][^tls]|❓|❓|❓| |AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]| |Other unixes|❓|❓|❓|❓| |macOS|✅|✅|N/A|N/A| @@ -80,6 +80,7 @@ Not all targets are available as rustup component for nightly. See notes in the [^xcoff]: XCOFF object file format is not supported. [^no-rustup]: Not available as [rustup component for nightly](https://rust-lang.github.io/rustup-components-history/). You can build it yourself. +[^tls]: FreeBSD requires setting `LD_STATIC_TLS_EXTRA=4096` to build cg_clif. In addition you need at least FreeBSD 14. ## Usage From b038641a28ea1bd77bb35ef84d0afafacc38e215 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:38:26 +0000 Subject: [PATCH 135/525] Use #[ignore] rather than commenting out for disabling sysroot tests --- ...oot_tests-Disable-long-running-tests.patch | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/patches/0028-sysroot_tests-Disable-long-running-tests.patch index 357b8d306cf6..853acab2773b 100644 --- a/patches/0028-sysroot_tests-Disable-long-running-tests.patch +++ b/patches/0028-sysroot_tests-Disable-long-running-tests.patch @@ -11,38 +11,41 @@ diff --git a/coretests/tests/slice.rs b/coretests/tests/slice.rs index 8402833..84592e0 100644 --- a/coretests/tests/slice.rs +++ b/coretests/tests/slice.rs -@@ -1809,6 +1809,7 @@ fn sort_unstable() { - } - } +@@ -1619,7 +1619,7 @@ fn brute_force_rotate_test_1() { -+/* #[test] #[cfg(not(target_arch = "wasm32"))] - #[cfg_attr(miri, ignore)] // Miri is too slow -@@ -1914,6 +1915,7 @@ fn select_nth_unstable() { - v.select_nth_unstable(0); - assert!(v == [0xDEADBEEF]); - } -+*/ +-#[cfg_attr(miri, ignore)] // Miri is too slow ++#[ignore] // Miri is too slow + fn select_nth_unstable() { + use core::cmp::Ordering::{Equal, Greater, Less}; - #[test] - #[should_panic(expected = "index 0 greater than length of slice")] -@@ -2462,6 +2462,7 @@ take_tests! { - #[cfg(not(miri))] // unused in Miri +@@ -2303,14 +2303,14 @@ split_off_tests! { const EMPTY_MAX: &'static [()] = &[(); usize::MAX]; -+/* // can't be a constant due to const mutability rules - #[cfg(not(miri))] // unused in Miri +-#[cfg(not(miri))] // unused in Miri ++#[cfg(any())] // unused in Miri macro_rules! empty_max_mut { -@@ -2485,6 +2486,7 @@ take_tests! { - (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), - (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), + () => { + &mut [(); usize::MAX] as _ + }; } -+*/ - #[test] - fn test_slice_from_ptr_range() { +-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) ++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) + split_off_tests! { + slice: &[(); usize::MAX], method: split_off, + (split_off_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]), +@@ -2318,7 +2318,7 @@ split_off_tests! { + (split_off_in_bounds_max_range_from, (usize::MAX..), Some(&[] as _), EMPTY_MAX), + } + +-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) ++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) + split_off_tests! { + slice: &mut [(); usize::MAX], method: split_off_mut, + (split_off_mut_in_bounds_max_range_to, (..usize::MAX), Some(empty_max_mut!()), &mut [(); 0]), diff --git a/alloctests/tests/sort/tests.rs b/alloctests/tests/sort/tests.rs index d321f8d..8b2040a 100644 --- a/alloctests/tests/sort/tests.rs From e23f9b37b4b75c7869d9977bde4a5a7fa4f5f84e Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 30 Sep 2025 03:58:56 -0500 Subject: [PATCH 136/525] add additional lookup path for ref/ptr/array template args --- src/etc/lldb_providers.py | 85 +++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 65f18baa937e..ad7c19264a8a 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -1,7 +1,7 @@ from __future__ import annotations import re import sys -from typing import List, TYPE_CHECKING +from typing import List, TYPE_CHECKING, Generator from lldb import ( SBData, @@ -13,7 +13,7 @@ from lldb import ( ) if TYPE_CHECKING: - from lldb import SBValue, SBType, SBTypeStaticField + from lldb import SBValue, SBType, SBTypeStaticField, SBTarget # from lldb.formatters import Logger @@ -133,19 +133,18 @@ class EmptySyntheticProvider: return False -def get_template_args(type_name: str) -> list[str]: +def get_template_args(type_name: str) -> Generator[str, None, None]: """ Takes a type name `T, D>` and returns a list of its generic args `["A", "tuple$", "D"]`. String-based replacement for LLDB's `SBType.template_args`, as LLDB is currently unable to populate this field for targets with PDB debug info. Also useful for manually altering the type - name of generics (e.g. `Vec` -> `Vec<&str>`). + name of generics (e.g. `Vec >` -> `Vec<&str>`). Each element of the returned list can be looked up for its `SBType` value via `SBTarget.FindFirstType()` """ - params = [] level = 0 start = 0 for i, c in enumerate(type_name): @@ -156,11 +155,55 @@ def get_template_args(type_name: str) -> list[str]: elif c == ">": level -= 1 if level == 0: - params.append(type_name[start:i].strip()) + yield type_name[start:i].strip() elif c == "," and level == 1: - params.append(type_name[start:i].strip()) + yield type_name[start:i].strip() start = i + 1 - return params + + +MSVC_PTR_PREFIX: List[str] = ["ref$<", "ref_mut$<", "ptr_const$<", "ptr_mut$<"] + + +def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType: + """ + RECURSIVE when arrays or references are nested (e.g. `ref$ >`, `array$ >`) + + Takes the template arg's name (likely from `get_template_args`) and finds/creates its + corresponding SBType. + + For non-reference/pointer/array types this is identical to calling + `target.FindFirstType(arg_name)` + + LLDB internally interprets refs, pointers, and arrays C-style (`&u8` -> `u8 *`, + `*const u8` -> `u8 *`, `[u8; 5]` -> `u8 [5]`). Looking up these names still doesn't work in the + current version of LLDB, so instead the types are generated via `base_type.GetPointerType()` and + `base_type.GetArrayType()`, which bypass the PDB file and ask clang directly for the type node. + """ + result = target.FindFirstType(arg_name) + + if result.IsValid(): + return result + + for prefix in MSVC_PTR_PREFIX: + if arg_name.startswith(prefix): + arg_name = arg_name[len(prefix) : -1].strip() + + result = resolve_msvc_template_arg(arg_name, target) + return result.GetPointerType() + + if arg_name.startswith("array$<"): + arg_name = arg_name[7:-1].strip() + + template_args = get_template_args(arg_name) + + element_name = next(template_args) + length = next(template_args) + + result = resolve_msvc_template_arg(element_name, target) + + return result.GetArrayType(int(length)) + + return result def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: @@ -808,6 +851,7 @@ class StdVecSyntheticProvider: # logger = Logger.Logger() # logger >> "[StdVecSyntheticProvider] for " + str(valobj.GetName()) self.valobj = valobj + self.element_type = None self.update() def num_children(self) -> int: @@ -841,8 +885,9 @@ class StdVecSyntheticProvider: self.element_type = self.valobj.GetType().GetTemplateArgumentType(0) if not self.element_type.IsValid(): - element_name = get_template_args(self.valobj.GetTypeName())[0] - self.element_type = self.valobj.target.FindFirstType(element_name) + arg_name = next(get_template_args(self.valobj.GetTypeName())) + + self.element_type = resolve_msvc_template_arg(arg_name, self.valobj.target) self.element_type_size = self.element_type.GetByteSize() @@ -918,6 +963,7 @@ class StdVecDequeSyntheticProvider: # logger = Logger.Logger() # logger >> "[StdVecDequeSyntheticProvider] for " + str(valobj.GetName()) self.valobj = valobj + self.element_type = None self.update() def num_children(self) -> int: @@ -954,6 +1000,12 @@ class StdVecDequeSyntheticProvider: ) self.element_type = self.valobj.GetType().GetTemplateArgumentType(0) + + if not self.element_type.IsValid(): + arg_name = next(get_template_args(self.valobj.GetTypeName())) + + self.element_type = resolve_msvc_template_arg(arg_name, self.valobj.target) + self.element_type_size = self.element_type.GetByteSize() def has_children(self) -> bool: @@ -1081,6 +1133,7 @@ class StdHashMapSyntheticProvider: element = self.data_ptr.CreateValueFromAddress( "[%s]" % index, address, self.pair_type ) + if self.show_values: return element else: @@ -1100,14 +1153,12 @@ class StdHashMapSyntheticProvider: self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned() - template_args = table.type.template_args + self.pair_type = table.GetType().GetTemplateArgumentType(0) - if template_args is None: - type_name = table.GetTypeName() - args = get_template_args(type_name) - self.pair_type = self.valobj.target.FindFirstType(args[0]) - else: - self.pair_type = template_args[0] + if not self.pair_type.IsValid(): + arg_name = next(get_template_args(table.GetTypeName())) + + self.pair_type = resolve_msvc_template_arg(arg_name, self.valobj.target) if self.pair_type.IsTypedefType(): self.pair_type = self.pair_type.GetTypedefedType() From dd7c7d028dd5b9f97e09a6c57fc62f1f7fb8f735 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 21 Aug 2025 22:19:40 +0200 Subject: [PATCH 137/525] use `codegen_instance_attrs` in some additional places --- src/abi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 29ee46194de1..9a9a1f4a2c0f 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( true } else { instance.is_some_and(|inst| { - fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD) + fx.tcx.codegen_instance_attrs(inst.def).flags.contains(CodegenFnAttrFlags::COLD) }) }; if is_cold { From 9aeab7807602c24685314e8c0f4e0a33e5ad5818 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 4 Oct 2025 20:57:18 +0200 Subject: [PATCH 138/525] improve text --- src/doc/rustc/src/platform-support/arm-linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/arm-linux.md b/src/doc/rustc/src/platform-support/arm-linux.md index b620763fa6df..652661b2d3aa 100644 --- a/src/doc/rustc/src/platform-support/arm-linux.md +++ b/src/doc/rustc/src/platform-support/arm-linux.md @@ -70,7 +70,7 @@ Targets that start with `armv4t` are for processors implementing the Armv4T architecture from 1994. These include the ARM7TDMI, as found in the Nokia 6110 brick-phone and the Game Boy Advance. The 'T' stands for *Thumb* and indicate that the processors can execute smaller 16-bit versions of some of the 32-bit -Arm instructions. A Thumb is like a small version of an Arm. +Arm instructions. This is because a Thumb is like a small version of an Arm. Targets that start with `armv5te` are for processors implementing the Armv5TE architecture. These are mostly from the ARM9 family, like the ARM946E-S found From c7b4a1d58a72b66f2dffe0f822bb879191593beb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:11:18 +0000 Subject: [PATCH 139/525] Rustup to rustc 1.92.0-nightly (839222065 2025-10-05) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 2697f26e8e85..9259a33c8c90 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-10-01" +channel = "nightly-2025-10-06" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 7f0b2bb7d283785493a97c0fa8739078a9a55114 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:29:01 +0000 Subject: [PATCH 140/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 3981a42eb119..78802f97af2c 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -141,6 +141,7 @@ rm -r tests/run-make/incr-add-rust-src-component rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export/extern-opt # something about rustc version mismatches rm -r tests/run-make/export # same +rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind # genuine bugs # ============ From 7201c1b95f0f4762d9db0141cb1183e03bab6f1c Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 02:09:20 -0700 Subject: [PATCH 141/525] remove DerefTemp and CopyFromDeref from runtime mir --- src/base.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/base.rs b/src/base.rs index ebf2ccf74de2..a529692c0743 100644 --- a/src/base.rs +++ b/src/base.rs @@ -600,11 +600,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let val = codegen_operand(fx, operand); lval.write_cvalue(fx, val); } - Rvalue::CopyForDeref(place) => { - let cplace = codegen_place(fx, place); - let val = cplace.to_cvalue(fx); - lval.write_cvalue(fx, val) - } Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { let place = codegen_place(fx, place); let ref_ = place.place_ref(fx, lval.layout()); @@ -928,6 +923,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); } + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), } } StatementKind::StorageLive(_) From 0e4df746ad940dc7b9d103e5e9c3cd1ae4fae841 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 9 Oct 2025 01:24:55 +0800 Subject: [PATCH 142/525] prefer to use repeat_n over repeat and take --- src/constant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index a56466750e75..faca92957e1a 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -318,7 +318,7 @@ fn data_id_for_static( let mut data = DataDescription::new(); data.set_align(align); let data_gv = module.declare_data_in_data(data_id, &mut data); - data.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect()); + data.define(std::iter::repeat_n(0, pointer_ty(tcx).bytes() as usize).collect()); data.write_data_addr(0, data_gv, 0); match module.define_data(ref_data_id, &data) { // Every time the static is referenced there will be another definition of this global, From 0f2b4700b07aeb037569282412cd356c3da21a7c Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 10 Oct 2025 01:48:09 +0000 Subject: [PATCH 143/525] Remove StatementKind::Deinit. --- src/base.rs | 1 - src/constant.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index ebf2ccf74de2..b3f9f598926c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -932,7 +932,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: } StatementKind::StorageLive(_) | StatementKind::StorageDead(_) - | StatementKind::Deinit(_) | StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::FakeRead(..) diff --git a/src/constant.rs b/src/constant.rs index faca92957e1a..293459cc11c2 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -597,7 +597,6 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( StatementKind::Assign(_) | StatementKind::FakeRead(_) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(_) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) From 67b7b7f66b0c23e0d0aa4cd10578cc1511eedcb4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 26 Jun 2025 13:44:01 +0000 Subject: [PATCH 144/525] Support #[alloc_error_handler] without the allocator shim Currently it is possible to avoid linking the allocator shim when __rust_no_alloc_shim_is_unstable_v2 is defined when linking rlibs directly as some build systems need. However this requires liballoc to be compiled with --cfg no_global_oom_handling, which places huge restrictions on what functions you can call and makes it impossible to use libstd. Or alternatively you have to define __rust_alloc_error_handler and (when using libstd) __rust_alloc_error_handler_should_panic using #[rustc_std_internal_symbol]. With this commit you can either use libstd and define __rust_alloc_error_handler_should_panic or not use libstd and use #[alloc_error_handler] instead. Both options are still unstable though. Eventually the alloc_error_handler may either be removed entirely (though the PR for that has been stale for years now) or we may start using weak symbols for it instead. For the latter case this commit is a prerequisite anyway. --- src/allocator.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 04f1129d87c1..9533f870434a 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -3,8 +3,8 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, + default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; @@ -72,17 +72,19 @@ fn codegen_inner( } } - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), - ); + if alloc_error_handler_kind == AllocatorKind::Default { + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], + returns: vec![], + }; + crate::common::create_wrapper_function( + module, + sig, + &mangle_internal_symbol(tcx, &global_fn_name(ALLOC_ERROR_HANDLER)), + &mangle_internal_symbol(tcx, &default_fn_name(ALLOC_ERROR_HANDLER)), + ); + } { let sig = Signature { From b453c19e91900d7f494446c37c3e25a04fac6478 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:08:55 +0000 Subject: [PATCH 145/525] Move computation of allocator shim contents to cg_ssa In the future this should make it easier to use weak symbols for the allocator shim on platforms that properly support weak symbols. And it would allow reusing the allocator shim code for handling default implementations of the upcoming externally implementable items feature on platforms that don't properly support weak symbols. --- src/allocator.rs | 79 ++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 9533f870434a..67b89114356b 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -3,10 +3,9 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - default_fn_name, global_fn_name, + AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; -use rustc_codegen_ssa::base::allocator_kind_for_codegen; +use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents}; use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; @@ -15,74 +14,54 @@ use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - tcx, - module, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + let methods = allocator_shim_contents(tcx, kind); + codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom); true } fn codegen_inner( tcx: TyCtxt<'_>, module: &mut dyn Module, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - arg_tys.push(usize_ty); // size - arg_tys.push(usize_ty); // align - } - AllocatorTy::Ptr => arg_tys.push(usize_ty), - AllocatorTy::Usize => arg_tys.push(usize_ty), + for method in methods { + let mut arg_tys = Vec::with_capacity(method.inputs.len()); + for input in method.inputs.iter() { + match input.ty { + AllocatorTy::Layout => { + arg_tys.push(usize_ty); // size + arg_tys.push(usize_ty); // align + } + AllocatorTy::Ptr => arg_tys.push(usize_ty), + AllocatorTy::Usize => arg_tys.push(usize_ty), - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { + panic!("invalid allocator arg") } } - let output = match method.output { - AllocatorTy::ResultPtr => Some(usize_ty), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: arg_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output.into_iter().map(AbiParam::new).collect(), - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, &global_fn_name(method.name)), - &mangle_internal_symbol(tcx, &default_fn_name(method.name)), - ); } - } + let output = match method.output { + AllocatorTy::ResultPtr => Some(usize_ty), + AllocatorTy::Never | AllocatorTy::Unit => None, + + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; - if alloc_error_handler_kind == AllocatorKind::Default { let sig = Signature { call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], + params: arg_tys.iter().cloned().map(AbiParam::new).collect(), + returns: output.into_iter().map(AbiParam::new).collect(), }; crate::common::create_wrapper_function( module, sig, - &mangle_internal_symbol(tcx, &global_fn_name(ALLOC_ERROR_HANDLER)), - &mangle_internal_symbol(tcx, &default_fn_name(ALLOC_ERROR_HANDLER)), + &mangle_internal_symbol(tcx, &global_fn_name(method.name)), + &mangle_internal_symbol(tcx, &default_fn_name(method.name)), ); } From 124bfc99c3087066c84731e06effcbb6b3a16559 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 13 Oct 2025 11:47:53 -0400 Subject: [PATCH 146/525] Remove parent def lookup hack that is no longer needed The tcx.parent tree appears to be correct now. --- .../rustc_hir_analysis/src/collect/generics_of.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 333cea23c414..3d2f0466cad0 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -77,20 +77,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // stable enough and does not need a feature gate anymore. Node::AnonConst(_) => { let parent_did = tcx.parent(def_id.to_def_id()); - - // We don't do this unconditionally because the `DefId` parent of an anon const - // might be an implicitly created closure during `async fn` desugaring. This would - // have the wrong generics. - // - // i.e. `async fn foo<'a>() { let a = [(); { 1 + 2 }]; bar().await() }` - // would implicitly have a closure in its body that would be the parent of - // the `{ 1 + 2 }` anon const. This closure's generics is simply a witness - // instead of `['a]`. - let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) { - parent_did - } else { - tcx.hir_get_parent_item(hir_id).to_def_id() - }; debug!(?parent_did); let mut in_param_ty = false; From f3d5c10e9e3224413061baeb38f35f750302ea9c Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Sun, 6 Jul 2025 20:58:14 +0100 Subject: [PATCH 147/525] Restrict sysroot crate imports to those defined in this repo. It's common to import dependencies from the sysroot via `extern crate` rather than use an explicit cargo dependency, when it's necessary to use the same dependency version as used by rustc itself. However, this is dangerous for crates.io crates, since rustc may not pull in the dependency on some targets, or may pull in multiple versions. In both cases, the `extern crate` fails to resolve. To address this, re-export all such dependencies from the appropriate `rustc_*` crates, and use this alias from crates which would otherwise need to use `extern crate`. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5fd7c4d4f41b..5d48d0c94c58 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,13 +26,12 @@ extern crate rustc_fs_util; extern crate rustc_hir; extern crate rustc_incremental; extern crate rustc_index; +extern crate rustc_log; extern crate rustc_metadata; extern crate rustc_session; extern crate rustc_span; extern crate rustc_symbol_mangling; extern crate rustc_target; -#[macro_use] -extern crate tracing; // This prevents duplicating functions and statics that are already part of the host rustc process. #[allow(unused_extern_crates)] @@ -46,6 +45,7 @@ use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenResults, TargetConfig}; +use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; From 10ee204ff7a4a39bb75ae10db3d62689dceb4f50 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 10 Oct 2025 21:29:29 -0400 Subject: [PATCH 148/525] Fix ICE on offsetted ZST pointer A grep for `const_usize.*align` found the same code copied to rustc_codegen_gcc but I don't see other cases where we get this wrong. --- src/constant.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 293459cc11c2..3243e12e6999 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -5,7 +5,9 @@ use std::cmp::Ordering; use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint}; +use rustc_middle::mir::interpret::{ + AllocId, GlobalAlloc, PointerArithmetic, Scalar, read_target_uint, +}; use rustc_middle::ty::{ExistentialTraitRef, ScalarInt}; use crate::prelude::*; @@ -138,8 +140,11 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { if alloc.inner().len() == 0 { - assert_eq!(offset, Size::ZERO); - fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64) + let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); + fx.bcx.ins().iconst( + fx.pointer_type, + fx.tcx.truncate_to_target_usize(val) as i64, + ) } else { let data_id = data_id_for_alloc_id( &mut fx.constants_cx, From 258d5530f14001f507477596a937f5d54a6f7c2a Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 16 Oct 2025 04:53:02 +0000 Subject: [PATCH 149/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 402ce0ef07d5db9ba26ae5c37ce6aff0c9002052. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1160b1b97285..1abf64f0bc3b 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -28d0a4a205f9e511ad2f51ee79a4aa19a704a455 +402ce0ef07d5db9ba26ae5c37ce6aff0c9002052 From bc911c2cdd480f853598213c793012e908d1edd0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 11 Oct 2025 14:45:54 +0200 Subject: [PATCH 150/525] std-detect: improve detect macro docs document that the detect macros expand to `true` when the feature is statically enabled --- library/std_detect/src/detect/arch/aarch64.rs | 9 +++++++-- library/std_detect/src/detect/arch/arm.rs | 5 ++++- library/std_detect/src/detect/arch/loongarch.rs | 6 +++++- library/std_detect/src/detect/arch/mips.rs | 5 ++++- library/std_detect/src/detect/arch/mips64.rs | 5 ++++- library/std_detect/src/detect/arch/powerpc.rs | 5 ++++- library/std_detect/src/detect/arch/powerpc64.rs | 5 ++++- library/std_detect/src/detect/arch/riscv.rs | 6 ++++-- library/std_detect/src/detect/arch/s390x.rs | 5 ++++- library/std_detect/src/detect/arch/x86.rs | 11 +++++------ 10 files changed, 45 insertions(+), 17 deletions(-) diff --git a/library/std_detect/src/detect/arch/aarch64.rs b/library/std_detect/src/detect/arch/aarch64.rs index 13570a25c1cf..5e85e96374ed 100644 --- a/library/std_detect/src/detect/arch/aarch64.rs +++ b/library/std_detect/src/detect/arch/aarch64.rs @@ -5,13 +5,18 @@ features! { @CFG: any(target_arch = "aarch64", target_arch = "arm64ec"); @MACRO_NAME: is_aarch64_feature_detected; @MACRO_ATTRS: - /// This macro tests, at runtime, whether an `aarch64` feature is enabled on aarch64 platforms. - /// Currently most features are only supported on linux-based platforms. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. /// /// This macro takes one argument which is a string literal of the feature being tested for. /// The feature names are mostly taken from their FEAT_* definitions in the [ARM Architecture /// Reference Manual][docs]. /// + /// Currently most features are only supported on linux-based platforms: on other platforms the + /// runtime check will always return `false`. + /// /// ## Supported arguments /// /// * `"aes"` - FEAT_AES & FEAT_PMULL diff --git a/library/std_detect/src/detect/arch/arm.rs b/library/std_detect/src/detect/arch/arm.rs index c3c8883ce315..75b8ca9a1e88 100644 --- a/library/std_detect/src/detect/arch/arm.rs +++ b/library/std_detect/src/detect/arch/arm.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "arm"; @MACRO_NAME: is_arm_feature_detected; @MACRO_ATTRS: - /// Checks if `arm` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] @NO_RUNTIME_DETECTION: "v7"; @NO_RUNTIME_DETECTION: "vfp2"; diff --git a/library/std_detect/src/detect/arch/loongarch.rs b/library/std_detect/src/detect/arch/loongarch.rs index d5a442fbbb8a..629962773811 100644 --- a/library/std_detect/src/detect/arch/loongarch.rs +++ b/library/std_detect/src/detect/arch/loongarch.rs @@ -5,7 +5,11 @@ features! { @CFG: any(target_arch = "loongarch32", target_arch = "loongarch64"); @MACRO_NAME: is_loongarch_feature_detected; @MACRO_ATTRS: - /// Checks if `loongarch` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. + /// /// Supported arguments are: /// /// * `"32s"` diff --git a/library/std_detect/src/detect/arch/mips.rs b/library/std_detect/src/detect/arch/mips.rs index e185fdfcaac6..9e1960eb96da 100644 --- a/library/std_detect/src/detect/arch/mips.rs +++ b/library/std_detect/src/detect/arch/mips.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "mips"; @MACRO_NAME: is_mips_feature_detected; @MACRO_ATTRS: - /// Checks if `mips` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] @FEATURE: #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] msa: "msa"; /// MIPS SIMD Architecture (MSA) diff --git a/library/std_detect/src/detect/arch/mips64.rs b/library/std_detect/src/detect/arch/mips64.rs index 69fe4869d30e..2bb44ba6e2b3 100644 --- a/library/std_detect/src/detect/arch/mips64.rs +++ b/library/std_detect/src/detect/arch/mips64.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "mips64"; @MACRO_NAME: is_mips64_feature_detected; @MACRO_ATTRS: - /// Checks if `mips64` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] @FEATURE: #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] msa: "msa"; /// MIPS SIMD Architecture (MSA) diff --git a/library/std_detect/src/detect/arch/powerpc.rs b/library/std_detect/src/detect/arch/powerpc.rs index c390993a48a6..be2db0b81c2f 100644 --- a/library/std_detect/src/detect/arch/powerpc.rs +++ b/library/std_detect/src/detect/arch/powerpc.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "powerpc"; @MACRO_NAME: is_powerpc_feature_detected; @MACRO_ATTRS: - /// Checks if `powerpc` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] @FEATURE: #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] altivec: "altivec"; /// Altivec diff --git a/library/std_detect/src/detect/arch/powerpc64.rs b/library/std_detect/src/detect/arch/powerpc64.rs index cf05baa6f799..98e8d5f32b75 100644 --- a/library/std_detect/src/detect/arch/powerpc64.rs +++ b/library/std_detect/src/detect/arch/powerpc64.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "powerpc64"; @MACRO_NAME: is_powerpc64_feature_detected; @MACRO_ATTRS: - /// Checks if `powerpc` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] @FEATURE: #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] altivec: "altivec"; /// Altivec diff --git a/library/std_detect/src/detect/arch/riscv.rs b/library/std_detect/src/detect/arch/riscv.rs index 1e57d09edb14..846d7f10d68f 100644 --- a/library/std_detect/src/detect/arch/riscv.rs +++ b/library/std_detect/src/detect/arch/riscv.rs @@ -5,8 +5,10 @@ features! { @CFG: any(target_arch = "riscv32", target_arch = "riscv64"); @MACRO_NAME: is_riscv_feature_detected; @MACRO_ATTRS: - /// A macro to test at *runtime* whether instruction sets are available on - /// RISC-V platforms. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. /// /// RISC-V standard defined the base sets and the extension sets. /// The base sets are RV32I, RV64I, RV32E or RV128I. Any RISC-V platform diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index 4c20d011680b..d59fbc7de3bd 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -5,7 +5,10 @@ features! { @CFG: target_arch = "s390x"; @MACRO_NAME: is_s390x_feature_detected; @MACRO_ATTRS: - /// Checks if `s390x` feature is enabled. + /// Check for the presence of a CPU feature at runtime. + /// + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility diff --git a/library/std_detect/src/detect/arch/x86.rs b/library/std_detect/src/detect/arch/x86.rs index bd749b88f566..21d8b5609d96 100644 --- a/library/std_detect/src/detect/arch/x86.rs +++ b/library/std_detect/src/detect/arch/x86.rs @@ -20,13 +20,12 @@ features! { @CFG: any(target_arch = "x86", target_arch = "x86_64"); @MACRO_NAME: is_x86_feature_detected; @MACRO_ATTRS: - /// A macro to test at *runtime* whether a CPU feature is available on - /// x86/x86-64 platforms. + /// Check for the presence of a CPU feature at runtime. /// - /// This macro is provided in the standard library and will detect at runtime - /// whether the specified CPU feature is detected. This does **not** resolve at - /// compile time unless the specified feature is already enabled for the entire - /// crate. Runtime detection currently relies mostly on the `cpuid` instruction. + /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) + /// the macro expands to `true`. + /// + /// Runtime detection currently relies mostly on the `cpuid` instruction. /// /// This macro only takes one argument which is a string literal of the feature /// being tested for. The feature names supported are the lowercase versions of From 379a05702326e64481f828eedd82239fdce1b065 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 13 Oct 2025 11:49:19 -0400 Subject: [PATCH 151/525] Fix lowering of CStr constants to valtrees They need an extra branch for the newtype. --- compiler/rustc_mir_build/src/thir/constant.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 52e6f2d3e1a5..6e071fb344c4 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -58,8 +58,12 @@ pub(crate) fn lit_to_const<'tcx>( (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ty::ValTree::from_scalar_int(tcx, n.into()) } - (ast::LitKind::CStr(byte_sym, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) => { - ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()) + (ast::LitKind::CStr(byte_sym, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) => + { + // A CStr is a newtype around a byte slice, so we create the inner slice here. + // We need a branch for each "level" of the data structure. + let bytes = ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()); + ty::ValTree::from_branches(tcx, [bytes]) } (ast::LitKind::Int(n, _), ty::Uint(ui)) if !neg => { let scalar_int = trunc(n.get(), *ui); From 439431aa628ae6839c2fcf2286a356c9ad467aa2 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 17 Oct 2025 14:01:06 +1100 Subject: [PATCH 152/525] ci: Switch back to default coreutils (uutils) after libffi-sys bump --- src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile | 2 -- src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile | 2 -- src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile index e840113047e6..04b46226acfa 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile @@ -2,8 +2,6 @@ FROM ubuntu:25.10 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ - # FIXME(#147556): Use GNU coreutils to work around a libffi-sys build failure. - coreutils-from-gnu coreutils-from-uutils- --allow-remove-essential \ g++ \ make \ ninja-build \ diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile index f5c0f6127a8d..095624d6fb71 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile @@ -3,8 +3,6 @@ FROM ubuntu:25.10 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ - # FIXME(#147556): Use GNU coreutils to work around a libffi-sys build failure. - coreutils-from-gnu coreutils-from-uutils- --allow-remove-essential \ bzip2 \ g++ \ make \ diff --git a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile index a54ce19f9716..4b61fd94a6cf 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile @@ -2,8 +2,6 @@ FROM ubuntu:25.10 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ - # FIXME(#147556): Use GNU coreutils to work around a libffi-sys build failure. - coreutils-from-gnu coreutils-from-uutils- --allow-remove-essential \ g++ \ make \ ninja-build \ From 2d8a0c18160abfdd903ac55d54c852038c303605 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:54:47 +0000 Subject: [PATCH 153/525] Rustup to rustc 1.92.0-nightly (53a741fc4 2025-10-16) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9259a33c8c90..4196e4872dff 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-10-06" +channel = "nightly-2025-10-17" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From ca23203edb4512047565297ce11784b11f427a50 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Oct 2025 11:35:42 +0000 Subject: [PATCH 154/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 2 ++ src/constant.rs | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 78802f97af2c..cbea3caf1211 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -49,6 +49,7 @@ rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg sup rm tests/ui/c-variadic/valid.rs # same rm tests/ui/c-variadic/trait-method.rs # same rm tests/ui/c-variadic/inherent-method.rs # same +rm tests/ui/sanitizer/kcfi-c-variadic.rs # same rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs @@ -62,6 +63,7 @@ rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't rm tests/ui/asm/global-asm-mono-sym-fn.rs # same rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported +rm tests/ui/asm/label-operand.rs # same rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same diff --git a/src/constant.rs b/src/constant.rs index 5ad78e97d2b8..38b66256ea30 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -141,11 +141,7 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { if alloc.inner().len() == 0 { - let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); - fx.bcx.ins().iconst( - fx.pointer_type, - fx.tcx.truncate_to_target_usize(val) as i64, - ) + fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64) } else { let data_id = data_id_for_alloc_id( &mut fx.constants_cx, @@ -213,7 +209,9 @@ pub(crate) fn codegen_const_value<'tcx>( } }; let val = if offset.bytes() != 0 { - fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap()) + fx.bcx + .ins() + .iadd_imm(base_addr, fx.tcx.truncate_to_target_usize(offset.bytes()) as i64) } else { base_addr }; From cff6452e9019051390c9bffc6a80574da71cca9b Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 17 Oct 2025 13:32:11 +0200 Subject: [PATCH 155/525] Ignore test-dashboard related files After bors merges a PR, a message may be posted from the CI onto the PR comment thread directing the user to use the following commands to look at the test differences: ``` cargo run --manifest-path src/ci/citool/Cargo.toml -- \ test-dashboard [SOMEID] --output-dir test-dashboard open test-dashboard/index.html ``` This command creates the `.citool-cache` and `test-dashboard` directories, whose contents should not enter the repository and can be ignored by `git`. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 5988a64916ad..0030f22363c2 100644 --- a/.gitignore +++ b/.gitignore @@ -90,6 +90,10 @@ node_modules ## Rustdoc GUI tests tests/rustdoc-gui/src/**.lock +## Test dashboard +.citool-cache/ +test-dashboard/ + ## direnv /.envrc /.direnv/ From cbae95602f093b56ce7ed1910848553ef893486e Mon Sep 17 00:00:00 2001 From: Eduard Stefes Date: Mon, 20 Oct 2025 22:56:42 +0200 Subject: [PATCH 156/525] Fix tests for big-endian The tests fail on s390x and presumably other big-endian systems, due to check of raw alloc values in the MIR output. To fix the tests remove the raw bytes from the MIR output (via: compile-flags: -Zdump-mir-exclude-alloc-bytes) and update the matching diffs. --- .../const_prop/invalid_constant.main.GVN.diff | 18 ++++++------------ tests/mir-opt/const_prop/invalid_constant.rs | 2 +- tests/mir-opt/const_prop/union.main.GVN.diff | 6 ++---- tests/mir-opt/const_prop/union.rs | 2 +- tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff | 6 ++---- tests/mir-opt/gvn_loop.rs | 1 + 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff index a4900a1ac72e..20923d0352cd 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff @@ -61,17 +61,11 @@ StorageDead(_1); return; } -+ } -+ -+ ALLOC0 (size: 4, align: 4) { -+ 00 00 00 00 │ .... -+ } -+ -+ ALLOC1 (size: 4, align: 4) { -+ 04 00 00 00 │ .... -+ } -+ -+ ALLOC2 (size: 4, align: 4) { -+ 01 00 11 00 │ .... } ++ ++ ALLOC0 (size: 4, align: 4) { .. } ++ ++ ALLOC1 (size: 4, align: 4) { .. } ++ ++ ALLOC2 (size: 4, align: 4) { .. } diff --git a/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs index b59103792bfc..901c3721d923 100644 --- a/tests/mir-opt/const_prop/invalid_constant.rs +++ b/tests/mir-opt/const_prop/invalid_constant.rs @@ -1,6 +1,6 @@ // skip-filecheck //@ test-mir-pass: GVN -//@ compile-flags: -Zmir-enable-passes=+RemoveZsts +//@ compile-flags: -Zmir-enable-passes=+RemoveZsts -Zdump-mir-exclude-alloc-bytes // Verify that we can pretty print invalid constants. #![feature(adt_const_params, unsized_const_params)] diff --git a/tests/mir-opt/const_prop/union.main.GVN.diff b/tests/mir-opt/const_prop/union.main.GVN.diff index 16a0432ab901..4212a44d0a0d 100644 --- a/tests/mir-opt/const_prop/union.main.GVN.diff +++ b/tests/mir-opt/const_prop/union.main.GVN.diff @@ -34,9 +34,7 @@ StorageDead(_1); return; } -+ } -+ -+ ALLOC0 (size: 4, align: 4) { -+ 01 00 00 00 │ .... } ++ ++ ALLOC0 (size: 4, align: 4) { .. } diff --git a/tests/mir-opt/const_prop/union.rs b/tests/mir-opt/const_prop/union.rs index 9f197a1a5833..fb822ff28b2d 100644 --- a/tests/mir-opt/const_prop/union.rs +++ b/tests/mir-opt/const_prop/union.rs @@ -1,6 +1,6 @@ //! Tests that we can propagate into places that are projections into unions //@ test-mir-pass: GVN -//@ compile-flags: -Zinline-mir +//@ compile-flags: -Zinline-mir -Zdump-mir-exclude-alloc-bytes fn val() -> u32 { 1 diff --git a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff index 92e5ccabedf9..e5d719cf3ca9 100644 --- a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff +++ b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff @@ -107,9 +107,7 @@ StorageDead(_11); goto -> bb4; } -+ } -+ -+ ALLOC0 (size: 8, align: 4) { -+ 01 00 00 00 __ __ __ __ │ ....░░░░ } ++ ++ ALLOC0 (size: 8, align: 4) { .. } diff --git a/tests/mir-opt/gvn_loop.rs b/tests/mir-opt/gvn_loop.rs index 6e9df55a968d..4a94d516cca2 100644 --- a/tests/mir-opt/gvn_loop.rs +++ b/tests/mir-opt/gvn_loop.rs @@ -1,4 +1,5 @@ //@ test-mir-pass: GVN +//@ compile-flags: -Zdump-mir-exclude-alloc-bytes #![crate_type = "lib"] #![feature(core_intrinsics, rustc_attrs)] From a20a4c25133b6e259979ddb07e4d277cb1b1878b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Oct 2025 10:58:27 +0000 Subject: [PATCH 157/525] Update to Cranelift 0.125 --- Cargo.lock | 72 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 24 +++++++++--------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a81f72e17fb8..09b6c6b87c30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e8ca189363907c025c5debe2bfe56c8c18503d4575d750f87e4ccbbfbd8681" +checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e169461bfd463df68b01b196522f263c905eadc852f6e57fd4ce4c5d76115ead" +checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a98298338375075287834defe333d552847110f3a04db0ce19bd308b4c40fbb" +checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf5f49a2e2ae284db75437a49cc13220a7fb394983d5545af1209ab0bbadee3" +checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85" [[package]] name = "cranelift-codegen" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c354d6db9e344f647f38c88849c482c6014b79a295aca23fa82f73b62caeda2d" +checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8008396957de750e26d0b40a76bea6e5623d970a5bfe4266ef0a79ccb8341" +checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ecb53eafe1ad1f7d7f7d0585ae5d42b2050978fa812216b0420d4752eb41cb" +checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2" [[package]] name = "cranelift-control" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9c43ac27fe178cadb17e7f4cf1320ba89b8875cc2bdee265cccfca49bc76c95" +checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15513ee4bf648d366654c6a9864fe870ca64f1eed4acabf9139056e68b3d44dc" +checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e4399d31f06b50fcb3fa0117ff4c393c22e521574eecf524cf932fc99cd78f" +checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a751ec2b7c2f281274a3798e37ba2344b55f60789e67aaa10d6bbea3f3f8a6b" +checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688" [[package]] name = "cranelift-jit" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b22769d71584df8b6a083e11a248da38c40c0b91b565c8c202b173b26cc861c" +checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d" dependencies = [ "anyhow", "cranelift-codegen", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb364ea65183c3961faf6cc5038bd88ceb957c3cd3480958bce28d02b194625" +checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546500d7cb424c423e118dfddc169aa61ed611c47fc1cf48783ed4e3f9800619" +checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3aae694e5dd436c87ac90d1468a1032ff63d54faa33dcfece7e8fc7072fbe73" +checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.124.1" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edeb6b718b23108a123ad1c8eecf6fa34d21a6b5518fc340dda80ce5bdf42377" +checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf" [[package]] name = "crc32fast" @@ -460,9 +460,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "37.0.1" +version = "38.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aea2b284343796fbbe749c36db092b43809762f8b9e46626561a8be4003dd85" +checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f" dependencies = [ "anyhow", "cfg-if", @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-math" -version = "37.0.1" +version = "38.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a058122e659373c3648a71de03436105f213037d8016bb68550c259d4b37931" +checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a" dependencies = [ "libm", ] diff --git a/Cargo.toml b/Cargo.toml index 3adf9f415c9a..f2001123e579 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.124.1", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.124.1" } -cranelift-module = { version = "0.124.1" } -cranelift-native = { version = "0.124.1" } -cranelift-jit = { version = "0.124.1", optional = true } -cranelift-object = { version = "0.124.1" } +cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.125.0" } +cranelift-module = { version = "0.125.0" } +cranelift-native = { version = "0.125.0" } +cranelift-jit = { version = "0.125.0", optional = true } +cranelift-object = { version = "0.125.0" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-37.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } From 4ee19d9e865ad619bbf790c01762cb66277016b6 Mon Sep 17 00:00:00 2001 From: Evgenii Zheltonozhskii Date: Tue, 21 Oct 2025 13:21:06 +0300 Subject: [PATCH 158/525] Constify Range functions --- library/core/src/ops/index_range.rs | 9 +- library/core/src/ops/range.rs | 168 ++++++++++++++++++---------- library/core/src/range.rs | 73 +++++++----- library/core/src/slice/index.rs | 11 +- 4 files changed, 171 insertions(+), 90 deletions(-) diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 507fa9460bea..84395ddadf2b 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -9,7 +9,8 @@ use crate::ub_checks; /// /// (Normal `Range` code needs to handle degenerate ranges like `10..0`, /// which takes extra checks compared to only handling the canonical form.) -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug)] +#[derive_const(Clone, Eq, PartialEq)] pub(crate) struct IndexRange { start: usize, end: usize, @@ -54,7 +55,7 @@ impl IndexRange { /// # Safety /// - Can only be called when `start < end`, aka when `len > 0`. #[inline] - unsafe fn next_unchecked(&mut self) -> usize { + const unsafe fn next_unchecked(&mut self) -> usize { debug_assert!(self.start < self.end); let value = self.start; @@ -66,7 +67,7 @@ impl IndexRange { /// # Safety /// - Can only be called when `start < end`, aka when `len > 0`. #[inline] - unsafe fn next_back_unchecked(&mut self) -> usize { + const unsafe fn next_back_unchecked(&mut self) -> usize { debug_assert!(self.start < self.end); // SAFETY: The range isn't empty, so this cannot overflow @@ -116,7 +117,7 @@ impl IndexRange { } #[inline] - fn assume_range(&self) { + const fn assume_range(&self) { // SAFETY: This is the type invariant unsafe { crate::hint::assert_unchecked(self.start <= self.end) } } diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 58a9431bd845..d781f3f7ace4 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -1,6 +1,6 @@ use crate::fmt; use crate::hash::Hash; - +use crate::marker::Destruct; /// An unbounded range (`..`). /// /// `RangeFull` is primarily used as a [slicing index], its shorthand is `..`. @@ -38,7 +38,8 @@ use crate::hash::Hash; /// [slicing index]: crate::slice::SliceIndex #[lang = "RangeFull"] #[doc(alias = "..")] -#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Hash)] +#[derive_const(Clone, Default, Eq, PartialEq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -75,7 +76,8 @@ impl fmt::Debug for RangeFull { /// ``` #[lang = "Range"] #[doc(alias = "..")] -#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Eq, Hash)] +#[derive_const(Clone, Default, PartialEq)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -117,10 +119,11 @@ impl> Range { /// ``` #[inline] #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -144,7 +147,11 @@ impl> Range { /// ``` #[inline] #[stable(feature = "range_is_empty", since = "1.47.0")] - pub fn is_empty(&self) -> bool { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn is_empty(&self) -> bool + where + Idx: [const] PartialOrd, + { !(self.start < self.end) } } @@ -184,7 +191,8 @@ impl> Range { /// ``` #[lang = "RangeFrom"] #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Eq, Hash)] +#[derive_const(Clone, PartialEq)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -217,10 +225,11 @@ impl> RangeFrom { /// ``` #[inline] #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -266,7 +275,8 @@ impl> RangeFrom { /// [slicing index]: crate::slice::SliceIndex #[lang = "RangeTo"] #[doc(alias = "..")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Eq, Hash)] +#[derive_const(Clone, PartialEq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { /// The upper bound of the range (exclusive). @@ -299,10 +309,11 @@ impl> RangeTo { /// ``` #[inline] #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -340,7 +351,8 @@ impl> RangeTo { /// ``` #[lang = "RangeInclusive"] #[doc(alias = "..=")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, Hash)] +#[derive_const(Eq, PartialEq)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { // Note that the fields here are not public to allow changing the @@ -506,10 +518,11 @@ impl> RangeInclusive { /// ``` #[inline] #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -542,7 +555,11 @@ impl> RangeInclusive { /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] #[inline] - pub fn is_empty(&self) -> bool { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn is_empty(&self) -> bool + where + Idx: [const] PartialOrd, + { self.exhausted || !(self.start <= self.end) } } @@ -587,7 +604,8 @@ impl> RangeInclusive { /// [slicing index]: crate::slice::SliceIndex #[lang = "RangeToInclusive"] #[doc(alias = "..=")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Hash)] +#[derive(Clone, PartialEq, Eq)] #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) @@ -620,10 +638,11 @@ impl> RangeToInclusive { /// ``` #[inline] #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -668,7 +687,8 @@ impl> RangeToInclusive { /// /// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range #[stable(feature = "collections_bound", since = "1.17.0")] -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] +#[derive(Copy, Debug, Hash)] +#[derive_const(Clone, Eq, PartialEq)] pub enum Bound { /// An inclusive bound. #[stable(feature = "collections_bound", since = "1.17.0")] @@ -685,7 +705,8 @@ impl Bound { /// Converts from `&Bound` to `Bound<&T>`. #[inline] #[stable(feature = "bound_as_ref_shared", since = "1.65.0")] - pub fn as_ref(&self) -> Bound<&T> { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn as_ref(&self) -> Bound<&T> { match *self { Included(ref x) => Included(x), Excluded(ref x) => Excluded(x), @@ -696,7 +717,7 @@ impl Bound { /// Converts from `&mut Bound` to `Bound<&mut T>`. #[inline] #[unstable(feature = "bound_as_ref", issue = "80996")] - pub fn as_mut(&mut self) -> Bound<&mut T> { + pub const fn as_mut(&mut self) -> Bound<&mut T> { match *self { Included(ref mut x) => Included(x), Excluded(ref mut x) => Excluded(x), @@ -778,7 +799,11 @@ impl Bound<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "bound_cloned", since = "1.55.0")] - pub fn cloned(self) -> Bound { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn cloned(self) -> Bound + where + T: [const] Clone, + { match self { Bound::Unbounded => Bound::Unbounded, Bound::Included(x) => Bound::Included(x.clone()), @@ -791,6 +816,8 @@ impl Bound<&T> { /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] #[rustc_diagnostic_item = "RangeBounds"] +#[const_trait] +#[rustc_const_unstable(feature = "const_range", issue = "none")] pub trait RangeBounds { /// Start index bound. /// @@ -841,8 +868,8 @@ pub trait RangeBounds { #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where - T: PartialOrd, - U: ?Sized + PartialOrd, + T: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { (match self.start_bound() { Included(start) => start <= item, @@ -909,7 +936,7 @@ pub trait RangeBounds { #[unstable(feature = "range_bounds_is_empty", issue = "137300")] fn is_empty(&self) -> bool where - T: PartialOrd, + T: [const] PartialOrd, { !match (self.start_bound(), self.end_bound()) { (Unbounded, _) | (_, Unbounded) => true, @@ -927,7 +954,9 @@ pub trait RangeBounds { /// `IntoBounds` is implemented by Rust’s built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[unstable(feature = "range_into_bounds", issue = "136903")] -pub trait IntoBounds: RangeBounds { +#[const_trait] +#[rustc_const_unstable(feature = "const_range", issue = "none")] +pub trait IntoBounds: [const] RangeBounds { /// Convert this range into the start and end bounds. /// Returns `(start_bound, end_bound)`. /// @@ -973,8 +1002,8 @@ pub trait IntoBounds: RangeBounds { fn intersect(self, other: R) -> (Bound, Bound) where Self: Sized, - T: Ord, - R: Sized + IntoBounds, + T: [const] Ord + [const] Destruct, + R: Sized + [const] IntoBounds, { let (self_start, self_end) = IntoBounds::into_bounds(self); let (other_start, other_end) = IntoBounds::into_bounds(other); @@ -1017,7 +1046,8 @@ pub trait IntoBounds: RangeBounds { use self::Bound::{Excluded, Included, Unbounded}; #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFull { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeFull { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -1027,14 +1057,16 @@ impl RangeBounds for RangeFull { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeFull { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeFull { fn into_bounds(self) -> (Bound, Bound) { (Unbounded, Unbounded) } } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFrom { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeFrom { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -1044,14 +1076,16 @@ impl RangeBounds for RangeFrom { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeFrom { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeFrom { fn into_bounds(self) -> (Bound, Bound) { (Included(self.start), Unbounded) } } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeTo { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeTo { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -1061,14 +1095,16 @@ impl RangeBounds for RangeTo { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeTo { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeTo { fn into_bounds(self) -> (Bound, Bound) { (Unbounded, Excluded(self.end)) } } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for Range { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for Range { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -1078,14 +1114,16 @@ impl RangeBounds for Range { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for Range { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for Range { fn into_bounds(self) -> (Bound, Bound) { (Included(self.start), Excluded(self.end)) } } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeInclusive { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -1101,7 +1139,8 @@ impl RangeBounds for RangeInclusive { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeInclusive { fn into_bounds(self) -> (Bound, Bound) { ( Included(self.start), @@ -1117,7 +1156,8 @@ impl IntoBounds for RangeInclusive { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeToInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeToInclusive { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -1127,14 +1167,16 @@ impl RangeBounds for RangeToInclusive { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeToInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeToInclusive { fn into_bounds(self) -> (Bound, Bound) { (Unbounded, Included(self.end)) } } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for (Bound, Bound) { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for (Bound, Bound) { fn start_bound(&self) -> Bound<&T> { match *self { (Included(ref start), _) => Included(start), @@ -1153,14 +1195,16 @@ impl RangeBounds for (Bound, Bound) { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for (Bound, Bound) { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for (Bound, Bound) { fn into_bounds(self) -> (Bound, Bound) { self } } #[stable(feature = "collections_range", since = "1.28.0")] -impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl<'a, T: ?Sized + 'a> const RangeBounds for (Bound<&'a T>, Bound<&'a T>) { fn start_bound(&self) -> Bound<&T> { self.0 } @@ -1177,7 +1221,8 @@ impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`. #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFrom<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -1193,7 +1238,8 @@ impl RangeBounds for RangeFrom<&T> { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `..end` with `(Bound::Unbounded, Bound::Excluded(end))`. #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeTo<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeTo<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -1209,7 +1255,8 @@ impl RangeBounds for RangeTo<&T> { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..end` with `(Bound::Included(start), Bound::Excluded(end))`. #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for Range<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for Range<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -1225,7 +1272,8 @@ impl RangeBounds for Range<&T> { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..=end` with `(Bound::Included(start), Bound::Included(end))`. #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeInclusive<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -1241,7 +1289,8 @@ impl RangeBounds for RangeInclusive<&T> { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `..=end` with `(Bound::Unbounded, Bound::Included(end))`. #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeToInclusive<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeToInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -1270,6 +1319,8 @@ pub enum OneSidedRangeBound { /// Types that implement `OneSidedRange` must return `Bound::Unbounded` /// from one of `RangeBounds::start_bound` or `RangeBounds::end_bound`. #[unstable(feature = "one_sided_range", issue = "69780")] +#[const_trait] +#[rustc_const_unstable(feature = "const_range", issue = "none")] pub trait OneSidedRange: RangeBounds { /// An internal-only helper function for `split_off` and /// `split_off_mut` that returns the bound of the one-sided range. @@ -1277,7 +1328,8 @@ pub trait OneSidedRange: RangeBounds { } #[unstable(feature = "one_sided_range", issue = "69780")] -impl OneSidedRange for RangeTo +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const OneSidedRange for RangeTo where Self: RangeBounds, { @@ -1287,7 +1339,8 @@ where } #[unstable(feature = "one_sided_range", issue = "69780")] -impl OneSidedRange for RangeFrom +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const OneSidedRange for RangeFrom where Self: RangeBounds, { @@ -1297,7 +1350,8 @@ where } #[unstable(feature = "one_sided_range", issue = "69780")] -impl OneSidedRange for RangeToInclusive +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const OneSidedRange for RangeToInclusive where Self: RangeBounds, { diff --git a/library/core/src/range.rs b/library/core/src/range.rs index a096a8ceafc8..96c56e96b3eb 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -118,10 +118,11 @@ impl> Range { /// ``` #[inline] #[unstable(feature = "new_range_api", issue = "125687")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -151,13 +152,18 @@ impl> Range { /// ``` #[inline] #[unstable(feature = "new_range_api", issue = "125687")] - pub fn is_empty(&self) -> bool { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn is_empty(&self) -> bool + where + Idx: [const] PartialOrd, + { !(self.start < self.end) } } #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for Range { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for Range { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -173,7 +179,8 @@ impl RangeBounds for Range { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..end` with `(Bound::Included(start), Bound::Excluded(end))`. #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for Range<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for Range<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -184,7 +191,8 @@ impl RangeBounds for Range<&T> { // #[unstable(feature = "range_into_bounds", issue = "136903")] #[unstable(feature = "new_range_api", issue = "125687")] -impl IntoBounds for Range { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for Range { fn into_bounds(self) -> (Bound, Bound) { (Included(self.start), Excluded(self.end)) } @@ -271,10 +279,11 @@ impl> RangeInclusive { /// ``` #[inline] #[unstable(feature = "new_range_api", issue = "125687")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -304,7 +313,11 @@ impl> RangeInclusive { /// ``` #[unstable(feature = "new_range_api", issue = "125687")] #[inline] - pub fn is_empty(&self) -> bool { + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn is_empty(&self) -> bool + where + Idx: [const] PartialOrd, + { !(self.start <= self.last) } } @@ -342,7 +355,8 @@ impl RangeInclusive { } #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for RangeInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeInclusive { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -358,7 +372,8 @@ impl RangeBounds for RangeInclusive { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..=end` with `(Bound::Included(start), Bound::Included(end))`. #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for RangeInclusive<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -369,7 +384,8 @@ impl RangeBounds for RangeInclusive<&T> { // #[unstable(feature = "range_into_bounds", issue = "136903")] #[unstable(feature = "new_range_api", issue = "125687")] -impl IntoBounds for RangeInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeInclusive { fn into_bounds(self) -> (Bound, Bound) { (Included(self.start), Included(self.last)) } @@ -485,17 +501,19 @@ impl> RangeFrom { /// ``` #[inline] #[unstable(feature = "new_range_api", issue = "125687")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } } #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for RangeFrom { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeFrom { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -511,7 +529,8 @@ impl RangeBounds for RangeFrom { /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`. #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for RangeFrom<&T> { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -522,7 +541,8 @@ impl RangeBounds for RangeFrom<&T> { // #[unstable(feature = "range_into_bounds", issue = "136903")] #[unstable(feature = "new_range_api", issue = "125687")] -impl IntoBounds for RangeFrom { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeFrom { fn into_bounds(self) -> (Bound, Bound) { (Included(self.start), Unbounded) } @@ -620,10 +640,11 @@ impl> RangeToInclusive { /// ``` #[inline] #[unstable(feature = "new_range_api", issue = "125687")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range", issue = "none")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: [const] PartialOrd, + U: ?Sized + [const] PartialOrd, { >::contains(self, item) } @@ -633,7 +654,8 @@ impl> RangeToInclusive { // because underflow would be possible with (..0).into() #[unstable(feature = "new_range_api", issue = "125687")] -impl RangeBounds for RangeToInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeToInclusive { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -643,7 +665,8 @@ impl RangeBounds for RangeToInclusive { } #[unstable(feature = "range_into_bounds", issue = "136903")] -impl IntoBounds for RangeToInclusive { +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const IntoBounds for RangeToInclusive { fn into_bounds(self) -> (Bound, Bound) { (Unbounded, Included(self.last)) } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index a9806060d3d8..aad046a7e5a9 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,6 +1,7 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::slice_get_unchecked; +use crate::marker::Destruct; use crate::panic::const_panic; use crate::ub_checks::assert_unsafe_precondition; use crate::{ops, range}; @@ -899,9 +900,10 @@ unsafe impl const SliceIndex<[T]> for range::RangeToInclusive { #[track_caller] #[unstable(feature = "slice_range", issue = "76393")] #[must_use] -pub fn range(range: R, bounds: ops::RangeTo) -> ops::Range +#[rustc_const_unstable(feature = "const_range", issue = "none")] +pub const fn range(range: R, bounds: ops::RangeTo) -> ops::Range where - R: ops::RangeBounds, + R: [const] ops::RangeBounds + [const] Destruct, { let len = bounds.end; @@ -984,7 +986,7 @@ where /// Converts a pair of `ops::Bound`s into `ops::Range` without performing any /// bounds checking or (in debug) overflow checking. -pub(crate) fn into_range_unchecked( +pub(crate) const fn into_range_unchecked( len: usize, (start, end): (ops::Bound, ops::Bound), ) -> ops::Range { @@ -1004,7 +1006,8 @@ pub(crate) fn into_range_unchecked( /// Converts pair of `ops::Bound`s into `ops::Range`. /// Returns `None` on overflowing indices. -pub(crate) fn into_range( +#[rustc_const_unstable(feature = "const_range", issue = "none")] +pub(crate) const fn into_range( len: usize, (start, end): (ops::Bound, ops::Bound), ) -> Option> { From 6031dfdaed2b4c59de9b53544961e633c7e1d42a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 16 Apr 2025 11:39:04 +0000 Subject: [PATCH 159/525] Allow unsizing pattern types with pointer base --- src/unsize.rs | 5 +++++ src/value_and_place.rs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/unsize.rs b/src/unsize.rs index d994f3e32ec3..c97eb3874b02 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -131,6 +131,11 @@ pub(crate) fn coerce_unsized_into<'tcx>( dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout())); }; match (&src_ty.kind(), &dst_ty.kind()) { + (ty::Pat(a, _), ty::Pat(b, _)) => { + let src = src.cast_pat_ty_to_base(fx.layout_of(*a)); + let dst = dst.place_transmute_type(fx, *b); + return coerce_unsized_into(fx, src, dst); + } (&ty::Ref(..), &ty::Ref(..)) | (&ty::Ref(..), &ty::RawPtr(..)) | (&ty::RawPtr(..), &ty::RawPtr(..)) => coerce_ptr(), diff --git a/src/value_and_place.rs b/src/value_and_place.rs index db9b80c0f6a0..9dcd4a33d44f 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -342,6 +342,14 @@ impl<'tcx> CValue<'tcx> { assert_eq!(self.layout().backend_repr, layout.backend_repr); CValue(self.0, layout) } + + pub(crate) fn cast_pat_ty_to_base(self, layout: TyAndLayout<'tcx>) -> Self { + let ty::Pat(base, _) = *self.layout().ty.kind() else { + panic!("not a pattern type: {:#?}", self.layout()) + }; + assert_eq!(layout.ty, base); + CValue(self.0, layout) + } } /// A place where you can write a value to or read a value from From 9d63e8c13597d8de412efd4f0a57f283c06be86a Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sun, 12 Oct 2025 22:01:08 +0000 Subject: [PATCH 160/525] Elaborate ShallowInitBox too. --- src/base.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/base.rs b/src/base.rs index 7e99eb09b91a..c97218797107 100644 --- a/src/base.rs +++ b/src/base.rs @@ -829,13 +829,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fx.bcx.ins().nop(); } } - Rvalue::ShallowInitBox(ref operand, content_ty) => { - let content_ty = fx.monomorphize(content_ty); - let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty)); - let operand = codegen_operand(fx, operand); - let operand = operand.load_scalar(fx); - lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); - } Rvalue::NullaryOp(ref null_op, ty) => { assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); let layout = fx.layout_of(fx.monomorphize(ty)); @@ -924,6 +917,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: lval.write_cvalue_transmute(fx, operand); } Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), + Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } StatementKind::StorageLive(_) From 736a276237b38fd219368a10a12b6f0f599dd584 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 22 Oct 2025 08:30:12 +0200 Subject: [PATCH 161/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 96fe3c31c2ec385f3d3263346bcdde3d118cdaf6. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1abf64f0bc3b..cca795330bce 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -402ce0ef07d5db9ba26ae5c37ce6aff0c9002052 +96fe3c31c2ec385f3d3263346bcdde3d118cdaf6 From 1d002666c1769a5c887f621cfa0f4214c3aac159 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 22 Oct 2025 08:22:13 +0200 Subject: [PATCH 162/525] make genmc tests less dependent on std internals --- .../genmc/pass/std/arc.check_count.stderr | 52 ------------------ src/tools/miri/tests/genmc/pass/std/arc.rs | 1 + .../genmc/pass/std/arc.try_upgrade.stderr | 54 ------------------- .../miri/tests/genmc/pass/std/empty_main.rs | 1 + .../tests/genmc/pass/std/empty_main.stderr | 30 ----------- .../tests/genmc/pass/std/spawn_std_threads.rs | 1 + .../genmc/pass/std/spawn_std_threads.stderr | 52 ------------------ .../tests/genmc/pass/std/thread_locals.rs | 1 + .../tests/genmc/pass/std/thread_locals.stderr | 52 ------------------ 9 files changed, 4 insertions(+), 240 deletions(-) diff --git a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr index 3dccd7059538..878077edb818 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr @@ -6,20 +6,8 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU64::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::option::Option::::unwrap_or_else::<{closure@std::thread::current::id::get_or_init::{closure#0}}>` at RUSTLIB/core/src/option.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/alloc/src/sync.rs:LL:CC @@ -28,7 +16,6 @@ LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acq | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::::downgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -42,7 +29,6 @@ LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acq | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::::downgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -59,15 +45,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC @@ -88,15 +66,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC @@ -114,10 +84,6 @@ LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relax | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::>::is_unique` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::sync::Arc::>::get_mut` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -131,17 +97,7 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU32::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::sync::PLATFORM::futex::Once::call` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::Once::call_once::<{closure@std::rt::cleanup::{closure#0}}>` at RUSTLIB/std/src/sync/poison/once.rs:LL:CC - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -150,14 +106,6 @@ LL | intrinsics::atomic_cxchg::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicPtr::::compare_exchange` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC Verification complete with 4 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/arc.rs b/src/tools/miri/tests/genmc/pass/std/arc.rs index addf6408c006..dee29127856d 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.rs +++ b/src/tools/miri/tests/genmc/pass/std/arc.rs @@ -1,5 +1,6 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows //@revisions: check_count try_upgrade +//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // Check that various operations on `std::sync::Arc` are handled properly in GenMC mode. // diff --git a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr index dc59632558c8..fc43c6313590 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr @@ -6,20 +6,8 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU64::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::option::Option::::unwrap_or_else::<{closure@std::thread::current::id::get_or_init::{closure#0}}>` at RUSTLIB/core/src/option.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/alloc/src/sync.rs:LL:CC @@ -28,7 +16,6 @@ LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acq | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::::downgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -42,7 +29,6 @@ LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acq | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::::downgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -59,15 +45,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC @@ -88,15 +66,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC @@ -114,10 +84,6 @@ LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relax | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::>::is_unique` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::sync::Arc::>::get_mut` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -131,17 +97,7 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU32::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::sync::PLATFORM::futex::Once::call` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::Once::call_once::<{closure@std::rt::cleanup::{closure#0}}>` at RUSTLIB/std/src/sync/poison/once.rs:LL:CC - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -150,15 +106,7 @@ LL | intrinsics::atomic_cxchg::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicPtr::::compare_exchange` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/alloc/src/sync.rs:LL:CC @@ -167,7 +115,6 @@ LL | if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_incr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE on thread `unnamed-ID`: - = note: inside `std::sync::Weak::::upgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside closure --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -181,7 +128,6 @@ LL | if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_incr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE on thread `unnamed-ID`: - = note: inside `std::sync::Weak::::upgrade` at RUSTLIB/alloc/src/sync.rs:LL:CC note: inside closure --> tests/genmc/pass/std/arc.rs:LL:CC | diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.rs b/src/tools/miri/tests/genmc/pass/std/empty_main.rs index 2ffc3388fb36..f0e4155ccd5d 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.rs +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows +//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // A lot of code runs before main, which we should be able to handle in GenMC mode. diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr index 44c307a6b3e4..1b8712167d8a 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr @@ -6,20 +6,8 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU64::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::option::Option::::unwrap_or_else::<{closure@std::thread::current::id::get_or_init::{closure#0}}>` at RUSTLIB/core/src/option.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -28,17 +16,7 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU32::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::sync::PLATFORM::futex::Once::call` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::Once::call_once::<{closure@std::rt::cleanup::{closure#0}}>` at RUSTLIB/std/src/sync/poison/once.rs:LL:CC - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -47,14 +25,6 @@ LL | intrinsics::atomic_cxchg::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicPtr::::compare_exchange` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC Verification complete with 1 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs index dadbee47b986..e32979dc2b51 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows +//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // We should be able to spawn and join standard library threads in GenMC mode. // Since these threads do nothing, we should only explore 1 program execution. diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr index 22a58f4e9cef..b148c11e39b1 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr @@ -6,20 +6,8 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU64::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::option::Option::::unwrap_or_else::<{closure@std::thread::current::id::get_or_init::{closure#0}}>` at RUSTLIB/core/src/option.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC @@ -31,15 +19,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside closure --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC @@ -50,7 +30,6 @@ LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).c = note: inside ` as std::iter::Iterator>::fold::<(), {closure@std::iter::adapters::map::map_fold, (), {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}, {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::for_each::<{closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `std::vec::Vec::>::extend_trusted::, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC = note: inside `> as std::vec::spec_extend::SpecExtend, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::spec_extend` at RUSTLIB/alloc/src/vec/spec_extend.rs:LL:CC = note: inside `> as std::vec::spec_from_iter_nested::SpecFromIterNested, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter_nested.rs:LL:CC = note: inside `> as std::vec::spec_from_iter::SpecFromIter, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter.rs:LL:CC @@ -72,15 +51,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside closure --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC @@ -91,7 +62,6 @@ LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).c = note: inside ` as std::iter::Iterator>::fold::<(), {closure@std::iter::adapters::map::map_fold, (), {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}, {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::for_each::<{closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `std::vec::Vec::>::extend_trusted::, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC = note: inside `> as std::vec::spec_extend::SpecExtend, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::spec_extend` at RUSTLIB/alloc/src/vec/spec_extend.rs:LL:CC = note: inside `> as std::vec::spec_from_iter_nested::SpecFromIterNested, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter_nested.rs:LL:CC = note: inside `> as std::vec::spec_from_iter::SpecFromIter, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter.rs:LL:CC @@ -110,10 +80,6 @@ LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relax | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::>::is_unique` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::sync::Arc::>::get_mut` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside closure --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC | @@ -135,17 +101,7 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU32::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::sync::PLATFORM::futex::Once::call` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::Once::call_once::<{closure@std::rt::cleanup::{closure#0}}>` at RUSTLIB/std/src/sync/poison/once.rs:LL:CC - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -154,14 +110,6 @@ LL | intrinsics::atomic_cxchg::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicPtr::::compare_exchange` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC Verification complete with 1 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.rs b/src/tools/miri/tests/genmc/pass/std/thread_locals.rs index d76975d2e92c..4dac775d3407 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.rs +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zmiri-ignore-leaks -Zmiri-genmc -Zmiri-disable-stacked-borrows +//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" use std::alloc::{Layout, alloc}; use std::cell::Cell; diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr index 40faedf49c6e..208de4e37ffb 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr @@ -6,20 +6,8 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU64::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::option::Option::::unwrap_or_else::<{closure@std::thread::current::id::get_or_init::{closure#0}}>` at RUSTLIB/core/src/option.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC @@ -31,15 +19,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/thread_locals.rs:LL:CC @@ -61,15 +41,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/thread_locals.rs:LL:CC @@ -88,10 +60,6 @@ LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relax | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: - = note: inside `std::sync::Arc::>::is_unique` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::sync::Arc::>::get_mut` at RUSTLIB/alloc/src/sync.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC note: inside closure --> tests/genmc/pass/std/thread_locals.rs:LL:CC | @@ -101,8 +69,6 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); = note: inside closure at RUSTLIB/core/src/ops/try_trait.rs:LL:CC = note: inside closure at RUSTLIB/core/src/array/iter/iter_inner.rs:LL:CC = note: inside `::try_fold::<(), {closure@std::array::iter::iter_inner::PolymorphicIter<[std::mem::MaybeUninit>]>::try_fold<(), {closure@std::ops::try_trait::NeverShortCircuit<()>::wrap_mut_2<(), std::thread::JoinHandle<()>, {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>::{closure#0}}, std::ops::try_trait::NeverShortCircuit<()>>::{closure#0}}, std::ops::try_trait::NeverShortCircuit<()>>` at RUSTLIB/core/src/ops/index_range.rs:LL:CC - = note: inside `std::array::iter::iter_inner::PolymorphicIter::<[std::mem::MaybeUninit>]>::try_fold::<(), {closure@std::ops::try_trait::NeverShortCircuit<()>::wrap_mut_2<(), std::thread::JoinHandle<()>, {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>::{closure#0}}, std::ops::try_trait::NeverShortCircuit<()>>` at RUSTLIB/core/src/array/iter/iter_inner.rs:LL:CC - = note: inside `std::array::iter::iter_inner::PolymorphicIter::<[std::mem::MaybeUninit>]>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>` at RUSTLIB/core/src/array/iter/iter_inner.rs:LL:CC = note: inside `, 3> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>` at RUSTLIB/core/src/array/iter.rs:LL:CC = note: inside `, 3> as std::iter::Iterator>::for_each::<{closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC note: inside `main` @@ -118,17 +84,7 @@ LL | intrinsics::atomic_cxchgweak::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicU32::compare_exchange_weak` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::sync::PLATFORM::futex::Once::call` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::Once::call_once::<{closure@std::rt::cleanup::{closure#0}}>` at RUSTLIB/std/src/sync/poison/once.rs:LL:CC - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. --> RUSTLIB/core/src/sync/atomic.rs:LL:CC @@ -137,14 +93,6 @@ LL | intrinsics::atomic_cxchg::` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sync::atomic::AtomicPtr::::compare_exchange` at RUSTLIB/core/src/sync/atomic.rs:LL:CC - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC Verification complete with 2 executions. No errors found. From 70aa534c8c00f715bce9a38e01e63678961f7955 Mon Sep 17 00:00:00 2001 From: Francisco Gouveia Date: Wed, 22 Oct 2025 08:57:30 +0100 Subject: [PATCH 163/525] Avoid panicking when `Cargo.toml` is not present --- src/tools/miri/cargo-miri/src/util.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/cargo-miri/src/util.rs b/src/tools/miri/cargo-miri/src/util.rs index 82c6a9293578..1952435c5997 100644 --- a/src/tools/miri/cargo-miri/src/util.rs +++ b/src/tools/miri/cargo-miri/src/util.rs @@ -213,7 +213,11 @@ fn cargo_extra_flags() -> Vec { pub fn get_cargo_metadata() -> Metadata { // This will honor the `CARGO` env var the same way our `cargo()` does. - MetadataCommand::new().no_deps().other_options(cargo_extra_flags()).exec().unwrap() + MetadataCommand::new() + .no_deps() + .other_options(cargo_extra_flags()) + .exec() + .unwrap_or_else(|err| show_error!("{}", err)) } /// Pulls all the crates in this workspace from the cargo metadata. From 827bd00438b70bee52f76e72a0da9a42c17bae59 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Tue, 21 Oct 2025 23:11:46 +0300 Subject: [PATCH 164/525] Implement `strip_circumfix` lib feature --- library/core/src/slice/mod.rs | 32 +++++++++++++++++++++++++++++++ library/core/src/str/mod.rs | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 61eb78294f68..157d7a070d86 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2725,6 +2725,38 @@ impl [T] { None } + /// Returns a subslice with the prefix and suffix removed. + /// + /// If the slice starts with `prefix` and ends with `suffix`, returns the subslice after the + /// prefix and before the suffix, wrapped in `Some`. + /// + /// If the slice does not start with `prefix` or does not end with `suffix`, returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(strip_circumfix)] + /// + /// let v = &[10, 50, 40, 30]; + /// assert_eq!(v.strip_circumfix(&[10], &[30]), Some(&[50, 40][..])); + /// assert_eq!(v.strip_circumfix(&[10], &[40, 30]), Some(&[50][..])); + /// assert_eq!(v.strip_circumfix(&[10, 50], &[40, 30]), Some(&[][..])); + /// assert_eq!(v.strip_circumfix(&[50], &[30]), None); + /// assert_eq!(v.strip_circumfix(&[10], &[40]), None); + /// assert_eq!(v.strip_circumfix(&[], &[40, 30]), Some(&[10, 50][..])); + /// assert_eq!(v.strip_circumfix(&[10, 50], &[]), Some(&[40, 30][..])); + /// ``` + #[must_use = "returns the subslice without modifying the original"] + #[unstable(feature = "strip_circumfix", issue = "147946")] + pub fn strip_circumfix(&self, prefix: &P, suffix: &S) -> Option<&[T]> + where + T: PartialEq, + S: SlicePattern + ?Sized, + P: SlicePattern + ?Sized, + { + self.strip_prefix(prefix)?.strip_suffix(suffix) + } + /// Returns a subslice with the optional prefix removed. /// /// If the slice starts with `prefix`, returns the subslice after the prefix. If `prefix` diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 82019b9b3afe..37dc401ed009 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2447,6 +2447,42 @@ impl str { suffix.strip_suffix_of(self) } + /// Returns a string slice with the prefix and suffix removed. + /// + /// If the string starts with the pattern `prefix` and ends with the pattern `suffix`, returns + /// the substring after the prefix and before the suffix, wrapped in `Some`. + /// Unlike [`trim_start_matches`] and [`trim_end_matches`], this method removes both the prefix + /// and suffix exactly once. + /// + /// If the string does not start with `prefix` or does not end with `suffix`, returns `None`. + /// + /// Each [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a + /// function or closure that determines if a character matches. + /// + /// [`char`]: prim@char + /// [pattern]: self::pattern + /// [`trim_start_matches`]: Self::trim_start_matches + /// [`trim_end_matches`]: Self::trim_end_matches + /// + /// # Examples + /// + /// ``` + /// #![feature(strip_circumfix)] + /// + /// assert_eq!("bar:hello:foo".strip_circumfix("bar:", ":foo"), Some("hello")); + /// assert_eq!("bar:foo".strip_circumfix("foo", "foo"), None); + /// assert_eq!("foo:bar;".strip_circumfix("foo:", ';'), Some("bar")); + /// ``` + #[must_use = "this returns the remaining substring as a new slice, \ + without modifying the original"] + #[unstable(feature = "strip_circumfix", issue = "147946")] + pub fn strip_circumfix(&self, prefix: P, suffix: S) -> Option<&str> + where + for<'a> S::Searcher<'a>: ReverseSearcher<'a>, + { + self.strip_prefix(prefix)?.strip_suffix(suffix) + } + /// Returns a string slice with the optional prefix removed. /// /// If the string starts with the pattern `prefix`, returns the substring after the prefix. From 424f7bf201cd470fc7134848c88f3abdcd7a1101 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 22 Oct 2025 13:11:39 +0200 Subject: [PATCH 165/525] native_call: we only support thin pointers as return type --- src/tools/miri/src/shims/native_lib/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 0a0d1bcb0a85..382839ea1eb1 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -7,7 +7,7 @@ use libffi::low::CodePtr; use libffi::middle::Type as FfiType; use rustc_abi::{HasDataLayout, Size}; use rustc_data_structures::either; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout}; use rustc_middle::ty::{self, IntTy, Ty, UintTy}; use rustc_span::Symbol; use serde::{Deserialize, Serialize}; @@ -144,7 +144,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { unsafe { ffi::call::<()>(fun, libffi_args) }; return interp_ok(ImmTy::uninit(dest.layout)); } - ty::RawPtr(..) => { + ty::RawPtr(ty, ..) if ty.is_sized(*this.tcx, this.typing_env()) => { let x = unsafe { ffi::call::<*const ()>(fun, libffi_args) }; let ptr = StrictPointer::new(Provenance::Wildcard, Size::from_bytes(x.addr())); Scalar::from_pointer(ptr, this) From cc27b04473f65d6c080a54a678f7e08a74f423f1 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Thu, 16 Oct 2025 21:23:43 +0000 Subject: [PATCH 166/525] Replace NullOp::SizeOf and NullOp::AlignOf by lang items. --- example/example.rs | 4 ---- example/mini_core.rs | 24 +++++++++++++++++++++--- example/mini_core_hello_world.rs | 8 ++++---- src/base.rs | 2 -- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/example/example.rs b/example/example.rs index aeb38331edb0..769d262b9ebb 100644 --- a/example/example.rs +++ b/example/example.rs @@ -72,10 +72,6 @@ pub fn debug_tuple() -> DebugTuple { DebugTuple(()) } -pub fn size_of() -> usize { - intrinsics::size_of::() -} - pub fn use_size_of() -> usize { size_of::() } diff --git a/example/mini_core.rs b/example/mini_core.rs index 2f53bbf8b793..304d0d648561 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -6,6 +6,7 @@ extern_types, decl_macro, rustc_attrs, + rustc_private, transparent_unions, auto_traits, freeze_impls, @@ -594,7 +595,7 @@ impl, U: ?Sized> CoerceUnsized> for Box {} impl Box { pub fn new(val: T) -> Box { unsafe { - let size = intrinsics::size_of::(); + let size = size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) @@ -646,11 +647,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn abort() -> !; #[rustc_intrinsic] - pub fn size_of() -> usize; + pub const fn size_of() -> usize; #[rustc_intrinsic] pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub fn align_of() -> usize; + pub const fn align_of() -> usize; #[rustc_intrinsic] pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] @@ -715,6 +716,23 @@ impl Index for [T] { } } +pub const fn size_of() -> usize { + ::SIZE +} + +pub const fn align_of() -> usize { + ::ALIGN +} + +trait SizedTypeProperties: Sized { + #[lang = "mem_size_const"] + const SIZE: usize = intrinsics::size_of::(); + + #[lang = "mem_align_const"] + const ALIGN: usize = intrinsics::align_of::(); +} +impl SizedTypeProperties for T {} + extern "C" { type VaListImpl; } diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 86602c6b2a3f..a9388814a7f5 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -109,10 +109,10 @@ fn start( puts(*argv as *const i8); } unsafe { - puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); + puts(*((argv as usize + size_of::<*const u8>()) as *const *const i8)); } unsafe { - puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); + puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const i8)); } } @@ -213,8 +213,8 @@ fn main() { assert_eq!(intrinsics::size_of_val(a) as u8, 16); assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); - assert_eq!(intrinsics::align_of::() as u8, 2); - assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8); + assert_eq!(align_of::() as u8, 2); + assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8); let u8_needs_drop = const { intrinsics::needs_drop::() }; assert!(!u8_needs_drop); diff --git a/src/base.rs b/src/base.rs index c97218797107..7d50548b4026 100644 --- a/src/base.rs +++ b/src/base.rs @@ -833,8 +833,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { - NullOp::SizeOf => layout.size.bytes(), - NullOp::AlignOf => layout.align.bytes(), NullOp::OffsetOf(fields) => fx .tcx .offset_of_subfield( From d521a79af50031e82f2a131d674a09e61ec7821c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 23 Oct 2025 04:53:19 +0000 Subject: [PATCH 167/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 6244effd0372d5d88fc859d3bf17ce1efcc2c9ec. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index cca795330bce..15dc8792af07 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -96fe3c31c2ec385f3d3263346bcdde3d118cdaf6 +6244effd0372d5d88fc859d3bf17ce1efcc2c9ec From ce35d4ca81e7ef02498c18d7f284143079b5f03c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 Oct 2025 08:56:00 +0200 Subject: [PATCH 168/525] SB wildcard handling: extend comments --- .../miri/src/borrow_tracker/stacked_borrows/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 127d832f73e7..488de363bbe0 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -675,16 +675,22 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr(), 0) { log_creation(this, Some((alloc_id, base_offset, orig_tag)))?; - // Still give it the new provenance, it got retagged after all. + // Still give it the new provenance, it got retagged after all. If this was a + // wildcard pointer, this will fix the AllocId and make future accesses with this + // reference to other allocations UB, but that's fine: due to subobject provenance, + // *all* future accesses with this reference should be UB! return interp_ok(Some(Provenance::Concrete { alloc_id, tag: new_tag })); } else { // This pointer doesn't come with an AllocId. :shrug: log_creation(this, None)?; - // Provenance unchanged. + // Provenance unchanged. Ideally we'd make this pointer UB to use like above, + // but there's no easy way to do that. return interp_ok(place.ptr().provenance); } } + // The pointer *must* have a valid AllocId to continue, so we want to resolve this to + // a concrete ID even for wildcard pointers. let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr(), 0)?; log_creation(this, Some((alloc_id, base_offset, orig_tag)))?; From bc6f1ef74a55ba5097dd80e898bea9cbe37c802e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 11:43:38 +0000 Subject: [PATCH 169/525] Rustup to rustc 1.92.0-nightly (1d23d0680 2025-10-22) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 4196e4872dff..3bede572d2c2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-10-17" +channel = "nightly-2025-10-23" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From a7f08dec439f24f52de20b2e856c9ab8fb2ff89a Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 23 Oct 2025 14:25:31 +0200 Subject: [PATCH 170/525] std: don't leak the thread closure if destroying the thread attributes fails --- library/std/src/sys/thread/unix.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 2a3e3a9715f8..9b26262bc80d 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -7,7 +7,7 @@ target_os = "aix", )))] use crate::ffi::CStr; -use crate::mem::{self, ManuallyDrop}; +use crate::mem::{self, DropGuard, ManuallyDrop}; use crate::num::NonZero; #[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::dlsym; @@ -52,10 +52,13 @@ impl Thread { name: Option<&str>, f: Box, ) -> io::Result { - let data = Box::into_raw(Box::new(ThreadData { name: name.map(Box::from), f })); - let mut native: libc::pthread_t = mem::zeroed(); + let data = Box::new(ThreadData { name: name.map(Box::from), f }); + let mut attr: mem::MaybeUninit = mem::MaybeUninit::uninit(); assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); + let mut attr = DropGuard::new(&mut attr, |attr| { + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0) + }); #[cfg(any(target_os = "espidf", target_os = "nuttx"))] if stack > 0 { @@ -90,8 +93,6 @@ impl Thread { // on the stack size, in which case we can only gracefully return // an error here. if libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size) != 0 { - assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); - drop(Box::from_raw(data)); return Err(io::const_error!( io::ErrorKind::InvalidInput, "invalid stack size" @@ -101,19 +102,16 @@ impl Thread { }; } + let data = Box::into_raw(data); + let mut native: libc::pthread_t = mem::zeroed(); let ret = libc::pthread_create(&mut native, attr.as_ptr(), thread_start, data as *mut _); - // Note: if the thread creation fails and this assert fails, then p will - // be leaked. However, an alternative design could cause double-free - // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); - - return if ret != 0 { - // The thread failed to start and as a result p was not consumed. Therefore, it is - // safe to reconstruct the box so that it gets deallocated. + return if ret == 0 { + Ok(Thread { id: native }) + } else { + // The thread failed to start and as a result `data` was not consumed. + // Therefore, it is safe to reconstruct the box so that it gets deallocated. drop(Box::from_raw(data)); Err(io::Error::from_raw_os_error(ret)) - } else { - Ok(Thread { id: native }) }; extern "C" fn thread_start(data: *mut libc::c_void) -> *mut libc::c_void { From 2f4813fa0ad1f046ac22659b136c0439787fb1e7 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 20 Aug 2025 00:25:31 +0300 Subject: [PATCH 171/525] Stabilize `vec_deque_pop_if` --- library/alloc/src/collections/vec_deque/mod.rs | 10 ++++------ library/alloctests/tests/lib.rs | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index ac619a42d356..07ed72c5f2ea 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1831,7 +1831,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vec_deque_pop_if)] /// use std::collections::VecDeque; /// /// let mut deque: VecDeque = vec![0, 1, 2, 3, 4].into(); @@ -1841,7 +1840,7 @@ impl VecDeque { /// assert_eq!(deque, [1, 2, 3, 4]); /// assert_eq!(deque.pop_front_if(pred), None); /// ``` - #[unstable(feature = "vec_deque_pop_if", issue = "135889")] + #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let first = self.front_mut()?; if predicate(first) { self.pop_front() } else { None } @@ -1854,7 +1853,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vec_deque_pop_if)] /// use std::collections::VecDeque; /// /// let mut deque: VecDeque = vec![0, 1, 2, 3, 4].into(); @@ -1864,10 +1862,10 @@ impl VecDeque { /// assert_eq!(deque, [0, 1, 2, 3]); /// assert_eq!(deque.pop_back_if(pred), None); /// ``` - #[unstable(feature = "vec_deque_pop_if", issue = "135889")] + #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { - let first = self.back_mut()?; - if predicate(first) { self.pop_back() } else { None } + let last = self.back_mut()?; + if predicate(last) { self.pop_back() } else { None } } /// Prepends an element to the deque. diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index f94f92397bb1..79b4622a0382 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -37,7 +37,6 @@ #![feature(str_as_str)] #![feature(strict_provenance_lints)] #![feature(string_replace_in_place)] -#![feature(vec_deque_pop_if)] #![feature(vec_deque_truncate_front)] #![feature(unique_rc_arc)] #![feature(macro_metavar_expr_concat)] From 420096d5f0c85f174486305b0018f479b7d912f0 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 24 Oct 2025 04:52:41 +0000 Subject: [PATCH 172/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 27050c0d15af664cf43ce4b0badec230e0bfcac5. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 15dc8792af07..405e0026b305 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6244effd0372d5d88fc859d3bf17ce1efcc2c9ec +27050c0d15af664cf43ce4b0badec230e0bfcac5 From b548b29e10dafaa433da634f07f2519cc502ecd8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 14:45:51 +0000 Subject: [PATCH 173/525] Skip codegen_crate call in check mode --- src/driver/aot.rs | 13 +------------ src/driver/jit.rs | 4 +--- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 7e77781dc2fc..7bf1efc10653 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -671,18 +671,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { } .to_owned(); - let cgus = if tcx.sess.opts.output_types.should_codegen() { - tcx.collect_and_partition_mono_items(()).codegen_units - } else { - // If only `--emit metadata` is used, we shouldn't perform any codegen. - // Also `tcx.collect_and_partition_mono_items` may panic in that case. - return Box::new(OngoingCodegen { - modules: vec![], - allocator_module: None, - crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter: ConcurrencyLimiter::new(0), - }); - }; + let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; if tcx.dep_graph.is_fully_enabled() { for cgu in cgus { diff --git a/src/driver/jit.rs b/src/driver/jit.rs index b3497503bf06..fec46bf26975 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -33,9 +33,7 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { } pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { - if !tcx.sess.opts.output_types.should_codegen() { - tcx.dcx().fatal("JIT mode doesn't work with `cargo check`"); - } + // FIXME error on check mode or crate types other than bin in CodegenBackend::init() if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); From 5aabbb63219eeb66adbfab2b9562d04f900fd56e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:02:01 +0000 Subject: [PATCH 174/525] Fix dev release after renaming the default branch to main --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 52a8eeee13d4..0930b924d177 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -231,7 +231,7 @@ jobs: release: runs-on: ubuntu-latest timeout-minutes: 10 - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} needs: [rustfmt, test, bench, dist] permissions: From 8760d55de6e5de6428588220589842360365f7bf Mon Sep 17 00:00:00 2001 From: The 8472 Date: Fri, 24 Oct 2025 23:55:52 +0200 Subject: [PATCH 175/525] benchmark path.components() iteration --- library/std/benches/path.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/std/benches/path.rs b/library/std/benches/path.rs index 094c00894a8e..912c783b31e4 100644 --- a/library/std/benches/path.rs +++ b/library/std/benches/path.rs @@ -55,6 +55,30 @@ fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) { }); } +#[bench] +fn bench_path_components_iter(b: &mut test::Bencher) { + let p = Path::new("/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/"); + + b.iter(|| { + for c in black_box(p).components() { + black_box(c); + } + }) +} + +#[bench] +fn bench_path_file_name(b: &mut test::Bencher) { + let p1 = Path::new("foo.bar"); + let p2 = Path::new("foo/bar"); + let p3 = Path::new("/bar"); + + b.iter(|| { + black_box(black_box(p1).file_name()); + black_box(black_box(p2).file_name()); + black_box(black_box(p3).file_name()); + }) +} + #[bench] #[cfg_attr(miri, ignore)] // Miri isn't fast... fn bench_path_hashset(b: &mut test::Bencher) { From ea3a4e714e0ab0e8782c544ad51a3ef28706fb92 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 25 Oct 2025 00:39:40 +0200 Subject: [PATCH 176/525] skip some Path prefix-component logic on platforms that don't have prefixes --- library/std/src/path.rs | 84 +++++++++++-------- library/std/src/sys/path/cygwin.rs | 1 + library/std/src/sys/path/sgx.rs | 1 + library/std/src/sys/path/uefi.rs | 1 + library/std/src/sys/path/unix.rs | 1 + .../std/src/sys/path/unsupported_backslash.rs | 1 + library/std/src/sys/path/windows.rs | 1 + 7 files changed, 55 insertions(+), 35 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 6e3b1e6e47d0..6873942f2a74 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -79,7 +79,7 @@ use crate::ops::{self, Deref}; use crate::rc::Rc; use crate::str::FromStr; use crate::sync::Arc; -use crate::sys::path::{MAIN_SEP_STR, is_sep_byte, is_verbatim_sep, parse_prefix}; +use crate::sys::path::{HAS_PREFIXES, MAIN_SEP_STR, is_sep_byte, is_verbatim_sep, parse_prefix}; use crate::{cmp, fmt, fs, io, sys}; //////////////////////////////////////////////////////////////////////////////// @@ -643,17 +643,26 @@ impl<'a> Components<'a> { // how long is the prefix, if any? #[inline] fn prefix_len(&self) -> usize { + if !HAS_PREFIXES { + return 0; + } self.prefix.as_ref().map(Prefix::len).unwrap_or(0) } #[inline] fn prefix_verbatim(&self) -> bool { + if !HAS_PREFIXES { + return false; + } self.prefix.as_ref().map(Prefix::is_verbatim).unwrap_or(false) } /// how much of the prefix is left from the point of view of iteration? #[inline] fn prefix_remaining(&self) -> usize { + if !HAS_PREFIXES { + return 0; + } if self.front == State::Prefix { self.prefix_len() } else { 0 } } @@ -707,7 +716,7 @@ impl<'a> Components<'a> { if self.has_physical_root { return true; } - if let Some(p) = self.prefix { + if HAS_PREFIXES && let Some(p) = self.prefix { if p.has_implicit_root() { return true; } @@ -732,7 +741,7 @@ impl<'a> Components<'a> { // corresponding path component unsafe fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option> { match comp { - b"." if self.prefix_verbatim() => Some(Component::CurDir), + b"." if HAS_PREFIXES && self.prefix_verbatim() => Some(Component::CurDir), b"." => None, // . components are normalized away, except at // the beginning of a path, which is treated // separately via `include_cur_dir` @@ -889,35 +898,7 @@ impl<'a> Iterator for Components<'a> { fn next(&mut self) -> Option> { while !self.finished() { match self.front { - State::Prefix if self.prefix_len() > 0 => { - self.front = State::StartDir; - debug_assert!(self.prefix_len() <= self.path.len()); - let raw = &self.path[..self.prefix_len()]; - self.path = &self.path[self.prefix_len()..]; - return Some(Component::Prefix(PrefixComponent { - raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) }, - parsed: self.prefix.unwrap(), - })); - } - State::Prefix => { - self.front = State::StartDir; - } - State::StartDir => { - self.front = State::Body; - if self.has_physical_root { - debug_assert!(!self.path.is_empty()); - self.path = &self.path[1..]; - return Some(Component::RootDir); - } else if let Some(p) = self.prefix { - if p.has_implicit_root() && !p.is_verbatim() { - return Some(Component::RootDir); - } - } else if self.include_cur_dir() { - debug_assert!(!self.path.is_empty()); - self.path = &self.path[1..]; - return Some(Component::CurDir); - } - } + // most likely case first State::Body if !self.path.is_empty() => { let (size, comp) = self.parse_next_component(); self.path = &self.path[size..]; @@ -928,6 +909,36 @@ impl<'a> Iterator for Components<'a> { State::Body => { self.front = State::Done; } + State::StartDir => { + self.front = State::Body; + if self.has_physical_root { + debug_assert!(!self.path.is_empty()); + self.path = &self.path[1..]; + return Some(Component::RootDir); + } else if HAS_PREFIXES && let Some(p) = self.prefix { + if p.has_implicit_root() && !p.is_verbatim() { + return Some(Component::RootDir); + } + } else if self.include_cur_dir() { + debug_assert!(!self.path.is_empty()); + self.path = &self.path[1..]; + return Some(Component::CurDir); + } + } + _ if const { !HAS_PREFIXES } => unreachable!(), + State::Prefix if self.prefix_len() == 0 => { + self.front = State::StartDir; + } + State::Prefix => { + self.front = State::StartDir; + debug_assert!(self.prefix_len() <= self.path.len()); + let raw = &self.path[..self.prefix_len()]; + self.path = &self.path[self.prefix_len()..]; + return Some(Component::Prefix(PrefixComponent { + raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) }, + parsed: self.prefix.unwrap(), + })); + } State::Done => unreachable!(), } } @@ -951,11 +962,11 @@ impl<'a> DoubleEndedIterator for Components<'a> { self.back = State::StartDir; } State::StartDir => { - self.back = State::Prefix; + self.back = if HAS_PREFIXES { State::Prefix } else { State::Done }; if self.has_physical_root { self.path = &self.path[..self.path.len() - 1]; return Some(Component::RootDir); - } else if let Some(p) = self.prefix { + } else if HAS_PREFIXES && let Some(p) = self.prefix { if p.has_implicit_root() && !p.is_verbatim() { return Some(Component::RootDir); } @@ -964,6 +975,7 @@ impl<'a> DoubleEndedIterator for Components<'a> { return Some(Component::CurDir); } } + _ if !HAS_PREFIXES => unreachable!(), State::Prefix if self.prefix_len() > 0 => { self.back = State::Done; return Some(Component::Prefix(PrefixComponent { @@ -3116,7 +3128,9 @@ impl Path { path: self.as_u8_slice(), prefix, has_physical_root: has_physical_root(self.as_u8_slice(), prefix), - front: State::Prefix, + // use a platform-specific initial state to avoid one turn of + // the state-machine when the platform doesn't have a Prefix. + front: const { if HAS_PREFIXES { State::Prefix } else { State::StartDir } }, back: State::Body, } } diff --git a/library/std/src/sys/path/cygwin.rs b/library/std/src/sys/path/cygwin.rs index da0982384b0e..416877a7280d 100644 --- a/library/std/src/sys/path/cygwin.rs +++ b/library/std/src/sys/path/cygwin.rs @@ -21,6 +21,7 @@ pub fn is_verbatim_sep(b: u8) -> bool { pub use super::windows_prefix::parse_prefix; +pub const HAS_PREFIXES: bool = true; pub const MAIN_SEP_STR: &str = "/"; pub const MAIN_SEP: char = '/'; diff --git a/library/std/src/sys/path/sgx.rs b/library/std/src/sys/path/sgx.rs index 32c7752f605d..dca61f3ea145 100644 --- a/library/std/src/sys/path/sgx.rs +++ b/library/std/src/sys/path/sgx.rs @@ -17,6 +17,7 @@ pub fn parse_prefix(_: &OsStr) -> Option> { None } +pub const HAS_PREFIXES: bool = false; pub const MAIN_SEP_STR: &str = "/"; pub const MAIN_SEP: char = '/'; diff --git a/library/std/src/sys/path/uefi.rs b/library/std/src/sys/path/uefi.rs index a3f4a3bfe1b6..6b8258685aa0 100644 --- a/library/std/src/sys/path/uefi.rs +++ b/library/std/src/sys/path/uefi.rs @@ -21,6 +21,7 @@ pub fn parse_prefix(_: &OsStr) -> Option> { None } +pub const HAS_PREFIXES: bool = true; pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs index 15530323a198..611d250db405 100644 --- a/library/std/src/sys/path/unix.rs +++ b/library/std/src/sys/path/unix.rs @@ -17,6 +17,7 @@ pub fn parse_prefix(_: &OsStr) -> Option> { None } +pub const HAS_PREFIXES: bool = false; pub const MAIN_SEP_STR: &str = "/"; pub const MAIN_SEP: char = '/'; diff --git a/library/std/src/sys/path/unsupported_backslash.rs b/library/std/src/sys/path/unsupported_backslash.rs index 30b06c132c98..8ed1fdc36e23 100644 --- a/library/std/src/sys/path/unsupported_backslash.rs +++ b/library/std/src/sys/path/unsupported_backslash.rs @@ -18,6 +18,7 @@ pub fn parse_prefix(_: &OsStr) -> Option> { None } +pub const HAS_PREFIXES: bool = true; pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index f124e1e5a71c..509b13b6ae81 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -9,6 +9,7 @@ mod tests; pub use super::windows_prefix::parse_prefix; +pub const HAS_PREFIXES: bool = true; pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; From d263ab36def3283211976b6f64815b22ae781dce Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 25 Oct 2025 13:59:23 +0200 Subject: [PATCH 177/525] replace u8 iterator with slice matching --- library/std/src/path.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 6873942f2a74..8c19f50e787a 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -729,10 +729,10 @@ impl<'a> Components<'a> { if self.has_root() { return false; } - let mut iter = self.path[self.prefix_remaining()..].iter(); - match (iter.next(), iter.next()) { - (Some(&b'.'), None) => true, - (Some(&b'.'), Some(&b)) => self.is_sep_byte(b), + let slice = &self.path[self.prefix_remaining()..]; + match slice { + [b'.'] => true, + [b'.', b, ..] => self.is_sep_byte(*b), _ => false, } } From 806b4436014fa3ab6a4c6876ccbe939ec24d927e Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 21 Oct 2025 21:42:24 +0000 Subject: [PATCH 178/525] add check for typo in let chains --- compiler/rustc_hir_typeck/src/errors.rs | 40 ++++++++++++- compiler/rustc_hir_typeck/src/expr.rs | 6 ++ compiler/rustc_hir_typeck/src/op.rs | 52 ++++++++++++----- .../parser/let-chains-assign-add-incorrect.rs | 28 +++++++++ .../let-chains-assign-add-incorrect.stderr | 58 +++++++++++++++++++ 5 files changed, 165 insertions(+), 19 deletions(-) create mode 100644 tests/ui/parser/let-chains-assign-add-incorrect.rs create mode 100644 tests/ui/parser/let-chains-assign-add-incorrect.stderr diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index d15d092b7d3d..142495c7042c 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -3,20 +3,21 @@ use std::borrow::Cow; use rustc_abi::ExternAbi; -use rustc_ast::Label; +use rustc_ast::{AssignOpKind, Label}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, - EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, + EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, struct_span_code_err, }; use rustc_hir as hir; use rustc_hir::ExprKind; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; +use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span, Symbol}; -use crate::fluent_generated as fluent; +use crate::{FnCtxt, fluent_generated as fluent}; #[derive(Diagnostic)] #[diag(hir_typeck_base_expression_double_dot, code = E0797)] @@ -1133,6 +1134,39 @@ impl Diagnostic<'_, G> for NakedFunctionsAsmBlock { } } +pub(crate) fn maybe_emit_plus_equals_diagnostic<'a>( + fnctxt: &FnCtxt<'a, '_>, + assign_op: Spanned, + lhs_expr: &hir::Expr<'_>, +) -> Result<(), Diag<'a>> { + if assign_op.node == hir::AssignOpKind::AddAssign + && let hir::ExprKind::Binary(bin_op, left, right) = &lhs_expr.kind + && bin_op.node == hir::BinOpKind::And + && crate::op::contains_let_in_chain(left) + && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &right.kind + && matches!(path.res, hir::def::Res::Local(_)) + { + let mut err = struct_span_code_err!( + fnctxt.dcx(), + assign_op.span, + E0368, + "binary assignment operation `+=` cannot be used in a let chain", + ); + + err.span_label(assign_op.span, "cannot use `+=` in a let chain"); + + err.span_suggestion( + assign_op.span, + "you might have meant to compare with `==` instead of assigning with `+=`", + "==", + Applicability::MaybeIncorrect, + ); + + return Err(err); + } + Ok(()) +} + #[derive(Diagnostic)] #[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)] pub(crate) struct NakedFunctionsMustNakedAsm { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2605aa18b91e..1009c7927854 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1249,6 +1249,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + // Skip suggestion if LHS contains a let-chain at this would likely be spurious + // cc: https://github.com/rust-lang/rust/issues/147664 + if crate::op::contains_let_in_chain(lhs) { + return; + } + let mut err = self.dcx().struct_span_err(op_span, "invalid left-hand side of assignment"); err.code(code); err.span_label(lhs.span, "cannot assign to this expression"); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index d18aed00a6f6..a175b3557c47 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -20,8 +20,8 @@ use {rustc_ast as ast, rustc_hir as hir}; use super::FnCtxt; use super::method::MethodCallee; -use crate::Expectation; use crate::method::TreatNotYetDefinedOpaques; +use crate::{Expectation, errors}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Checks a `a = b` @@ -308,23 +308,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut path = None; let lhs_ty_str = self.tcx.short_string(lhs_ty, &mut path); let rhs_ty_str = self.tcx.short_string(rhs_ty, &mut path); + let (mut err, output_def_id) = match op { + // Try and detect when `+=` was incorrectly + // used instead of `==` in a let-chain Op::AssignOp(assign_op) => { - let s = assign_op.node.as_str(); - let mut err = struct_span_code_err!( - self.dcx(), - expr.span, - E0368, - "binary assignment operation `{}` cannot be applied to type `{}`", - s, - lhs_ty_str, - ); - err.span_label( - lhs_expr.span, - format!("cannot use `{}` on type `{}`", s, lhs_ty_str), - ); - self.note_unmet_impls_on_type(&mut err, &errors, false); - (err, None) + if let Err(e) = + errors::maybe_emit_plus_equals_diagnostic(&self, assign_op, lhs_expr) + { + (e, None) + } else { + let s = assign_op.node.as_str(); + let mut err = struct_span_code_err!( + self.dcx(), + expr.span, + E0368, + "binary assignment operation `{}` cannot be applied to type `{}`", + s, + lhs_ty_str, + ); + err.span_label( + lhs_expr.span, + format!("cannot use `{}` on type `{}`", s, lhs_ty_str), + ); + self.note_unmet_impls_on_type(&mut err, &errors, false); + (err, None) + } } Op::BinOp(bin_op) => { let message = match bin_op.node { @@ -1084,6 +1093,17 @@ fn lang_item_for_unop(tcx: TyCtxt<'_>, op: hir::UnOp) -> (Symbol, Option) -> bool { + match &expr.kind { + hir::ExprKind::Let(..) => true, + hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, left, right) => { + contains_let_in_chain(left) || contains_let_in_chain(right) + } + _ => false, + } +} + // Binary operator categories. These categories summarize the behavior // with respect to the builtin operations supported. #[derive(Clone, Copy)] diff --git a/tests/ui/parser/let-chains-assign-add-incorrect.rs b/tests/ui/parser/let-chains-assign-add-incorrect.rs new file mode 100644 index 000000000000..f3b497f5c183 --- /dev/null +++ b/tests/ui/parser/let-chains-assign-add-incorrect.rs @@ -0,0 +1,28 @@ +//@ edition:2024 + +fn test_where_left_is_not_let() { + let mut y = 2; + if let x = 1 && true && y += 2 {}; + //~^ ERROR expected expression, found `let` statement + //~| NOTE only supported directly in conditions of `if` and `while` expressions + //~| ERROR mismatched types + //~| NOTE expected `bool`, found integer + //~| NOTE expected because this is `bool` + //~| ERROR binary assignment operation `+=` cannot be used in a let chain + //~| NOTE cannot use `+=` in a let chain + //~| HELP you might have meant to compare with `==` instead of assigning with `+=` +} + +fn test_where_left_is_let() { + let mut y = 2; + if let x = 1 && y += 2 {}; + //~^ ERROR expected expression, found `let` statement + //~| NOTE only supported directly in conditions of `if` and `while` expressions + //~| ERROR mismatched types + //~| NOTE expected `bool`, found integer + //~| ERROR binary assignment operation `+=` cannot be used in a let chain + //~| NOTE cannot use `+=` in a let chain + //~| HELP you might have meant to compare with `==` instead of assigning with `+=` +} + +fn main() {} diff --git a/tests/ui/parser/let-chains-assign-add-incorrect.stderr b/tests/ui/parser/let-chains-assign-add-incorrect.stderr new file mode 100644 index 000000000000..38811e0733a5 --- /dev/null +++ b/tests/ui/parser/let-chains-assign-add-incorrect.stderr @@ -0,0 +1,58 @@ +error: expected expression, found `let` statement + --> $DIR/let-chains-assign-add-incorrect.rs:5:8 + | +LL | if let x = 1 && true && y += 2 {}; + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/let-chains-assign-add-incorrect.rs:18:8 + | +LL | if let x = 1 && y += 2 {}; + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error[E0308]: mismatched types + --> $DIR/let-chains-assign-add-incorrect.rs:5:29 + | +LL | if let x = 1 && true && y += 2 {}; + | ----------------- ^ expected `bool`, found integer + | | + | expected because this is `bool` + +error[E0368]: binary assignment operation `+=` cannot be used in a let chain + --> $DIR/let-chains-assign-add-incorrect.rs:5:31 + | +LL | if let x = 1 && true && y += 2 {}; + | ^^ cannot use `+=` in a let chain + | +help: you might have meant to compare with `==` instead of assigning with `+=` + | +LL - if let x = 1 && true && y += 2 {}; +LL + if let x = 1 && true && y == 2 {}; + | + +error[E0308]: mismatched types + --> $DIR/let-chains-assign-add-incorrect.rs:18:21 + | +LL | if let x = 1 && y += 2 {}; + | ^ expected `bool`, found integer + +error[E0368]: binary assignment operation `+=` cannot be used in a let chain + --> $DIR/let-chains-assign-add-incorrect.rs:18:23 + | +LL | if let x = 1 && y += 2 {}; + | ^^ cannot use `+=` in a let chain + | +help: you might have meant to compare with `==` instead of assigning with `+=` + | +LL - if let x = 1 && y += 2 {}; +LL + if let x = 1 && y == 2 {}; + | + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0368. +For more information about an error, try `rustc --explain E0308`. From ea96b7905626aed8c7a8c25825151d1106983144 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 26 Aug 2025 20:18:13 +0000 Subject: [PATCH 179/525] add parser check for pointer typo --- compiler/rustc_parse/src/parser/ty.rs | 39 +++ .../did_you_mean/c-style-pointer-types.fixed | 113 +++++++ .../ui/did_you_mean/c-style-pointer-types.rs | 113 +++++++ .../did_you_mean/c-style-pointer-types.stderr | 302 ++++++++++++++++++ 4 files changed, 567 insertions(+) create mode 100644 tests/ui/did_you_mean/c-style-pointer-types.fixed create mode 100644 tests/ui/did_you_mean/c-style-pointer-types.rs create mode 100644 tests/ui/did_you_mean/c-style-pointer-types.stderr diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 6168647183fd..92703d1a913e 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -398,6 +398,10 @@ impl<'a> Parser<'a> { // Qualified path let (qself, path) = self.parse_qpath(PathStyle::Type)?; TyKind::Path(Some(qself), path) + } else if (self.token.is_keyword(kw::Const) || self.token.is_keyword(kw::Mut)) + && self.look_ahead(1, |t| *t == token::Star) + { + self.parse_ty_c_style_pointer()? } else if self.check_path() { self.parse_path_start_ty(lo, allow_plus, ty_generics)? } else if self.can_begin_bound() { @@ -579,6 +583,41 @@ impl<'a> Parser<'a> { Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } + /// Parses a raw pointer with a C-style typo + fn parse_ty_c_style_pointer(&mut self) -> PResult<'a, TyKind> { + let kw_span = self.token.span; + let mutbl = self.parse_const_or_mut(); + + if let Some(mutbl) = mutbl + && self.eat(exp!(Star)) + { + let star_span = self.prev_token.span; + + let mutability = match mutbl { + Mutability::Not => "const", + Mutability::Mut => "mut", + }; + + let ty = self.parse_ty_no_question_mark_recover()?; + + self.dcx() + .struct_span_err( + kw_span, + format!("raw pointer types must be written as `*{mutability} T`"), + ) + .with_multipart_suggestion( + format!("put the `*` before `{mutability}`"), + vec![(star_span, String::new()), (kw_span.shrink_to_lo(), "*".to_string())], + Applicability::MachineApplicable, + ) + .emit(); + + return Ok(TyKind::Ptr(MutTy { ty, mutbl })); + } + // This is unreachable because we always get into if above and return from it + unreachable!("this could never happen") + } + /// Parses a raw pointer type: `*[const | mut] $type`. fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> { let mutbl = self.parse_const_or_mut().unwrap_or_else(|| { diff --git a/tests/ui/did_you_mean/c-style-pointer-types.fixed b/tests/ui/did_you_mean/c-style-pointer-types.fixed new file mode 100644 index 000000000000..2517c8f1954d --- /dev/null +++ b/tests/ui/did_you_mean/c-style-pointer-types.fixed @@ -0,0 +1,113 @@ +//@ run-rustfix + +#![allow(unused)] + +pub const P1: *const u8 = 0 as _; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P2: *mut u8 = 1 as _; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P3: *const i32 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P4: *const i32 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P5: *mut i32 = std::ptr::null_mut(); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P6: *mut i32 = std::ptr::null_mut(); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P7: *const Vec = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P8: *const std::collections::HashMap = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func1(p: *const u8) {} +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func2(p: *mut u8) {} +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +fn func3() -> *const u8 { std::ptr::null() } +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func4() -> *mut u8 { std::ptr::null_mut() } +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +struct S1 { + field: *const u8, + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +struct S2 { + field: *mut u8, + //~^ ERROR: raw pointer types must be written as `*mut T` + //~| HELP: put the `*` before `mut` +} + +type Tuple1 = (*const u8, i32); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Tuple2 = (*mut u8, i32); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +type Array1 = [*const u8; 10]; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Array2 = [*mut u8; 10]; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +type Alias1 = *const u8; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Alias2 = *mut u8; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P9: *const u8 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P10: *const u8 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +impl S1 { + fn method(self, size: *const u32) {} + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +trait Trait1 { + fn method(p: *const u8); + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +fn generic_func() -> *const T { std::ptr::null() } +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn main() {} diff --git a/tests/ui/did_you_mean/c-style-pointer-types.rs b/tests/ui/did_you_mean/c-style-pointer-types.rs new file mode 100644 index 000000000000..562d85fb75fb --- /dev/null +++ b/tests/ui/did_you_mean/c-style-pointer-types.rs @@ -0,0 +1,113 @@ +//@ run-rustfix + +#![allow(unused)] + +pub const P1: const* u8 = 0 as _; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P2: mut* u8 = 1 as _; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P3: const* i32 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P4: const* i32 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P5: mut* i32 = std::ptr::null_mut(); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P6: mut* i32 = std::ptr::null_mut(); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P7: const* Vec = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P8: const* std::collections::HashMap = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func1(p: const* u8) {} +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func2(p: mut* u8) {} +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +fn func3() -> const* u8 { std::ptr::null() } +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn func4() -> mut* u8 { std::ptr::null_mut() } +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +struct S1 { + field: const* u8, + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +struct S2 { + field: mut* u8, + //~^ ERROR: raw pointer types must be written as `*mut T` + //~| HELP: put the `*` before `mut` +} + +type Tuple1 = (const* u8, i32); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Tuple2 = (mut* u8, i32); +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +type Array1 = [const* u8; 10]; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Array2 = [mut* u8; 10]; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +type Alias1 = const* u8; +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +type Alias2 = mut* u8; +//~^ ERROR: raw pointer types must be written as `*mut T` +//~| HELP: put the `*` before `mut` + +pub const P9: const *u8 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +pub const P10: const * u8 = std::ptr::null(); +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +impl S1 { + fn method(self, size: const* u32) {} + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +trait Trait1 { + fn method(p: const* u8); + //~^ ERROR: raw pointer types must be written as `*const T` + //~| HELP: put the `*` before `const` +} + +fn generic_func() -> const* T { std::ptr::null() } +//~^ ERROR: raw pointer types must be written as `*const T` +//~| HELP: put the `*` before `const` + +fn main() {} diff --git a/tests/ui/did_you_mean/c-style-pointer-types.stderr b/tests/ui/did_you_mean/c-style-pointer-types.stderr new file mode 100644 index 000000000000..bbab72c01662 --- /dev/null +++ b/tests/ui/did_you_mean/c-style-pointer-types.stderr @@ -0,0 +1,302 @@ +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:5:15 + | +LL | pub const P1: const* u8 = 0 as _; + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P1: const* u8 = 0 as _; +LL + pub const P1: *const u8 = 0 as _; + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:9:15 + | +LL | pub const P2: mut* u8 = 1 as _; + | ^^^ + | +help: put the `*` before `mut` + | +LL - pub const P2: mut* u8 = 1 as _; +LL + pub const P2: *mut u8 = 1 as _; + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:13:15 + | +LL | pub const P3: const* i32 = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P3: const* i32 = std::ptr::null(); +LL + pub const P3: *const i32 = std::ptr::null(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:17:15 + | +LL | pub const P4: const* i32 = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P4: const* i32 = std::ptr::null(); +LL + pub const P4: *const i32 = std::ptr::null(); + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:21:15 + | +LL | pub const P5: mut* i32 = std::ptr::null_mut(); + | ^^^ + | +help: put the `*` before `mut` + | +LL - pub const P5: mut* i32 = std::ptr::null_mut(); +LL + pub const P5: *mut i32 = std::ptr::null_mut(); + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:25:15 + | +LL | pub const P6: mut* i32 = std::ptr::null_mut(); + | ^^^ + | +help: put the `*` before `mut` + | +LL - pub const P6: mut* i32 = std::ptr::null_mut(); +LL + pub const P6: *mut i32 = std::ptr::null_mut(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:29:15 + | +LL | pub const P7: const* Vec = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P7: const* Vec = std::ptr::null(); +LL + pub const P7: *const Vec = std::ptr::null(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:33:15 + | +LL | pub const P8: const* std::collections::HashMap = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P8: const* std::collections::HashMap = std::ptr::null(); +LL + pub const P8: *const std::collections::HashMap = std::ptr::null(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:37:13 + | +LL | fn func1(p: const* u8) {} + | ^^^^^ + | +help: put the `*` before `const` + | +LL - fn func1(p: const* u8) {} +LL + fn func1(p: *const u8) {} + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:41:13 + | +LL | fn func2(p: mut* u8) {} + | ^^^ + | +help: put the `*` before `mut` + | +LL - fn func2(p: mut* u8) {} +LL + fn func2(p: *mut u8) {} + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:45:15 + | +LL | fn func3() -> const* u8 { std::ptr::null() } + | ^^^^^ + | +help: put the `*` before `const` + | +LL - fn func3() -> const* u8 { std::ptr::null() } +LL + fn func3() -> *const u8 { std::ptr::null() } + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:49:15 + | +LL | fn func4() -> mut* u8 { std::ptr::null_mut() } + | ^^^ + | +help: put the `*` before `mut` + | +LL - fn func4() -> mut* u8 { std::ptr::null_mut() } +LL + fn func4() -> *mut u8 { std::ptr::null_mut() } + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:54:12 + | +LL | field: const* u8, + | ^^^^^ + | +help: put the `*` before `const` + | +LL - field: const* u8, +LL + field: *const u8, + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:60:12 + | +LL | field: mut* u8, + | ^^^ + | +help: put the `*` before `mut` + | +LL - field: mut* u8, +LL + field: *mut u8, + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:65:16 + | +LL | type Tuple1 = (const* u8, i32); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - type Tuple1 = (const* u8, i32); +LL + type Tuple1 = (*const u8, i32); + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:69:16 + | +LL | type Tuple2 = (mut* u8, i32); + | ^^^ + | +help: put the `*` before `mut` + | +LL - type Tuple2 = (mut* u8, i32); +LL + type Tuple2 = (*mut u8, i32); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:73:16 + | +LL | type Array1 = [const* u8; 10]; + | ^^^^^ + | +help: put the `*` before `const` + | +LL - type Array1 = [const* u8; 10]; +LL + type Array1 = [*const u8; 10]; + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:77:16 + | +LL | type Array2 = [mut* u8; 10]; + | ^^^ + | +help: put the `*` before `mut` + | +LL - type Array2 = [mut* u8; 10]; +LL + type Array2 = [*mut u8; 10]; + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:81:15 + | +LL | type Alias1 = const* u8; + | ^^^^^ + | +help: put the `*` before `const` + | +LL - type Alias1 = const* u8; +LL + type Alias1 = *const u8; + | + +error: raw pointer types must be written as `*mut T` + --> $DIR/c-style-pointer-types.rs:85:15 + | +LL | type Alias2 = mut* u8; + | ^^^ + | +help: put the `*` before `mut` + | +LL - type Alias2 = mut* u8; +LL + type Alias2 = *mut u8; + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:89:15 + | +LL | pub const P9: const *u8 = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P9: const *u8 = std::ptr::null(); +LL + pub const P9: *const u8 = std::ptr::null(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:93:16 + | +LL | pub const P10: const * u8 = std::ptr::null(); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - pub const P10: const * u8 = std::ptr::null(); +LL + pub const P10: *const u8 = std::ptr::null(); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:98:27 + | +LL | fn method(self, size: const* u32) {} + | ^^^^^ + | +help: put the `*` before `const` + | +LL - fn method(self, size: const* u32) {} +LL + fn method(self, size: *const u32) {} + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:104:18 + | +LL | fn method(p: const* u8); + | ^^^^^ + | +help: put the `*` before `const` + | +LL - fn method(p: const* u8); +LL + fn method(p: *const u8); + | + +error: raw pointer types must be written as `*const T` + --> $DIR/c-style-pointer-types.rs:109:25 + | +LL | fn generic_func() -> const* T { std::ptr::null() } + | ^^^^^ + | +help: put the `*` before `const` + | +LL - fn generic_func() -> const* T { std::ptr::null() } +LL + fn generic_func() -> *const T { std::ptr::null() } + | + +error: aborting due to 25 previous errors + From b247f67d64db520c206a9ba3b716f69bf237b02f Mon Sep 17 00:00:00 2001 From: Taj Pereira Date: Sat, 25 Oct 2025 06:11:13 +1030 Subject: [PATCH 180/525] Rename downcast_[ref|mut]_unchecked -> downcast_unchecked_[ref|mut] Undo rust-analyzer changes --- library/core/src/any.rs | 36 +++++++++---------- ...us-assoc-type-path-suggest-similar-item.rs | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 3ab95438c3ff..3935dfe309c1 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -227,7 +227,7 @@ impl dyn Any { // SAFETY: just checked whether we are pointing to the correct type, and we can rely on // that check for memory safety because we have implemented Any for all types; no other // impls can exist as they would conflict with our impl. - unsafe { Some(self.downcast_ref_unchecked()) } + unsafe { Some(self.downcast_unchecked_ref()) } } else { None } @@ -263,7 +263,7 @@ impl dyn Any { // SAFETY: just checked whether we are pointing to the correct type, and we can rely on // that check for memory safety because we have implemented Any for all types; no other // impls can exist as they would conflict with our impl. - unsafe { Some(self.downcast_mut_unchecked()) } + unsafe { Some(self.downcast_unchecked_mut()) } } else { None } @@ -281,7 +281,7 @@ impl dyn Any { /// let x: Box = Box::new(1_usize); /// /// unsafe { - /// assert_eq!(*x.downcast_ref_unchecked::(), 1); + /// assert_eq!(*x.downcast_unchecked_ref::(), 1); /// } /// ``` /// @@ -291,7 +291,7 @@ impl dyn Any { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_ref_unchecked(&self) -> &T { + pub unsafe fn downcast_unchecked_ref(&self) -> &T { debug_assert!(self.is::()); // SAFETY: caller guarantees that T is the correct type unsafe { &*(self as *const dyn Any as *const T) } @@ -309,7 +309,7 @@ impl dyn Any { /// let mut x: Box = Box::new(1_usize); /// /// unsafe { - /// *x.downcast_mut_unchecked::() += 1; + /// *x.downcast_unchecked_mut::() += 1; /// } /// /// assert_eq!(*x.downcast_ref::().unwrap(), 2); @@ -321,7 +321,7 @@ impl dyn Any { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { + pub unsafe fn downcast_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is::()); // SAFETY: caller guarantees that T is the correct type unsafe { &mut *(self as *mut dyn Any as *mut T) } @@ -417,7 +417,7 @@ impl dyn Any + Send { /// let x: Box = Box::new(1_usize); /// /// unsafe { - /// assert_eq!(*x.downcast_ref_unchecked::(), 1); + /// assert_eq!(*x.downcast_unchecked_ref::(), 1); /// } /// ``` /// @@ -427,9 +427,9 @@ impl dyn Any + Send { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_ref_unchecked(&self) -> &T { + pub unsafe fn downcast_unchecked_ref(&self) -> &T { // SAFETY: guaranteed by caller - unsafe { ::downcast_ref_unchecked::(self) } + unsafe { ::downcast_unchecked_ref::(self) } } /// Forwards to the method defined on the type `dyn Any`. @@ -444,7 +444,7 @@ impl dyn Any + Send { /// let mut x: Box = Box::new(1_usize); /// /// unsafe { - /// *x.downcast_mut_unchecked::() += 1; + /// *x.downcast_unchecked_mut::() += 1; /// } /// /// assert_eq!(*x.downcast_ref::().unwrap(), 2); @@ -456,9 +456,9 @@ impl dyn Any + Send { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { + pub unsafe fn downcast_unchecked_mut(&mut self) -> &mut T { // SAFETY: guaranteed by caller - unsafe { ::downcast_mut_unchecked::(self) } + unsafe { ::downcast_unchecked_mut::(self) } } } @@ -551,7 +551,7 @@ impl dyn Any + Send + Sync { /// let x: Box = Box::new(1_usize); /// /// unsafe { - /// assert_eq!(*x.downcast_ref_unchecked::(), 1); + /// assert_eq!(*x.downcast_unchecked_ref::(), 1); /// } /// ``` /// # Safety @@ -560,9 +560,9 @@ impl dyn Any + Send + Sync { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_ref_unchecked(&self) -> &T { + pub unsafe fn downcast_unchecked_ref(&self) -> &T { // SAFETY: guaranteed by caller - unsafe { ::downcast_ref_unchecked::(self) } + unsafe { ::downcast_unchecked_ref::(self) } } /// Forwards to the method defined on the type `Any`. @@ -577,7 +577,7 @@ impl dyn Any + Send + Sync { /// let mut x: Box = Box::new(1_usize); /// /// unsafe { - /// *x.downcast_mut_unchecked::() += 1; + /// *x.downcast_unchecked_mut::() += 1; /// } /// /// assert_eq!(*x.downcast_ref::().unwrap(), 2); @@ -588,9 +588,9 @@ impl dyn Any + Send + Sync { /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] - pub unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { + pub unsafe fn downcast_unchecked_mut(&mut self) -> &mut T { // SAFETY: guaranteed by caller - unsafe { ::downcast_mut_unchecked::(self) } + unsafe { ::downcast_unchecked_mut::(self) } } } diff --git a/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs index a9c2c20ef374..45f9f6bc5191 100644 --- a/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs +++ b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs @@ -44,7 +44,7 @@ fn main() { //~^ ERROR ambiguous associated type [E0223] //~| HELP if there were a trait named `Example` with associated type `wrapping` - // this one ideally should suggest `downcast_mut_unchecked` + // this one ideally should suggest `downcast_unchecked_mut` ::downcast::mut_unchecked; //~^ ERROR ambiguous associated type [E0223] //~| HELP if there were a trait named `Example` with associated type `downcast` From 2e5d395f2bfdedfda6bddc4797fbd4c04711efde Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 3 May 2025 22:58:27 -0600 Subject: [PATCH 181/525] refactor ub_checks and contract_checks to share logic --- compiler/rustc_borrowck/src/type_check/mod.rs | 3 +-- compiler/rustc_codegen_cranelift/src/base.rs | 13 ++--------- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 8 ++----- .../src/check_consts/check.rs | 2 +- .../rustc_const_eval/src/interpret/machine.rs | 22 ++++++++----------- .../src/interpret/operator.rs | 3 +-- compiler/rustc_middle/src/mir/mod.rs | 4 +++- compiler/rustc_middle/src/mir/pretty.rs | 6 +++-- compiler/rustc_middle/src/mir/statement.rs | 5 ++--- compiler/rustc_middle/src/mir/syntax.rs | 15 +++++++++++++ compiler/rustc_middle/src/mir/traversal.rs | 4 ++-- .../src/move_paths/builder.rs | 2 +- .../rustc_mir_transform/src/cost_checker.rs | 3 ++- compiler/rustc_mir_transform/src/gvn.rs | 3 +-- .../rustc_mir_transform/src/instsimplify.rs | 5 ++++- .../src/known_panics_lint.rs | 3 +-- .../src/lower_intrinsics.rs | 9 ++++++-- .../rustc_mir_transform/src/promote_consts.rs | 3 +-- compiler/rustc_mir_transform/src/validate.rs | 2 +- compiler/rustc_public/src/mir/body.rs | 9 ++++++-- .../src/unstable/convert/stable/mir.rs | 7 ++++-- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/miri/src/machine.rs | 9 ++------ 23 files changed, 75 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d1d0bff8fe06..46f39ea8f250 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1046,8 +1046,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} - &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} + &Rvalue::NullaryOp(NullOp::RuntimeChecks(_), _) => {} Rvalue::ShallowInitBox(_operand, ty) => { let trait_ref = diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 7d50548b4026..6a1217a6a49b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -841,17 +841,8 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fields.iter(), ) .bytes(), - NullOp::UbChecks => { - let val = fx.tcx.sess.ub_checks(); - let val = CValue::by_val( - fx.bcx.ins().iconst(types::I8, i64::from(val)), - fx.layout_of(fx.tcx.types.bool), - ); - lval.write_cvalue(fx, val); - return; - } - NullOp::ContractChecks => { - let val = fx.tcx.sess.contract_checks(); + NullOp::RuntimeChecks(kind) => { + let val = kind.value(fx.tcx.sess); let val = CValue::by_val( fx.bcx.ins().iconst(types::I8, i64::from(val)), fx.layout_of(fx.tcx.types.bool), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 640f7211dc99..9f7eb9bc51bb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -618,12 +618,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .bytes(); bx.cx().const_usize(val) } - mir::NullOp::UbChecks => { - let val = bx.tcx().sess.ub_checks(); - bx.cx().const_bool(val) - } - mir::NullOp::ContractChecks => { - let val = bx.tcx().sess.contract_checks(); + mir::NullOp::RuntimeChecks(kind) => { + let val = kind.value(bx.tcx().sess); bx.cx().const_bool(val) } }; diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index ca173fe26c2f..c0a9bd187c14 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -646,7 +646,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp( - NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, + NullOp::OffsetOf(_) | NullOp::RuntimeChecks(_), _, ) => {} Rvalue::ShallowInitBox(_, _) => {} diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 1725635e0b47..27b1ca01514c 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -298,11 +298,11 @@ pub trait Machine<'tcx>: Sized { interp_ok(()) } - /// Determines the result of a `NullaryOp::UbChecks` invocation. - fn ub_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>; - - /// Determines the result of a `NullaryOp::ContractChecks` invocation. - fn contract_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>; + /// Determines the result of a `NullaryOp::RuntimeChecks` invocation. + fn runtime_checks( + _ecx: &InterpCx<'tcx, Self>, + r: mir::RuntimeChecks, + ) -> InterpResult<'tcx, bool>; /// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction. /// You can use this to detect long or endlessly running programs. @@ -681,14 +681,10 @@ pub macro compile_time_machine(<$tcx: lifetime>) { } #[inline(always)] - fn ub_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> { - // We can't look at `tcx.sess` here as that can differ across crates, which can lead to - // unsound differences in evaluating the same constant at different instantiation sites. - interp_ok(true) - } - - #[inline(always)] - fn contract_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> { + fn runtime_checks( + _ecx: &InterpCx<$tcx, Self>, + _r: mir::RuntimeChecks, + ) -> InterpResult<$tcx, bool> { // We can't look at `tcx.sess` here as that can differ across crates, which can lead to // unsound differences in evaluating the same constant at different instantiation sites. interp_ok(true) diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 58b90abf0129..feba23769209 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -522,8 +522,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.tcx.offset_of_subfield(self.typing_env, layout, fields.iter()).bytes(); ImmTy::from_uint(val, usize_layout()) } - UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx), - ContractChecks => ImmTy::from_bool(M::contract_checks(self)?, *self.tcx), + RuntimeChecks(r) => ImmTy::from_bool(M::runtime_checks(self, r)?, *self.tcx), }) } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index fab04df500a5..802adceb063e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -649,7 +649,9 @@ impl<'tcx> Body<'tcx> { } match rvalue { - Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)), + Rvalue::NullaryOp(NullOp::RuntimeChecks(kind), _) => { + Some((kind.value(tcx.sess) as u128, targets)) + } Rvalue::Use(Operand::Constant(constant)) => { let bits = eval_mono_const(constant)?; Some((bits, targets)) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 17d8eeee68bf..a7941290de2e 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1093,8 +1093,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { let t = with_no_trimmed_paths!(format!("{}", t)); match op { NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"), - NullOp::UbChecks => write!(fmt, "UbChecks()"), - NullOp::ContractChecks => write!(fmt, "ContractChecks()"), + NullOp::RuntimeChecks(RuntimeChecks::UbChecks) => write!(fmt, "UbChecks()"), + NullOp::RuntimeChecks(RuntimeChecks::ContractChecks) => { + write!(fmt, "ContractChecks()") + } } } ThreadLocalRef(did) => ty::tls::with(|tcx| { diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 3cbb4b70b062..a1f5ffb0b277 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -795,8 +795,7 @@ impl<'tcx> Rvalue<'tcx> { } Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => tcx.types.usize, - Rvalue::NullaryOp(NullOp::ContractChecks, _) - | Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool, + Rvalue::NullaryOp(NullOp::RuntimeChecks(_), _) => tcx.types.bool, Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64), AggregateKind::Tuple => { @@ -864,7 +863,7 @@ impl<'tcx> NullOp<'tcx> { pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self { NullOp::OffsetOf(_) => tcx.types.usize, - NullOp::UbChecks | NullOp::ContractChecks => tcx.types.bool, + NullOp::RuntimeChecks(_) => tcx.types.bool, } } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 9d99239546ae..865b91817b3c 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1565,6 +1565,12 @@ pub enum AggregateKind<'tcx> { pub enum NullOp<'tcx> { /// Returns the offset of a field OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>), + /// Returns whether we should perform some checking at runtime. + RuntimeChecks(RuntimeChecks), +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +pub enum RuntimeChecks { /// Returns whether we should perform some UB-checking at runtime. /// See the `ub_checks` intrinsic docs for details. UbChecks, @@ -1573,6 +1579,15 @@ pub enum NullOp<'tcx> { ContractChecks, } +impl RuntimeChecks { + pub fn value(self, sess: &rustc_session::Session) -> bool { + match self { + Self::UbChecks => sess.ub_checks(), + Self::ContractChecks => sess.contract_checks(), + } + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)] pub enum UnOp { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 9308570d89d1..7f6c7376501f 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -293,9 +293,9 @@ pub fn reverse_postorder<'a, 'tcx>( /// reachable. /// /// Such a traversal is mostly useful because it lets us skip lowering the `false` side -/// of `if ::CONST`, as well as [`NullOp::UbChecks`]. +/// of `if ::CONST`, as well as [`NullOp::RuntimeChecks`]. /// -/// [`NullOp::UbChecks`]: rustc_middle::mir::NullOp::UbChecks +/// [`NullOp::RuntimeChecks`]: rustc_middle::mir::NullOp::RuntimeChecks pub fn mono_reachable<'a, 'tcx>( body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index dd65f0699e97..8801fa8d9fd3 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -452,7 +452,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | Rvalue::RawPtr(..) | Rvalue::Discriminant(..) | Rvalue::NullaryOp( - NullOp::OffsetOf(..) | NullOp::UbChecks | NullOp::ContractChecks, + NullOp::OffsetOf(..) | NullOp::RuntimeChecks(_), _, ) => {} } diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 00a8293966b0..1a9af0e22bbe 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -75,7 +75,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, _location: Location) { match rvalue { - Rvalue::NullaryOp(NullOp::UbChecks, ..) + // FIXME: Should we do the same for `OverflowChecks`? + Rvalue::NullaryOp(NullOp::RuntimeChecks(RuntimeChecks::UbChecks), ..) if !self .tcx .sess diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 8eae80e235cc..e19a88d519a4 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -675,8 +675,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { .tcx .offset_of_subfield(self.typing_env(), arg_layout, fields.iter()) .bytes(), - NullOp::UbChecks => return None, - NullOp::ContractChecks => return None, + NullOp::RuntimeChecks(_) => return None, }; ImmTy::from_uint(val, ty).into() } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 932744e4fa25..51e18516534a 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -169,7 +169,10 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>) { - let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue else { return }; + // FIXME: Should we do the same for overflow checks? + let Rvalue::NullaryOp(NullOp::RuntimeChecks(RuntimeChecks::UbChecks), _) = *rvalue else { + return; + }; let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks()); let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 131e3943689b..dab2267eea69 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -612,8 +612,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { .tcx .offset_of_subfield(self.typing_env, op_layout, fields.iter()) .bytes(), - NullOp::UbChecks => return None, - NullOp::ContractChecks => return None, + NullOp::RuntimeChecks(_) => return None, }; ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into() } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index ad7c52064a8e..e6fa30a72b9b 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -23,13 +23,18 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { sym::unreachable => { terminator.kind = TerminatorKind::Unreachable; } - sym::ub_checks => { + sym::ub_checks | sym::contract_checks => { + let op = match intrinsic.name { + sym::ub_checks => RuntimeChecks::UbChecks, + sym::contract_checks => RuntimeChecks::ContractChecks, + _ => unreachable!(), + }; let target = target.unwrap(); block.statements.push(Statement::new( terminator.source_info, StatementKind::Assign(Box::new(( *destination, - Rvalue::NullaryOp(NullOp::UbChecks, tcx.types.bool), + Rvalue::NullaryOp(NullOp::RuntimeChecks(op), tcx.types.bool), ))), )); terminator.kind = TerminatorKind::Goto { target }; diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 9204c221515c..da5814c6b4cc 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -451,8 +451,7 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::NullaryOp(op, _) => match op { NullOp::OffsetOf(_) => {} - NullOp::UbChecks => {} - NullOp::ContractChecks => {} + NullOp::RuntimeChecks(_) => {} }, Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable), diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 5a9018a62c57..0e71e396c144 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1478,7 +1478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Rvalue::Repeat(_, _) | Rvalue::ThreadLocalRef(_) | Rvalue::RawPtr(_, _) - | Rvalue::NullaryOp(NullOp::UbChecks | NullOp::ContractChecks, _) + | Rvalue::NullaryOp(NullOp::RuntimeChecks(_), _) | Rvalue::Discriminant(_) => {} Rvalue::WrapUnsafeBinder(op, ty) => { diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index 1a939cbe8dba..551f666023b0 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -642,8 +642,7 @@ impl Rvalue { .ok_or_else(|| error!("Expected a `RigidTy` but found: {place_ty:?}")) } Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => Ok(Ty::usize_ty()), - Rvalue::NullaryOp(NullOp::ContractChecks, _) - | Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()), + Rvalue::NullaryOp(NullOp::RuntimeChecks(_), _) => Ok(Ty::bool_ty()), Rvalue::Aggregate(ak, ops) => match *ak { AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64), AggregateKind::Tuple => Ok(Ty::new_tuple( @@ -1024,6 +1023,12 @@ pub enum CastKind { pub enum NullOp { /// Returns the offset of a field. OffsetOf(Vec<(VariantIdx, FieldIdx)>), + /// Codegen conditions for runtime checks. + RuntimeChecks(RuntimeChecks), +} + +#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] +pub enum RuntimeChecks { /// cfg!(ub_checks), but at codegen time UbChecks, /// cfg!(contract_checks), but at codegen time diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index f850bc5f89b8..1de5a2b32779 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -322,12 +322,15 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { cx: &CompilerCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::NullOp::*; + use rustc_middle::mir::RuntimeChecks::*; match self { OffsetOf(indices) => crate::mir::NullOp::OffsetOf( indices.iter().map(|idx| idx.stable(tables, cx)).collect(), ), - UbChecks => crate::mir::NullOp::UbChecks, - ContractChecks => crate::mir::NullOp::ContractChecks, + RuntimeChecks(op) => crate::mir::NullOp::RuntimeChecks(match op { + UbChecks => crate::mir::RuntimeChecks::UbChecks, + ContractChecks => crate::mir::RuntimeChecks::ContractChecks, + }), } } } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 90ea2616890a..0cf1ad348953 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,7 +194,7 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _) + Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::RuntimeChecks(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, cx.tcx); diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index fadbdf5cea99..393895fe1a46 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1329,13 +1329,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } #[inline(always)] - fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> { - interp_ok(ecx.tcx.sess.ub_checks()) - } - - #[inline(always)] - fn contract_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> { - interp_ok(ecx.tcx.sess.contract_checks()) + fn runtime_checks(ecx: &InterpCx<'tcx, Self>, r: mir::RuntimeChecks) -> InterpResult<'tcx, bool> { + interp_ok(r.value(&ecx.tcx.sess)) } #[inline(always)] From abd9fb44e08443a590ea91d37cff9783011fb323 Mon Sep 17 00:00:00 2001 From: hax0kartik Date: Sun, 26 Oct 2025 12:28:48 +0530 Subject: [PATCH 182/525] O_NOFOLLOW is not supported on VxWorks --- library/std/src/sys/fs/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index 74354227d84a..bc1052b6f8c5 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -122,7 +122,7 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { with_native_path(path, &|path| imp::set_perm(path, perm.clone())) } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "vxworks")))] pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { use crate::fs::OpenOptions; @@ -139,7 +139,7 @@ pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io options.open(path)?.set_permissions(perm) } -#[cfg(not(unix))] +#[cfg(any(not(unix), target_os = "vxworks"))] pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> { crate::unimplemented!( "`set_permissions_nofollow` is currently only implemented on Unix platforms" From ff138802a0a7bb5ef4dd96ab80407cfea20cca12 Mon Sep 17 00:00:00 2001 From: hax0kartik Date: Sun, 26 Oct 2025 15:45:24 +0530 Subject: [PATCH 183/525] Ignore unix socket related tests on VxWorks --- library/std/src/os/unix/net/tests.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs index 4666b5e3c6c1..d88c97113efe 100644 --- a/library/std/src/os/unix/net/tests.rs +++ b/library/std/src/os/unix/net/tests.rs @@ -24,6 +24,7 @@ macro_rules! or_panic { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn basic() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -51,6 +52,7 @@ fn basic() { } #[test] +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn vectored() { let (mut s1, mut s2) = or_panic!(UnixStream::pair()); @@ -71,6 +73,7 @@ fn vectored() { } #[test] +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn pair() { let msg1 = b"hello"; let msg2 = b"world!"; @@ -95,6 +98,7 @@ fn pair() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn try_clone() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -122,6 +126,7 @@ fn try_clone() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn iter() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -144,6 +149,7 @@ fn iter() { } #[test] +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn long_path() { let dir = tmpdir(); let socket_path = dir.path().join( @@ -173,6 +179,7 @@ fn long_path() { #[cfg(not(target_os = "nto"))] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn timeouts() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -202,6 +209,7 @@ fn timeouts() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_read_timeout() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -223,6 +231,7 @@ fn test_read_timeout() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_read_with_timeout() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -252,6 +261,7 @@ fn test_read_with_timeout() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_stream_timeout_zero_duration() { let dir = tmpdir(); let socket_path = dir.path().join("sock"); @@ -272,6 +282,7 @@ fn test_unix_stream_timeout_zero_duration() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram() { let dir = tmpdir(); let path1 = dir.path().join("sock1"); @@ -290,6 +301,7 @@ fn test_unix_datagram() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unnamed_unix_datagram() { let dir = tmpdir(); let path1 = dir.path().join("sock1"); @@ -308,6 +320,7 @@ fn test_unnamed_unix_datagram() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram_connect_to_recv_addr() { let dir = tmpdir(); let path1 = dir.path().join("sock1"); @@ -334,6 +347,7 @@ fn test_unix_datagram_connect_to_recv_addr() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_connect_unix_datagram() { let dir = tmpdir(); let path1 = dir.path().join("sock1"); @@ -361,6 +375,7 @@ fn test_connect_unix_datagram() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram_recv() { let dir = tmpdir(); let path1 = dir.path().join("sock1"); @@ -378,6 +393,7 @@ fn test_unix_datagram_recv() { } #[test] +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn datagram_pair() { let msg1 = b"hello"; let msg2 = b"world!"; @@ -404,6 +420,7 @@ fn datagram_pair() { // when passed zero Durations #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram_timeout_zero_duration() { let dir = tmpdir(); let path = dir.path().join("sock"); @@ -562,6 +579,7 @@ fn test_abstract_no_pathname_and_not_unnamed() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_stream_peek() { let (txdone, rxdone) = crate::sync::mpsc::channel(); @@ -595,6 +613,7 @@ fn test_unix_stream_peek() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram_peek() { let dir = tmpdir(); let path1 = dir.path().join("sock"); @@ -620,6 +639,7 @@ fn test_unix_datagram_peek() { #[test] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets +#[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] fn test_unix_datagram_peek_from() { let dir = tmpdir(); let path1 = dir.path().join("sock"); From e36689aea7a5153c50d9db4fe4955ba96033a592 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:18:22 +0000 Subject: [PATCH 184/525] Add FileCheck to branch.rs --- tests/mir-opt/copy-prop/branch.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/branch.rs b/tests/mir-opt/copy-prop/branch.rs index fc9b8dc41b16..a26e224fa708 100644 --- a/tests/mir-opt/copy-prop/branch.rs +++ b/tests/mir-opt/copy-prop/branch.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that we bail out when there are multiple assignments to the same local. //@ test-mir-pass: CopyProp @@ -12,6 +11,14 @@ fn cond() -> bool { // EMIT_MIR branch.foo.CopyProp.diff fn foo() -> i32 { + // CHECK-LABEL: fn foo( + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: bb3: { + // CHECK: [[y]] = copy [[x]]; + // CHECK: bb5: { + // CHECK: [[y]] = copy [[x]]; + // CHECK: _0 = copy [[y]]; let x = val(); let y = if cond() { From 3b1e20ce5d40640f35adb0f6714f5ced3a4b7288 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:18:40 +0000 Subject: [PATCH 185/525] Add FileCheck to calls.rs --- tests/mir-opt/copy-prop/calls.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/calls.rs b/tests/mir-opt/copy-prop/calls.rs index 8937c0d2ecb2..f19b114523d3 100644 --- a/tests/mir-opt/copy-prop/calls.rs +++ b/tests/mir-opt/copy-prop/calls.rs @@ -1,4 +1,3 @@ -// skip-filecheck // Check that CopyProp does propagate return values of call terminators. //@ test-mir-pass: CopyProp //@ needs-unwind @@ -13,6 +12,13 @@ fn dummy(x: u8) -> u8 { // EMIT_MIR calls.nrvo.CopyProp.diff fn nrvo() -> u8 { + // CHECK-LABEL: fn nrvo( + // CHECK: debug y => _0; + // CHECK-NOT: StorageLive(_1); + // CHECK-NOT: _1 = dummy(const 5_u8) + // CHECK: _0 = dummy(const 5_u8) + // CHECK-NOT: _0 = copy _1; + // CHECK-NOT: StorageDead(_1); let y = dummy(5); // this should get NRVO y } @@ -20,6 +26,11 @@ fn nrvo() -> u8 { // EMIT_MIR calls.multiple_edges.CopyProp.diff #[custom_mir(dialect = "runtime", phase = "initial")] fn multiple_edges(t: bool) -> u8 { + // CHECK-LABEL: fn multiple_edges( + // CHECK: bb1: { + // CHECK: _2 = dummy(const 13_u8) + // CHECK: bb2: { + // CHECK: _0 = copy _2; mir! { let x: u8; { From c204231d9685fd43d6e35b9d3865a9e9b6d9b07b Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:18:55 +0000 Subject: [PATCH 186/525] Add FileCheck to copy_propagation_arg.rs --- .../mir-opt/copy-prop/copy_propagation_arg.rs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.rs b/tests/mir-opt/copy-prop/copy_propagation_arg.rs index e062e1e97288..6c234c3aac0f 100644 --- a/tests/mir-opt/copy-prop/copy_propagation_arg.rs +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that CopyProp does not propagate an assignment to a function argument // (doing so can break usages of the original argument value) @@ -9,25 +8,46 @@ fn dummy(x: u8) -> u8 { // EMIT_MIR copy_propagation_arg.foo.CopyProp.diff fn foo(mut x: u8) { + // CHECK-LABEL: fn foo( + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[three:_.*]] = copy [[x]]; + // CHECK: [[two:_.*]] = dummy(move [[three]]) + // CHECK: [[x]] = move [[two]]; // calling `dummy` to make a use of `x` that copyprop cannot eliminate x = dummy(x); // this will assign a local to `x` } // EMIT_MIR copy_propagation_arg.bar.CopyProp.diff fn bar(mut x: u8) { + // CHECK-LABEL: fn bar( + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[three:_.*]] = copy [[x]]; + // CHECK: dummy(move [[three]]) + // CHECK: [[x]] = const 5_u8; dummy(x); x = 5; } // EMIT_MIR copy_propagation_arg.baz.CopyProp.diff fn baz(mut x: i32) -> i32 { - // self-assignment to a function argument should be eliminated + // CHECK-LABEL: fn baz( + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[x2:_.*]] = copy [[x]]; + // CHECK: [[x]] = move [[x2]]; + // CHECK: _0 = copy [[x]]; + // In the original case for DestProp, the self-assignment to a function argument is eliminated, + // but in CopyProp it is not eliminated. x = x; x } // EMIT_MIR copy_propagation_arg.arg_src.CopyProp.diff fn arg_src(mut x: i32) -> i32 { + // CHECK-LABEL: fn arg_src( + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: [[y]] = copy [[x]]; + // CHECK: [[x]] = const 123_i32; let y = x; x = 123; // Don't propagate this assignment to `y` y From 17b0d9036531ea67ed45efe4bb39b6ff0a597c40 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:19:16 +0000 Subject: [PATCH 187/525] Add FileCheck to custom_move_arg.rs --- tests/mir-opt/copy-prop/custom_move_arg.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs index 3dce7807b347..54490b07f32f 100644 --- a/tests/mir-opt/copy-prop/custom_move_arg.rs +++ b/tests/mir-opt/copy-prop/custom_move_arg.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //@ test-mir-pass: CopyProp @@ -12,6 +11,13 @@ struct NotCopy(bool); // EMIT_MIR custom_move_arg.f.CopyProp.diff #[custom_mir(dialect = "runtime")] fn f(_1: NotCopy) { + // CHECK-LABEL: fn f( + // CHECK: bb0: { + // CHECK-NOT: _2 = copy _1; + // CHECK: _0 = opaque::(copy _1) + // CHECK: bb1: { + // CHECK-NOT: _3 = move _2; + // CHECK: _0 = opaque::(copy _1) mir! { { let _2 = _1; From ff260c850c24a100fe5fa55d93fc6e4aef3b2186 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:19:29 +0000 Subject: [PATCH 188/525] Add FileCheck to cycle.rs --- tests/mir-opt/copy-prop/cycle.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/cycle.rs b/tests/mir-opt/copy-prop/cycle.rs index 1c0c9eae7fea..9f8312cc8fcd 100644 --- a/tests/mir-opt/copy-prop/cycle.rs +++ b/tests/mir-opt/copy-prop/cycle.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code. //@ test-mir-pass: CopyProp @@ -8,6 +7,18 @@ fn val() -> i32 { // EMIT_MIR cycle.main.CopyProp.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: debug z => [[y]]; + // CHECK-NOT: StorageLive([[y]]); + // CHECK: [[y]] = copy [[x]]; + // CHECK-NOT: StorageLive(_3); + // CHECK-NOT: _3 = copy [[y]]; + // CHECK-NOT: StorageLive(_4); + // CHECK-NOT: _4 = copy _3; + // CHECK-NOT: _1 = move _4; + // CHECK: [[x]] = copy [[y]]; let mut x = val(); let y = x; let z = y; From 109870df2c9cde6e342cd85b8d6a0d08fb3cf1df Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:19:48 +0000 Subject: [PATCH 189/525] Add FileCheck to dead_stores_79191.rs --- tests/mir-opt/copy-prop/dead_stores_79191.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.rs b/tests/mir-opt/copy-prop/dead_stores_79191.rs index 24420e19fa80..016680b9530a 100644 --- a/tests/mir-opt/copy-prop/dead_stores_79191.rs +++ b/tests/mir-opt/copy-prop/dead_stores_79191.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //@ test-mir-pass: CopyProp @@ -8,6 +7,14 @@ fn id(x: T) -> T { // EMIT_MIR dead_stores_79191.f.CopyProp.after.mir fn f(mut a: usize) -> usize { + // CHECK-LABEL: fn f( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: [[b]] = copy [[a]]; + // CHECK: [[a]] = const 5_usize; + // CHECK: [[a]] = copy [[b]]; + // CHECK: [[c:_.*]] = copy [[a]] + // CHECK: id::(move [[c]]) let b = a; a = 5; a = b; From 76dc555dc900b6b8a5fa82bea57d45ebe4d8e981 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 11:20:00 +0000 Subject: [PATCH 190/525] remove dead_stores_better.rs As we discussed, it is identical with dead_stores_79191 --- ...es_better.f.CopyProp.after.panic-abort.mir | 26 ------------------- ...s_better.f.CopyProp.after.panic-unwind.mir | 26 ------------------- tests/mir-opt/copy-prop/dead_stores_better.rs | 23 ---------------- 3 files changed, 75 deletions(-) delete mode 100644 tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir delete mode 100644 tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir delete mode 100644 tests/mir-opt/copy-prop/dead_stores_better.rs diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir deleted file mode 100644 index 4781fdfd902a..000000000000 --- a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-abort.mir +++ /dev/null @@ -1,26 +0,0 @@ -// MIR for `f` after CopyProp - -fn f(_1: usize) -> usize { - debug a => _1; - let mut _0: usize; - let _2: usize; - let mut _3: usize; - let mut _4: usize; - scope 1 { - debug b => _2; - } - - bb0: { - _2 = copy _1; - _1 = const 5_usize; - _1 = copy _2; - StorageLive(_4); - _4 = copy _1; - _0 = id::(move _4) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_4); - return; - } -} diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir deleted file mode 100644 index f5fded45c13b..000000000000 --- a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.panic-unwind.mir +++ /dev/null @@ -1,26 +0,0 @@ -// MIR for `f` after CopyProp - -fn f(_1: usize) -> usize { - debug a => _1; - let mut _0: usize; - let _2: usize; - let mut _3: usize; - let mut _4: usize; - scope 1 { - debug b => _2; - } - - bb0: { - _2 = copy _1; - _1 = const 5_usize; - _1 = copy _2; - StorageLive(_4); - _4 = copy _1; - _0 = id::(move _4) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_4); - return; - } -} diff --git a/tests/mir-opt/copy-prop/dead_stores_better.rs b/tests/mir-opt/copy-prop/dead_stores_better.rs deleted file mode 100644 index 4b1874294016..000000000000 --- a/tests/mir-opt/copy-prop/dead_stores_better.rs +++ /dev/null @@ -1,23 +0,0 @@ -// skip-filecheck -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates -// that that pass enables this one to do more optimizations. - -//@ test-mir-pass: CopyProp -//@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination - -fn id(x: T) -> T { - x -} - -// EMIT_MIR dead_stores_better.f.CopyProp.after.mir -pub fn f(mut a: usize) -> usize { - let b = a; - a = 5; - a = b; - id(a) -} - -fn main() { - f(0); -} From dd2d3908769b3e77abfbd08d577fbba2cb6b3416 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:03 +0000 Subject: [PATCH 191/525] Add FileCheck to issue_107511.rs --- tests/mir-opt/copy-prop/issue_107511.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/issue_107511.rs b/tests/mir-opt/copy-prop/issue_107511.rs index 5e8fc8df42e2..d345d2db2b7d 100644 --- a/tests/mir-opt/copy-prop/issue_107511.rs +++ b/tests/mir-opt/copy-prop/issue_107511.rs @@ -1,9 +1,12 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //@ test-mir-pass: CopyProp // EMIT_MIR issue_107511.main.CopyProp.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: debug i => [[i:_.*]]; + // CHECK-NOT: StorageLive([[i]]); + // CHECK-NOT: StorageDead([[i]]); let mut sum = 0; let a = [0, 10, 20, 30]; From 13e971e532b221d87cc8f0dc4e44a78a3d54e9e0 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:22 +0000 Subject: [PATCH 192/525] Add FileCheck to move_arg.rs --- tests/mir-opt/copy-prop/move_arg.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/move_arg.rs b/tests/mir-opt/copy-prop/move_arg.rs index 498340534324..b7adae333196 100644 --- a/tests/mir-opt/copy-prop/move_arg.rs +++ b/tests/mir-opt/copy-prop/move_arg.rs @@ -1,10 +1,13 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Test that we do not move multiple times from the same local. //@ test-mir-pass: CopyProp // EMIT_MIR move_arg.f.CopyProp.diff pub fn f(a: T) { + // CHECK-LABEL: fn f( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[a]]; + // CHECK: g::(copy [[a]], copy [[a]]) let b = a; g(a, b); } From 3d12668f211bd37ef35b3595bd5dc1bfa6ce650f Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:33 +0000 Subject: [PATCH 193/525] Add FileCheck to move_projection.rs --- tests/mir-opt/copy-prop/move_projection.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/move_projection.rs b/tests/mir-opt/copy-prop/move_projection.rs index 0ac1c4e0ba26..73473ee749f8 100644 --- a/tests/mir-opt/copy-prop/move_projection.rs +++ b/tests/mir-opt/copy-prop/move_projection.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //@ test-mir-pass: CopyProp @@ -15,6 +14,15 @@ struct Foo(u8); #[custom_mir(dialect = "runtime")] fn f(a: Foo) -> bool { + // CHECK-LABEL: fn f( + // CHECK-SAME: [[a:_.*]]: Foo) + // CHECK: bb0: { + // CHECK-NOT: _2 = copy [[a]]; + // CHECK-NOT: _3 = move (_2.0: u8); + // CHECK: [[c:_.*]] = copy ([[a]].0: u8); + // CHECK: _0 = opaque::(copy [[a]]) + // CHECK: bb1: { + // CHECK: _0 = opaque::(move [[c]]) mir! { { let b = a; From 6eaf4fedcff2884f7df72a7249423033abfba58b Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:41 +0000 Subject: [PATCH 194/525] Add FileCheck to mutate_through_pointer.rs --- tests/mir-opt/copy-prop/mutate_through_pointer.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs index 53cca045248d..7523da8a292e 100644 --- a/tests/mir-opt/copy-prop/mutate_through_pointer.rs +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ test-mir-pass: CopyProp // // This attempts to mutate `a` via a pointer derived from `addr_of!(a)`. That is UB @@ -18,6 +17,10 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn f(c: bool) -> bool { + // CHECK-LABEL: fn f( + // CHECK: _2 = copy _1; + // CHECK-NOT: _3 = &raw const _1; + // CHECK: _3 = &raw const _2; mir! { { let a = c; From aa83f1799b486beca16cc21c72af906d6cee5097 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:50 +0000 Subject: [PATCH 195/525] Add FileCheck to non_dominate.rs --- tests/mir-opt/copy-prop/non_dominate.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/non_dominate.rs b/tests/mir-opt/copy-prop/non_dominate.rs index c01275370ea7..a6db10c461f5 100644 --- a/tests/mir-opt/copy-prop/non_dominate.rs +++ b/tests/mir-opt/copy-prop/non_dominate.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ test-mir-pass: CopyProp #![feature(custom_mir, core_intrinsics)] @@ -8,6 +7,11 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn f(c: bool) -> bool { + // CHECK-LABEL: fn f( + // CHECK: bb2: { + // CHECK: _2 = copy _3; + // CHECK: bb3: { + // CHECK: _0 = copy _2; mir! { let a: bool; let b: bool; From 8ae4d57afb72594fc2ede4aad8a97c65c02f3b23 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:40:56 +0000 Subject: [PATCH 196/525] Add FileCheck to partial_init.rs --- tests/mir-opt/copy-prop/partial_init.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/partial_init.rs b/tests/mir-opt/copy-prop/partial_init.rs index 88e94988181d..0135d7c321b8 100644 --- a/tests/mir-opt/copy-prop/partial_init.rs +++ b/tests/mir-opt/copy-prop/partial_init.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ test-mir-pass: CopyProp // Verify that we do not ICE on partial initializations. @@ -9,6 +8,9 @@ use core::intrinsics::mir::*; // EMIT_MIR partial_init.main.CopyProp.diff #[custom_mir(dialect = "runtime", phase = "post-cleanup")] pub fn main() { + // CHECK-LABEL: fn main( + // CHECK: let mut [[x:_.*]]: (isize,); + // CHECK: ([[x]].0: isize) = const 1_isize; mir! ( let x: (isize, ); { From 620b9b15cd9c8cba3542761b550e20b7298359b8 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 4 Jan 2025 12:41:01 +0000 Subject: [PATCH 197/525] Add FileCheck to reborrow.rs --- tests/mir-opt/copy-prop/reborrow.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/copy-prop/reborrow.rs b/tests/mir-opt/copy-prop/reborrow.rs index 51a1f92cde2f..8bc81106e994 100644 --- a/tests/mir-opt/copy-prop/reborrow.rs +++ b/tests/mir-opt/copy-prop/reborrow.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that CopyProp considers reborrows as not mutating the pointer. //@ test-mir-pass: CopyProp @@ -8,6 +7,9 @@ fn opaque(_: impl Sized) {} // EMIT_MIR reborrow.remut.CopyProp.diff fn remut(mut x: u8) { + // CHECK-LABEL: fn remut( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug c => [[a]]; let a = &mut x; let b = &mut *a; //< this cannot mutate a. let c = a; //< so `c` and `a` can be merged. @@ -16,6 +18,9 @@ fn remut(mut x: u8) { // EMIT_MIR reborrow.reraw.CopyProp.diff fn reraw(mut x: u8) { + // CHECK-LABEL: fn reraw( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug c => [[a]]; let a = &mut x; let b = &raw mut *a; //< this cannot mutate a. let c = a; //< so `c` and `a` can be merged. @@ -24,6 +29,9 @@ fn reraw(mut x: u8) { // EMIT_MIR reborrow.miraw.CopyProp.diff fn miraw(mut x: u8) { + // CHECK-LABEL: fn miraw( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug c => [[a]]; let a = &raw mut x; let b = unsafe { &raw mut *a }; //< this cannot mutate a. let c = a; //< so `c` and `a` can be merged. @@ -32,6 +40,9 @@ fn miraw(mut x: u8) { // EMIT_MIR reborrow.demiraw.CopyProp.diff fn demiraw(mut x: u8) { + // CHECK-LABEL: fn demiraw( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug c => [[a]]; let a = &raw mut x; let b = unsafe { &mut *a }; //< this cannot mutate a. let c = a; //< so `c` and `a` can be merged. From c4d6b0b8ea2a0c3e5520639722fa5a9b66a7aecb Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 9 Oct 2025 17:02:26 +0530 Subject: [PATCH 198/525] Implement `simd_fma` and `simd_relaxed_fma` in const-eval --- .../src/interpret/intrinsics.rs | 70 ++++++++++++------- .../src/interpret/intrinsics/simd.rs | 42 ++++++++++- .../rustc_const_eval/src/interpret/machine.rs | 4 +- src/tools/miri/src/intrinsics/simd.rs | 58 --------------- src/tools/miri/src/machine.rs | 4 +- 5 files changed, 88 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index f0f06d469c1e..f0712644465a 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -25,6 +25,15 @@ use super::{ }; use crate::fluent_generated as fluent; +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum MulAddType { + /// Used with `fma` and `simd_fma`, always uses fused-multiply-add + Fused, + /// Used with `fmuladd` and `simd_relaxed_fma`, nondeterministically determines whether to use + /// fma or simple multiply-add + Nondeterministic, +} + /// Directly returns an `Allocation` containing an absolute path representation of the given type. pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, u64) { let path = crate::util::type_name(tcx, ty); @@ -630,14 +639,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dest, rustc_apfloat::Round::NearestTiesToEven, )?, - sym::fmaf16 => self.fma_intrinsic::(args, dest)?, - sym::fmaf32 => self.fma_intrinsic::(args, dest)?, - sym::fmaf64 => self.fma_intrinsic::(args, dest)?, - sym::fmaf128 => self.fma_intrinsic::(args, dest)?, - sym::fmuladdf16 => self.float_muladd_intrinsic::(args, dest)?, - sym::fmuladdf32 => self.float_muladd_intrinsic::(args, dest)?, - sym::fmuladdf64 => self.float_muladd_intrinsic::(args, dest)?, - sym::fmuladdf128 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmaf16 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, + sym::fmaf32 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, + sym::fmaf64 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, + sym::fmaf128 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, + sym::fmuladdf16 => { + self.float_muladd_intrinsic::(args, dest, MulAddType::Nondeterministic)? + } + sym::fmuladdf32 => { + self.float_muladd_intrinsic::(args, dest, MulAddType::Nondeterministic)? + } + sym::fmuladdf64 => { + self.float_muladd_intrinsic::(args, dest, MulAddType::Nondeterministic)? + } + sym::fmuladdf128 => { + self.float_muladd_intrinsic::(args, dest, MulAddType::Nondeterministic)? + } // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), @@ -1038,40 +1055,41 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } - fn fma_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> + fn float_muladd( + &self, + a: Scalar, + b: Scalar, + c: Scalar, + typ: MulAddType, + ) -> InterpResult<'tcx, Scalar> where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let c: F = self.read_scalar(&args[2])?.to_float()?; + let a: F = a.to_float()?; + let b: F = b.to_float()?; + let c: F = c.to_float()?; - let res = a.mul_add(b, c).value; + let fuse = typ == MulAddType::Fused || M::float_fuse_mul_add(self); + + let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value }; let res = self.adjust_nan(res, &[a, b, c]); - self.write_scalar(res, dest)?; - interp_ok(()) + interp_ok(res.into()) } fn float_muladd_intrinsic( &mut self, args: &[OpTy<'tcx, M::Provenance>], dest: &PlaceTy<'tcx, M::Provenance>, + typ: MulAddType, ) -> InterpResult<'tcx, ()> where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let c: F = self.read_scalar(&args[2])?.to_float()?; + let a = self.read_scalar(&args[0])?; + let b = self.read_scalar(&args[1])?; + let c = self.read_scalar(&args[2])?; - let fuse = M::float_fuse_mul_add(self); - - let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value }; - let res = self.adjust_nan(res, &[a, b, c]); + let res = self.float_muladd::(a, b, c, typ)?; self.write_scalar(res, dest)?; interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 0dba66ae9372..84489028e190 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -1,5 +1,6 @@ use either::Either; use rustc_abi::Endian; +use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::{Float, Round}; use rustc_middle::mir::interpret::{InterpErrorKind, UndefinedBehaviorInfo}; use rustc_middle::ty::FloatTy; @@ -8,8 +9,8 @@ use rustc_span::{Symbol, sym}; use tracing::trace; use super::{ - ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Provenance, Scalar, Size, interp_ok, - throw_ub_format, + ImmTy, InterpCx, InterpResult, Machine, MulAddType, OpTy, PlaceTy, Provenance, Scalar, Size, + interp_ok, throw_ub_format, }; use crate::interpret::Writeable; @@ -701,6 +702,43 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; } } + sym::simd_fma | sym::simd_relaxed_fma => { + // `simd_fma` should always deterministically use `mul_add`, whereas `relaxed_fma` + // is non-deterministic, and can use either `mul_add` or `a * b + c` + let typ = match intrinsic_name { + sym::simd_fma => MulAddType::Fused, + sym::simd_relaxed_fma => MulAddType::Nondeterministic, + _ => unreachable!(), + }; + + let (a, a_len) = self.project_to_simd(&args[0])?; + let (b, b_len) = self.project_to_simd(&args[1])?; + let (c, c_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, a_len); + assert_eq!(dest_len, b_len); + assert_eq!(dest_len, c_len); + + for i in 0..dest_len { + let a = self.read_scalar(&self.project_index(&a, i)?)?; + let b = self.read_scalar(&self.project_index(&b, i)?)?; + let c = self.read_scalar(&self.project_index(&c, i)?)?; + let dest = self.project_index(&dest, i)?; + + let ty::Float(float_ty) = dest.layout.ty.kind() else { + span_bug!(self.cur_span(), "{} operand is not a float", intrinsic_name) + }; + + let val = match float_ty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => self.float_muladd::(a, b, c, typ)?, + FloatTy::F64 => self.float_muladd::(a, b, c, typ)?, + FloatTy::F128 => unimplemented!("f16_f128"), + }; + self.write_scalar(val, &dest)?; + } + } // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 1725635e0b47..236c35ec7b96 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -290,7 +290,7 @@ pub trait Machine<'tcx>: Sized { } /// Determines whether the `fmuladd` intrinsics fuse the multiply-add or use separate operations. - fn float_fuse_mul_add(_ecx: &mut InterpCx<'tcx, Self>) -> bool; + fn float_fuse_mul_add(_ecx: &InterpCx<'tcx, Self>) -> bool; /// Called before a basic block terminator is executed. #[inline] @@ -676,7 +676,7 @@ pub macro compile_time_machine(<$tcx: lifetime>) { } #[inline(always)] - fn float_fuse_mul_add(_ecx: &mut InterpCx<$tcx, Self>) -> bool { + fn float_fuse_mul_add(_ecx: &InterpCx<$tcx, Self>) -> bool { true } diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 1e7366b5a826..2b176093cb36 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -1,5 +1,3 @@ -use rand::Rng; -use rustc_apfloat::Float; use rustc_middle::ty; use rustc_middle::ty::FloatTy; @@ -83,62 +81,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(val, &dest)?; } } - "fma" | "relaxed_fma" => { - let [a, b, c] = check_intrinsic_arg_count(args)?; - let (a, a_len) = this.project_to_simd(a)?; - let (b, b_len) = this.project_to_simd(b)?; - let (c, c_len) = this.project_to_simd(c)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(dest_len, a_len); - assert_eq!(dest_len, b_len); - assert_eq!(dest_len, c_len); - - for i in 0..dest_len { - let a = this.read_scalar(&this.project_index(&a, i)?)?; - let b = this.read_scalar(&this.project_index(&b, i)?)?; - let c = this.read_scalar(&this.project_index(&c, i)?)?; - let dest = this.project_index(&dest, i)?; - - let fuse: bool = intrinsic_name == "fma" - || (this.machine.float_nondet && this.machine.rng.get_mut().random()); - - // Works for f32 and f64. - // FIXME: using host floats to work around https://github.com/rust-lang/miri/issues/2468. - let ty::Float(float_ty) = dest.layout.ty.kind() else { - span_bug!(this.cur_span(), "{} operand is not a float", intrinsic_name) - }; - let val = match float_ty { - FloatTy::F16 => unimplemented!("f16_f128"), - FloatTy::F32 => { - let a = a.to_f32()?; - let b = b.to_f32()?; - let c = c.to_f32()?; - let res = if fuse { - a.mul_add(b, c).value - } else { - ((a * b).value + c).value - }; - let res = this.adjust_nan(res, &[a, b, c]); - Scalar::from(res) - } - FloatTy::F64 => { - let a = a.to_f64()?; - let b = b.to_f64()?; - let c = c.to_f64()?; - let res = if fuse { - a.mul_add(b, c).value - } else { - ((a * b).value + c).value - }; - let res = this.adjust_nan(res, &[a, b, c]); - Scalar::from(res) - } - FloatTy::F128 => unimplemented!("f16_f128"), - }; - this.write_scalar(val, &dest)?; - } - } "expose_provenance" => { let [op] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index fadbdf5cea99..da90f6b84664 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1324,8 +1324,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } #[inline(always)] - fn float_fuse_mul_add(ecx: &mut InterpCx<'tcx, Self>) -> bool { - ecx.machine.float_nondet && ecx.machine.rng.get_mut().random() + fn float_fuse_mul_add(ecx: &InterpCx<'tcx, Self>) -> bool { + ecx.machine.float_nondet && ecx.machine.rng.borrow_mut().random() } #[inline(always)] From 727da8c4238ca97b28ae3c8a17e09e5d8c9fba8d Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Mon, 13 Oct 2025 00:40:17 +0000 Subject: [PATCH 199/525] Cache the set of string constants for suggestions. --- compiler/rustc_mir_transform/src/liveness.rs | 81 ++++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 82f9dfe4745d..a5fdcb0469f0 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -164,45 +164,6 @@ fn is_capture(place: PlaceRef<'_>) -> bool { } } -/// Give a diagnostic when any of the string constants look like a naked format string that would -/// interpolate our dead local. -fn maybe_suggest_literal_matching_name( - body: &Body<'_>, - name: Symbol, -) -> Vec { - struct LiteralFinder<'body, 'tcx> { - body: &'body Body<'tcx>, - name: String, - name_colon: String, - found: Vec, - } - - impl<'tcx> Visitor<'tcx> for LiteralFinder<'_, 'tcx> { - fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, loc: Location) { - if let ty::Ref(_, ref_ty, _) = constant.ty().kind() - && ref_ty.kind() == &ty::Str - { - let rendered_constant = constant.const_.to_string(); - if rendered_constant.contains(&self.name) - || rendered_constant.contains(&self.name_colon) - { - let lit = self.body.source_info(loc).span; - self.found.push(errors::UnusedVariableStringInterp { lit }); - } - } - } - } - - let mut finder = LiteralFinder { - body, - name: format!("{{{name}}}"), - name_colon: format!("{{{name}:"), - found: vec![], - }; - finder.visit_body(body); - finder.found -} - /// Give a diagnostic when an unused variable may be a typo of a unit variant or a struct. fn maybe_suggest_unit_pattern_typo<'tcx>( tcx: TyCtxt<'tcx>, @@ -879,6 +840,44 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> { fn report_fully_unused(&mut self) { let tcx = self.tcx; + // Give a diagnostic when any of the string constants look like a naked format string that + // would interpolate our dead local. + let mut string_constants_in_body = None; + let mut maybe_suggest_literal_matching_name = |name: Symbol| { + // Visiting MIR to enumerate string constants can be expensive, so cache the result. + let string_constants_in_body = string_constants_in_body.get_or_insert_with(|| { + struct LiteralFinder { + found: Vec<(Span, String)>, + } + + impl<'tcx> Visitor<'tcx> for LiteralFinder { + fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, _: Location) { + if let ty::Ref(_, ref_ty, _) = constant.ty().kind() + && ref_ty.kind() == &ty::Str + { + let rendered_constant = constant.const_.to_string(); + self.found.push((constant.span, rendered_constant)); + } + } + } + + let mut finder = LiteralFinder { found: vec![] }; + finder.visit_body(self.body); + finder.found + }); + + let brace_name = format!("{{{name}"); + string_constants_in_body + .iter() + .filter(|(_, rendered_constant)| { + rendered_constant + .split(&brace_name) + .any(|c| matches!(c.chars().next(), Some('}' | ':'))) + }) + .map(|&(lit, _)| errors::UnusedVariableStringInterp { lit }) + .collect::>() + }; + // First, report fully unused locals. for (index, place) in self.checked_places.iter() { if self.ever_live.contains(index) { @@ -940,7 +939,7 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> { def_span, errors::UnusedVariable { name, - string_interp: maybe_suggest_literal_matching_name(self.body, name), + string_interp: maybe_suggest_literal_matching_name(name), sugg, }, ); @@ -1030,7 +1029,7 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> { spans, errors::UnusedVariable { name, - string_interp: maybe_suggest_literal_matching_name(self.body, name), + string_interp: maybe_suggest_literal_matching_name(name), sugg, }, ); From 0246980060943f14fe9820d92b18d744162ab63d Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 27 Oct 2025 15:25:53 +0800 Subject: [PATCH 200/525] Fix not applicable on while for replace_is_method_with_if_let_method Example --- ```rust fn main() { let mut x = Some(1); while x.is_som$0e() { x = None } } ``` **Before this PR** Assist not applicable **After this PR** ```rust fn main() { let mut x = Some(1); while let Some(${0:x1}) = x { x = None } } ``` --- .../replace_is_method_with_if_let_method.rs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs index c57fd4d439dc..5a2307739cff 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs @@ -1,3 +1,4 @@ +use either::Either; use ide_db::syntax_helpers::suggest_name; use syntax::ast::{self, AstNode, syntax_factory::SyntaxFactory}; @@ -24,9 +25,9 @@ pub(crate) fn replace_is_method_with_if_let_method( acc: &mut Assists, ctx: &AssistContext<'_>, ) -> Option<()> { - let if_expr = ctx.find_node_at_offset::()?; + let has_cond = ctx.find_node_at_offset::>()?; - let cond = if_expr.condition()?; + let cond = either::for_both!(&has_cond, it => it.condition())?; let cond = cover_let_chain(cond, ctx.selection_trimmed())?; let call_expr = match cond { ast::Expr::MethodCallExpr(call) => call, @@ -39,7 +40,7 @@ pub(crate) fn replace_is_method_with_if_let_method( let receiver = call_expr.receiver()?; let mut name_generator = suggest_name::NameGenerator::new_from_scope_locals( - ctx.sema.scope(if_expr.syntax()), + ctx.sema.scope(has_cond.syntax()), ); let var_name = if let ast::Expr::PathExpr(path_expr) = receiver.clone() { name_generator.suggest_name(&path_expr.path()?.to_string()) @@ -48,9 +49,9 @@ pub(crate) fn replace_is_method_with_if_let_method( }; let (assist_id, message, text) = if name_ref.text() == "is_some" { - ("replace_is_some_with_if_let_some", "Replace `is_some` with `if let Some`", "Some") + ("replace_is_some_with_if_let_some", "Replace `is_some` with `let Some`", "Some") } else { - ("replace_is_ok_with_if_let_ok", "Replace `is_ok` with `if let Ok`", "Ok") + ("replace_is_ok_with_if_let_ok", "Replace `is_ok` with `let Ok`", "Ok") }; acc.add( @@ -250,6 +251,25 @@ fn main() { ); } + #[test] + fn replace_is_some_with_while_let_some() { + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let mut x = Some(1); + while x.is_som$0e() { x = None } +} +"#, + r#" +fn main() { + let mut x = Some(1); + while let Some(${0:x1}) = x { x = None } +} +"#, + ); + } + #[test] fn replace_is_some_with_if_let_some_not_applicable_after_l_curly() { check_assist_not_applicable( From 0c7ff008304cded2d82b156f815d14dcb9281db7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Oct 2025 14:40:36 +0100 Subject: [PATCH 201/525] add -Zmiri-user-relevant-crates --- src/tools/miri/README.md | 6 ++++++ src/tools/miri/src/bin/miri.rs | 2 ++ src/tools/miri/src/eval.rs | 3 +++ src/tools/miri/src/helpers.rs | 21 +------------------- src/tools/miri/src/machine.rs | 35 ++++++++++++++++++++++++++++------ 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index d47967c0a4d3..878319415808 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -373,6 +373,12 @@ environment variable. We first document the most relevant and most commonly used ensure alignment. (The standard library `align_to` method works fine in both modes; under symbolic alignment it only fills the middle slice when the allocation guarantees sufficient alignment.) +* `-Zmiri-user-relevant-crates=,,...` extends the list of crates that Miri considers + "user-relevant". This affects the rendering of backtraces (for user-relevant crates, Miri shows + not just the function name but the actual code) and it affects the spans collected for data races + and aliasing violations (where Miri will show the span of the topmost non-`#[track_caller]` frame + in a user-relevant crate). When using `cargo miri`, the crates in the local workspace are always + considered user-relevant. The remaining flags are for advanced use only, and more likely to change or be removed. Some of these are **unsound**, which means they can lead diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 40ad571fe1ab..6ef6e340b3d9 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -710,6 +710,8 @@ fn main() { fatal_error!("-Zmiri-force-page-size requires a power of 2: {page_size}"); }; miri_config.page_size = Some(page_size); + } else if let Some(param) = arg.strip_prefix("-Zmiri-user-relevant-crates=") { + miri_config.user_relevant_crates.extend(param.split(',').map(|s| s.to_owned())); } else { // Forward to rustc. rustc_args.push(arg); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 82ca38c3752b..20b506bad91e 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -115,6 +115,8 @@ pub struct MiriConfig { pub float_rounding_error: FloatRoundingErrorMode, /// Whether Miri artifically introduces short reads/writes on file descriptors. pub short_fd_operations: bool, + /// A list of crates that are considered user-relevant. + pub user_relevant_crates: Vec, } impl Default for MiriConfig { @@ -158,6 +160,7 @@ impl Default for MiriConfig { float_nondet: true, float_rounding_error: FloatRoundingErrorMode::Random, short_fd_operations: true, + user_relevant_crates: vec![], } } } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index ab2804fae0d7..769e501c4533 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1091,7 +1091,7 @@ impl<'tcx> MiriMachine<'tcx> { /// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`. pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool { let def_id = frame.instance().def_id(); - (def_id.is_local() || self.local_crates.contains(&def_id.krate)) + (def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)) && !frame.instance().def.requires_caller_location(self.tcx) } } @@ -1102,25 +1102,6 @@ pub fn isolation_abort_error<'tcx>(name: &str) -> InterpResult<'tcx> { ))) } -/// Retrieve the list of local crates that should have been passed by cargo-miri in -/// MIRI_LOCAL_CRATES and turn them into `CrateNum`s. -pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec { - // Convert the local crate names from the passed-in config into CrateNums so that they can - // be looked up quickly during execution - let local_crate_names = std::env::var("MIRI_LOCAL_CRATES") - .map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::>()) - .unwrap_or_default(); - let mut local_crates = Vec::new(); - for &crate_num in tcx.crates(()) { - let name = tcx.crate_name(crate_num); - let name = name.as_str(); - if local_crate_names.iter().any(|local_name| local_name == name) { - local_crates.push(crate_num); - } - } - local_crates -} - pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar { // SIMD uses all-1 as pattern for "true". In two's complement, // -1 has all its bits set to one and `from_int` will truncate or diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index fadbdf5cea99..1482ca0c345a 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -580,8 +580,8 @@ pub struct MiriMachine<'tcx> { /// Equivalent setting as RUST_BACKTRACE on encountering an error. pub(crate) backtrace_style: BacktraceStyle, - /// Crates which are considered local for the purposes of error reporting. - pub(crate) local_crates: Vec, + /// Crates which are considered user-relevant for the purposes of error reporting. + pub(crate) user_relevant_crates: Vec, /// Mapping extern static names to their pointer. extern_statics: FxHashMap, @@ -684,7 +684,7 @@ impl<'tcx> MiriMachine<'tcx> { genmc_ctx: Option>, ) -> Self { let tcx = layout_cx.tcx(); - let local_crates = helpers::get_local_crates(tcx); + let user_relevant_crates = Self::get_user_relevant_crates(tcx, config); let layouts = PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types"); let profiler = config.measureme_out.as_ref().map(|out| { @@ -774,7 +774,7 @@ impl<'tcx> MiriMachine<'tcx> { string_cache: Default::default(), exported_symbols_cache: FxHashMap::default(), backtrace_style: config.backtrace_style, - local_crates, + user_relevant_crates, extern_statics: FxHashMap::default(), rng: RefCell::new(rng), allocator: (!config.native_lib.is_empty()) @@ -865,6 +865,29 @@ impl<'tcx> MiriMachine<'tcx> { symbols } + /// Retrieve the list of user-relevant crates based on MIRI_LOCAL_CRATES as set by cargo-miri, + /// and extra crates set in the config. + fn get_user_relevant_crates(tcx: TyCtxt<'_>, config: &MiriConfig) -> Vec { + // Convert the local crate names from the passed-in config into CrateNums so that they can + // be looked up quickly during execution + let local_crate_names = std::env::var("MIRI_LOCAL_CRATES") + .map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::>()) + .unwrap_or_default(); + let mut local_crates = Vec::new(); + for &crate_num in tcx.crates(()) { + let name = tcx.crate_name(crate_num); + let name = name.as_str(); + if local_crate_names + .iter() + .chain(&config.user_relevant_crates) + .any(|local_name| local_name == name) + { + local_crates.push(crate_num); + } + } + local_crates + } + pub(crate) fn late_init( ecx: &mut MiriInterpCx<'tcx>, config: &MiriConfig, @@ -889,7 +912,7 @@ impl<'tcx> MiriMachine<'tcx> { /// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate. pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool { let def_id = frame.instance.def_id(); - def_id.is_local() || self.local_crates.contains(&def_id.krate) + def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate) } /// Called when the interpreter is going to shut down abnormally, such as due to a Ctrl-C. @@ -1006,7 +1029,7 @@ impl VisitProvenance for MiriMachine<'_> { string_cache: _, exported_symbols_cache: _, backtrace_style: _, - local_crates: _, + user_relevant_crates: _, rng: _, allocator: _, tracked_alloc_ids: _, From ca3e640f991081834db613ae4154daed4d734e81 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 24 Oct 2025 12:03:45 +0200 Subject: [PATCH 202/525] add tool to check sembr --- src/doc/rustc-dev-guide/.gitignore | 1 + src/doc/rustc-dev-guide/ci/sembr/Cargo.lock | 466 +++++++++++++++++++ src/doc/rustc-dev-guide/ci/sembr/Cargo.toml | 16 + src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 254 ++++++++++ 4 files changed, 737 insertions(+) create mode 100644 src/doc/rustc-dev-guide/ci/sembr/Cargo.lock create mode 100644 src/doc/rustc-dev-guide/ci/sembr/Cargo.toml create mode 100644 src/doc/rustc-dev-guide/ci/sembr/src/main.rs diff --git a/src/doc/rustc-dev-guide/.gitignore b/src/doc/rustc-dev-guide/.gitignore index f03fcae753f4..f2e57fc68ffb 100644 --- a/src/doc/rustc-dev-guide/.gitignore +++ b/src/doc/rustc-dev-guide/.gitignore @@ -1,6 +1,7 @@ book ci/date-check/target/ +ci/sembr/target/ # Generated by check-in.sh pulls.json diff --git a/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock b/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock new file mode 100644 index 000000000000..1e690cc7f1e7 --- /dev/null +++ b/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock @@ -0,0 +1,466 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "clap" +version = "4.5.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ignore" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "imara-diff" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c" +dependencies = [ + "hashbrown", + "memchr", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sembr" +version = "0.0.0" +dependencies = [ + "anyhow", + "clap", + "ignore", + "imara-diff", + "regex", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" diff --git a/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml b/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml new file mode 100644 index 000000000000..00818e2b3c2d --- /dev/null +++ b/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sembr" +edition = "2024" + +[dependencies] +anyhow = "1" +ignore = "0.4" +imara-diff = "0.2" + +[dependencies.regex] +version = "1" +features = ["pattern"] + +[dependencies.clap] +version = "4" +features = ["derive"] diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs new file mode 100644 index 000000000000..6b3753d8b82f --- /dev/null +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -0,0 +1,254 @@ +use std::path::PathBuf; +use std::sync::LazyLock; +use std::{fs, process}; + +use anyhow::Result; +use clap::Parser; +use ignore::Walk; +use imara_diff::{Algorithm, BasicLineDiffPrinter, Diff, InternedInput, UnifiedDiffConfig}; +use regex::Regex; + +#[derive(Parser)] +struct Cli { + root_dir: PathBuf, + #[arg(long)] + overwrite: bool, + #[arg(long, default_value_t = 100)] + line_length_limit: usize, + #[arg(long)] + show_diff: bool, +} + +static REGEX_IGNORE: LazyLock = LazyLock::new(|| Regex::new(r"(\d\.|\-|\*)\s+").unwrap()); +static REGEX_IGNORE_END: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)$").unwrap()); +static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)\s+").unwrap()); + +fn main() -> Result<()> { + let cli = Cli::parse(); + let mut compliant = Vec::new(); + let mut not_compliant = Vec::new(); + let mut made_compliant = Vec::new(); + for result in Walk::new(cli.root_dir) { + let entry = result?; + if entry.file_type().expect("no stdin").is_dir() { + continue; + } + let path = entry.into_path(); + if let Some(extension) = path.extension() { + if extension != "md" { + continue; + } + let old = fs::read_to_string(&path)?; + let new = lengthen_lines(&comply(&old), cli.line_length_limit); + if new == old { + compliant.push(path.clone()); + } else if cli.overwrite { + fs::write(&path, new)?; + made_compliant.push(path.clone()); + } else if cli.show_diff { + println!("{}:", path.display()); + show_diff(&old, &new); + println!("---"); + } else { + not_compliant.push(path.clone()); + } + } + } + if !compliant.is_empty() { + display("compliant", &compliant); + } + if !made_compliant.is_empty() { + display("made compliant", &made_compliant); + } + if !not_compliant.is_empty() { + display("not compliant", ¬_compliant); + process::exit(1); + } + Ok(()) +} + +fn show_diff(old: &str, new: &str) { + let input = InternedInput::new(old, new); + let mut diff = Diff::compute(Algorithm::Histogram, &input); + diff.postprocess_lines(&input); + let diff = diff + .unified_diff(&BasicLineDiffPrinter(&input.interner), UnifiedDiffConfig::default(), &input) + .to_string(); + print!("{diff}"); +} + +fn display(header: &str, paths: &[PathBuf]) { + println!("{header}:"); + for element in paths { + println!("- {}", element.display()); + } +} + +fn ignore(line: &str, in_code_block: bool) -> bool { + in_code_block + || line.contains("e.g.") + || line.contains("i.e.") + || line.contains('|') + || line.trim_start().starts_with('>') + || line.starts_with('#') + || line.trim().is_empty() + || REGEX_IGNORE.is_match(line) +} + +fn comply(content: &str) -> String { + let content: Vec<_> = content.lines().map(std::borrow::ToOwned::to_owned).collect(); + let mut new_content = content.clone(); + let mut new_n = 0; + let mut in_code_block = false; + for (n, line) in content.into_iter().enumerate() { + if n != 0 { + new_n += 1; + } + if line.trim_start().starts_with("```") { + in_code_block = !in_code_block; + continue; + } + if ignore(&line, in_code_block) { + continue; + } + if REGEX_SPLIT.is_match(&line) { + let indent = line.find(|ch: char| !ch.is_whitespace()).unwrap(); + let new_lines: Vec<_> = line + .split_inclusive(&*REGEX_SPLIT) + .map(|portion| format!("{:indent$}{}", "", portion.trim())) + .collect(); + new_content.splice(new_n..=new_n, new_lines.clone()); + new_n += new_lines.len() - 1; + } + } + new_content.join("\n") + "\n" +} + +fn lengthen_lines(content: &str, limit: usize) -> String { + let content: Vec<_> = content.lines().map(std::borrow::ToOwned::to_owned).collect(); + let mut new_content = content.clone(); + let mut new_n = 0; + let mut in_code_block = false; + let mut skip_next = false; + for (n, line) in content.iter().enumerate() { + if skip_next { + skip_next = false; + continue; + } + if n != 0 { + new_n += 1; + } + if line.trim_start().starts_with("```") { + in_code_block = !in_code_block; + continue; + } + if ignore(line, in_code_block) || REGEX_SPLIT.is_match(line) { + continue; + } + let Some(next_line) = content.get(n + 1) else { + continue; + }; + if ignore(next_line, in_code_block) || REGEX_IGNORE_END.is_match(line) { + continue; + } + if line.len() + next_line.len() < limit { + new_content[new_n] = format!("{line} {}", next_line.trim_start()); + new_content.remove(new_n + 1); + skip_next = true; + } + } + new_content.join("\n") + "\n" +} + +#[test] +fn test_sembr() { + let original = "\ +# some. heading +must! be; split? and. normalizes space +1. ignore numbered +ignore | tables +ignore e.g. and i.e. +- ignore. list +* ignore. list +``` +some code. block +``` +some more text. +"; + let expected = "\ +# some. heading +must! +be; +split? +and. +normalizes space +1. ignore numbered +ignore | tables +ignore e.g. and i.e. +- ignore. list +* ignore. list +``` +some code. block +``` +some more text. +"; + assert_eq!(expected, comply(original)); +} + +#[test] +fn test_prettify() { + let original = "\ +do not split +short sentences +"; + let expected = "\ +do not split short sentences +"; + assert_eq!(expected, lengthen_lines(original, 50)); +} + +#[test] +fn test_prettify_prefix_spaces() { + let original = "\ + do not split + short sentences +"; + let expected = "\ + do not split short sentences +"; + assert_eq!(expected, lengthen_lines(original, 50)); +} + +#[test] +fn test_sembr_then_prettify() { + let original = "\ +hi there. do +not split +short sentences. +hi again. +"; + let expected = "\ +hi there. +do +not split +short sentences. +hi again. +"; + let processed = comply(original); + assert_eq!(expected, processed); + let expected = "\ +hi there. +do not split +short sentences. +hi again. +"; + let processed = lengthen_lines(&processed, 50); + assert_eq!(expected, processed); + let expected = "\ +hi there. +do not split short sentences. +hi again. +"; + let processed = lengthen_lines(&processed, 50); + assert_eq!(expected, processed); +} From 7dd4509c11e659c7986fe4fc66f7418dcc28ccac Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 16:17:32 +0200 Subject: [PATCH 203/525] sample output --- src/doc/rustc-dev-guide/src/walkthrough.md | 205 +++++++++++---------- 1 file changed, 110 insertions(+), 95 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/walkthrough.md b/src/doc/rustc-dev-guide/src/walkthrough.md index b4c3379347ed..57d59d4d166a 100644 --- a/src/doc/rustc-dev-guide/src/walkthrough.md +++ b/src/doc/rustc-dev-guide/src/walkthrough.md @@ -1,10 +1,10 @@ # Walkthrough: a typical contribution There are _a lot_ of ways to contribute to the Rust compiler, including fixing -bugs, improving performance, helping design features, providing feedback on -existing features, etc. This chapter does not claim to scratch the surface. -Instead, it walks through the design and implementation of a new feature. Not -all of the steps and processes described here are needed for every +bugs, improving performance, helping design features, providing feedback on existing features, etc. +This chapter does not claim to scratch the surface. +Instead, it walks through the design and implementation of a new feature. +Not all of the steps and processes described here are needed for every contribution, and I will try to point those out as they arise. In general, if you are interested in making a contribution and aren't sure @@ -12,8 +12,8 @@ where to start, please feel free to ask! ## Overview -The feature I will discuss in this chapter is the `?` Kleene operator for -macros. Basically, we want to be able to write something like this: +The feature I will discuss in this chapter is the `?` Kleene operator for macros. +Basically, we want to be able to write something like this: ```rust,ignore macro_rules! foo { @@ -36,25 +36,30 @@ fn main() { So basically, the `$(pat)?` matcher in the macro means "this pattern can occur 0 or 1 times", similar to other regex syntaxes. -There were a number of steps to go from an idea to stable Rust feature. Here is -a quick list. We will go through each of these in order below. As I mentioned -before, not all of these are needed for every type of contribution. +There were a number of steps to go from an idea to stable Rust feature. +Here is a quick list. +We will go through each of these in order below. +As I mentioned before, not all of these are needed for every type of contribution. - **Idea discussion/Pre-RFC** A Pre-RFC is an early draft or design discussion - of a feature. This stage is intended to flesh out the design space a bit and - get a grasp on the different merits and problems with an idea. It's a great - way to get early feedback on your idea before presenting it to the wider - audience. You can find the original discussion [here][prerfc]. + of a feature. + This stage is intended to flesh out the design space a bit and + get a grasp on the different merits and problems with an idea. + It's a great way to get early feedback on your idea before presenting it to the wider + audience. + You can find the original discussion [here][prerfc]. - **RFC** This is when you formally present your idea to the community for - consideration. You can find the RFC [here][rfc]. + consideration. + You can find the RFC [here][rfc]. - **Implementation** Implement your idea unstably in the compiler. You can find the original implementation [here][impl1]. - **Possibly iterate/refine** As the community gets experience with your feature on the nightly compiler and in `std`, there may be additional - feedback about design choice that might be adjusted. This particular feature - went [through][impl2] a [number][impl3] of [iterations][impl4]. + feedback about design choice that might be adjusted. + This particular feature went [through][impl2] a [number][impl3] of [iterations][impl4]. - **Stabilization** When your feature has baked enough, a Rust team member may - [propose to stabilize it][merge]. If there is consensus, this is done. + [propose to stabilize it][merge]. + If there is consensus, this is done. - **Relax** Your feature is now a stable Rust feature! [prerfc]: https://internals.rust-lang.org/t/pre-rfc-at-most-one-repetition-macro-patterns/6557 @@ -75,58 +80,63 @@ before, not all of these are needed for every type of contribution. [rfcwhen]: https://github.com/rust-lang/rfcs#when-you-need-to-follow-this-process -An RFC is a document that describes the feature or change you are proposing in -detail. Anyone can write an RFC; the process is the same for everyone, -including Rust team members. +An RFC is a document that describes the feature or change you are proposing in detail. +Anyone can write an RFC; +the process is the same for everyone, including Rust team members. -To open an RFC, open a PR on the -[rust-lang/rfcs](https://github.com/rust-lang/rfcs) repo on GitHub. You can -find detailed instructions in the +To open an RFC, open a PR on the [rust-lang/rfcs](https://github.com/rust-lang/rfcs) repo on GitHub. +You can find detailed instructions in the [README](https://github.com/rust-lang/rfcs#what-the-process-is). Before opening an RFC, you should do the research to "flesh out" your idea. -Hastily-proposed RFCs tend not to be accepted. You should generally have a good -description of the motivation, impact, disadvantages, and potential +Hastily-proposed RFCs tend not to be accepted. +You should generally have a good description of the motivation, impact, disadvantages, and potential interactions with other features. -If that sounds like a lot of work, it's because it is. But no fear! Even if -you're not a compiler hacker, you can get great feedback by doing a _pre-RFC_. -This is an _informal_ discussion of the idea. The best place to do this is -internals.rust-lang.org. Your post doesn't have to follow any particular -structure. It doesn't even need to be a cohesive idea. Generally, you will get -tons of feedback that you can integrate back to produce a good RFC. +If that sounds like a lot of work, it's because it is. +But no fear! +Even if you're not a compiler hacker, you can get great feedback by doing a _pre-RFC_. +This is an _informal_ discussion of the idea. +The best place to do this is internals.rust-lang.org. +Your post doesn't have to follow any particular structure. +It doesn't even need to be a cohesive idea. +Generally, you will get tons of feedback that you can integrate back to produce a good RFC. -(Another pro-tip: try searching the RFCs repo and internals for prior related -ideas. A lot of times an idea has already been considered and was either -rejected or postponed to be tried again later. This can save you and everybody -else some time) +(Another pro-tip: try searching the RFCs repo and internals for prior related ideas. +A lot of times an idea has already been considered and was either +rejected or postponed to be tried again later. +This can save you and everybody else some time) In the case of our example, a participant in the pre-RFC thread pointed out a -syntax ambiguity and a potential resolution. Also, the overall feedback seemed -positive. In this case, the discussion converged pretty quickly, but for some +syntax ambiguity and a potential resolution. +Also, the overall feedback seemed positive. +In this case, the discussion converged pretty quickly, but for some ideas, a lot more discussion can happen (e.g. see [this RFC][nonascii] which -received a whopping 684 comments!). If that happens, don't be discouraged; it -means the community is interested in your idea, but it perhaps needs some +received a whopping 684 comments!). +If that happens, don't be discouraged; +it means the community is interested in your idea, but it perhaps needs some adjustments. [nonascii]: https://github.com/rust-lang/rfcs/pull/2457 -The RFC for our `?` macro feature did receive some discussion on the RFC thread -too. As with most RFCs, there were a few questions that we couldn't answer by -discussion: we needed experience using the feature to decide. Such questions -are listed in the "Unresolved Questions" section of the RFC. Also, over the -course of the RFC discussion, you will probably want to update the RFC document +The RFC for our `?` macro feature did receive some discussion on the RFC thread too. +As with most RFCs, there were a few questions that we couldn't answer by +discussion: we needed experience using the feature to decide. +Such questions are listed in the "Unresolved Questions" section of the RFC. +Also, over the course of the RFC discussion, you will probably want to update the RFC document itself to reflect the course of the discussion (e.g. new alternatives or prior work may be added or you may decide to change parts of the proposal itself). In the end, when the discussion seems to reach a consensus and die down a bit, a Rust team member may propose to move to "final comment period" (FCP) with one -of three possible dispositions. This means that they want the other members of -the appropriate teams to review and comment on the RFC. More discussion may -ensue, which may result in more changes or unresolved questions being added. At -some point, when everyone is satisfied, the RFC enters the FCP, which is the -last chance for people to bring up objections. When the FCP is over, the -disposition is adopted. Here are the three possible dispositions: +of three possible dispositions. +This means that they want the other members of +the appropriate teams to review and comment on the RFC. +More discussion may ensue, which may result in more changes or unresolved questions being added. +At some point, when everyone is satisfied, the RFC enters the FCP, which is the +last chance for people to bring up objections. +When the FCP is over, the disposition is adopted. +Here are the three possible dispositions: - _Merge_: accept the feature. Here is the proposal to merge for our [`?` macro feature][rfcmerge]. @@ -136,14 +146,14 @@ disposition is adopted. Here are the three possible dispositions: will go a different direction. - _Postpone_: there is interest in going this direction but not at the moment. This happens most often because the appropriate Rust team doesn't have the - bandwidth to shepherd the feature through the process to stabilization. Often - this is the case when the feature doesn't fit into the team's roadmap. + bandwidth to shepherd the feature through the process to stabilization. + Often this is the case when the feature doesn't fit into the team's roadmap. Postponed ideas may be revisited later. [rfcmerge]: https://github.com/rust-lang/rfcs/pull/2298#issuecomment-360582667 -When an RFC is merged, the PR is merged into the RFCs repo. A new _tracking -issue_ is created in the [rust-lang/rust] repo to track progress on the feature +When an RFC is merged, the PR is merged into the RFCs repo. +A new _tracking issue_ is created in the [rust-lang/rust] repo to track progress on the feature and discuss unresolved questions, implementation progress and blockers, etc. Here is the tracking issue on for our [`?` macro feature][tracking]. @@ -158,93 +168,98 @@ To make a change to the compiler, open a PR against the [rust-lang/rust] repo. [rust-lang/rust]: https://github.com/rust-lang/rust Depending on the feature/change/bug fix/improvement, implementation may be -relatively-straightforward or it may be a major undertaking. You can always ask -for help or mentorship from more experienced compiler devs. Also, you don't -have to be the one to implement your feature; but keep in mind that if you -don't, it might be a while before someone else does. +relatively-straightforward or it may be a major undertaking. +You can always ask for help or mentorship from more experienced compiler devs. +Also, you don't have to be the one to implement your feature; +but keep in mind that if you don't, it might be a while before someone else does. For the `?` macro feature, I needed to go understand the relevant parts of -macro expansion in the compiler. Personally, I find that [improving the +macro expansion in the compiler. +Personally, I find that [improving the comments][comments] in the code is a helpful way of making sure I understand it, but you don't have to do that if you don't want to. [comments]: https://github.com/rust-lang/rust/pull/47732 -I then [implemented][impl1] the original feature, as described in the RFC. When -a new feature is implemented, it goes behind a _feature gate_, which means that -you have to use `#![feature(my_feature_name)]` to use the feature. The feature -gate is removed when the feature is stabilized. +I then [implemented][impl1] the original feature, as described in the RFC. +When a new feature is implemented, it goes behind a _feature gate_, which means that +you have to use `#![feature(my_feature_name)]` to use the feature. +The feature gate is removed when the feature is stabilized. **Most bug fixes and improvements** don't require a feature gate. You can just make your changes/improvements. -When you open a PR on the [rust-lang/rust], a bot will assign your PR to a -reviewer. If there is a particular Rust team member you are working with, you can +When you open a PR on the [rust-lang/rust], a bot will assign your PR to a reviewer. +If there is a particular Rust team member you are working with, you can request that reviewer by leaving a comment on the thread with `r? @reviewer-github-id` (e.g. `r? @eddyb`). If you don't know who to request, -don't request anyone; the bot will assign someone automatically based on which files you changed. +don't request anyone; +the bot will assign someone automatically based on which files you changed. The reviewer may request changes before they approve your PR, they may mark the PR with label "S-waiting-on-author" after leaving comments, this means that the PR is blocked on you to make -some requested changes. When you finished iterating on the changes, you can mark the PR as +some requested changes. +When you finished iterating on the changes, you can mark the PR as `S-waiting-on-review` again by leaving a comment with `@rustbot ready`, this will remove the `S-waiting-on-author` label and add the `S-waiting-on-review` label. -Feel free to ask questions or discuss things you don't understand or disagree with. However, -recognize that the PR won't be merged unless someone on the Rust team approves -it. If a reviewer leave a comment like `r=me after fixing ...`, that means they approve the PR and +Feel free to ask questions or discuss things you don't understand or disagree with. +However, recognize that the PR won't be merged unless someone on the Rust team approves +it. +If a reviewer leave a comment like `r=me after fixing ...`, that means they approve the PR and you can merge it with comment with `@bors r=reviewer-github-id`(e.g. `@bors r=eddyb`) to merge it -after fixing trivial issues. Note that `r=someone` requires permission and bors could say -something like "🔑 Insufficient privileges..." when commenting `r=someone`. In that case, -you have to ask the reviewer to revisit your PR. +after fixing trivial issues. +Note that `r=someone` requires permission and bors could say +something like "🔑 Insufficient privileges..." when commenting `r=someone`. +In that case, you have to ask the reviewer to revisit your PR. -When your reviewer approves the PR, it will go into a queue for yet another bot -called `@bors`. `@bors` manages the CI build/merge queue. When your PR reaches -the head of the `@bors` queue, `@bors` will test out the merge by running all -tests against your PR on GitHub Actions. This takes a lot of time to -finish. If all tests pass, the PR is merged and becomes part of the next -nightly compiler! +When your reviewer approves the PR, it will go into a queue for yet another bot called `@bors`. +`@bors` manages the CI build/merge queue. +When your PR reaches the head of the `@bors` queue, `@bors` will test out the merge by running all +tests against your PR on GitHub Actions. +This takes a lot of time to finish. +If all tests pass, the PR is merged and becomes part of the next nightly compiler! There are a couple of things that may happen for some PRs during the review process - If the change is substantial enough, the reviewer may request an FCP on - the PR. This gives all members of the appropriate team a chance to review the - changes. + the PR. + This gives all members of the appropriate team a chance to review the changes. - If the change may cause breakage, the reviewer may request a [crater] run. This compiles the compiler with your changes and then attempts to compile all - crates on crates.io with your modified compiler. This is a great smoke test + crates on crates.io with your modified compiler. + This is a great smoke test to check if you introduced a change to compiler behavior that affects a large portion of the ecosystem. - If the diff of your PR is large or the reviewer is busy, your PR may have - some merge conflicts with other PRs that happen to get merged first. You - should fix these merge conflicts using the normal git procedures. + some merge conflicts with other PRs that happen to get merged first. + You should fix these merge conflicts using the normal git procedures. [crater]: ./tests/crater.html If you are not doing a new feature or something like that (e.g. if you are -fixing a bug), then that's it! Thanks for your contribution :) +fixing a bug), then that's it! +Thanks for your contribution :) ## Refining your implementation As people get experience with your new feature on nightly, slight changes may -be proposed and unresolved questions may become resolved. Updates/changes go -through the same process for implementing any other changes, as described +be proposed and unresolved questions may become resolved. +Updates/changes go through the same process for implementing any other changes, as described above (i.e. submit a PR, go through review, wait for `@bors`, etc). -Some changes may be major enough to require an FCP and some review by Rust team -members. +Some changes may be major enough to require an FCP and some review by Rust team members. For the `?` macro feature, we went through a few different iterations after the original implementation: [1][impl2], [2][impl3], [3][impl4]. Along the way, we decided that `?` should not take a separator, which was -previously an unresolved question listed in the RFC. We also changed the -disambiguation strategy: we decided to remove the ability to use `?` as a +previously an unresolved question listed in the RFC. +We also changed the disambiguation strategy: we decided to remove the ability to use `?` as a separator token for other repetition operators (e.g. `+` or `*`). However, since this was a breaking change, we decided to do it over an edition boundary. Thus, the new feature can be enabled only in edition 2018. These deviations -from the original RFC required [another -FCP](https://github.com/rust-lang/rust/issues/51934). +from the original RFC required [another FCP](https://github.com/rust-lang/rust/issues/51934). ## Stabilization @@ -264,8 +279,8 @@ The stabilization report for our feature is [here][stabrep]. [stabrep]: https://github.com/rust-lang/rust/issues/48075#issuecomment-433243048 After this, [a PR is made][stab] to remove the feature gate, enabling the feature by -default (on the 2018 edition). A note is added to the [Release notes][relnotes] -about the feature. +default (on the 2018 edition). +A note is added to the [Release notes][relnotes] about the feature. [stab]: https://github.com/rust-lang/rust/pull/56245 From cf99a9ec4f59b389a9d7acf9d556bd675055bd6c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 24 Oct 2025 10:53:49 +0200 Subject: [PATCH 204/525] check on ci --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 79d03080dce3..30e93c42a0ab 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -82,3 +82,9 @@ jobs: git add . git commit -m "Deploy ${GITHUB_SHA} to gh-pages" git push --quiet -f "https://x-token:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}" HEAD:gh-pages + + - name: Check if files comply with semantic line breaks + continue-on-error: true + run: | + # using split_inclusive that uses regex feature that uses an unstable feature + RUSTC_BOOTSTRAP=true cargo run --manifest-path ci/sembr/Cargo.toml src From 8f70d2de7d886294a4a706f9be442fb28cde1316 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Oct 2025 15:31:49 +0100 Subject: [PATCH 205/525] add miri magic function to configure allocation tracking at runtime --- src/tools/miri/README.md | 3 ++- src/tools/miri/src/diagnostics.rs | 8 +++--- src/tools/miri/src/machine.rs | 4 +-- src/tools/miri/src/shims/foreign_items.rs | 15 +++++++++++ .../miri/tests/pass/alloc-access-tracking.rs | 27 ++++++------------- .../tests/pass/alloc-access-tracking.stderr | 26 +++++++++++------- src/tools/miri/tests/utils/miri_extern.rs | 5 ++++ 7 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index d47967c0a4d3..9b7accca7b11 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -474,7 +474,8 @@ to Miri failing to detect cases of undefined behavior in a program. * `-Zmiri-track-alloc-id=,,...` shows a backtrace when the given allocations are being allocated or freed. This helps in debugging memory leaks and use after free bugs. Specifying this argument multiple times does not overwrite the previous - values, instead it appends its values to the list. Listing an id multiple times has no effect. + values, instead it appends its values to the list. Listing an ID multiple times has no effect. + You can also add IDs at runtime using `miri_track_alloc`. * `-Zmiri-track-pointer-tag=,,...` shows a backtrace when a given pointer tag is created and when (if ever) it is popped from a borrow stack (which is where the tag becomes invalid and any future use of it will error). This helps you in finding out why UB is diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 1c3de9035cf8..0e756d89a2dc 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -126,7 +126,7 @@ pub enum NonHaltingDiagnostic { CreatedPointerTag(NonZero, Option, Option<(AllocId, AllocRange, ProvenanceExtra)>), /// This `Item` was popped from the borrow stack. The string explains the reason. PoppedPointerTag(Item, String), - CreatedAlloc(AllocId, Size, Align, MemoryKind), + TrackingAlloc(AllocId, Size, Align), FreedAlloc(AllocId), AccessedAlloc(AllocId, AccessKind), RejectedIsolatedOp(String), @@ -656,7 +656,7 @@ impl<'tcx> MiriMachine<'tcx> { ("GenMC might miss possible behaviors of this code".to_string(), DiagLevel::Warning), CreatedPointerTag(..) | PoppedPointerTag(..) - | CreatedAlloc(..) + | TrackingAlloc(..) | AccessedAlloc(..) | FreedAlloc(..) | ProgressReport { .. } @@ -673,9 +673,9 @@ impl<'tcx> MiriMachine<'tcx> { "created tag {tag:?} with {perm} at {alloc_id:?}{range:?} derived from {orig_tag:?}" ), PoppedPointerTag(item, cause) => format!("popped tracked tag for item {item:?}{cause}"), - CreatedAlloc(AllocId(id), size, align, kind) => + TrackingAlloc(AllocId(id), size, align) => format!( - "created {kind} allocation of {size} bytes (alignment {align} bytes) with id {id}", + "now tracking allocation of {size} bytes (alignment {align} bytes) with id {id}", size = size.bytes(), align = align.bytes(), ), diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index fadbdf5cea99..d4ea525eb36d 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -595,7 +595,7 @@ pub struct MiriMachine<'tcx> { /// The allocation IDs to report when they are being allocated /// (helps for debugging memory leaks and use after free bugs). - tracked_alloc_ids: FxHashSet, + pub(crate) tracked_alloc_ids: FxHashSet, /// For the tracked alloc ids, also report read/write accesses. track_alloc_accesses: bool, @@ -928,7 +928,7 @@ impl<'tcx> MiriMachine<'tcx> { align: Align, ) -> InterpResult<'tcx, AllocExtra<'tcx>> { if ecx.machine.tracked_alloc_ids.contains(&id) { - ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind)); + ecx.emit_diagnostic(NonHaltingDiagnostic::TrackingAlloc(id, size, align)); } let borrow_tracker = ecx diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 74818cf0740b..74a1ac729e88 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -350,6 +350,21 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { MiriMemoryKind::Miri.into(), )?; } + "miri_track_alloc" => { + let [ptr] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { + err_machine_stop!(TerminationInfo::Abort(format!( + "pointer passed to `miri_get_alloc_id` must not be dangling, got {ptr:?}" + ))) + })?; + if this.machine.tracked_alloc_ids.insert(alloc_id) { + let info = this.get_alloc_info(alloc_id); + this.emit_diagnostic(NonHaltingDiagnostic::TrackingAlloc( + alloc_id, info.size, info.align, + )); + } + } "miri_start_unwind" => { let [payload] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index 9eba0ca171bc..3578a4863301 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,26 +1,15 @@ -#![no_std] -#![no_main] -//@compile-flags: -Zmiri-track-alloc-id=19 -Zmiri-track-alloc-accesses -Cpanic=abort -//@normalize-stderr-test: "id 19" -> "id $$ALLOC" -//@only-target: linux # alloc IDs differ between OSes (due to extern static allocations) +//@compile-flags: -Zmiri-track-alloc-accesses +//@normalize-stderr-test: "id \d+" -> "id $$ALLOC" -extern "Rust" { - fn miri_alloc(size: usize, align: usize) -> *mut u8; - fn miri_dealloc(ptr: *mut u8, size: usize, align: usize); -} +#[path = "../utils/mod.rs"] +mod utils; -#[no_mangle] -fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { +fn main() { unsafe { - let ptr = miri_alloc(123, 1); + let mut b = Box::<[u8; 123]>::new_uninit(); + let ptr = b.as_mut_ptr() as *mut u8; + utils::miri_track_alloc(ptr); *ptr = 42; // Crucially, only a write is printed here, no read! assert_eq!(*ptr, 42); - miri_dealloc(ptr, 123, 1); } - 0 -} - -#[panic_handler] -fn panic_handler(_: &core::panic::PanicInfo) -> ! { - loop {} } diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index af124776402d..3b4dc8f5ea99 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -1,11 +1,11 @@ -note: created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC +note: now tracking allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC --> tests/pass/alloc-access-tracking.rs:LL:CC | -LL | let ptr = miri_alloc(123, 1); - | ^^^^^^^^^^^^^^^^^^ tracking was triggered here +LL | utils::miri_track_alloc(ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | = note: BACKTRACE: - = note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC + = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC note: write access to allocation with id $ALLOC --> tests/pass/alloc-access-tracking.rs:LL:CC @@ -14,7 +14,7 @@ LL | *ptr = 42; // Crucially, only a write is printed here, no read! | ^^^^^^^^^ tracking was triggered here | = note: BACKTRACE: - = note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC + = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC note: read access to allocation with id $ALLOC --> tests/pass/alloc-access-tracking.rs:LL:CC @@ -23,15 +23,21 @@ LL | assert_eq!(*ptr, 42); | ^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | = note: BACKTRACE: - = note: inside `miri_start` at RUSTLIB/core/src/macros/mod.rs:LL:CC + = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: freed allocation with id $ALLOC - --> tests/pass/alloc-access-tracking.rs:LL:CC + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | miri_dealloc(ptr, 123, 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | = note: BACKTRACE: - = note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC + = note: inside `> as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::ptr::drop_in_place::>> - shim(Some(std::boxed::Box>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC +note: inside `main` + --> tests/pass/alloc-access-tracking.rs:LL:CC + | +LL | } + | ^ diff --git a/src/tools/miri/tests/utils/miri_extern.rs b/src/tools/miri/tests/utils/miri_extern.rs index 633f337f7e7c..09f9ca032d43 100644 --- a/src/tools/miri/tests/utils/miri_extern.rs +++ b/src/tools/miri/tests/utils/miri_extern.rs @@ -119,6 +119,11 @@ extern "Rust" { /// Miri-provided extern function to deallocate memory. pub fn miri_dealloc(ptr: *mut u8, size: usize, align: usize); + /// Add the allocation that this pointer points to to the "tracked" allocations. + /// This is equivalent to `-Zmiri-track-allic-id=`, but also works if the ID is + /// only known at runtime. + pub fn miri_track_alloc(ptr: *const u8); + /// Convert a path from the host Miri runs on to the target Miri interprets. /// Performs conversion of path separators as needed. /// From 057f15e928b911667d1049adcf2abfaaff6c3e06 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 16:33:58 +0200 Subject: [PATCH 206/525] sample output --- .../src/tests/codegen-backend-tests/cg_gcc.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index 6bd6007c8969..69db2094838d 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -21,7 +21,8 @@ you can use the following command to run UI tests locally using the GCC backend, If a different test suite has failed on CI, you will have to modify the `tests/ui` part. -To reproduce the whole CI job locally, you can run `cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-gcc`. See [Testing with Docker](../docker.md) for more information. +To reproduce the whole CI job locally, you can run `cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-gcc`. +See [Testing with Docker](../docker.md) for more information. ### What to do in case of a GCC job failure? @@ -32,15 +33,16 @@ If fixing a compiler test that fails with the GCC backend is non-trivial, you ca ## Choosing which codegen backends are built The `rust.codegen-backends = [...]` bootstrap option affects which codegen backends will be built and -included in the sysroot of the produced `rustc`. To use the GCC codegen backend, `"gcc"` has to -be included in this array in `bootstrap.toml`: +included in the sysroot of the produced `rustc`. +To use the GCC codegen backend, `"gcc"` has to be included in this array in `bootstrap.toml`: ```toml rust.codegen-backends = ["llvm", "gcc"] ``` If you don't want to change your `bootstrap.toml` file, you can alternatively run your `x` -commands with `--set 'rust.codegen-backends=["llvm", "gcc"]'`. For example: +commands with `--set 'rust.codegen-backends=["llvm", "gcc"]'`. +For example: ```bash ./x build --set 'rust.codegen-backends=["llvm", "gcc"]' @@ -48,7 +50,8 @@ commands with `--set 'rust.codegen-backends=["llvm", "gcc"]'`. For example: The first backend in the `codegen-backends` array will determine which backend will be used as the *default backend* of the built `rustc`. This also determines which backend will be used to compile the -stage 1 standard library (or anything built in stage 2+). To produce `rustc` that uses the GCC backend +stage 1 standard library (or anything built in stage 2+). +To produce `rustc` that uses the GCC backend by default, you can thus put `"gcc"` as the first element of this array: ```bash @@ -69,7 +72,8 @@ Note that in order for this to work, the tested compiler must have the GCC codeg ## Downloading GCC from CI The `gcc.download-ci-gcc` bootstrap option controls if GCC (which is a dependency of the GCC codegen backend) -will be downloaded from CI or built locally. The default value is `true`, which will download GCC from CI +will be downloaded from CI or built locally. +The default value is `true`, which will download GCC from CI if there are no local changes to the GCC sources and the given host target is available on CI. ## Running tests of the backend itself From e7fb68aa52050d28a9913b660d36fc51eea70ee5 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 24 Oct 2025 13:13:40 +0300 Subject: [PATCH 207/525] Properly support opaques By letting the solver take control of them (reveal them when needed and define them when needed), by providing them in the `TypingMode` plus few helpers. --- src/tools/rust-analyzer/.typos.toml | 1 + .../crates/hir-ty/src/autoderef.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 296 +++--------------- .../crates/hir-ty/src/infer/coerce.rs | 23 +- .../crates/hir-ty/src/infer/expr.rs | 29 +- .../crates/hir-ty/src/infer/opaques.rs | 147 +++++++++ .../crates/hir-ty/src/infer/path.rs | 7 +- .../crates/hir-ty/src/infer/unify.rs | 67 ++-- .../rust-analyzer/crates/hir-ty/src/lib.rs | 6 +- .../crates/hir-ty/src/method_resolution.rs | 122 +++++--- .../crates/hir-ty/src/mir/borrowck.rs | 8 +- .../crates/hir-ty/src/next_solver/def_id.rs | 23 ++ .../hir-ty/src/next_solver/generic_arg.rs | 8 + .../hir-ty/src/next_solver/infer/mod.rs | 66 +++- .../src/next_solver/infer/opaque_types/mod.rs | 4 +- .../next_solver/infer/opaque_types/table.rs | 8 - .../crates/hir-ty/src/next_solver/interner.rs | 68 ++-- .../crates/hir-ty/src/next_solver/solver.rs | 91 ++++-- .../crates/hir-ty/src/opaques.rs | 199 ++++++++++++ .../crates/hir-ty/src/tests/incremental.rs | 2 + .../crates/hir-ty/src/tests/opaque_types.rs | 5 +- .../crates/hir-ty/src/tests/regression.rs | 2 +- .../hir-ty/src/tests/regression/new_solver.rs | 2 +- .../crates/hir-ty/src/tests/traits.rs | 10 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 26 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 8 +- .../crates/ide/src/hover/tests.rs | 2 +- .../crates/ide/src/signature_help.rs | 10 +- 28 files changed, 742 insertions(+), 500 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml index 99464150dab4..e954b08fb1e1 100644 --- a/src/tools/rust-analyzer/.typos.toml +++ b/src/tools/rust-analyzer/.typos.toml @@ -33,6 +33,7 @@ trivias = "trivias" thir = "thir" jod = "jod" tructure = "tructure" +taits = "taits" [default.extend-identifiers] anc = "anc" diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index 6dd3cdb745aa..392b0b040825 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -38,7 +38,7 @@ pub fn autoderef<'db>( env: Arc>, ty: Canonical<'db, Ty<'db>>, ) -> impl Iterator> + use<'db> { - let mut table = InferenceTable::new(db, env); + let mut table = InferenceTable::new(db, env, None); let ty = table.instantiate_canonical(ty); let mut autoderef = Autoderef::new_no_tracking(&mut table, ty); let mut v = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 361e66522df6..016edb2310eb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -21,6 +21,7 @@ pub(crate) mod diagnostics; mod expr; mod fallback; mod mutability; +mod opaques; mod pat; mod path; pub(crate) mod unify; @@ -31,8 +32,7 @@ use base_db::Crate; use either::Either; use hir_def::{ AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, - ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, - VariantId, + ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::{LangItem, LangItemTarget, lang_item}, @@ -44,11 +44,11 @@ use hir_def::{ use hir_expand::{mod_path::ModPath, name::Name}; use indexmap::IndexSet; use intern::sym; -use la_arena::{ArenaMap, Entry}; +use la_arena::ArenaMap; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ - AliasTyKind, Flags, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, + AliasTyKind, TypeFoldable, inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _}, }; use stdx::never; @@ -61,7 +61,6 @@ use crate::{ coerce::{CoerceMany, DynamicCoerceMany}, diagnostics::{Diagnostics, InferenceTyLoweringContext as TyLoweringContext}, expr::ExprIsRead, - unify::InferenceTable, }, lower::{ ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic, @@ -69,10 +68,7 @@ use crate::{ mir::MirSpan, next_solver::{ AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, Ty, TyKind, - Tys, - abi::Safety, - fold::fold_tys, - infer::traits::{Obligation, ObligationCause}, + Tys, abi::Safety, infer::traits::ObligationCause, }, traits::FnTrait, utils::TargetFeatureIsSafeInTarget, @@ -132,6 +128,8 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc Arc { /// unresolved or missing subpatterns or subpatterns of mismatched types. pub(crate) type_of_pat: ArenaMap>, pub(crate) type_of_binding: ArenaMap>, - pub(crate) type_of_rpit: ArenaMap, Ty<'db>>, + pub(crate) type_of_opaque: FxHashMap>, type_mismatches: FxHashMap>, /// Whether there are any type-mismatching errors in the result. // FIXME: This isn't as useful as initially thought due to us falling back placeholders to @@ -499,7 +501,7 @@ impl<'db> InferenceResult<'db> { type_of_expr: Default::default(), type_of_pat: Default::default(), type_of_binding: Default::default(), - type_of_rpit: Default::default(), + type_of_opaque: Default::default(), type_mismatches: Default::default(), has_errors: Default::default(), error_ty, @@ -640,8 +642,14 @@ impl<'db> InferenceResult<'db> { // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please. pub fn return_position_impl_trait_types( &self, + db: &'db dyn HirDatabase, ) -> impl Iterator, Ty<'db>)> { - self.type_of_rpit.iter().map(|(k, v)| (k, *v)) + self.type_of_opaque.iter().filter_map(move |(&id, &ty)| { + let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else { + return None; + }; + Some((rpit_idx, ty)) + }) } } @@ -707,6 +715,7 @@ struct InternedStandardTypes<'db> { re_static: Region<'db>, re_error: Region<'db>, + re_erased: Region<'db>, empty_args: GenericArgs<'db>, empty_tys: Tys<'db>, @@ -742,6 +751,7 @@ impl<'db> InternedStandardTypes<'db> { re_static, re_error: Region::error(interner), + re_erased: Region::new_erased(interner), empty_args: GenericArgs::new_from_iter(interner, []), empty_tys: Tys::new_from_iter(interner, []), @@ -848,11 +858,6 @@ fn find_continuable<'a, 'db>( } } -enum ImplTraitReplacingMode<'db> { - ReturnPosition(FxHashSet>), - TypeAlias, -} - impl<'body, 'db> InferenceContext<'body, 'db> { fn new( db: &'db dyn HirDatabase, @@ -861,7 +866,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { resolver: Resolver<'db>, ) -> Self { let trait_env = db.trait_environment_for_body(owner); - let table = unify::InferenceTable::new(db, trait_env); + let table = unify::InferenceTable::new(db, trait_env, Some(owner)); let types = InternedStandardTypes::new(table.interner()); InferenceContext { result: InferenceResult::new(types.error), @@ -952,7 +957,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you // used this function for another workaround, mention it here. If you really need this function and believe that // there is no problem in it being `pub(crate)`, remove this comment. - pub(crate) fn resolve_all(self) -> InferenceResult<'db> { + fn resolve_all(self) -> InferenceResult<'db> { let InferenceContext { mut table, mut result, tuple_field_accesses_rev, diagnostics, .. } = self; @@ -967,7 +972,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { type_of_expr, type_of_pat, type_of_binding, - type_of_rpit, + type_of_opaque, type_mismatches, has_errors, error_ty: _, @@ -999,11 +1004,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { *has_errors = *has_errors || ty.references_non_lt_error(); } type_of_binding.shrink_to_fit(); - for ty in type_of_rpit.values_mut() { - *ty = table.resolve_completely(*ty); - *has_errors = *has_errors || ty.references_non_lt_error(); - } - type_of_rpit.shrink_to_fit(); + type_of_opaque.shrink_to_fit(); *has_errors |= !type_mismatches.is_empty(); @@ -1084,9 +1085,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> { LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container), ); - // Constants might be defining usage sites of TAITs. - self.make_tait_coercion_table(iter::once(return_ty)); - self.return_ty = return_ty; } @@ -1098,9 +1096,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> { LifetimeElisionKind::Elided(self.types.re_static), ); - // Statics might be defining usage sites of TAITs. - self.make_tait_coercion_table(iter::once(return_ty)); - self.return_ty = return_ty; } @@ -1138,16 +1133,12 @@ impl<'body, 'db> InferenceContext<'body, 'db> { let ty = self.process_user_written_ty(ty); self.write_binding_ty(self_param, ty); } - let mut tait_candidates = FxHashSet::default(); for (ty, pat) in param_tys.zip(&*self.body.params) { let ty = self.process_user_written_ty(ty); self.infer_top_pat(*pat, ty, None); - if ty.flags().intersects(TypeFlags::HAS_TY_OPAQUE.union(TypeFlags::HAS_TY_INFER)) { - tait_candidates.insert(ty); - } } - let return_ty = match data.ret_type { + self.return_ty = match data.ret_type { Some(return_ty) => { let return_ty = self.with_ty_lowering( &data.store, @@ -1158,45 +1149,12 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ctx.lower_ty(return_ty) }, ); - let return_ty = self.insert_type_vars(return_ty); - if let Some(rpits) = self.db.return_type_impl_traits(func) { - let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default()); - let result = self.insert_inference_vars_for_impl_trait(return_ty, &mut mode); - if let ImplTraitReplacingMode::ReturnPosition(taits) = mode { - tait_candidates.extend(taits); - } - let rpits = (*rpits).as_ref().skip_binder(); - for (id, _) in rpits.impl_traits.iter() { - if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) { - never!("Missed RPIT in `insert_inference_vars_for_rpit`"); - e.insert(self.types.error); - } - } - result - } else { - return_ty - } + self.process_user_written_ty(return_ty) } None => self.types.unit, }; - self.return_ty = self.process_user_written_ty(return_ty); self.return_coercion = Some(CoerceMany::new(self.return_ty)); - - // Functions might be defining usage sites of TAITs. - // To define an TAITs, that TAIT must appear in the function's signatures. - // So, it suffices to check for params and return types. - fold_tys(self.interner(), self.return_ty, |ty| { - match ty.kind() { - TyKind::Alias(AliasTyKind::Opaque, _) | TyKind::Infer(..) => { - tait_candidates.insert(self.return_ty); - } - _ => {} - } - ty - }); - - self.make_tait_coercion_table(tait_candidates.iter().copied()); } #[inline] @@ -1204,193 +1162,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> { self.table.interner() } - fn insert_inference_vars_for_impl_trait( - &mut self, - t: T, - mode: &mut ImplTraitReplacingMode<'db>, - ) -> T - where - T: TypeFoldable>, - { - fold_tys(self.interner(), t, |ty| { - let ty = self.table.try_structurally_resolve_type(ty); - let opaque_ty_id = match ty.kind() { - TyKind::Alias(AliasTyKind::Opaque, alias_ty) => alias_ty.def_id.expect_opaque_ty(), - _ => return ty, - }; - let (impl_traits, idx) = match self.db.lookup_intern_impl_trait_id(opaque_ty_id) { - // We don't replace opaque types from other kind with inference vars - // because `insert_inference_vars_for_impl_traits` for each kinds - // and unreplaced opaque types of other kind are resolved while - // inferencing because of `tait_coercion_table`. - ImplTraitId::ReturnTypeImplTrait(def, idx) => { - if matches!(mode, ImplTraitReplacingMode::TypeAlias) { - // RPITs don't have `tait_coercion_table`, so use inserted inference - // vars for them. - if let Some(ty) = self.result.type_of_rpit.get(idx) { - return *ty; - } - return ty; - } - (self.db.return_type_impl_traits(def), idx) - } - ImplTraitId::TypeAliasImplTrait(def, idx) => { - if let ImplTraitReplacingMode::ReturnPosition(taits) = mode { - // Gather TAITs while replacing RPITs because TAITs inside RPITs - // may not visited while replacing TAITs - taits.insert(ty); - return ty; - } - (self.db.type_alias_impl_traits(def), idx) - } - }; - let Some(impl_traits) = impl_traits else { - return ty; - }; - let bounds = - (*impl_traits).as_ref().map_bound(|its| its.impl_traits[idx].predicates.as_slice()); - let var = match self.result.type_of_rpit.entry(idx) { - Entry::Occupied(entry) => return *entry.get(), - Entry::Vacant(entry) => *entry.insert(self.table.next_ty_var()), - }; - for clause in bounds.iter_identity_copied() { - let clause = self.insert_inference_vars_for_impl_trait(clause, mode); - self.table.register_predicate(Obligation::new( - self.interner(), - ObligationCause::new(), - self.table.trait_env.env, - clause, - )); - } - var - }) - } - - /// The coercion of a non-inference var into an opaque type should fail, - /// but not in the defining sites of the TAITs. - /// In such cases, we insert an proxy inference var for each TAIT, - /// and coerce into it instead of TAIT itself. - /// - /// The inference var stretagy is effective because; - /// - /// - It can still unify types that coerced into TAITs - /// - We are pushing `impl Trait` bounds into it - /// - /// This function inserts a map that maps the opaque type to that proxy inference var. - fn make_tait_coercion_table(&mut self, tait_candidates: impl Iterator>) { - struct TypeAliasImplTraitCollector<'a, 'db> { - db: &'a dyn HirDatabase, - table: &'a mut InferenceTable<'db>, - assocs: FxHashMap)>, - non_assocs: FxHashMap>, - } - - impl<'db> TypeVisitor> for TypeAliasImplTraitCollector<'_, 'db> { - type Result = (); - - fn visit_ty(&mut self, ty: Ty<'db>) { - let ty = self.table.try_structurally_resolve_type(ty); - - if let TyKind::Alias(AliasTyKind::Opaque, alias_ty) = ty.kind() - && let id = alias_ty.def_id.expect_opaque_ty() - && let ImplTraitId::TypeAliasImplTrait(alias_id, _) = - self.db.lookup_intern_impl_trait_id(id) - { - let loc = self.db.lookup_intern_type_alias(alias_id); - match loc.container { - ItemContainerId::ImplId(impl_id) => { - self.assocs.insert(id, (impl_id, ty)); - } - ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => { - self.non_assocs.insert(id, ty); - } - _ => {} - } - } - - ty.super_visit_with(self) - } - } - - let mut collector = TypeAliasImplTraitCollector { - db: self.db, - table: &mut self.table, - assocs: FxHashMap::default(), - non_assocs: FxHashMap::default(), - }; - for ty in tait_candidates { - ty.visit_with(&mut collector); - } - - // Non-assoc TAITs can be define-used everywhere as long as they are - // in function signatures or const types, etc - let mut taits = collector.non_assocs; - - // assoc TAITs(ATPITs) can be only define-used inside their impl block. - // They cannot be define-used in inner items like in the following; - // - // ``` - // impl Trait for Struct { - // type Assoc = impl Default; - // - // fn assoc_fn() -> Self::Assoc { - // let foo: Self::Assoc = true; // Allowed here - // - // fn inner() -> Self::Assoc { - // false // Not allowed here - // } - // - // foo - // } - // } - // ``` - let impl_id = match self.owner { - DefWithBodyId::FunctionId(it) => { - let loc = self.db.lookup_intern_function(it); - if let ItemContainerId::ImplId(impl_id) = loc.container { - Some(impl_id) - } else { - None - } - } - DefWithBodyId::ConstId(it) => { - let loc = self.db.lookup_intern_const(it); - if let ItemContainerId::ImplId(impl_id) = loc.container { - Some(impl_id) - } else { - None - } - } - _ => None, - }; - - if let Some(impl_id) = impl_id { - taits.extend(collector.assocs.into_iter().filter_map(|(id, (impl_, ty))| { - if impl_ == impl_id { Some((id, ty)) } else { None } - })); - } - - let tait_coercion_table: FxHashMap<_, _> = taits - .into_iter() - .filter_map(|(id, ty)| { - if let ImplTraitId::TypeAliasImplTrait(..) = self.db.lookup_intern_impl_trait_id(id) - { - let ty = self.insert_inference_vars_for_impl_trait( - ty, - &mut ImplTraitReplacingMode::TypeAlias, - ); - Some((id, ty)) - } else { - None - } - }) - .collect(); - - if !tait_coercion_table.is_empty() { - self.table.tait_coercion_table = Some(tait_coercion_table); - } - } - fn infer_body(&mut self) { match self.return_coercion { Some(_) => self.infer_return(self.body.body_expr), @@ -2006,12 +1777,15 @@ impl<'body, 'db> InferenceContext<'body, 'db> { Some(struct_.into()) } - fn get_traits_in_scope(&self) -> Either, &FxHashSet> { - let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable(); + fn get_traits_in_scope<'a>( + resolver: &Resolver<'db>, + traits_in_scope: &'a FxHashSet, + ) -> Either, &'a FxHashSet> { + let mut b_traits = resolver.traits_in_scope_from_block_scopes().peekable(); if b_traits.peek().is_some() { - Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect()) + Either::Left(traits_in_scope.iter().copied().chain(b_traits).collect()) } else { - Either::Right(&self.traits_in_scope) + Either::Right(traits_in_scope) } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index 78889ccb89a2..40de9234abc5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -60,8 +60,7 @@ use crate::{ next_solver::{ Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, CallableIdWrapper, Canonical, ClauseKind, CoercePredicate, Const, ConstKind, DbInterner, ErrorGuaranteed, - GenericArgs, PolyFnSig, PredicateKind, Region, RegionKind, SolverDefId, TraitRef, Ty, - TyKind, + GenericArgs, PolyFnSig, PredicateKind, Region, RegionKind, TraitRef, Ty, TyKind, infer::{ InferCtxt, InferOk, InferResult, relate::RelateResult, @@ -223,24 +222,6 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> { } } - // If we are coercing into a TAIT, coerce into its proxy inference var, instead. - // FIXME(next-solver): This should not be here. This is not how rustc does thing, and it also not allows us - // to normalize opaques defined in our scopes. Instead, we should properly register - // `TypingMode::Analysis::defining_opaque_types_and_generators`, and rely on the solver to reveal - // them for us (we'll also need some global-like registry for the values, something we cannot - // really implement, therefore we can really support only RPITs and ITIAT or the new `#[define_opaque]` - // TAIT, not the old global TAIT). - let mut b = b; - if let Some(tait_table) = &self.table.tait_coercion_table - && let TyKind::Alias(rustc_type_ir::Opaque, opaque_ty) = b.kind() - && let SolverDefId::InternedOpaqueTyId(opaque_ty_id) = opaque_ty.def_id - && !matches!(a.kind(), TyKind::Infer(..) | TyKind::Alias(rustc_type_ir::Opaque, _)) - && let Some(ty) = tait_table.get(&opaque_ty_id) - { - b = self.table.shallow_resolve(*ty); - } - let b = b; - // Coercing *from* an unresolved inference variable means that // we have no information about the source type. This will always // ultimately fall back to some form of subtyping. @@ -1528,7 +1509,7 @@ fn coerce<'db>( env: Arc>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, ) -> Result<(Vec>, Ty<'db>), TypeError>> { - let mut table = InferenceTable::new(db, env); + let mut table = InferenceTable::new(db, env, None); let interner = table.interner(); let ((ty1_with_vars, ty2_with_vars), vars) = table.infer_ctxt.instantiate_canonical(tys); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index fd4e374d9c89..b7ab109b3b9d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -1458,10 +1458,11 @@ impl<'db> InferenceContext<'_, 'db> { ) -> Ty<'db> { let coerce_ty = expected.coercion_target_type(&mut self.table); let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr); - let prev_env = block_id.map(|block_id| { + let prev_state = block_id.map(|block_id| { let prev_env = self.table.trait_env.clone(); TraitEnvironment::with_block(&mut self.table.trait_env, block_id); - prev_env + let prev_block = self.table.infer_ctxt.interner.block.replace(block_id); + (prev_env, prev_block) }); let (break_ty, ty) = @@ -1576,8 +1577,9 @@ impl<'db> InferenceContext<'_, 'db> { } }); self.resolver.reset_to_guard(g); - if let Some(prev_env) = prev_env { + if let Some((prev_env, prev_block)) = prev_state { self.table.trait_env = prev_env; + self.table.infer_ctxt.interner.block = prev_block; } break_ty.unwrap_or(ty) @@ -1689,10 +1691,11 @@ impl<'db> InferenceContext<'_, 'db> { // work out while people are typing let canonicalized_receiver = self.canonicalize(receiver_ty); let resolved = method_resolution::lookup_method( - self.db, &canonicalized_receiver, - self.table.trait_env.clone(), - self.get_traits_in_scope().as_ref().left_or_else(|&it| it), + &mut self.table, + Self::get_traits_in_scope(&self.resolver, &self.traits_in_scope) + .as_ref() + .left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), name, ); @@ -1844,10 +1847,11 @@ impl<'db> InferenceContext<'_, 'db> { let canonicalized_receiver = self.canonicalize(receiver_ty); let resolved = method_resolution::lookup_method( - self.db, &canonicalized_receiver, - self.table.trait_env.clone(), - self.get_traits_in_scope().as_ref().left_or_else(|&it| it), + &mut self.table, + Self::get_traits_in_scope(&self.resolver, &self.traits_in_scope) + .as_ref() + .left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), method_name, ); @@ -1892,9 +1896,10 @@ impl<'db> InferenceContext<'_, 'db> { let assoc_func_with_same_name = method_resolution::iterate_method_candidates( &canonicalized_receiver, - self.db, - self.table.trait_env.clone(), - self.get_traits_in_scope().as_ref().left_or_else(|&it| it), + &mut self.table, + Self::get_traits_in_scope(&self.resolver, &self.traits_in_scope) + .as_ref() + .left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), Some(method_name), method_resolution::LookupMode::Path, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs new file mode 100644 index 000000000000..f7719f50ac3e --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs @@ -0,0 +1,147 @@ +//! Defining opaque types via inference. + +use rustc_type_ir::{TypeVisitableExt, fold_regions}; +use tracing::{debug, instrument}; + +use crate::{ + infer::InferenceContext, + next_solver::{ + EarlyBinder, OpaqueTypeKey, SolverDefId, TypingMode, + infer::{opaque_types::OpaqueHiddenType, traits::ObligationCause}, + }, +}; + +impl<'db> InferenceContext<'_, 'db> { + /// This takes all the opaque type uses during HIR typeck. It first computes + /// the concrete hidden type by iterating over all defining uses. + /// + /// A use during HIR typeck is defining if all non-lifetime arguments are + /// unique generic parameters and the hidden type does not reference any + /// inference variables. + /// + /// It then uses these defining uses to guide inference for all other uses. + #[instrument(level = "debug", skip(self))] + pub(super) fn handle_opaque_type_uses(&mut self) { + // We clone the opaques instead of stealing them here as they are still used for + // normalization in the next generation trait solver. + let opaque_types: Vec<_> = self.table.infer_ctxt.clone_opaque_types(); + + self.compute_definition_site_hidden_types(opaque_types); + } +} + +#[expect(unused, reason = "rustc has this")] +#[derive(Copy, Clone, Debug)] +enum UsageKind<'db> { + None, + NonDefiningUse(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>), + UnconstrainedHiddenType(OpaqueHiddenType<'db>), + HasDefiningUse(OpaqueHiddenType<'db>), +} + +impl<'db> UsageKind<'db> { + fn merge(&mut self, other: UsageKind<'db>) { + match (&*self, &other) { + (UsageKind::HasDefiningUse(_), _) | (_, UsageKind::None) => unreachable!(), + (UsageKind::None, _) => *self = other, + // When mergining non-defining uses, prefer earlier ones. This means + // the error happens as early as possible. + ( + UsageKind::NonDefiningUse(..) | UsageKind::UnconstrainedHiddenType(..), + UsageKind::NonDefiningUse(..), + ) => {} + // When merging unconstrained hidden types, we prefer later ones. This is + // used as in most cases, the defining use is the final return statement + // of our function, and other uses with defining arguments are likely not + // intended to be defining. + ( + UsageKind::NonDefiningUse(..) | UsageKind::UnconstrainedHiddenType(..), + UsageKind::UnconstrainedHiddenType(..) | UsageKind::HasDefiningUse(_), + ) => *self = other, + } + } +} + +impl<'db> InferenceContext<'_, 'db> { + fn compute_definition_site_hidden_types( + &mut self, + mut opaque_types: Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)>, + ) { + for entry in opaque_types.iter_mut() { + *entry = self.table.infer_ctxt.resolve_vars_if_possible(*entry); + } + debug!(?opaque_types); + + let interner = self.interner(); + let TypingMode::Analysis { defining_opaque_types_and_generators } = + self.table.infer_ctxt.typing_mode() + else { + unreachable!(); + }; + + for def_id in defining_opaque_types_and_generators { + let def_id = match def_id { + SolverDefId::InternedOpaqueTyId(it) => it, + _ => continue, + }; + + // We do actually need to check this the second pass (we can't just + // store this), because we can go from `UnconstrainedHiddenType` to + // `HasDefiningUse` (because of fallback) + let mut usage_kind = UsageKind::None; + for &(opaque_type_key, hidden_type) in &opaque_types { + if opaque_type_key.def_id != def_id.into() { + continue; + } + + usage_kind.merge(self.consider_opaque_type_use(opaque_type_key, hidden_type)); + + if let UsageKind::HasDefiningUse(..) = usage_kind { + break; + } + } + + if let UsageKind::HasDefiningUse(ty) = usage_kind { + for &(opaque_type_key, hidden_type) in &opaque_types { + if opaque_type_key.def_id != def_id.into() { + continue; + } + + let expected = + EarlyBinder::bind(ty.ty).instantiate(interner, opaque_type_key.args); + self.demand_eqtype(expected, hidden_type.ty); + } + + self.result.type_of_opaque.insert(def_id, ty.ty); + + continue; + } + + self.result.type_of_opaque.insert(def_id, self.types.error); + } + } + + #[tracing::instrument(skip(self), ret)] + fn consider_opaque_type_use( + &self, + opaque_type_key: OpaqueTypeKey<'db>, + hidden_type: OpaqueHiddenType<'db>, + ) -> UsageKind<'db> { + // We ignore uses of the opaque if they have any inference variables + // as this can frequently happen with recursive calls. + // + // See `tests/ui/traits/next-solver/opaques/universal-args-non-defining.rs`. + if hidden_type.ty.has_non_region_infer() { + return UsageKind::UnconstrainedHiddenType(hidden_type); + } + + let cause = ObligationCause::new(); + let at = self.table.infer_ctxt.at(&cause, self.table.trait_env.env); + let hidden_type = match at.deeply_normalize(hidden_type) { + Ok(hidden_type) => hidden_type, + Err(_errors) => OpaqueHiddenType { ty: self.types.error }, + }; + let hidden_type = fold_regions(self.interner(), hidden_type, |_, _| self.types.re_erased); + UsageKind::HasDefiningUse(hidden_type) + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 2dae7cb04ffa..9ade8420138d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -310,9 +310,10 @@ impl<'db> InferenceContext<'_, 'db> { let mut not_visible = None; let res = method_resolution::iterate_method_candidates( &canonical_ty, - self.db, - self.table.trait_env.clone(), - self.get_traits_in_scope().as_ref().left_or_else(|&it| it), + &mut self.table, + Self::get_traits_in_scope(&self.resolver, &self.traits_in_scope) + .as_ref() + .left_or_else(|&it| it), VisibleFromModule::Filter(self.resolver.module()), Some(name), method_resolution::LookupMode::Path, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index a18cdda559d0..0f582a1c2313 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -2,10 +2,10 @@ use std::fmt; -use hir_def::{AdtId, GenericParamId, lang_item::LangItem}; +use hir_def::{AdtId, DefWithBodyId, GenericParamId, lang_item::LangItem}; use hir_expand::name::Name; use intern::sym; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashSet; use rustc_type_ir::{ DebruijnIndex, InferConst, InferTy, RegionVid, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UpcastFrom, @@ -17,12 +17,12 @@ use triomphe::Arc; use crate::{ TraitEnvironment, - db::{HirDatabase, InternedOpaqueTyId}, + db::HirDatabase, infer::InferenceContext, next_solver::{ self, AliasTy, Binder, Canonical, ClauseKind, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Predicate, PredicateKind, Region, RegionKind, - SolverDefId, SolverDefIds, TraitRef, Ty, TyKind, TypingMode, + SolverDefId, TraitRef, Ty, TyKind, TypingMode, fulfill::{FulfillmentCtxt, NextSolverError}, infer::{ DbInternerInferExt, InferCtxt, InferOk, InferResult, @@ -139,10 +139,7 @@ fn could_unify_impl<'db>( select: for<'a> fn(&mut ObligationCtxt<'a, 'db>) -> Vec>, ) -> bool { let interner = DbInterner::new_with(db, Some(env.krate), env.block); - // FIXME(next-solver): I believe this should use `PostAnalysis` (this is only used for IDE things), - // but this causes some bug because of our incorrect impl of `type_of_opaque_hir_typeck()` for TAIT - // and async blocks. - let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); let at = infcx.at(&cause, env.env); let ((ty1_with_vars, ty2_with_vars), _) = infcx.instantiate_canonical(tys); @@ -158,7 +155,6 @@ fn could_unify_impl<'db>( pub(crate) struct InferenceTable<'db> { pub(crate) db: &'db dyn HirDatabase, pub(crate) trait_env: Arc>, - pub(crate) tait_coercion_table: Option>>, pub(crate) infer_ctxt: InferCtxt<'db>, pub(super) fulfillment_cx: FulfillmentCtxt<'db>, pub(super) diverging_type_vars: FxHashSet>, @@ -170,15 +166,23 @@ pub(crate) struct InferenceTableSnapshot<'db> { } impl<'db> InferenceTable<'db> { - pub(crate) fn new(db: &'db dyn HirDatabase, trait_env: Arc>) -> Self { + /// Inside hir-ty you should use this for inference only, and always pass `owner`. + /// Outside it, always pass `owner = None`. + pub(crate) fn new( + db: &'db dyn HirDatabase, + trait_env: Arc>, + owner: Option, + ) -> Self { let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block); - let infer_ctxt = interner.infer_ctxt().build(rustc_type_ir::TypingMode::Analysis { - defining_opaque_types_and_generators: SolverDefIds::new_from_iter(interner, []), - }); + let typing_mode = match owner { + Some(owner) => TypingMode::typeck_for_body(interner, owner.into()), + // IDE things wants to reveal opaque types. + None => TypingMode::PostAnalysis, + }; + let infer_ctxt = interner.infer_ctxt().build(typing_mode); InferenceTable { db, trait_env, - tait_coercion_table: None, fulfillment_cx: FulfillmentCtxt::new(&infer_ctxt), infer_ctxt, diverging_type_vars: FxHashSet::default(), @@ -698,40 +702,7 @@ impl<'db> InferenceTable<'db> { where T: TypeFoldable>, { - struct Folder<'a, 'db> { - table: &'a mut InferenceTable<'db>, - } - impl<'db> TypeFolder> for Folder<'_, 'db> { - fn cx(&self) -> DbInterner<'db> { - self.table.interner() - } - - fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> { - if !ty.references_error() { - return ty; - } - - if ty.is_ty_error() { self.table.next_ty_var() } else { ty.super_fold_with(self) } - } - - fn fold_const(&mut self, ct: Const<'db>) -> Const<'db> { - if !ct.references_error() { - return ct; - } - - if ct.is_ct_error() { - self.table.next_const_var() - } else { - ct.super_fold_with(self) - } - } - - fn fold_region(&mut self, r: Region<'db>) -> Region<'db> { - if r.is_error() { self.table.next_region_var() } else { r } - } - } - - ty.fold_with(&mut Folder { table: self }) + self.infer_ctxt.insert_type_vars(ty) } /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 25579e04ed01..fdacc1d899dc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -27,9 +27,11 @@ mod infer; mod inhabitedness; mod lower; pub mod next_solver; +mod opaques; mod specialization; mod target_feature; mod utils; +mod variance; pub mod autoderef; pub mod consteval; @@ -50,7 +52,6 @@ pub mod traits; mod test_db; #[cfg(test)] mod tests; -mod variance; use std::hash::Hash; @@ -471,6 +472,7 @@ where } } +/// To be used from `hir` only. pub fn callable_sig_from_fn_trait<'db>( self_ty: Ty<'db>, trait_env: Arc>, @@ -482,7 +484,7 @@ pub fn callable_sig_from_fn_trait<'db>( .trait_items(db) .associated_type_by_name(&Name::new_symbol_root(sym::Output))?; - let mut table = InferenceTable::new(db, trait_env.clone()); + let mut table = InferenceTable::new(db, trait_env.clone(), None); // Register two obligations: // - Self: FnOnce diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index cec63566338f..1e3089736205 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -489,9 +489,8 @@ pub fn def_crates<'db>( /// Look up the method with the given name. pub(crate) fn lookup_method<'db>( - db: &'db dyn HirDatabase, ty: &Canonical<'db, Ty<'db>>, - env: Arc>, + table: &mut InferenceTable<'db>, traits_in_scope: &FxHashSet, visible_from_module: VisibleFromModule, name: &Name, @@ -499,8 +498,7 @@ pub(crate) fn lookup_method<'db>( let mut not_visible = None; let res = iterate_method_candidates( ty, - db, - env, + table, traits_in_scope, visible_from_module, Some(name), @@ -656,8 +654,7 @@ impl ReceiverAdjustments { // FIXME add a context type here? pub(crate) fn iterate_method_candidates<'db, T>( ty: &Canonical<'db, Ty<'db>>, - db: &'db dyn HirDatabase, - env: Arc>, + table: &mut InferenceTable<'db>, traits_in_scope: &FxHashSet, visible_from_module: VisibleFromModule, name: Option<&Name>, @@ -665,10 +662,9 @@ pub(crate) fn iterate_method_candidates<'db, T>( mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option, ) -> Option { let mut slot = None; - _ = iterate_method_candidates_dyn( + _ = iterate_method_candidates_dyn_impl( ty, - db, - env, + table, traits_in_scope, visible_from_module, name, @@ -985,6 +981,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool is_not_orphan } +/// To be used from `hir` only. pub fn iterate_path_candidates<'db>( ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, @@ -1007,6 +1004,7 @@ pub fn iterate_path_candidates<'db>( ) } +/// To be used from `hir` only. pub fn iterate_method_candidates_dyn<'db>( ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, @@ -1016,6 +1014,26 @@ pub fn iterate_method_candidates_dyn<'db>( name: Option<&Name>, mode: LookupMode, callback: &mut dyn MethodCandidateCallback, +) -> ControlFlow<()> { + iterate_method_candidates_dyn_impl( + ty, + &mut InferenceTable::new(db, env, None), + traits_in_scope, + visible_from_module, + name, + mode, + callback, + ) +} + +fn iterate_method_candidates_dyn_impl<'db>( + ty: &Canonical<'db, Ty<'db>>, + table: &mut InferenceTable<'db>, + traits_in_scope: &FxHashSet, + visible_from_module: VisibleFromModule, + name: Option<&Name>, + mode: LookupMode, + callback: &mut dyn MethodCandidateCallback, ) -> ControlFlow<()> { let _p = tracing::info_span!( "iterate_method_candidates_dyn", @@ -1046,28 +1064,28 @@ pub fn iterate_method_candidates_dyn<'db>( // the methods by autoderef order of *receiver types*, not *self // types*. - let mut table = InferenceTable::new(db, env); - let ty = table.instantiate_canonical(*ty); - let deref_chain = autoderef_method_receiver(&mut table, ty); + table.run_in_snapshot(|table| { + let ty = table.instantiate_canonical(*ty); + let deref_chain = autoderef_method_receiver(table, ty); - deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| { - iterate_method_candidates_with_autoref( - &mut table, - receiver_ty, - adj, - traits_in_scope, - visible_from_module, - name, - callback, - ) + deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| { + iterate_method_candidates_with_autoref( + table, + receiver_ty, + adj, + traits_in_scope, + visible_from_module, + name, + callback, + ) + }) }) } LookupMode::Path => { // No autoderef for path lookups iterate_method_candidates_for_self_ty( ty, - db, - env, + table, traits_in_scope, visible_from_module, name, @@ -1250,39 +1268,39 @@ fn iterate_method_candidates_by_receiver<'db>( #[tracing::instrument(skip_all, fields(name = ?name))] fn iterate_method_candidates_for_self_ty<'db>( self_ty: &Canonical<'db, Ty<'db>>, - db: &'db dyn HirDatabase, - env: Arc>, + table: &mut InferenceTable<'db>, traits_in_scope: &FxHashSet, visible_from_module: VisibleFromModule, name: Option<&Name>, callback: &mut dyn MethodCandidateCallback, ) -> ControlFlow<()> { - let mut table = InferenceTable::new(db, env); - let self_ty = table.instantiate_canonical(*self_ty); - iterate_inherent_methods( - self_ty, - &mut table, - name, - None, - None, - visible_from_module, - LookupMode::Path, - &mut |adjustments, item, is_visible| { - callback.on_inherent_method(adjustments, item, is_visible) - }, - )?; - iterate_trait_method_candidates( - self_ty, - &mut table, - traits_in_scope, - name, - None, - None, - LookupMode::Path, - &mut |adjustments, item, is_visible| { - callback.on_trait_method(adjustments, item, is_visible) - }, - ) + table.run_in_snapshot(|table| { + let self_ty = table.instantiate_canonical(*self_ty); + iterate_inherent_methods( + self_ty, + table, + name, + None, + None, + visible_from_module, + LookupMode::Path, + &mut |adjustments, item, is_visible| { + callback.on_inherent_method(adjustments, item, is_visible) + }, + )?; + iterate_trait_method_candidates( + self_ty, + table, + traits_in_scope, + name, + None, + None, + LookupMode::Path, + &mut |adjustments, item, is_visible| { + callback.on_trait_method(adjustments, item, is_visible) + }, + ) + }) } #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index db16c943968f..01892657bc21 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -17,7 +17,7 @@ use crate::{ display::DisplayTarget, mir::OperandKind, next_solver::{ - DbInterner, GenericArgs, SolverDefIds, Ty, TypingMode, + DbInterner, GenericArgs, Ty, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, }; @@ -100,11 +100,11 @@ pub fn borrowck_query<'db>( let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block()); let env = db.trait_environment_for_body(def); let mut res = vec![]; + // This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`. + let typing_mode = TypingMode::borrowck(interner, def.into()); all_mir_bodies(db, def, |body| { // FIXME(next-solver): Opaques. - let infcx = interner.infer_ctxt().build(TypingMode::Borrowck { - defining_opaque_types: SolverDefIds::new_from_iter(interner, []), - }); + let infcx = interner.infer_ctxt().build(typing_mode); res.push(BorrowckResult { mutability_of_locals: mutability_of_locals(&infcx, &body), moved_out_of_ref: moved_out_of_ref(&infcx, &env, &body), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs index 0ff0b086a087..77f21062b473 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs @@ -154,6 +154,29 @@ impl From for SolverDefId { } } +impl TryFrom for DefWithBodyId { + type Error = (); + + #[inline] + fn try_from(value: SolverDefId) -> Result { + let id = match value { + SolverDefId::ConstId(id) => id.into(), + SolverDefId::FunctionId(id) => id.into(), + SolverDefId::StaticId(id) => id.into(), + SolverDefId::EnumVariantId(id) | SolverDefId::Ctor(Ctor::Enum(id)) => id.into(), + SolverDefId::InternedOpaqueTyId(_) + | SolverDefId::TraitId(_) + | SolverDefId::TypeAliasId(_) + | SolverDefId::ImplId(_) + | SolverDefId::InternedClosureId(_) + | SolverDefId::InternedCoroutineId(_) + | SolverDefId::Ctor(Ctor::Struct(_)) + | SolverDefId::AdtId(_) => return Err(()), + }; + Ok(id) + } +} + impl TryFrom for GenericDefId { type Error = (); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs index 90bd44aee86f..dedd6a1a6da5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs @@ -63,6 +63,14 @@ impl<'db> GenericArg<'db> { } } + #[inline] + pub(crate) fn expect_region(self) -> Region<'db> { + match self { + GenericArg::Lifetime(region) => region, + _ => panic!("expected a region, got {self:?}"), + } + } + pub fn error_from_id(interner: DbInterner<'db>, id: GenericParamId) -> GenericArg<'db> { match id { GenericParamId::TypeParamId(_) => Ty::new_error(interner, ErrorGuaranteed).into(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs index 36c6c48c5a0b..7b8f52bf7203 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs @@ -13,27 +13,27 @@ use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage}; use region_constraints::{RegionConstraintCollector, RegionConstraintStorage}; use rustc_next_trait_solver::solve::SolverDelegateEvalExt; use rustc_pattern_analysis::Captures; -use rustc_type_ir::TypeFoldable; -use rustc_type_ir::error::{ExpectedFound, TypeError}; -use rustc_type_ir::inherent::{ - Const as _, GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _, -}; use rustc_type_ir::{ ClosureKind, ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy, - IntVarValue, IntVid, OutlivesPredicate, RegionVid, TyVid, UniverseIndex, + IntVarValue, IntVid, OutlivesPredicate, RegionVid, TermKind, TyVid, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, UniverseIndex, + error::{ExpectedFound, TypeError}, + inherent::{ + Const as _, GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _, + }, }; -use rustc_type_ir::{TermKind, TypeVisitableExt}; use snapshot::undo_log::InferCtxtUndoLogs; use tracing::{debug, instrument}; use traits::{ObligationCause, PredicateObligations}; use type_variable::TypeVariableOrigin; use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey}; -use crate::next_solver::fold::BoundVarReplacerDelegate; -use crate::next_solver::infer::select::EvaluationResult; -use crate::next_solver::infer::traits::PredicateObligation; -use crate::next_solver::obligation_ctxt::ObligationCtxt; -use crate::next_solver::{BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, SolverContext}; +use crate::next_solver::{ + BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, SolverContext, + fold::BoundVarReplacerDelegate, + infer::{select::EvaluationResult, traits::PredicateObligation}, + obligation_ctxt::ObligationCtxt, +}; use super::{ AliasTerm, Binder, CanonicalQueryInput, CanonicalVarValues, Const, ConstKind, DbInterner, @@ -46,7 +46,7 @@ use super::{ pub mod at; pub mod canonical; mod context; -mod opaque_types; +pub mod opaque_types; pub mod region_constraints; pub mod relate; pub mod resolve; @@ -400,6 +400,46 @@ impl<'db> InferCtxt<'db> { )) } + pub(crate) fn insert_type_vars(&self, ty: T) -> T + where + T: TypeFoldable>, + { + struct Folder<'a, 'db> { + infcx: &'a InferCtxt<'db>, + } + impl<'db> TypeFolder> for Folder<'_, 'db> { + fn cx(&self) -> DbInterner<'db> { + self.infcx.interner + } + + fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> { + if !ty.references_error() { + return ty; + } + + if ty.is_ty_error() { self.infcx.next_ty_var() } else { ty.super_fold_with(self) } + } + + fn fold_const(&mut self, ct: Const<'db>) -> Const<'db> { + if !ct.references_error() { + return ct; + } + + if ct.is_ct_error() { + self.infcx.next_const_var() + } else { + ct.super_fold_with(self) + } + } + + fn fold_region(&mut self, r: Region<'db>) -> Region<'db> { + if r.is_error() { self.infcx.next_region_var() } else { r } + } + } + + ty.fold_with(&mut Folder { infcx: self }) + } + /// Evaluates whether the predicate can be satisfied in the given /// `ParamEnv`, and returns `false` if not certain. However, this is /// not entirely accurate if inference variables are involved. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/mod.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/mod.rs index 06d998488e15..6b6104b2d903 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/mod.rs @@ -4,9 +4,11 @@ pub(crate) mod table; pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable}; +use macros::{TypeFoldable, TypeVisitable}; + use crate::next_solver::{OpaqueTypeKey, Ty, infer::InferCtxt}; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, TypeVisitable, TypeFoldable)] pub struct OpaqueHiddenType<'db> { pub ty: Ty<'db>, } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs index 0f8b23870fd0..00177d21ac76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs @@ -122,14 +122,6 @@ impl<'db> OpaqueTypeStorage<'db> { } } -impl<'db> Drop for OpaqueTypeStorage<'db> { - fn drop(&mut self) { - if !self.opaque_types.is_empty() { - panic!("{:?}", self.opaque_types) - } - } -} - pub(crate) struct OpaqueTypeTable<'a, 'db> { storage: &'a mut OpaqueTypeStorage<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index c1ccbaf78a70..b18e08bea49b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -7,8 +7,8 @@ pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db}; use base_db::Crate; use hir_def::{ - AdtId, AttrDefId, BlockId, CallableDefId, EnumVariantId, ItemContainerId, StructId, UnionId, - VariantId, + AdtId, AttrDefId, BlockId, CallableDefId, DefWithBodyId, EnumVariantId, ItemContainerId, + StructId, UnionId, VariantId, lang_item::LangItem, signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags}, }; @@ -29,7 +29,7 @@ use rustc_type_ir::{ use crate::{ FnAbi, - db::{HirDatabase, InternedCoroutine}, + db::{HirDatabase, InternedCoroutine, InternedCoroutineId}, method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint}, next_solver::{ AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper, @@ -96,7 +96,7 @@ macro_rules! _interned_vec_nolifetime_salsa { } }; ($name:ident, $ty:ty, nofold) => { - #[salsa::interned(constructor = new_, debug)] + #[salsa::interned(constructor = new_)] pub struct $name { #[returns(ref)] inner_: smallvec::SmallVec<[$ty; 2]>, @@ -119,6 +119,12 @@ macro_rules! _interned_vec_nolifetime_salsa { } } + impl<'db> std::fmt::Debug for $name<'db> { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_slice().fmt(fmt) + } + } + impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> { type Item = $ty; @@ -1866,9 +1872,42 @@ impl<'db> Interner for DbInterner<'db> { Binder::bind_with_vars(inner, bound_vars) } - fn opaque_types_defined_by(self, _defining_anchor: Self::LocalDefId) -> Self::LocalDefIds { - // FIXME(next-solver) - SolverDefIds::new_from_iter(self, []) + fn opaque_types_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds { + let Ok(def_id) = DefWithBodyId::try_from(def_id) else { + return SolverDefIds::default(); + }; + let mut result = Vec::new(); + crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result); + SolverDefIds::new_from_iter(self, result) + } + + fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds { + let Ok(def_id) = DefWithBodyId::try_from(def_id) else { + return SolverDefIds::default(); + }; + let mut result = Vec::new(); + + crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result); + + // Collect coroutines. + let body = self.db.body(def_id); + body.exprs().for_each(|(expr_id, expr)| { + if matches!( + expr, + hir_def::hir::Expr::Async { .. } + | hir_def::hir::Expr::Closure { + closure_kind: hir_def::hir::ClosureKind::Async + | hir_def::hir::ClosureKind::Coroutine(_), + .. + } + ) { + let coroutine = + InternedCoroutineId::new(self.db, InternedCoroutine(def_id, expr_id)); + result.push(coroutine.into()); + } + }); + + SolverDefIds::new_from_iter(self, result) } fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool { @@ -1913,12 +1952,10 @@ impl<'db> Interner for DbInterner<'db> { let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque); match impl_trait_id { crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { - let infer = self.db().infer(func.into()); - EarlyBinder::bind(infer.type_of_rpit[idx]) + crate::opaques::rpit_hidden_types(self.db, func)[idx] } - crate::ImplTraitId::TypeAliasImplTrait(..) => { - // FIXME(next-solver) - EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed)) + crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => { + crate::opaques::tait_hidden_types(self.db, type_alias)[idx] } } } @@ -1969,13 +2006,6 @@ impl<'db> Interner for DbInterner<'db> { true } - fn opaque_types_and_coroutines_defined_by( - self, - _defining_anchor: Self::LocalDefId, - ) -> Self::LocalDefIds { - Default::default() - } - type Probe = rustc_type_ir::solve::inspect::Probe>; fn mk_probe(self, probe: rustc_type_ir::solve::inspect::Probe) -> Self::Probe { probe diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index 487d164f8691..7b96b4008fec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -2,17 +2,22 @@ use hir_def::{AssocItemId, GeneralConstId}; use rustc_next_trait_solver::delegate::SolverDelegate; -use rustc_type_ir::GenericArgKind; -use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::{ - InferCtxtLike, Interner, PredicatePolarity, TypeFlags, TypeVisitableExt, - inherent::{IntoKind, Term as _, Ty as _}, + AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags, + TypeVisitableExt, + inherent::{IntoKind, SliceLike, Term as _, Ty as _}, + lang_items::SolverTraitLangItem, solve::{Certainty, NoSolution}, }; +use tracing::debug; -use crate::next_solver::{CanonicalVarKind, ImplIdWrapper}; -use crate::next_solver::{ - ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate, util::sizedness_fast_path, +use crate::{ + ImplTraitId, + next_solver::{ + AliasTy, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, GenericArgs, ImplIdWrapper, + ParamEnv, Predicate, PredicateKind, SubtypePredicate, Ty, TyKind, fold::fold_tys, + util::sizedness_fast_path, + }, }; use super::{ @@ -76,7 +81,7 @@ impl<'db> SolverDelegate for SolverContext<'db> { fn well_formed_goals( &self, - _param_env: ::ParamEnv, + _param_env: ParamEnv<'db>, _arg: ::Term, ) -> Option< Vec< @@ -125,18 +130,60 @@ impl<'db> SolverDelegate for SolverContext<'db> { fn add_item_bounds_for_hidden_type( &self, - _def_id: ::DefId, - _args: ::GenericArgs, - _param_env: ::ParamEnv, - _hidden_ty: ::Ty, - _goals: &mut Vec< - rustc_type_ir::solve::Goal< - Self::Interner, - ::Predicate, - >, - >, + def_id: SolverDefId, + args: GenericArgs<'db>, + param_env: ParamEnv<'db>, + hidden_ty: Ty<'db>, + goals: &mut Vec>>, ) { - unimplemented!() + let interner = self.interner; + let opaque_id = def_id.expect_opaque_ty(); + // Require that the hidden type is well-formed. We have to + // make sure we wf-check the hidden type to fix #114728. + // + // However, we don't check that all types are well-formed. + // We only do so for types provided by the user or if they are + // "used", e.g. for method selection. + // + // This means we never check the wf requirements of the hidden + // type during MIR borrowck, causing us to infer the wrong + // lifetime for its member constraints which then results in + // unexpected region errors. + goals.push(Goal::new(interner, param_env, ClauseKind::WellFormed(hidden_ty.into()))); + + let replace_opaques_in = |clause: Clause<'db>| { + fold_tys(interner, clause, |ty| match ty.kind() { + // Replace all other mentions of the same opaque type with the hidden type, + // as the bounds must hold on the hidden type after all. + TyKind::Alias( + AliasTyKind::Opaque, + AliasTy { def_id: def_id2, args: args2, .. }, + ) if def_id == def_id2 && args == args2 => hidden_ty, + _ => ty, + }) + }; + + let db = interner.db; + let (opaques_table, opaque_idx) = match opaque_id.loc(db) { + ImplTraitId::ReturnTypeImplTrait(func, opaque_idx) => { + (db.return_type_impl_traits(func), opaque_idx) + } + ImplTraitId::TypeAliasImplTrait(type_alias, opaque_idx) => { + (db.type_alias_impl_traits(type_alias), opaque_idx) + } + }; + let item_bounds = opaques_table + .as_deref() + .unwrap() + .as_ref() + .map_bound(|table| &table.impl_traits[opaque_idx].predicates); + for predicate in item_bounds.iter_instantiated_copied(interner, args.as_slice()) { + let predicate = replace_opaques_in(predicate); + + // Require that the predicate holds for the concrete type. + debug!(?predicate); + goals.push(Goal::new(interner, param_env, predicate)); + } } fn fetch_eligible_assoc_item( @@ -190,8 +237,8 @@ impl<'db> SolverDelegate for SolverContext<'db> { fn is_transmutable( &self, - _dst: ::Ty, - _src: ::Ty, + _dst: Ty<'db>, + _src: Ty<'db>, _assume: ::Const, ) -> Result { unimplemented!() @@ -199,7 +246,7 @@ impl<'db> SolverDelegate for SolverContext<'db> { fn evaluate_const( &self, - _param_env: ::ParamEnv, + _param_env: ParamEnv<'db>, uv: rustc_type_ir::UnevaluatedConst, ) -> Option<::Const> { let c = match uv.def { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs new file mode 100644 index 000000000000..8531f2437739 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs @@ -0,0 +1,199 @@ +//! Handling of opaque types, detection of defining scope and hidden type. + +use hir_def::{ + AssocItemId, AssocItemLoc, DefWithBodyId, FunctionId, HasModule, ItemContainerId, TypeAliasId, +}; +use hir_expand::name::Name; +use la_arena::ArenaMap; +use rustc_type_ir::inherent::Ty as _; +use syntax::ast; +use triomphe::Arc; + +use crate::{ + ImplTraitId, + db::{HirDatabase, InternedOpaqueTyId}, + lower::{ImplTraitIdx, ImplTraits}, + next_solver::{ + DbInterner, EarlyBinder, ErrorGuaranteed, SolverDefId, Ty, TypingMode, + infer::{DbInternerInferExt, traits::ObligationCause}, + obligation_ctxt::ObligationCtxt, + }, +}; + +pub(crate) fn opaque_types_defined_by( + db: &dyn HirDatabase, + def_id: DefWithBodyId, + result: &mut Vec, +) { + if let DefWithBodyId::FunctionId(func) = def_id { + // A function may define its own RPITs. + extend_with_opaques( + db, + db.return_type_impl_traits(func), + |opaque_idx| ImplTraitId::ReturnTypeImplTrait(func, opaque_idx), + result, + ); + } + + let extend_with_taits = |type_alias| { + extend_with_opaques( + db, + db.type_alias_impl_traits(type_alias), + |opaque_idx| ImplTraitId::TypeAliasImplTrait(type_alias, opaque_idx), + result, + ); + }; + + // Collect opaques from assoc items. + let extend_with_atpit_from_assoc_items = |assoc_items: &[(Name, AssocItemId)]| { + assoc_items + .iter() + .filter_map(|&(_, assoc_id)| match assoc_id { + AssocItemId::TypeAliasId(it) => Some(it), + AssocItemId::FunctionId(_) | AssocItemId::ConstId(_) => None, + }) + .for_each(extend_with_taits); + }; + let extend_with_atpit_from_container = |container| match container { + ItemContainerId::ImplId(impl_id) => { + if db.impl_signature(impl_id).target_trait.is_some() { + extend_with_atpit_from_assoc_items(&impl_id.impl_items(db).items); + } + } + ItemContainerId::TraitId(trait_id) => { + extend_with_atpit_from_assoc_items(&trait_id.trait_items(db).items); + } + _ => {} + }; + match def_id { + DefWithBodyId::ConstId(id) => extend_with_atpit_from_container(id.loc(db).container), + DefWithBodyId::FunctionId(id) => extend_with_atpit_from_container(id.loc(db).container), + DefWithBodyId::StaticId(_) | DefWithBodyId::VariantId(_) => {} + } + + // FIXME: Collect opaques from `#[define_opaque]`. + + fn extend_with_opaques<'db>( + db: &'db dyn HirDatabase, + opaques: Option>>>, + mut make_impl_trait: impl FnMut(ImplTraitIdx<'db>) -> ImplTraitId<'db>, + result: &mut Vec, + ) { + if let Some(opaques) = opaques { + for (opaque_idx, _) in (*opaques).as_ref().skip_binder().impl_traits.iter() { + let opaque_id = InternedOpaqueTyId::new(db, make_impl_trait(opaque_idx)); + result.push(opaque_id.into()); + } + } + } +} + +// These are firewall queries to prevent drawing dependencies between infers: + +#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +pub(crate) fn rpit_hidden_types<'db>( + db: &'db dyn HirDatabase, + function: FunctionId, +) -> ArenaMap, EarlyBinder<'db, Ty<'db>>> { + let infer = db.infer(function.into()); + let mut result = ArenaMap::new(); + for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) { + result.insert(opaque, EarlyBinder::bind(hidden_type)); + } + result.shrink_to_fit(); + result +} + +#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +pub(crate) fn tait_hidden_types<'db>( + db: &'db dyn HirDatabase, + type_alias: TypeAliasId, +) -> ArenaMap, EarlyBinder<'db, Ty<'db>>> { + let loc = type_alias.loc(db); + let module = loc.module(db); + let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block()); + let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let mut ocx = ObligationCtxt::new(&infcx); + let cause = ObligationCause::dummy(); + let param_env = db.trait_environment(type_alias.into()).env; + + let defining_bodies = tait_defining_bodies(db, &loc); + + let taits_count = db + .type_alias_impl_traits(type_alias) + .map_or(0, |taits| (*taits).as_ref().skip_binder().impl_traits.len()); + + let mut result = ArenaMap::with_capacity(taits_count); + for defining_body in defining_bodies { + let infer = db.infer(defining_body); + for (&opaque, &hidden_type) in &infer.type_of_opaque { + let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else { + continue; + }; + if opaque_owner != type_alias { + continue; + } + // In the presence of errors, we attempt to create a unified type from all + // types. rustc doesn't do that, but this should improve the experience. + let hidden_type = infcx.insert_type_vars(hidden_type); + match result.entry(opaque_idx) { + la_arena::Entry::Vacant(entry) => { + entry.insert(EarlyBinder::bind(hidden_type)); + } + la_arena::Entry::Occupied(entry) => { + _ = ocx.eq(&cause, param_env, entry.get().instantiate_identity(), hidden_type); + } + } + } + } + + _ = ocx.try_evaluate_obligations(); + + // Fill missing entries. + for idx in 0..taits_count { + let idx = la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(idx as u32)); + match result.entry(idx) { + la_arena::Entry::Vacant(entry) => { + entry.insert(EarlyBinder::bind(Ty::new_error(interner, ErrorGuaranteed))); + } + la_arena::Entry::Occupied(mut entry) => { + *entry.get_mut() = entry.get().map_bound(|hidden_type| { + infcx.resolve_vars_if_possible(hidden_type).replace_infer_with_error(interner) + }); + } + } + } + + result +} + +fn tait_defining_bodies( + db: &dyn HirDatabase, + loc: &AssocItemLoc, +) -> Vec { + let from_assoc_items = |assoc_items: &[(Name, AssocItemId)]| { + // Associated Type Position Impl Trait. + assoc_items + .iter() + .filter_map(|&(_, assoc_id)| match assoc_id { + AssocItemId::FunctionId(it) => Some(it.into()), + AssocItemId::ConstId(it) => Some(it.into()), + AssocItemId::TypeAliasId(_) => None, + }) + .collect() + }; + match loc.container { + ItemContainerId::ImplId(impl_id) => { + if db.impl_signature(impl_id).target_trait.is_some() { + return from_assoc_items(&impl_id.impl_items(db).items); + } + } + ItemContainerId::TraitId(trait_id) => { + return from_assoc_items(&trait_id.trait_items(db).items); + } + _ => {} + } + + // FIXME: Support general TAITs, or decisively decide not to. + Vec::new() +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index bc4701970c76..14ec161c91c8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -591,6 +591,7 @@ fn main() { "function_signature_shim", "function_signature_with_source_map_shim", "trait_environment_shim", + "return_type_impl_traits_shim", "expr_scopes_shim", "struct_signature_shim", "struct_signature_with_source_map_shim", @@ -686,6 +687,7 @@ fn main() { "return_type_impl_traits_shim", "infer_shim", "function_signature_with_source_map_shim", + "return_type_impl_traits_shim", "expr_scopes_shim", "struct_signature_with_source_map_shim", "generic_predicates_shim", diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs index 5cdd170198ba..ca986336ff30 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs @@ -31,7 +31,6 @@ fn test() { } #[test] -#[ignore = "FIXME(next-solver): This currently generates a type mismatch, need to switch opaque type handling to the solver"] fn associated_type_impl_traits_complex() { check_types( r#" @@ -116,6 +115,7 @@ fn foo() { ); } +#[ignore = "FIXME(next-solver): TAIT support was removed, need to rework it to work with `#[define_opaque]`"] #[test] fn type_alias_impl_trait_simple() { check_no_mismatches( @@ -135,9 +135,6 @@ static ALIAS: AliasTy = { "#, ); - // FIXME(next-solver): This should emit type mismatch error but leaving it for now - // as we should fully migrate into next-solver without chalk-ir and TAIT should be - // reworked on r-a to handle `#[define_opaque(T)]` check_infer_with_mismatches( r#" trait Trait {} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 7c79393e65ac..c71cd80d2989 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -725,7 +725,7 @@ fn issue_4885() { 138..146 'bar(key)': impl Future>::Bar> 142..145 'key': &'? K 162..165 'key': &'? K - 224..227 '{ }': () + 224..227 '{ }': impl Future>::Bar> "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs index 5983ec764790..dfbdd25645f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs @@ -180,7 +180,7 @@ impl<'a> IntoIterator for &'a Grid { "#, expect![[r#" 150..154 'self': &'a Grid - 174..181 '{ }': impl Iterator + 174..181 '{ }': <&'a Grid as IntoIterator>::IntoIter "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index f72ca22fd229..c0e439310e98 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -1211,7 +1211,7 @@ fn test(x: impl Trait, y: &impl Trait) { expect![[r#" 29..33 'self': &'? Self 54..58 'self': &'? Self - 98..100 '{}': () + 98..100 '{}': impl Trait 110..111 'x': impl Trait 130..131 'y': &'? impl Trait 151..268 '{ ...2(); }': () @@ -1373,11 +1373,11 @@ fn test() { expect![[r#" 49..53 'self': &'? mut Self 101..105 'self': &'? Self - 184..195 '{ loop {} }': ({unknown}, {unknown}) + 184..195 '{ loop {} }': (impl Iterator>, impl Trait) 186..193 'loop {}': ! 191..193 '{}': () 206..207 't': T - 268..279 '{ loop {} }': ({unknown}, {unknown}) + 268..279 '{ loop {} }': (impl Iterator>, impl Trait) 270..277 'loop {}': ! 275..277 '{}': () 291..413 '{ ...o(); }': () @@ -1419,7 +1419,7 @@ fn foo() -> (impl FnOnce(&str, T), impl Trait) { } "#, expect![[r#" - 134..165 '{ ...(C)) }': (impl FnOnce(&'? str, T), Bar) + 134..165 '{ ...(C)) }': (impl FnOnce(&'? str, T), impl Trait) 140..163 '(|inpu...ar(C))': (impl FnOnce(&'? str, T), Bar) 141..154 '|input, t| {}': impl FnOnce(&'? str, T) 142..147 'input': &'? str @@ -1441,7 +1441,7 @@ fn return_pos_impl_trait_in_projection() { trait Future { type Output; } impl Future for () { type Output = i32; } type Foo = (::Output, F); -fn foo() -> Foo> { +fn foo() -> Foo> { (0, ()) } "#, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 7f6d4ff17f9f..00c8eb774580 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -107,24 +107,26 @@ pub fn next_trait_solve_canonical_in_ctxt<'db>( infer_ctxt: &InferCtxt<'db>, goal: Canonical<'db, Goal<'db, Predicate<'db>>>, ) -> NextTraitSolveResult { - let context = SolverContext(infer_ctxt.clone()); + infer_ctxt.probe(|_| { + let context = <&SolverContext<'db>>::from(infer_ctxt); - tracing::info!(?goal); + tracing::info!(?goal); - let (goal, var_values) = context.instantiate_canonical(&goal); - tracing::info!(?var_values); + let (goal, var_values) = context.instantiate_canonical(&goal); + tracing::info!(?var_values); - let res = context.evaluate_root_goal(goal, Span::dummy(), None); + let res = context.evaluate_root_goal(goal, Span::dummy(), None); - let res = res.map(|r| (r.has_changed, r.certainty)); + let res = res.map(|r| (r.has_changed, r.certainty)); - tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res); + tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res); - match res { - Err(_) => NextTraitSolveResult::NoSolution, - Ok((_, Certainty::Yes)) => NextTraitSolveResult::Certain, - Ok((_, Certainty::Maybe { .. })) => NextTraitSolveResult::Uncertain, - } + match res { + Err(_) => NextTraitSolveResult::NoSolution, + Ok((_, Certainty::Yes)) => NextTraitSolveResult::Certain, + Ok((_, Certainty::Maybe { .. })) => NextTraitSolveResult::Uncertain, + } + }) } /// Solve a trait goal using next trait solver. diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 2bb2f80ecc05..f2faf99fc9e8 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -5136,10 +5136,7 @@ impl<'db> Type<'db> { AliasTy::new(interner, alias.id.into(), args), ); - // FIXME(next-solver): This needs to be `PostAnalysis`, but this currently causes errors due to our incorrect - // handling of opaques. `non_body_analysis()` will also cause errors (from not revealing opaques inside their - // defining places), so we choose between two bad options. - let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let ty = structurally_normalize_ty(&infcx, projection, self.env.clone()); if ty.is_ty_error() { None } else { Some(self.derived(ty)) } } @@ -5758,8 +5755,7 @@ impl<'db> Type<'db> { pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue { let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block); - // FIXME: This should be `PostAnalysis` I believe. - let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.clone()) } } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 91fb4d0a6715..3a195314a781 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -10809,7 +10809,7 @@ type Foo$0 = impl Sized; --- - needs Drop + no Drop "#]], ); check( diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index 5f7e12cf53f8..e927fd57ae96 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -1996,6 +1996,12 @@ fn f &T>(f: F) { #[test] fn regression_13579() { + // FIXME(next-solver): There should be signature help available here. + // The reason it is not is because of a trait solver bug. Since `Error` is not provided + // nor it can be inferred, it becomes an error type. The bug is that the solver ignores + // predicates on error types, and they do not guide infer vars, not allowing us to infer + // that `take`'s return type is callable. + // https://github.com/rust-lang/rust/pull/146602 should fix the solver bug. check( r#" fn f() { @@ -2008,9 +2014,7 @@ fn take( move || count } "#, - expect![[r#" - impl Fn() -> i32 - "#]], + expect![""], ); } From 4c0120e53256e21150fcdcd3cae93b987685c74d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 17:21:26 +0200 Subject: [PATCH 208/525] handle a corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 8 +++++--- .../src/tests/codegen-backend-tests/cg_gcc.md | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 6b3753d8b82f..7f07d6e81420 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -19,7 +19,8 @@ struct Cli { show_diff: bool, } -static REGEX_IGNORE: LazyLock = LazyLock::new(|| Regex::new(r"(\d\.|\-|\*)\s+").unwrap()); +static REGEX_IGNORE: LazyLock = + LazyLock::new(|| Regex::new(r"^\s*(\d\.|\-|\*)\s+").unwrap()); static REGEX_IGNORE_END: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)$").unwrap()); static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)\s+").unwrap()); @@ -173,7 +174,7 @@ ignore e.g. and i.e. ``` some code. block ``` -some more text. +sentence with *italics* should not be ignored. truly. "; let expected = "\ # some. heading @@ -190,7 +191,8 @@ ignore e.g. and i.e. ``` some code. block ``` -some more text. +sentence with *italics* should not be ignored. +truly. "; assert_eq!(expected, comply(original)); } diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index 69db2094838d..4325cc58797f 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -49,7 +49,8 @@ For example: ``` The first backend in the `codegen-backends` array will determine which backend will be used as the -*default backend* of the built `rustc`. This also determines which backend will be used to compile the +*default backend* of the built `rustc`. +This also determines which backend will be used to compile the stage 1 standard library (or anything built in stage 2+). To produce `rustc` that uses the GCC backend by default, you can thus put `"gcc"` as the first element of this array: From 023c4ef74fccdc2711f1a97514978ea214cf41ca Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 2 Aug 2025 23:46:56 +0300 Subject: [PATCH 209/525] When renaming `self` to other name, change callers method method call syntax to assoc fn syntax --- src/tools/rust-analyzer/crates/ide/src/lib.rs | 5 +- .../rust-analyzer/crates/ide/src/rename.rs | 350 +++++++++++++++++- .../crates/rust-analyzer/src/config.rs | 10 +- .../rust-analyzer/src/handlers/request.rs | 8 +- 4 files changed, 358 insertions(+), 15 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 857252832ffe..ece5bac6df4b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -106,7 +106,7 @@ pub use crate::{ move_item::Direction, navigation_target::{NavigationTarget, TryToNav, UpmappingResult}, references::{FindAllRefsConfig, ReferenceSearchResult}, - rename::RenameError, + rename::{RenameConfig, RenameError}, runnables::{Runnable, RunnableKind, TestId, UpdateTest}, signature_help::SignatureHelp, static_index::{ @@ -830,8 +830,9 @@ impl Analysis { &self, position: FilePosition, new_name: &str, + config: &RenameConfig, ) -> Cancellable> { - self.with_db(|db| rename::rename(db, position, new_name)) + self.with_db(|db| rename::rename(db, position, new_name, config)) } pub fn prepare_rename( diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 8922a8eb4858..ce5963919d9a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -4,7 +4,7 @@ //! tests. This module also implements a couple of magic tricks, like renaming //! `self` and to `self` (to switch between associated function and method). -use hir::{AsAssocItem, InFile, Name, Semantics, sym}; +use hir::{AsAssocItem, FindPathConfig, HasContainer, HirDisplay, InFile, Name, Semantics, sym}; use ide_db::{ FileId, FileRange, RootDatabase, defs::{Definition, NameClass, NameRefClass}, @@ -27,6 +27,23 @@ pub use ide_db::rename::RenameError; type RenameResult = Result; +pub struct RenameConfig { + pub prefer_no_std: bool, + pub prefer_prelude: bool, + pub prefer_absolute: bool, +} + +impl RenameConfig { + fn find_path_config(&self) -> FindPathConfig { + FindPathConfig { + prefer_no_std: self.prefer_no_std, + prefer_prelude: self.prefer_prelude, + prefer_absolute: self.prefer_absolute, + allow_unstable: true, + } + } +} + /// This is similar to `collect::, _>>`, but unlike it, it succeeds if there is *any* `Ok` item. fn ok_if_any(iter: impl Iterator>) -> Result, E> { let mut err = None; @@ -100,6 +117,7 @@ pub(crate) fn rename( db: &RootDatabase, position: FilePosition, new_name: &str, + config: &RenameConfig, ) -> RenameResult { let sema = Semantics::new(db); let file_id = sema @@ -158,7 +176,14 @@ pub(crate) fn rename( if let Definition::Local(local) = def { if let Some(self_param) = local.as_self_param(sema.db) { cov_mark::hit!(rename_self_to_param); - return rename_self_to_param(&sema, local, self_param, &new_name, kind); + return rename_self_to_param( + &sema, + local, + self_param, + &new_name, + kind, + config.find_path_config(), + ); } if kind == IdentifierKind::LowercaseSelf { cov_mark::hit!(rename_to_self); @@ -360,7 +385,7 @@ fn transform_assoc_fn_into_method_call( f: hir::Function, ) { let calls = Definition::Function(f).usages(sema).all(); - for (file_id, calls) in calls { + for (_file_id, calls) in calls { for call in calls { let Some(fn_name) = call.name.as_name_ref() else { continue }; let Some(path) = fn_name.syntax().parent().and_then(ast::PathSegment::cast) else { @@ -409,6 +434,12 @@ fn transform_assoc_fn_into_method_call( .unwrap_or_else(|| arg_list.syntax().text_range().end()), }; let replace_range = TextRange::new(replace_start, replace_end); + let macro_file = sema.hir_file_for(fn_name.syntax()); + let Some((replace_range, _)) = + InFile::new(macro_file, replace_range).original_node_file_range_opt(sema.db) + else { + continue; + }; let Some(macro_mapped_self) = sema.original_range_opt(self_arg.syntax()) else { continue; @@ -426,8 +457,8 @@ fn transform_assoc_fn_into_method_call( replacement.push('('); source_change.insert_source_edit( - file_id.file_id(sema.db), - TextEdit::replace(replace_range, replacement), + replace_range.file_id.file_id(sema.db), + TextEdit::replace(replace_range.range, replacement), ); } } @@ -514,12 +545,189 @@ fn rename_to_self( Ok(source_change) } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum CallReceiverAdjust { + Deref, + Ref, + RefMut, + None, +} + +fn method_to_assoc_fn_call_self_adjust( + sema: &Semantics<'_, RootDatabase>, + self_arg: &ast::Expr, +) -> CallReceiverAdjust { + let mut result = CallReceiverAdjust::None; + let self_adjust = sema.expr_adjustments(self_arg); + if let Some(self_adjust) = self_adjust { + let mut i = 0; + while i < self_adjust.len() { + if matches!(self_adjust[i].kind, hir::Adjust::Deref(..)) + && matches!( + self_adjust.get(i + 1), + Some(hir::Adjustment { kind: hir::Adjust::Borrow(..), .. }) + ) + { + // Deref then ref (reborrow), skip them. + i += 2; + continue; + } + + match self_adjust[i].kind { + hir::Adjust::Deref(_) if result == CallReceiverAdjust::None => { + // Autoref takes precedence over deref, because if given a `&Type` the compiler will deref + // it automatically. + result = CallReceiverAdjust::Deref; + } + hir::Adjust::Borrow(hir::AutoBorrow::Ref(mutability)) => { + match (result, mutability) { + (CallReceiverAdjust::RefMut, hir::Mutability::Shared) => {} + (_, hir::Mutability::Mut) => result = CallReceiverAdjust::RefMut, + (_, hir::Mutability::Shared) => result = CallReceiverAdjust::Ref, + } + } + _ => {} + } + + i += 1; + } + } + result +} + +fn transform_method_call_into_assoc_fn( + sema: &Semantics<'_, RootDatabase>, + source_change: &mut SourceChange, + f: hir::Function, + find_path_config: FindPathConfig, +) { + let calls = Definition::Function(f).usages(sema).all(); + for (_file_id, calls) in calls { + for call in calls { + let Some(fn_name) = call.name.as_name_ref() else { continue }; + let Some(method_call) = fn_name.syntax().parent().and_then(ast::MethodCallExpr::cast) + else { + continue; + }; + let Some(mut self_arg) = method_call.receiver() else { + continue; + }; + + let Some(scope) = sema.scope(fn_name.syntax()) else { + continue; + }; + let self_adjust = method_to_assoc_fn_call_self_adjust(sema, &self_arg); + + // Strip parentheses, function arguments have higher precedence than any operator. + while let ast::Expr::ParenExpr(it) = &self_arg { + self_arg = match it.expr() { + Some(it) => it, + None => break, + }; + } + + let needs_comma = method_call.arg_list().is_some_and(|it| it.args().next().is_some()); + + let self_needs_parens = self_adjust != CallReceiverAdjust::None + && self_arg.precedence().needs_parentheses_in(ExprPrecedence::Prefix); + + let replace_start = method_call.syntax().text_range().start(); + let replace_end = method_call + .arg_list() + .and_then(|it| it.l_paren_token()) + .map(|it| it.text_range().end()) + .unwrap_or_else(|| method_call.syntax().text_range().end()); + let replace_range = TextRange::new(replace_start, replace_end); + let macro_file = sema.hir_file_for(fn_name.syntax()); + let Some((replace_range, _)) = + InFile::new(macro_file, replace_range).original_node_file_range_opt(sema.db) + else { + continue; + }; + + let fn_container_path = match f.container(sema.db) { + hir::ItemContainer::Trait(trait_) => { + // FIXME: We always put it as `Trait::function`. Is it better to use `Type::function` (but + // that could conflict with an inherent method)? Or maybe `::function`? + // Or let the user decide? + let Some(path) = scope.module().find_path( + sema.db, + hir::ItemInNs::Types(trait_.into()), + find_path_config, + ) else { + continue; + }; + path.display(sema.db, replace_range.file_id.edition(sema.db)).to_string() + } + hir::ItemContainer::Impl(impl_) => { + let ty = impl_.self_ty(sema.db); + match ty.as_adt() { + Some(adt) => { + let Some(path) = scope.module().find_path( + sema.db, + hir::ItemInNs::Types(adt.into()), + find_path_config, + ) else { + continue; + }; + path.display(sema.db, replace_range.file_id.edition(sema.db)) + .to_string() + } + None => { + let Ok(mut ty) = + ty.display_source_code(sema.db, scope.module().into(), false) + else { + continue; + }; + ty.insert(0, '<'); + ty.push('>'); + ty + } + } + } + _ => continue, + }; + + let Some(macro_mapped_self) = sema.original_range_opt(self_arg.syntax()) else { + continue; + }; + let mut replacement = String::new(); + replacement.push_str(&fn_container_path); + replacement.push_str("::"); + format_to!(replacement, "{fn_name}"); + replacement.push('('); + replacement.push_str(match self_adjust { + CallReceiverAdjust::Deref => "*", + CallReceiverAdjust::Ref => "&", + CallReceiverAdjust::RefMut => "&mut ", + CallReceiverAdjust::None => "", + }); + if self_needs_parens { + replacement.push('('); + } + replacement.push_str(macro_mapped_self.text(sema.db)); + if self_needs_parens { + replacement.push(')'); + } + if needs_comma { + replacement.push_str(", "); + } + + source_change.insert_source_edit( + replace_range.file_id.file_id(sema.db), + TextEdit::replace(replace_range.range, replacement), + ); + } + } +} + fn rename_self_to_param( sema: &Semantics<'_, RootDatabase>, local: hir::Local, self_param: hir::SelfParam, new_name: &Name, identifier_kind: IdentifierKind, + find_path_config: FindPathConfig, ) -> RenameResult { if identifier_kind == IdentifierKind::LowercaseSelf { // Let's do nothing rather than complain. @@ -527,6 +735,11 @@ fn rename_self_to_param( return Ok(SourceChange::default()); } + let fn_def = match local.parent(sema.db) { + hir::DefWithBody::Function(func) => func, + _ => bail!("Cannot rename local to self outside of function"), + }; + let InFile { file_id, value: self_param } = sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?; @@ -554,6 +767,7 @@ fn rename_self_to_param( ), ) })); + transform_method_call_into_assoc_fn(sema, &mut source_change, fn_def, find_path_config); Ok(source_change) } @@ -587,7 +801,10 @@ mod tests { use crate::fixture; - use super::{RangeInfo, RenameError}; + use super::{RangeInfo, RenameConfig, RenameError}; + + const TEST_CONFIG: RenameConfig = + RenameConfig { prefer_no_std: false, prefer_prelude: true, prefer_absolute: false }; #[track_caller] fn check( @@ -603,7 +820,7 @@ mod tests { panic!("Prepare rename to '{new_name}' was failed: {err}") } let rename_result = analysis - .rename(position, new_name) + .rename(position, new_name, &TEST_CONFIG) .unwrap_or_else(|err| panic!("Rename to '{new_name}' was cancelled: {err}")); match rename_result { Ok(source_change) => { @@ -635,7 +852,7 @@ mod tests { #[track_caller] fn check_conflicts(new_name: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str) { let (analysis, position, conflicts) = fixture::annotations(ra_fixture); - let source_change = analysis.rename(position, new_name).unwrap().unwrap(); + let source_change = analysis.rename(position, new_name, &TEST_CONFIG).unwrap().unwrap(); let expected_conflicts = conflicts .into_iter() .map(|(file_range, _)| (file_range.file_id, file_range.range)) @@ -662,8 +879,10 @@ mod tests { expect: Expect, ) { let (analysis, position) = fixture::position(ra_fixture); - let source_change = - analysis.rename(position, new_name).unwrap().expect("Expect returned a RenameError"); + let source_change = analysis + .rename(position, new_name, &TEST_CONFIG) + .unwrap() + .expect("Expect returned a RenameError"); expect.assert_eq(&filter_expect(source_change)) } @@ -3585,6 +3804,117 @@ impl Foo { fn bar(v: Foo) { v.foo(123); +} + "#, + ); + } + + #[test] + fn rename_to_self_callers_in_macro() { + check( + "self", + r#" +struct Foo; + +impl Foo { + fn foo(th$0is: &Self, v: i32) {} +} + +macro_rules! m { ($it:expr) => { $it } } +fn bar(v: Foo) { + m!(Foo::foo(&v, 123)); +} + "#, + r#" +struct Foo; + +impl Foo { + fn foo(&self, v: i32) {} +} + +macro_rules! m { ($it:expr) => { $it } } +fn bar(v: Foo) { + m!(v.foo( 123)); +} + "#, + ); + } + + #[test] + fn rename_from_self_callers() { + check( + "this", + r#" +//- minicore: add +struct Foo; +impl Foo { + fn foo(&sel$0f) {} +} +impl core::ops::Add for Foo { + type Output = Foo; + + fn add(self, _rhs: Self) -> Self::Output { + Foo + } +} + +fn bar(v: &Foo) { + v.foo(); + (Foo + Foo).foo(); +} + +mod baz { + fn baz(v: super::Foo) { + v.foo(); + } +} + "#, + r#" +struct Foo; +impl Foo { + fn foo(this: &Self) {} +} +impl core::ops::Add for Foo { + type Output = Foo; + + fn add(self, _rhs: Self) -> Self::Output { + Foo + } +} + +fn bar(v: &Foo) { + Foo::foo(v); + Foo::foo(&(Foo + Foo)); +} + +mod baz { + fn baz(v: super::Foo) { + crate::Foo::foo(&v); + } +} + "#, + ); + // Multiple args: + check( + "this", + r#" +struct Foo; +impl Foo { + fn foo(&sel$0f, _v: i32) {} +} + +fn bar() { + Foo.foo(1); +} + "#, + r#" +struct Foo; +impl Foo { + fn foo(this: &Self, _v: i32) {} +} + +fn bar() { + Foo::foo(&Foo, 1); } "#, ); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 652c2e32ffa6..6d2907ee56aa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -12,7 +12,7 @@ use ide::{ CompletionFieldsToResolve, DiagnosticsConfig, GenericParameterHints, GotoDefinitionConfig, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, - Snippet, SnippetScope, SourceRootId, + RenameConfig, Snippet, SnippetScope, SourceRootId, }; use ide_db::{ MiniCore, SnippetCap, @@ -1705,6 +1705,14 @@ impl Config { } } + pub fn rename(&self, source_root: Option) -> RenameConfig { + RenameConfig { + prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), + prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), + prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(), + } + } + pub fn call_hierarchy<'a>(&self, minicore: MiniCore<'a>) -> CallHierarchyConfig<'a> { CallHierarchyConfig { exclude_tests: self.references_excludeTests().to_owned(), minicore } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 55d092f30f6b..2976441d762a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -1325,8 +1325,12 @@ pub(crate) fn handle_rename( let _p = tracing::info_span!("handle_rename").entered(); let position = try_default!(from_proto::file_position(&snap, params.text_document_position)?); - let mut change = - snap.analysis.rename(position, ¶ms.new_name)?.map_err(to_proto::rename_error)?; + let source_root = snap.analysis.source_root_id(position.file_id).ok(); + let config = snap.config.rename(source_root); + let mut change = snap + .analysis + .rename(position, ¶ms.new_name, &config)? + .map_err(to_proto::rename_error)?; // this is kind of a hack to prevent double edits from happening when moving files // When a module gets renamed by renaming the mod declaration this causes the file to move From 14a99007fbf1a1e45a13cb04ee2855150e01e6bf Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 17:33:51 +0200 Subject: [PATCH 210/525] fix env use --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 30e93c42a0ab..c9c23bf9935a 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -87,4 +87,4 @@ jobs: continue-on-error: true run: | # using split_inclusive that uses regex feature that uses an unstable feature - RUSTC_BOOTSTRAP=true cargo run --manifest-path ci/sembr/Cargo.toml src + RUSTC_BOOTSTRAP=1 cargo run --manifest-path ci/sembr/Cargo.toml src From cc1ab9325cdcfc7543d79391db2d003af33c75ef Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 17:49:09 +0200 Subject: [PATCH 211/525] sample output --- src/doc/rustc-dev-guide/src/tests/ci.md | 230 +++++++++++++----------- 1 file changed, 121 insertions(+), 109 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 6c0b5c2e8455..0be87c064537 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -7,18 +7,18 @@ From a high-level point of view, when you open a pull request at `rust-lang/rust`, the following will happen: - A small [subset](#pull-request-builds) of tests and checks are run after each - push to the PR. This should help catch common errors. + push to the PR. + This should help catch common errors. - When the PR is approved, the [bors] bot enqueues the PR into a [merge queue]. - Once the PR gets to the front of the queue, bors will create a merge commit - and run the [full test suite](#auto-builds) on it. The merge commit either - contains only one specific PR or it can be a ["rollup"](#rollups) which + and run the [full test suite](#auto-builds) on it. + The merge commit either contains only one specific PR or it can be a ["rollup"](#rollups) which combines multiple PRs together, to reduce CI costs and merge delays. - Once the whole test suite finishes, two things can happen. Either CI fails with an error that needs to be addressed by the developer, or CI succeeds and the merge commit is then pushed to the `master` branch. -If you want to modify what gets executed on CI, see [Modifying CI -jobs](#modifying-ci-jobs). +If you want to modify what gets executed on CI, see [Modifying CI jobs](#modifying-ci-jobs). ## CI workflow @@ -26,10 +26,10 @@ jobs](#modifying-ci-jobs). Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are -unified for all CI jobs that we execute. When a commit is pushed to a -corresponding branch or a PR, the workflow executes the -[`src/ci/citool`] crate, which dynamically generates the specific CI -jobs that should be executed. This script uses the [`jobs.yml`] file as an +unified for all CI jobs that we execute. +When a commit is pushed to a corresponding branch or a PR, the workflow executes the +[`src/ci/citool`] crate, which dynamically generates the specific CI jobs that should be executed. +This script uses the [`jobs.yml`] file as an input, which contains a declarative configuration of all our CI jobs. > Almost all build steps shell out to separate scripts. This keeps the CI fairly @@ -38,21 +38,22 @@ input, which contains a declarative configuration of all our CI jobs. > orchestrating the scripts that drive the process. In essence, all CI jobs run `./x test`, `./x dist` or some other command with -different configurations, across various operating systems, targets, and -platforms. There are two broad categories of jobs that are executed, `dist` and -non-`dist` jobs. +different configurations, across various operating systems, targets, and platforms. +There are two broad categories of jobs that are executed, `dist` and non-`dist` jobs. - Dist jobs build a full release of the compiler for a specific platform, - including all the tools we ship through rustup. Those builds are then uploaded + including all the tools we ship through rustup. + Those builds are then uploaded to the `rust-lang-ci2` S3 bucket and are available to be locally installed - with the [rustup-toolchain-install-master] tool. The same builds are also used + with the [rustup-toolchain-install-master] tool. + The same builds are also used for actual releases: our release process basically consists of copying those artifacts from `rust-lang-ci2` to the production endpoint and signing them. - Non-dist jobs run our full test suite on the platform, and the test suite of - all the tools we ship through rustup; The amount of stuff we test depends on + all the tools we ship through rustup; + The amount of stuff we test depends on the platform (for example some tests are run only on Tier 1 platforms), and - some quicker platforms are grouped together on the same builder to avoid - wasting CI resources. + some quicker platforms are grouped together on the same builder to avoid wasting CI resources. Based on an input event (usually a push to a branch), we execute one of three kinds of builds (sets of jobs). @@ -65,13 +66,15 @@ kinds of builds (sets of jobs). ### Pull Request builds -After each push to a pull request, a set of `pr` jobs are executed. Currently, -these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-check-2` -and `tidy` jobs, all running on Linux. These execute a relatively short -(~40 minutes) and lightweight test suite that should catch common issues. More -specifically, they run a set of lints, they try to perform a cross-compile check +After each push to a pull request, a set of `pr` jobs are executed. +Currently, these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-check-2` +and `tidy` jobs, all running on Linux. +These execute a relatively short +(~40 minutes) and lightweight test suite that should catch common issues. +More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts), and they test the -compiler using a *system* version of LLVM. Unfortunately, it would take too many +compiler using a *system* version of LLVM. +Unfortunately, it would take too many resources to run the full test suite for each commit on every PR. > **Note on doc comments** @@ -84,27 +87,28 @@ resources to run the full test suite for each commit on every PR. > Thus, it is a good idea to run `./x doc xxx` locally for any doc comment > changes to help catch these early. -PR jobs are defined in the `pr` section of [`jobs.yml`]. Their results can be observed +PR jobs are defined in the `pr` section of [`jobs.yml`]. +Their results can be observed directly on the PR, in the "CI checks" section at the bottom of the PR page. ### Auto builds -Before a commit can be merged into the `master` branch, it needs to pass our -complete test suite. We call this an `auto` build. This build runs tens of CI -jobs that exercise various tests across operating systems and targets. The full -test suite is quite slow; it can take several hours until all the `auto` CI -jobs finish. +Before a commit can be merged into the `master` branch, it needs to pass our complete test suite. +We call this an `auto` build. +This build runs tens of CI jobs that exercise various tests across operating systems and targets. +The full test suite is quite slow; +it can take several hours until all the `auto` CI jobs finish. Most platforms only run the build steps, some run a restricted set of tests; only a subset run the full suite of tests (see Rust's [platform tiers]). -Auto jobs are defined in the `auto` section of [`jobs.yml`]. They are executed -on the `auto` branch under the `rust-lang/rust` repository, +Auto jobs are defined in the `auto` section of [`jobs.yml`]. +They are executed on the `auto` branch under the `rust-lang/rust` repository, and the final result will be reported via a comment made by bors on the corresponding PR. The live results can be seen on [the GitHub Actions workflows page]. -At any given time, at most a single `auto` build is being executed. Find out -more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). +At any given time, at most a single `auto` build is being executed. +Find out more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). [platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support @@ -112,7 +116,8 @@ more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). Sometimes we want to run a subset of the test suite on CI for a given PR, or build a set of compiler artifacts from that PR, without attempting to merge it. -We call this a "try build". A try build is started after a user with the proper +We call this a "try build". +A try build is started after a user with the proper permissions posts a PR comment with the `@bors try` command. There are several use-cases for try builds: @@ -121,9 +126,9 @@ There are several use-cases for try builds: For this, a working compiler build is needed, which can be generated with a try build that runs the [dist-x86_64-linux] CI job, which builds an optimized version of the compiler on Linux (this job is currently executed by default - when you start a try build). To create a try build and schedule it for a - performance benchmark, you can use the `@bors try @rust-timer queue` command - combination. + when you start a try build). + To create a try build and schedule it for a + performance benchmark, you can use the `@bors try @rust-timer queue` command combination. - Check the impact of the PR across the Rust ecosystem, using a [Crater](crater.md) run. Again, a working compiler build is needed for this, which can be produced by the [dist-x86_64-linux] CI job. @@ -131,25 +136,32 @@ There are several use-cases for try builds: passes the test suite executed by that job. By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of -[`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build -will not execute any tests, and it will allow compilation warnings. It is useful when you want to +[`jobs.yml`] will be executed. +We call this mode a "fast try build". +Such a try build will not execute any tests, and it will allow compilation warnings. +It is useful when you want to get an optimized toolchain as fast as possible, for a Crater run or performance benchmarks, -even if it might not be working fully correctly. If you want to do a full build for the default try job, +even if it might not be working fully correctly. +If you want to do a full build for the default try job, specify its job name in a job pattern (explained below). If you want to run custom CI jobs in a try build and make sure that they pass all tests and do not produce any compilation warnings, you can select CI jobs to be executed by specifying a *job pattern*, which can be used in one of two ways: - You can add a set of `try-job: ` directives to the PR description (described below) and then - simply run `@bors try`. CI will read these directives and run the jobs that you have specified. This is + simply run `@bors try`. + CI will read these directives and run the jobs that you have specified. + This is useful if you want to rerun the same set of try jobs multiple times, after incrementally modifying a PR. - You can specify the job pattern using the `jobs` parameter of the try command: `@bors try jobs=`. - This is useful for one-off try builds with specific jobs. Note that the `jobs` parameter has a higher priority - than the PR description directives. + This is useful for one-off try builds with specific jobs. + Note that the `jobs` parameter has a higher priority than the PR description directives. - There can also be multiple patterns specified, e.g. `@bors try jobs=job1,job2,job3`. Each job pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, -for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using +for example `*msvc*` or `*-alt`. +You can start at most 20 jobs in a single try build. +When using glob patterns in the PR description, you can optionally wrap them in backticks (`` ` ``) to avoid GitHub rendering the pattern as Markdown if it contains e.g. an asterisk. Note that this escaping will not work when using the `@bors jobs=` parameter. @@ -198,8 +210,7 @@ a single try build running on a single PR at any given time. Note that try builds are handled using the [new bors] implementation. -[rustc-perf]: https://github.com/rust-lang/rustc-perf -[new bors]: https://github.com/rust-lang/bors +[rustc-perf]: https://github.com/rust-lang/rustc-perf [new bors]: https://github.com/rust-lang/bors ### Modifying CI jobs @@ -208,20 +219,20 @@ If you want to modify what gets executed on our CI, you can simply modify the You can also modify what gets executed temporarily, for example to test a particular platform or configuration that is challenging to test locally (for -example, if a Windows build fails, but you don't have access to a Windows -machine). Don't hesitate to use CI resources in such situations. +example, if a Windows build fails, but you don't have access to a Windows machine). +Don't hesitate to use CI resources in such situations. You can perform an arbitrary CI job in two ways: - Use the [try build](#try-builds) functionality, and specify the CI jobs that you want to be executed in try builds in your PR description. - Modify the [`pr`](#pull-request-builds) section of `jobs.yml` to specify which - CI jobs should be executed after each push to your PR. This might be faster - than repeatedly starting try builds. + CI jobs should be executed after each push to your PR. + This might be faster than repeatedly starting try builds. To modify the jobs executed after each push to a PR, you can simply copy one of -the job definitions from the `auto` section to the `pr` section. For example, -the `x86_64-msvc` job is responsible for running the 64-bit MSVC tests. You can -copy it to the `pr` section to cause it to be executed after a commit is pushed +the job definitions from the `auto` section to the `pr` section. +For example, the `x86_64-msvc` job is responsible for running the 64-bit MSVC tests. +You can copy it to the `pr` section to cause it to be executed after a commit is pushed to your PR, like this: ```yaml @@ -238,8 +249,8 @@ pr: <<: *job-windows-8c ``` -Then you can commit the file and push it to your PR branch on GitHub. GitHub -Actions should then execute this CI job after each push to your PR. +Then you can commit the file and push it to your PR branch on GitHub. +GitHub Actions should then execute this CI job after each push to your PR.
@@ -247,12 +258,12 @@ Actions should then execute this CI job after each push to your PR. you have made to `jobs.yml`, if they were supposed to be temporary!** A good practice is to prefix `[WIP]` in PR title while still running try jobs -and `[DO NOT MERGE]` in the commit that modifies the CI jobs for testing -purposes. +and `[DO NOT MERGE]` in the commit that modifies the CI jobs for testing purposes.
Although you are welcome to use CI, just be conscious that this is a shared -resource with limited concurrency. Try not to enable too many jobs at once; +resource with limited concurrency. +Try not to enable too many jobs at once; one or two should be sufficient in most cases. ## Merging PRs serially with bors @@ -265,26 +276,28 @@ after the build happened. To ensure a `master` branch that works all the time, we forbid manual merges. Instead, all PRs have to be approved through our bot, [bors] (the software -behind it is called [homu]). All the approved PRs are put in a [merge queue] -(sorted by priority and creation date) and are automatically tested one at the -time. If all the builders are green, the PR is merged, otherwise the failure is +behind it is called [homu]). +All the approved PRs are put in a [merge queue] +(sorted by priority and creation date) and are automatically tested one at the time. +If all the builders are green, the PR is merged, otherwise the failure is recorded and the PR will have to be re-approved again. Bors doesn’t interact with CI services directly, but it works by pushing the merge commit it wants to test to specific branches (like `auto` or `try`), which -are configured to execute CI checks. Bors then detects the outcome of the build -by listening for either Commit Statuses or Check Runs. Since the merge commit is +are configured to execute CI checks. +Bors then detects the outcome of the build by listening for either Commit Statuses or Check Runs. +Since the merge commit is based on the latest `master` and only one can be tested at the same time, when the results are green, `master` is fast-forwarded to that merge commit. Unfortunately, testing a single PR at a time, combined with our long CI (~2 hours for a full run), means we can’t merge a lot of PRs in a single day, and a -single failure greatly impacts our throughput. The maximum number of -PRs we can merge in a day is around ~10. +single failure greatly impacts our throughput. +The maximum number of PRs we can merge in a day is around ~10. The long CI run times, and requirement for a large builder pool, is largely due -to the fact that full release artifacts are built in the `dist-` builders. This -is worth it because these release artifacts: +to the fact that full release artifacts are built in the `dist-` builders. +This is worth it because these release artifacts: - Allow perf testing even at a later date. - Allow bisection when bugs are discovered later. @@ -295,23 +308,23 @@ is worth it because these release artifacts: Some PRs don’t need the full test suite to be executed: trivial changes like typo fixes or README improvements *shouldn’t* break the build, and testing every -single one of them for 2+ hours would be wasteful. To solve this, we -regularly create a "rollup", a PR where we merge several pending trivial PRs so -they can be tested together. Rollups are created manually by a team member using -the "create a rollup" button on the [merge queue]. The team member uses their -judgment to decide if a PR is risky or not. +single one of them for 2+ hours would be wasteful. +To solve this, we regularly create a "rollup", a PR where we merge several pending trivial PRs so +they can be tested together. +Rollups are created manually by a team member using +the "create a rollup" button on the [merge queue]. +The team member uses their judgment to decide if a PR is risky or not. ## Docker All CI jobs, except those on macOS and Windows, are executed inside that -platform’s custom [Docker container]. This has a lot of advantages for us: +platform’s custom [Docker container]. +This has a lot of advantages for us: - The build environment is consistent regardless of the changes of the - underlying image (switching from the trusty image to xenial was painless for - us). + underlying image (switching from the trusty image to xenial was painless for us). - We can use ancient build environments to ensure maximum binary compatibility, - for example [using older CentOS releases][dist-x86_64-linux] on our Linux - builders. + for example [using older CentOS releases][dist-x86_64-linux] on our Linux builders. - We can avoid reinstalling tools (like QEMU or the Android emulator) every time, thanks to Docker image caching. - Users can run the same tests in the same environment locally by just running this command: @@ -325,13 +338,11 @@ platform’s custom [Docker container]. This has a lot of advantages for us: The Docker images prefixed with `dist-` are used for building artifacts while those without that prefix run tests and checks. -We also run tests for less common architectures (mainly Tier 2 and Tier 3 -platforms) in CI. Since those platforms are not x86, we either run everything -inside QEMU, or we just cross-compile if we don’t want to run the tests for that -platform. +We also run tests for less common architectures (mainly Tier 2 and Tier 3 platforms) in CI. +Since those platforms are not x86, we either run everything +inside QEMU, or we just cross-compile if we don’t want to run the tests for that platform. -These builders are running on a special pool of builders set up and maintained -for us by GitHub. +These builders are running on a special pool of builders set up and maintained for us by GitHub. [Docker container]: https://github.com/rust-lang/rust/tree/master/src/ci/docker @@ -341,16 +352,16 @@ Our CI workflow uses various caching mechanisms, mainly for two things: ### Docker images caching -The Docker images we use to run most of the Linux-based builders take a *long* -time to fully build. To speed up the build, we cache them using [Docker registry -caching], with the intermediate artifacts being stored on [ghcr.io]. We also -push the built Docker images to ghcr, so that they can be reused by other tools -(rustup) or by developers running the Docker build locally (to speed up their -build). +The Docker images we use to run most of the Linux-based builders take a *long* time to fully build. +To speed up the build, we cache them using [Docker registry +caching], with the intermediate artifacts being stored on [ghcr.io]. +We also push the built Docker images to ghcr, so that they can be reused by other tools +(rustup) or by developers running the Docker build locally (to speed up their build). Since we test multiple, diverged branches (`master`, `beta` and `stable`), we can’t rely on a single cache for the images, otherwise builds on a branch would -override the cache for the others. Instead, we store the images under different +override the cache for the others. +Instead, we store the images under different tags, identifying them with a custom hash made from the contents of all the Dockerfiles and related scripts. @@ -367,17 +378,17 @@ invalidated if one of the following changes: ### LLVM caching with Sccache We build some C/C++ stuff in various CI jobs, and we rely on [Sccache] to cache -the intermediate LLVM artifacts. Sccache is a distributed ccache developed by +the intermediate LLVM artifacts. +Sccache is a distributed ccache developed by Mozilla, which can use an object storage bucket as the storage backend. -With Sccache there's no need to calculate the hash key ourselves. Sccache -invalidates the cache automatically when it detects changes to relevant inputs, -such as the source code, the version of the compiler, and important environment -variables. +With Sccache there's no need to calculate the hash key ourselves. +Sccache invalidates the cache automatically when it detects changes to relevant inputs, +such as the source code, the version of the compiler, and important environment variables. So we just pass the Sccache wrapper on top of Cargo and Sccache does the rest. -We store the persistent artifacts on the S3 bucket, `rust-lang-ci-sccache2`. So -when the CI runs, if Sccache sees that LLVM is being compiled with the same C/C++ +We store the persistent artifacts on the S3 bucket, `rust-lang-ci-sccache2`. +So when the CI runs, if Sccache sees that LLVM is being compiled with the same C/C++ compiler and the LLVM source code is the same, Sccache retrieves the individual compiled translation units from S3. @@ -396,26 +407,28 @@ receives the build logs on failure, and extracts the error message automatically posting it on the PR thread. The bot is not hardcoded to look for error strings, but was trained with a bunch -of build failures to recognize which lines are common between builds and which -are not. While the generated snippets can be weird sometimes, the bot is pretty -good at identifying the relevant lines, even if it’s an error we've never seen -before. +of build failures to recognize which lines are common between builds and which are not. +While the generated snippets can be weird sometimes, the bot is pretty +good at identifying the relevant lines, even if it’s an error we've never seen before. [rla]: https://github.com/rust-lang/rust-log-analyzer ### Toolstate to support allowed failures The `rust-lang/rust` repo doesn’t only test the compiler on its CI, but also a -variety of tools and documentation. Some documentation is pulled in via git -submodules. If we blocked merging rustc PRs on the documentation being fixed, we +variety of tools and documentation. +Some documentation is pulled in via git submodules. +If we blocked merging rustc PRs on the documentation being fixed, we would be stuck in a chicken-and-egg problem, because the documentation's CI would not pass since updating it would need the not-yet-merged version of rustc to test against (and we usually require CI to be passing). To avoid the problem, submodules are allowed to fail, and their status is -recorded in [rust-toolstate]. When a submodule breaks, a bot automatically pings +recorded in [rust-toolstate]. +When a submodule breaks, a bot automatically pings the maintainers so they know about the breakage, and it records the failure on -the toolstate repository. The release process will then ignore broken tools on +the toolstate repository. +The release process will then ignore broken tools on nightly, removing them from the shipped nightlies. While tool failures are allowed most of the time, they’re automatically @@ -448,8 +461,8 @@ To learn more about the dashboard, see the [Datadog CI docs]. ## Determining the CI configuration If you want to determine which `bootstrap.toml` settings are used in CI for a -particular job, it is probably easiest to just look at the build log. To do -this: +particular job, it is probably easiest to just look at the build log. +To do this: 1. Go to @@ -463,8 +476,7 @@ this: [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml [`src/ci/citool`]: https://github.com/rust-lang/rust/blob/master/src/ci/citool -[bors]: https://github.com/bors -[homu]: https://github.com/rust-lang/homu +[bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu [merge queue]: https://bors.rust-lang.org/queue/rust [dist-x86_64-linux]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile [the GitHub Actions workflows page]: https://github.com/rust-lang/rust/actions From 0c218410b46728d425981c82727e10100aa0aefc Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 18:08:34 +0200 Subject: [PATCH 212/525] fix corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 12 ++++++++++++ src/doc/rustc-dev-guide/src/tests/ci.md | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 7f07d6e81420..accdcb68c319 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -22,6 +22,8 @@ struct Cli { static REGEX_IGNORE: LazyLock = LazyLock::new(|| Regex::new(r"^\s*(\d\.|\-|\*)\s+").unwrap()); static REGEX_IGNORE_END: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)$").unwrap()); +static REGEX_IGNORE_LINK_TARGETS: LazyLock = + LazyLock::new(|| Regex::new(r"^\[.+\]: ").unwrap()); static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)\s+").unwrap()); fn main() -> Result<()> { @@ -94,6 +96,7 @@ fn ignore(line: &str, in_code_block: bool) -> bool { || line.starts_with('#') || line.trim().is_empty() || REGEX_IGNORE.is_match(line) + || REGEX_IGNORE_LINK_TARGETS.is_match(line) } fn comply(content: &str) -> String { @@ -221,6 +224,15 @@ fn test_prettify_prefix_spaces() { assert_eq!(expected, lengthen_lines(original, 50)); } +#[test] +fn test_prettify_ignore_link_targets() { + let original = "\ +[a target]: https://example.com +[another target]: https://example.com +"; + assert_eq!(original, lengthen_lines(original, 100)); +} + #[test] fn test_sembr_then_prettify() { let original = "\ diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 0be87c064537..c0e48b314403 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -210,7 +210,8 @@ a single try build running on a single PR at any given time. Note that try builds are handled using the [new bors] implementation. -[rustc-perf]: https://github.com/rust-lang/rustc-perf [new bors]: https://github.com/rust-lang/bors +[rustc-perf]: https://github.com/rust-lang/rustc-perf +[new bors]: https://github.com/rust-lang/bors ### Modifying CI jobs @@ -476,7 +477,8 @@ To do this: [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml [`src/ci/citool`]: https://github.com/rust-lang/rust/blob/master/src/ci/citool -[bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu +[bors]: https://github.com/bors +[homu]: https://github.com/rust-lang/homu [merge queue]: https://bors.rust-lang.org/queue/rust [dist-x86_64-linux]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile [the GitHub Actions workflows page]: https://github.com/rust-lang/rust/actions From 08235dd08ad891f5c1a70cdcd92f5d903bdbcb46 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 18:33:21 +0200 Subject: [PATCH 213/525] about sembr tool --- src/doc/rustc-dev-guide/src/contributing.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 44d630080bbf..56583525e739 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -391,6 +391,13 @@ Just a few things to keep in mind: - Please try to avoid overly long lines and use semantic line breaks (where you break the line after each sentence). There is no strict limit on line lengths; let the sentence or part of the sentence flow to its proper end on the same line. + You can use a tool in ci/sembr to help with this. + Its help output can be seen with this command: + + ```console + cargo run --manifest-path ci/sembr/Cargo.toml -- --help + ``` + - When contributing text to the guide, please contextualize the information with some time period and/or a reason so that the reader knows how much to trust the information. Aim to provide a reasonable amount of context, possibly including but not limited to: From 8654d0e6784c8fb1e6545c3664c0d2cb28aa0861 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 27 Oct 2025 18:34:29 +0200 Subject: [PATCH 214/525] sembr tool: add some hints on usage --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index accdcb68c319..edf5b6401cd9 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -10,9 +10,12 @@ use regex::Regex; #[derive(Parser)] struct Cli { - root_dir: PathBuf, + /// File or directory to check + path: PathBuf, #[arg(long)] + /// Modify files that do not comply overwrite: bool, + /// Applies to lines that are to be split #[arg(long, default_value_t = 100)] line_length_limit: usize, #[arg(long)] @@ -31,7 +34,7 @@ fn main() -> Result<()> { let mut compliant = Vec::new(); let mut not_compliant = Vec::new(); let mut made_compliant = Vec::new(); - for result in Walk::new(cli.root_dir) { + for result in Walk::new(cli.path) { let entry = result?; if entry.file_type().expect("no stdin").is_dir() { continue; From 74b2a94b5ebb1e07db8eac629ce4f6915a877052 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 27 Oct 2025 19:13:00 +0200 Subject: [PATCH 215/525] Consider all matches for flyimport even when searched with a qualifier --- .../ide-completion/src/tests/flyimport.rs | 22 ++++ .../ide-db/src/imports/import_assets.rs | 116 ++++++++++-------- 2 files changed, 86 insertions(+), 52 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 0cd42089b487..e139a5e27088 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -1953,3 +1953,25 @@ fn foo() { expect![""], ); } + +#[test] +fn multiple_matches_with_qualifier() { + check( + r#" +//- /foo.rs crate:foo +pub mod env { + pub fn var() {} + pub fn _var() {} +} + +//- /bar.rs crate:bar deps:foo +fn main() { + env::var$0 +} + "#, + expect![[r#" + fn _var() (use foo::env) fn() + fn var() (use foo::env) fn() + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 0c235c8d9a57..50edfcaa78ee 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -1,6 +1,6 @@ //! Look up accessible paths for items. -use std::ops::ControlFlow; +use std::{convert::Infallible, ops::ControlFlow}; use hir::{ AsAssocItem, AssocItem, AssocItemContainer, Complete, Crate, FindPathConfig, HasCrate, @@ -9,6 +9,7 @@ use hir::{ }; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; +use smallvec::SmallVec; use syntax::{ AstNode, SyntaxNode, ast::{self, HasName, make}, @@ -416,7 +417,7 @@ fn path_applicable_imports( NameToImport::Exact(first_qsegment.as_str().to_owned(), true), AssocSearchMode::Exclude, ) - .filter_map(|(item, do_not_complete)| { + .flat_map(|(item, do_not_complete)| { // we found imports for `first_qsegment`, now we need to filter these imports by whether // they result in resolving the rest of the path successfully validate_resolvable( @@ -446,10 +447,10 @@ fn validate_resolvable( resolved_qualifier: ItemInNs, unresolved_qualifier: &[Name], complete_in_flyimport: CompleteInFlyimport, -) -> Option { +) -> SmallVec<[LocatedImport; 1]> { let _p = tracing::info_span!("ImportAssets::import_for_item").entered(); - let qualifier = { + let qualifier = (|| { let mut adjusted_resolved_qualifier = resolved_qualifier; if !unresolved_qualifier.is_empty() { match resolved_qualifier { @@ -464,69 +465,80 @@ fn validate_resolvable( } match adjusted_resolved_qualifier { - ItemInNs::Types(def) => def, - _ => return None, + ItemInNs::Types(def) => Some(def), + _ => None, } - }; - let import_path_candidate = mod_path(resolved_qualifier)?; + })(); + let Some(qualifier) = qualifier else { return SmallVec::new() }; + let Some(import_path_candidate) = mod_path(resolved_qualifier) else { return SmallVec::new() }; + let mut result = SmallVec::new(); let ty = match qualifier { ModuleDef::Module(module) => { - return items_locator::items_with_name_in_module( + items_locator::items_with_name_in_module::( db, module, candidate.clone(), AssocSearchMode::Exclude, - |it| match scope_filter(it) { - true => ControlFlow::Break(it), - false => ControlFlow::Continue(()), + |item| { + if scope_filter(item) { + result.push(LocatedImport::new( + import_path_candidate.clone(), + resolved_qualifier, + item, + complete_in_flyimport, + )); + } + ControlFlow::Continue(()) }, - ) - .map(|item| { - LocatedImport::new( - import_path_candidate, - resolved_qualifier, - item, - complete_in_flyimport, - ) - }); + ); + return result; } // FIXME - ModuleDef::Trait(_) => return None, + ModuleDef::Trait(_) => return SmallVec::new(), ModuleDef::TypeAlias(alias) => alias.ty(db), ModuleDef::BuiltinType(builtin) => builtin.ty(db), ModuleDef::Adt(adt) => adt.ty(db), - _ => return None, + _ => return SmallVec::new(), }; - ty.iterate_path_candidates(db, scope, &FxHashSet::default(), None, None, |assoc| { - // FIXME: Support extra trait imports - if assoc.container_or_implemented_trait(db).is_some() { - return None; - } - let name = assoc.name(db)?; - let is_match = match candidate { - NameToImport::Prefix(text, true) => name.as_str().starts_with(text), - NameToImport::Prefix(text, false) => { - name.as_str().chars().zip(text.chars()).all(|(name_char, candidate_char)| { - name_char.eq_ignore_ascii_case(&candidate_char) - }) + ty.iterate_path_candidates::( + db, + scope, + &FxHashSet::default(), + None, + None, + |assoc| { + // FIXME: Support extra trait imports + if assoc.container_or_implemented_trait(db).is_some() { + return None; } - NameToImport::Exact(text, true) => name.as_str() == text, - NameToImport::Exact(text, false) => name.as_str().eq_ignore_ascii_case(text), - NameToImport::Fuzzy(text, true) => text.chars().all(|c| name.as_str().contains(c)), - NameToImport::Fuzzy(text, false) => text - .chars() - .all(|c| name.as_str().chars().any(|name_char| name_char.eq_ignore_ascii_case(&c))), - }; - if !is_match { - return None; - } - Some(LocatedImport::new( - import_path_candidate.clone(), - resolved_qualifier, - assoc_to_item(assoc), - complete_in_flyimport, - )) - }) + let name = assoc.name(db)?; + let is_match = match candidate { + NameToImport::Prefix(text, true) => name.as_str().starts_with(text), + NameToImport::Prefix(text, false) => { + name.as_str().chars().zip(text.chars()).all(|(name_char, candidate_char)| { + name_char.eq_ignore_ascii_case(&candidate_char) + }) + } + NameToImport::Exact(text, true) => name.as_str() == text, + NameToImport::Exact(text, false) => name.as_str().eq_ignore_ascii_case(text), + NameToImport::Fuzzy(text, true) => text.chars().all(|c| name.as_str().contains(c)), + NameToImport::Fuzzy(text, false) => text.chars().all(|c| { + name.as_str().chars().any(|name_char| name_char.eq_ignore_ascii_case(&c)) + }), + }; + if !is_match { + return None; + } + result.push(LocatedImport::new( + import_path_candidate.clone(), + resolved_qualifier, + assoc_to_item(assoc), + complete_in_flyimport, + )); + None + }, + ); + result } pub fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option { From 3009a73b8a839805d47f4a30af40a8ed9f5f3f16 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 28 Oct 2025 03:53:50 +0900 Subject: [PATCH 216/525] fix: Resolve `target-dir` more precisely --- .../project-model/src/build_dependencies.rs | 10 ++- .../project-model/src/cargo_workspace.rs | 34 ++++++--- .../crates/project-model/src/lib.rs | 2 +- .../crates/project-model/src/sysroot.rs | 7 +- .../crates/project-model/src/tests.rs | 8 +-- .../crates/project-model/src/workspace.rs | 72 ++++--------------- .../rust-analyzer/src/cli/rustc_tests.rs | 9 +-- .../crates/rust-analyzer/src/config.rs | 61 +++++++++------- .../crates/rust-analyzer/src/flycheck.rs | 46 ++++++++---- .../rust-analyzer/src/handlers/request.rs | 1 + .../crates/rust-analyzer/src/reload.rs | 13 +++- .../crates/rust-analyzer/src/test_runner.rs | 5 +- 12 files changed, 132 insertions(+), 136 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs index 3a682d5a4d83..fedc6944f5f8 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs @@ -86,6 +86,7 @@ impl WorkspaceBuildScripts { config, &allowed_features, workspace.manifest_path(), + workspace.target_directory().as_ref(), current_dir, sysroot, toolchain, @@ -106,8 +107,9 @@ impl WorkspaceBuildScripts { let (_guard, cmd) = Self::build_command( config, &Default::default(), - // This is not gonna be used anyways, so just construct a dummy here + // These are not gonna be used anyways, so just construct a dummy here &ManifestPath::try_from(working_directory.clone()).unwrap(), + working_directory.as_ref(), working_directory, &Sysroot::empty(), None, @@ -430,6 +432,7 @@ impl WorkspaceBuildScripts { config: &CargoConfig, allowed_features: &FxHashSet, manifest_path: &ManifestPath, + target_dir: &Utf8Path, current_dir: &AbsPath, sysroot: &Sysroot, toolchain: Option<&semver::Version>, @@ -450,8 +453,9 @@ impl WorkspaceBuildScripts { cmd.arg("--manifest-path"); cmd.arg(manifest_path); - if let Some(target_dir) = &config.target_dir { - cmd.arg("--target-dir").arg(target_dir); + if let Some(target_dir) = config.target_dir_config.target_dir(Some(target_dir)) { + cmd.arg("--target-dir"); + cmd.arg(target_dir.as_ref()); } if let Some(target) = &config.target { diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 76ba01f3a263..731104981ac7 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -1,7 +1,6 @@ //! See [`CargoWorkspace`]. -use std::ops; -use std::str::from_utf8; +use std::{borrow::Cow, ops, str::from_utf8}; use anyhow::Context; use base_db::Env; @@ -95,6 +94,29 @@ impl Default for CargoFeatures { } } +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum TargetDirectoryConfig { + #[default] + None, + UseSubdirectory, + Directory(Utf8PathBuf), +} + +impl TargetDirectoryConfig { + pub fn target_dir<'a>( + &'a self, + ws_target_dir: Option<&'a Utf8Path>, + ) -> Option> { + match self { + TargetDirectoryConfig::None => None, + TargetDirectoryConfig::UseSubdirectory => { + Some(Cow::Owned(ws_target_dir?.join("rust-analyzer"))) + } + TargetDirectoryConfig::Directory(dir) => Some(Cow::Borrowed(dir)), + } + } +} + #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct CargoConfig { /// Whether to pass `--all-targets` to cargo invocations. @@ -121,7 +143,7 @@ pub struct CargoConfig { pub extra_env: FxHashMap>, pub invocation_strategy: InvocationStrategy, /// Optional path to use instead of `target` when building - pub target_dir: Option, + pub target_dir_config: TargetDirectoryConfig, /// Gate `#[test]` behind `#[cfg(test)]` pub set_test: bool, /// Load the project without any dependencies @@ -715,21 +737,15 @@ impl FetchMetadata { } } - pub(crate) fn no_deps_metadata(&self) -> Option<&cargo_metadata::Metadata> { - self.no_deps_result.as_ref().ok() - } - /// Executes the metadata-fetching command. /// /// A successful result may still contain a metadata error if the full fetch failed, /// but the fallback `--no-deps` pre-fetch succeeded during command construction. pub(crate) fn exec( self, - target_dir: &Utf8Path, locked: bool, progress: &dyn Fn(String), ) -> anyhow::Result<(cargo_metadata::Metadata, Option)> { - _ = target_dir; let Self { mut command, manifest_path: _, diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index e36b90488151..910bc0a96be5 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -62,7 +62,7 @@ pub use crate::{ build_dependencies::{ProcMacroDylibPath, WorkspaceBuildScripts}, cargo_workspace::{ CargoConfig, CargoFeatures, CargoMetadataConfig, CargoWorkspace, Package, PackageData, - PackageDependency, RustLibSource, Target, TargetData, TargetKind, + PackageDependency, RustLibSource, Target, TargetData, TargetDirectoryConfig, TargetKind, }, manifest_path::ManifestPath, project_json::{ProjectJson, ProjectJsonData}, diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index 5cc399bfe76d..920afe65d7cd 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -9,7 +9,7 @@ use std::{env, fs, ops::Not, path::Path, process::Command}; use anyhow::{Result, format_err}; use itertools::Itertools; -use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; +use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; use stdx::format_to; use toolchain::{Tool, probe_for_binary}; @@ -219,7 +219,6 @@ impl Sysroot { &self, sysroot_source_config: &RustSourceWorkspaceConfig, no_deps: bool, - target_dir: &Utf8Path, progress: &dyn Fn(String), ) -> Option { assert!(matches!(self.workspace, RustLibSrcWorkspace::Empty), "workspace already loaded"); @@ -233,7 +232,6 @@ impl Sysroot { match self.load_library_via_cargo( &library_manifest, src_root, - target_dir, cargo_config, no_deps, progress, @@ -328,7 +326,6 @@ impl Sysroot { &self, library_manifest: &ManifestPath, current_dir: &AbsPath, - target_dir: &Utf8Path, cargo_config: &CargoMetadataConfig, no_deps: bool, progress: &dyn Fn(String), @@ -345,7 +342,7 @@ impl Sysroot { let locked = true; let (mut res, err) = FetchMetadata::new(library_manifest, current_dir, &cargo_config, self, no_deps) - .exec(target_dir, locked, progress)?; + .exec(locked, progress)?; // Patch out `rustc-std-workspace-*` crates to point to the real crates. // This is done prior to `CrateGraph` construction to prevent de-duplication logic from failing. diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 711cdd11b9a8..1908fc02904a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -238,12 +238,8 @@ fn smoke_test_real_sysroot_cargo() { ); let cwd = AbsPathBuf::assert_utf8(temp_dir().join("smoke_test_real_sysroot_cargo")); std::fs::create_dir_all(&cwd).unwrap(); - let loaded_sysroot = sysroot.load_workspace( - &RustSourceWorkspaceConfig::default_cargo(), - false, - &Utf8PathBuf::default(), - &|_| (), - ); + let loaded_sysroot = + sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo(), false, &|_| ()); if let Some(loaded_sysroot) = loaded_sysroot { sysroot.set_workspace(loaded_sysroot); } diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index b88db419574d..3c696256854c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -16,7 +16,7 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; use span::{Edition, FileId}; -use toolchain::{NO_RUSTUP_AUTO_INSTALL_ENV, Tool}; +use toolchain::Tool; use tracing::instrument; use tracing::{debug, error, info}; use triomphe::Arc; @@ -295,11 +295,6 @@ impl ProjectWorkspace { &sysroot, *no_deps, ); - let target_dir = config - .target_dir - .clone() - .or_else(|| fetch_metadata.no_deps_metadata().map(|m| m.target_directory.clone())) - .unwrap_or_else(|| workspace_dir.join("target").into()); // We spawn a bunch of processes to query various information about the workspace's // toolchain and sysroot @@ -345,7 +340,7 @@ impl ProjectWorkspace { }, &sysroot, *no_deps, - ).exec(&target_dir, true, progress) { + ).exec(true, progress) { Ok((meta, _error)) => { let workspace = CargoWorkspace::new( meta, @@ -374,7 +369,7 @@ impl ProjectWorkspace { }) }); - let cargo_metadata = s.spawn(|| fetch_metadata.exec(&target_dir, false, progress)); + let cargo_metadata = s.spawn(|| fetch_metadata.exec(false, progress)); let loaded_sysroot = s.spawn(|| { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( @@ -383,7 +378,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - &target_dir, progress, ) }); @@ -463,12 +457,6 @@ impl ProjectWorkspace { let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env) .unwrap_or_default(); let toolchain = version::get(query_config, &config.extra_env).ok().flatten(); - let project_root = project_json.project_root(); - let target_dir = config - .target_dir - .clone() - .or_else(|| cargo_target_dir(project_json.manifest()?, &config.extra_env, &sysroot)) - .unwrap_or_else(|| project_root.join("target").into()); // We spawn a bunch of processes to query various information about the workspace's // toolchain and sysroot @@ -486,7 +474,6 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::Json(*sysroot_project), config.no_deps, - &target_dir, progress, ) } else { @@ -497,7 +484,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - &target_dir, progress, ) } @@ -545,11 +531,6 @@ impl ProjectWorkspace { .unwrap_or_default(); let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env); let target_data = target_data::get(query_config, None, &config.extra_env); - let target_dir = config - .target_dir - .clone() - .or_else(|| cargo_target_dir(detached_file, &config.extra_env, &sysroot)) - .unwrap_or_else(|| dir.join("target").into()); let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( @@ -558,7 +539,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - &target_dir, &|_| (), ); if let Some(loaded_sysroot) = loaded_sysroot { @@ -579,21 +559,15 @@ impl ProjectWorkspace { &sysroot, config.no_deps, ); - let target_dir = config - .target_dir - .clone() - .or_else(|| fetch_metadata.no_deps_metadata().map(|m| m.target_directory.clone())) - .unwrap_or_else(|| dir.join("target").into()); - let cargo_script = - fetch_metadata.exec(&target_dir, false, &|_| ()).ok().map(|(ws, error)| { - let cargo_config_extra_env = - cargo_config_env(detached_file, &config_file, &config.extra_env); - ( - CargoWorkspace::new(ws, detached_file.clone(), cargo_config_extra_env, false), - WorkspaceBuildScripts::default(), - error.map(Arc::new), - ) - }); + let cargo_script = fetch_metadata.exec(false, &|_| ()).ok().map(|(ws, error)| { + let cargo_config_extra_env = + cargo_config_env(detached_file, &config_file, &config.extra_env); + ( + CargoWorkspace::new(ws, detached_file.clone(), cargo_config_extra_env, false), + WorkspaceBuildScripts::default(), + error.map(Arc::new), + ) + }); Ok(ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile { @@ -1902,25 +1876,3 @@ fn sysroot_metadata_config( kind: "sysroot", } } - -fn cargo_target_dir( - manifest: &ManifestPath, - extra_env: &FxHashMap>, - sysroot: &Sysroot, -) -> Option { - let cargo = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env); - let mut meta = cargo_metadata::MetadataCommand::new(); - meta.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1); - meta.cargo_path(cargo.get_program()); - meta.manifest_path(manifest); - // `--no-deps` doesn't (over)write lockfiles as it doesn't do any package resolve. - // So we can use it to get `target_directory` before copying lockfiles - meta.no_deps(); - let mut other_options = vec![]; - if manifest.is_rust_manifest() { - meta.env("RUSTC_BOOTSTRAP", "1"); - other_options.push("-Zscript".to_owned()); - } - meta.other_options(other_options); - meta.exec().map(|m| m.target_directory).ok() -} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 20567149bb4b..eb28a47ec0ad 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -9,7 +9,6 @@ use hir::{ChangeWithProcMacros, Crate}; use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig}; use ide_db::base_db; use itertools::Either; -use paths::Utf8PathBuf; use profile::StopWatch; use project_model::toolchain_info::{QueryConfig, target_data}; use project_model::{ @@ -75,12 +74,8 @@ impl Tester { }; let mut sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env); - let loaded_sysroot = sysroot.load_workspace( - &RustSourceWorkspaceConfig::default_cargo(), - false, - &Utf8PathBuf::default(), - &|_| (), - ); + let loaded_sysroot = + sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo(), false, &|_| ()); if let Some(loaded_sysroot) = loaded_sysroot { sysroot.set_workspace(loaded_sysroot); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6d2907ee56aa..10a392a5b7fc 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -23,7 +23,7 @@ use itertools::{Either, Itertools}; use paths::{Utf8Path, Utf8PathBuf}; use project_model::{ CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectJsonFromCommand, - ProjectManifest, RustLibSource, + ProjectManifest, RustLibSource, TargetDirectoryConfig, }; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; @@ -2285,7 +2285,7 @@ impl Config { run_build_script_command: self.cargo_buildScripts_overrideCommand(source_root).clone(), extra_args: self.cargo_extraArgs(source_root).clone(), extra_env: self.cargo_extraEnv(source_root).clone(), - target_dir: self.target_dir_from_config(source_root), + target_dir_config: self.target_dir_from_config(source_root), set_test: *self.cfg_setTest(source_root), no_deps: *self.cargo_noDeps(source_root), } @@ -2373,7 +2373,7 @@ impl Config { extra_args: self.extra_args(source_root).clone(), extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(), extra_env: self.extra_env(source_root).clone(), - target_dir: self.target_dir_from_config(source_root), + target_dir_config: self.target_dir_from_config(source_root), set_test: true, } } @@ -2431,7 +2431,7 @@ impl Config { extra_args: self.check_extra_args(source_root), extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(), extra_env: self.check_extra_env(source_root), - target_dir: self.target_dir_from_config(source_root), + target_dir_config: self.target_dir_from_config(source_root), set_test: *self.cfg_setTest(source_root), }, ansi_color_output: self.color_diagnostic_output(), @@ -2439,17 +2439,12 @@ impl Config { } } - fn target_dir_from_config(&self, source_root: Option) -> Option { - self.cargo_targetDir(source_root).as_ref().and_then(|target_dir| match target_dir { - TargetDirectory::UseSubdirectory(true) => { - let env_var = env::var("CARGO_TARGET_DIR").ok(); - let mut path = Utf8PathBuf::from(env_var.as_deref().unwrap_or("target")); - path.push("rust-analyzer"); - Some(path) - } - TargetDirectory::UseSubdirectory(false) => None, - TargetDirectory::Directory(dir) => Some(dir.clone()), - }) + fn target_dir_from_config(&self, source_root: Option) -> TargetDirectoryConfig { + match &self.cargo_targetDir(source_root) { + Some(TargetDirectory::UseSubdirectory(true)) => TargetDirectoryConfig::UseSubdirectory, + Some(TargetDirectory::UseSubdirectory(false)) | None => TargetDirectoryConfig::None, + Some(TargetDirectory::Directory(dir)) => TargetDirectoryConfig::Directory(dir.clone()), + } } pub fn check_on_save(&self, source_root: Option) -> bool { @@ -3966,7 +3961,7 @@ fn doc_comment_to_string(doc: &[&str]) -> String { #[cfg(test)] mod tests { - use std::fs; + use std::{borrow::Cow, fs}; use test_utils::{ensure_file_contents, project_root}; @@ -4101,9 +4096,13 @@ mod tests { (config, _, _) = config.apply_change(change); assert_eq!(config.cargo_targetDir(None), &None); - assert!( - matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none()) - ); + assert!(matches!( + config.flycheck(None), + FlycheckConfig::CargoCommand { + options: CargoOptions { target_dir_config: TargetDirectoryConfig::None, .. }, + .. + } + )); } #[test] @@ -4119,11 +4118,16 @@ mod tests { (config, _, _) = config.apply_change(change); assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true))); - let target = + let ws_target_dir = Utf8PathBuf::from(std::env::var("CARGO_TARGET_DIR").unwrap_or("target".to_owned())); - assert!( - matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(target.join("rust-analyzer"))) - ); + assert!(matches!( + config.flycheck(None), + FlycheckConfig::CargoCommand { + options: CargoOptions { target_dir_config, .. }, + .. + } if target_dir_config.target_dir(Some(&ws_target_dir)).map(Cow::into_owned) + == Some(ws_target_dir.join("rust-analyzer")) + )); } #[test] @@ -4142,8 +4146,13 @@ mod tests { config.cargo_targetDir(None), &Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder"))) ); - assert!( - matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder"))) - ); + assert!(matches!( + config.flycheck(None), + FlycheckConfig::CargoCommand { + options: CargoOptions { target_dir_config, .. }, + .. + } if target_dir_config.target_dir(None).map(Cow::into_owned) + == Some(Utf8PathBuf::from("other_folder")) + )); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 73a51bba3d9a..db6743d4e5b6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -13,6 +13,7 @@ use crossbeam_channel::{Receiver, Sender, select_biased, unbounded}; use ide_db::FxHashSet; use itertools::Itertools; use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; +use project_model::TargetDirectoryConfig; use rustc_hash::FxHashMap; use serde::Deserialize as _; use serde_derive::Deserialize; @@ -46,7 +47,7 @@ pub(crate) struct CargoOptions { pub(crate) extra_args: Vec, pub(crate) extra_test_bin_args: Vec, pub(crate) extra_env: FxHashMap>, - pub(crate) target_dir: Option, + pub(crate) target_dir_config: TargetDirectoryConfig, } #[derive(Clone, Debug)] @@ -58,7 +59,7 @@ pub(crate) enum Target { } impl CargoOptions { - pub(crate) fn apply_on_command(&self, cmd: &mut Command) { + pub(crate) fn apply_on_command(&self, cmd: &mut Command, ws_target_dir: Option<&Utf8Path>) { for target in &self.target_tuples { cmd.args(["--target", target.as_str()]); } @@ -82,8 +83,8 @@ impl CargoOptions { cmd.arg(self.features.join(" ")); } } - if let Some(target_dir) = &self.target_dir { - cmd.arg("--target-dir").arg(target_dir); + if let Some(target_dir) = self.target_dir_config.target_dir(ws_target_dir) { + cmd.arg("--target-dir").arg(target_dir.as_ref()); } } } @@ -158,6 +159,7 @@ impl FlycheckHandle { sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, + ws_target_dir: Option, ) -> FlycheckHandle { let actor = FlycheckActor::new( id, @@ -167,6 +169,7 @@ impl FlycheckHandle { sysroot_root, workspace_root, manifest_path, + ws_target_dir, ); let (sender, receiver) = unbounded::(); let thread = @@ -314,6 +317,7 @@ struct FlycheckActor { sender: Sender, config: FlycheckConfig, manifest_path: Option, + ws_target_dir: Option, /// Either the workspace root of the workspace we are flychecking, /// or the project root of the project. root: Arc, @@ -355,6 +359,7 @@ impl FlycheckActor { sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, + ws_target_dir: Option, ) -> FlycheckActor { tracing::info!(%id, ?workspace_root, "Spawning flycheck"); FlycheckActor { @@ -366,6 +371,7 @@ impl FlycheckActor { root: Arc::new(workspace_root), scope: FlycheckScope::Workspace, manifest_path, + ws_target_dir, command_handle: None, command_receiver: None, diagnostics_cleared_for: Default::default(), @@ -428,15 +434,24 @@ impl FlycheckActor { CargoCheckParser, sender, match &self.config { - FlycheckConfig::CargoCommand { options, .. } => Some( - options - .target_dir - .as_deref() - .unwrap_or( - Utf8Path::new("target").join("rust-analyzer").as_path(), - ) - .join(format!("flycheck{}", self.id)), - ), + FlycheckConfig::CargoCommand { options, .. } => { + let ws_target_dir = + self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path); + let target_dir = + options.target_dir_config.target_dir(ws_target_dir); + + // If `"rust-analyzer.cargo.targetDir": null`, we should use + // workspace's target dir instead of hard-coded fallback. + let target_dir = target_dir.as_deref().or(ws_target_dir); + + Some( + target_dir + .unwrap_or( + Utf8Path::new("target").join("rust-analyzer").as_path(), + ) + .join(format!("flycheck{}", self.id)), + ) + } _ => None, }, ) { @@ -672,7 +687,10 @@ impl FlycheckActor { cmd.arg("--keep-going"); - options.apply_on_command(&mut cmd); + options.apply_on_command( + &mut cmd, + self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path), + ); cmd.args(&options.extra_args); Some(cmd) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 2976441d762a..14817df37667 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -264,6 +264,7 @@ pub(crate) fn handle_run_test( path, state.config.cargo_test_options(None), cargo.workspace_root(), + Some(cargo.target_directory().as_ref()), target, state.test_run_sender.clone(), )?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 1475f02447d2..bb971eb13bed 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -23,6 +23,7 @@ use ide_db::{ use itertools::Itertools; use load_cargo::{ProjectFolders, load_proc_macro}; use lsp_types::FileSystemWatcher; +use paths::Utf8Path; use proc_macro_api::ProcMacroClient; use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts}; use stdx::{format_to, thread::ThreadIntent}; @@ -876,6 +877,7 @@ impl GlobalState { None, self.config.root_path().clone(), None, + None, )] } crate::flycheck::InvocationStrategy::PerWorkspace => { @@ -890,13 +892,17 @@ impl GlobalState { | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. - } => (cargo.workspace_root(), Some(cargo.manifest_path())), + } => ( + cargo.workspace_root(), + Some(cargo.manifest_path()), + Some(cargo.target_directory()), + ), ProjectWorkspaceKind::Json(project) => { // Enable flychecks for json projects if a custom flycheck command was supplied // in the workspace configuration. match config { FlycheckConfig::CustomCommand { .. } => { - (project.path(), None) + (project.path(), None, None) } _ => return None, } @@ -906,7 +912,7 @@ impl GlobalState { ws.sysroot.root().map(ToOwned::to_owned), )) }) - .map(|(id, (root, manifest_path), sysroot_root)| { + .map(|(id, (root, manifest_path, target_dir), sysroot_root)| { FlycheckHandle::spawn( id, next_gen, @@ -915,6 +921,7 @@ impl GlobalState { sysroot_root, root.to_path_buf(), manifest_path.map(|it| it.to_path_buf()), + target_dir.map(|it| AsRef::::as_ref(it).to_path_buf()), ) }) .collect() diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs index 0c8658c75df0..9a65e708a056 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs @@ -2,7 +2,7 @@ //! thread and report the result of each test in a channel. use crossbeam_channel::Sender; -use paths::AbsPath; +use paths::{AbsPath, Utf8Path}; use project_model::TargetKind; use serde::Deserialize as _; use serde_derive::Deserialize; @@ -98,6 +98,7 @@ impl CargoTestHandle { path: Option<&str>, options: CargoOptions, root: &AbsPath, + ws_target_dir: Option<&Utf8Path>, test_target: TestTarget, sender: Sender, ) -> std::io::Result { @@ -123,7 +124,7 @@ impl CargoTestHandle { cmd.arg("--no-fail-fast"); cmd.arg("--manifest-path"); cmd.arg(root.join("Cargo.toml")); - options.apply_on_command(&mut cmd); + options.apply_on_command(&mut cmd, ws_target_dir); cmd.arg("--"); if let Some(path) = path { cmd.arg(path); From 506341bcdd269738195bc12753f7a17e22687973 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 28 Oct 2025 00:22:44 +0200 Subject: [PATCH 217/525] Avoid calling `specializes()` query on crates that do not define `#![feature(specialization)]` To save memory. --- .../crates/hir-ty/src/specialization.rs | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs index 611947b96b71..f4ee4de44639 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs @@ -20,7 +20,7 @@ use crate::{ // and indeed I was unable to cause cycles even with erroneous code. However, in r-a we can // create a cycle if there is an error in the impl's where clauses. I believe well formed code // cannot create a cycle, but a cycle handler is required nevertheless. -fn specializes_cycle( +fn specializes_query_cycle( _db: &dyn HirDatabase, _specializing_impl_def_id: ImplId, _parent_impl_def_id: ImplId, @@ -39,31 +39,14 @@ fn specializes_cycle( /// `parent_impl_def_id` is a const impl (conditionally based off of some `[const]` /// bounds), then `specializing_impl_def_id` must also be const for the same /// set of types. -#[salsa::tracked(cycle_result = specializes_cycle)] -pub(crate) fn specializes( +#[salsa::tracked(cycle_result = specializes_query_cycle)] +fn specializes_query( db: &dyn HirDatabase, specializing_impl_def_id: ImplId, parent_impl_def_id: ImplId, ) -> bool { - let module = specializing_impl_def_id.loc(db).container; - - // We check that the specializing impl comes from a crate that has specialization enabled. - // - // We don't really care if the specialized impl (the parent) is in a crate that has - // specialization enabled, since it's not being specialized. - // - // rustc also checks whether the specializing impls comes from a macro marked - // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]` - // is an internal feature, std is not using it for specialization nor is likely to - // ever use it, and we don't have the span information necessary to replicate that. - let def_map = crate_def_map(db, module.krate()); - if !def_map.is_unstable_feature_enabled(&sym::specialization) - && !def_map.is_unstable_feature_enabled(&sym::min_specialization) - { - return false; - } - - let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block()); + let trait_env = db.trait_environment(specializing_impl_def_id.into()); + let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block); let specializing_impl_signature = db.impl_signature(specializing_impl_def_id); let parent_impl_signature = db.impl_signature(parent_impl_def_id); @@ -87,7 +70,7 @@ pub(crate) fn specializes( // create a parameter environment corresponding to an identity instantiation of the specializing impl, // i.e. the most generic instantiation of the specializing impl. - let param_env = db.trait_environment(specializing_impl_def_id.into()).env; + let param_env = trait_env.env; // Create an infcx, taking the predicates of the specializing impl as assumptions: let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); @@ -148,3 +131,31 @@ pub(crate) fn specializes( true } + +// This function is used to avoid creating the query for crates that does not define `#![feature(specialization)]`, +// as the solver is calling this a lot, and creating the query consumes a lot of memory. +pub(crate) fn specializes( + db: &dyn HirDatabase, + specializing_impl_def_id: ImplId, + parent_impl_def_id: ImplId, +) -> bool { + let module = specializing_impl_def_id.loc(db).container; + + // We check that the specializing impl comes from a crate that has specialization enabled. + // + // We don't really care if the specialized impl (the parent) is in a crate that has + // specialization enabled, since it's not being specialized. + // + // rustc also checks whether the specializing impls comes from a macro marked + // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]` + // is an internal feature, std is not using it for specialization nor is likely to + // ever use it, and we don't have the span information necessary to replicate that. + let def_map = crate_def_map(db, module.krate()); + if !def_map.is_unstable_feature_enabled(&sym::specialization) + && !def_map.is_unstable_feature_enabled(&sym::min_specialization) + { + return false; + } + + specializes_query(db, specializing_impl_def_id, parent_impl_def_id) +} From 0c108b1d8348c9ff3e28af2f41d41c957fcc1720 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 27 Oct 2025 23:46:04 +0100 Subject: [PATCH 218/525] perf: Reduce `client_commands` allocations in proto conversion --- .../rust-analyzer/src/handlers/request.rs | 56 +++++++++++++------ .../crates/rust-analyzer/src/lsp/to_proto.rs | 9 ++- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 2976441d762a..66a7a0b825f1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -33,7 +33,9 @@ use triomphe::Arc; use vfs::{AbsPath, AbsPathBuf, FileId, VfsPath}; use crate::{ - config::{Config, RustfmtConfig, WorkspaceSymbolConfig}, + config::{ + ClientCommandsConfig, Config, HoverActionsConfig, RustfmtConfig, WorkspaceSymbolConfig, + }, diagnostics::convert_diagnostic, global_state::{FetchWorkspaceRequest, GlobalState, GlobalStateSnapshot}, line_index::LineEndings, @@ -1463,13 +1465,14 @@ pub(crate) fn handle_code_action( resolve, frange, )?; + let client_commands = snap.config.client_commands(); for (index, assist) in assists.into_iter().enumerate() { let resolve_data = if code_action_resolve_cap { Some((index, params.clone(), snap.file_version(file_id))) } else { None }; - let code_action = to_proto::code_action(&snap, assist, resolve_data)?; + let code_action = to_proto::code_action(&snap, &client_commands, assist, resolve_data)?; // Check if the client supports the necessary `ResourceOperation`s. let changes = code_action.edit.as_ref().and_then(|it| it.document_changes.as_ref()); @@ -1570,7 +1573,7 @@ pub(crate) fn handle_code_action_resolve( )) .into()); } - let ca = to_proto::code_action(&snap, assist.clone(), None)?; + let ca = to_proto::code_action(&snap, &snap.config.client_commands(), assist.clone(), None)?; code_action.edit = ca.edit; code_action.command = ca.command; @@ -2134,9 +2137,11 @@ fn to_command_link(command: lsp_types::Command, tooltip: String) -> lsp_ext::Com fn show_impl_command_link( snap: &GlobalStateSnapshot, position: &FilePosition, + implementations: bool, + show_references: bool, ) -> Option { - if snap.config.hover_actions().implementations - && snap.config.client_commands().show_reference + if implementations + && show_references && let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) { let uri = to_proto::url(snap, position.file_id); @@ -2161,9 +2166,11 @@ fn show_impl_command_link( fn show_ref_command_link( snap: &GlobalStateSnapshot, position: &FilePosition, + references: bool, + show_reference: bool, ) -> Option { - if snap.config.hover_actions().references - && snap.config.client_commands().show_reference + if references + && show_reference && let Some(ref_search_res) = snap .analysis .find_all_refs( @@ -2198,8 +2205,9 @@ fn show_ref_command_link( fn runnable_action_links( snap: &GlobalStateSnapshot, runnable: Runnable, + hover_actions_config: &HoverActionsConfig, + client_commands_config: &ClientCommandsConfig, ) -> Option { - let hover_actions_config = snap.config.hover_actions(); if !hover_actions_config.runnable() { return None; } @@ -2209,7 +2217,6 @@ fn runnable_action_links( return None; } - let client_commands_config = snap.config.client_commands(); if !(client_commands_config.run_single || client_commands_config.debug_single) { return None; } @@ -2244,11 +2251,10 @@ fn runnable_action_links( fn goto_type_action_links( snap: &GlobalStateSnapshot, nav_targets: &[HoverGotoTypeData], + hover_actions: &HoverActionsConfig, + client_commands: &ClientCommandsConfig, ) -> Option { - if !snap.config.hover_actions().goto_type_def - || nav_targets.is_empty() - || !snap.config.client_commands().goto_location - { + if !hover_actions.goto_type_def || nav_targets.is_empty() || !client_commands.goto_location { return None; } @@ -2268,13 +2274,29 @@ fn prepare_hover_actions( snap: &GlobalStateSnapshot, actions: &[HoverAction], ) -> Vec { + let hover_actions = snap.config.hover_actions(); + let client_commands = snap.config.client_commands(); actions .iter() .filter_map(|it| match it { - HoverAction::Implementation(position) => show_impl_command_link(snap, position), - HoverAction::Reference(position) => show_ref_command_link(snap, position), - HoverAction::Runnable(r) => runnable_action_links(snap, r.clone()), - HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), + HoverAction::Implementation(position) => show_impl_command_link( + snap, + position, + hover_actions.implementations, + client_commands.show_reference, + ), + HoverAction::Reference(position) => show_ref_command_link( + snap, + position, + hover_actions.references, + client_commands.show_reference, + ), + HoverAction::Runnable(r) => { + runnable_action_links(snap, r.clone(), &hover_actions, &client_commands) + } + HoverAction::GoToType(targets) => { + goto_type_action_links(snap, targets, &hover_actions, &client_commands) + } }) .collect() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 024c13e1918d..995e6c4cc020 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -26,7 +26,7 @@ use serde_json::to_value; use vfs::AbsPath; use crate::{ - config::{CallInfoConfig, Config}, + config::{CallInfoConfig, ClientCommandsConfig, Config}, global_state::GlobalStateSnapshot, line_index::{LineEndings, LineIndex, PositionEncoding}, lsp::{ @@ -258,10 +258,12 @@ pub(crate) fn completion_items( let max_relevance = items.iter().map(|it| it.relevance.score()).max().unwrap_or_default(); let mut res = Vec::with_capacity(items.len()); + let client_commands = config.client_commands(); for item in items { completion_item( &mut res, config, + &client_commands, fields_to_resolve, line_index, version, @@ -283,6 +285,7 @@ pub(crate) fn completion_items( fn completion_item( acc: &mut Vec, config: &Config, + client_commands: &ClientCommandsConfig, fields_to_resolve: &CompletionFieldsToResolve, line_index: &LineIndex, version: Option, @@ -342,7 +345,7 @@ fn completion_item( } else { item.deprecated.then(|| vec![lsp_types::CompletionItemTag::DEPRECATED]) }; - let command = if item.trigger_call_info && config.client_commands().trigger_parameter_hints { + let command = if item.trigger_call_info && client_commands.trigger_parameter_hints { if fields_to_resolve.resolve_command { something_to_resolve |= true; None @@ -1500,6 +1503,7 @@ pub(crate) fn code_action_kind(kind: AssistKind) -> lsp_types::CodeActionKind { pub(crate) fn code_action( snap: &GlobalStateSnapshot, + commands: &ClientCommandsConfig, assist: Assist, resolve_data: Option<(usize, lsp_types::CodeActionParams, Option)>, ) -> Cancellable { @@ -1513,7 +1517,6 @@ pub(crate) fn code_action( command: None, }; - let commands = snap.config.client_commands(); res.command = match assist.command { Some(assists::Command::TriggerParameterHints) if commands.trigger_parameter_hints => { Some(command::trigger_parameter_hints()) From 08b188c8f1c6aee66529208960e73ebda0c06bc0 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 28 Oct 2025 13:24:09 +1100 Subject: [PATCH 219/525] Remove `cleanup_debug_info_options` This "cleanup" function is more than a decade old, and I can't find any evidence of modern-day bootstrap being able to pass any of these flags to `--host-rustcflags` or `--target-rustcflags`. --- .../compiletest/src/runtest/debuginfo.rs | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 9175a38ffa5c..bc597597ce12 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -8,7 +8,6 @@ use tracing::debug; use super::debugger::DebuggerCommands; use super::{Debugger, Emit, ProcRes, TestCx, Truncated, WillExecute}; -use crate::common::Config; use crate::debuggers::{extract_gdb_version, is_android_gdb_target}; impl TestCx<'_> { @@ -21,18 +20,6 @@ impl TestCx<'_> { } fn run_debuginfo_cdb_test(&self) { - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_cdb_test_no_opt(); - } - - fn run_debuginfo_cdb_test_no_opt(&self) { let exe_file = self.make_exe_name(); // Existing PDB files are update in-place. When changing the debuginfo @@ -118,18 +105,6 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test(&self) { - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_gdb_test_no_opt(); - } - - fn run_debuginfo_gdb_test_no_opt(&self) { let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb") .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -355,18 +330,6 @@ impl TestCx<'_> { self.fatal("Can't run LLDB test because LLDB's python path is not set."); } - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_lldb_test_no_opt(); - } - - fn run_debuginfo_lldb_test_no_opt(&self) { // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); let compile_result = self.compile_test(should_run, Emit::None); @@ -501,11 +464,4 @@ impl TestCx<'_> { .env("PYTHONPATH", pythonpath), ) } - - fn cleanup_debug_info_options(&self, options: &Vec) -> Vec { - // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS. - let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()]; - - options.iter().filter(|x| !options_to_remove.contains(x)).cloned().collect() - } } From a9c7730fe0084f795acc5e8078b83eceef6774b9 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 28 Oct 2025 06:10:06 +0200 Subject: [PATCH 220/525] contributing.md: ease copy-paste Also, tidy does a lot more than follow Rust Style Guide --- src/doc/rustc-dev-guide/src/contributing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 1ade4953d2e6..43e3fb5b0a16 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -269,15 +269,15 @@ Be patient; this can take a while and the queue can sometimes be long. PRs are n ### Opening a PR -You are now ready to file a pull request? Great! Here are a few points you -should be aware of. +You are now ready to file a pull request (PR)? +Great! Here are a few points you should be aware of. All pull requests should be filed against the `master` branch, unless you know for sure that you should target a different branch. -Make sure your pull request is in compliance with Rust's style guidelines by running +Run some style checks before you submit the PR: - $ ./x test tidy --bless + ./x test tidy --bless We recommend to make this check before every pull request (and every new commit in a pull request); you can add [git hooks] From 192f862c93b0f89f47e4104e90e90882776e1c06 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 15 Oct 2025 16:50:36 +0200 Subject: [PATCH 221/525] tests: activate misspelled `gdb-check` in `function-arg-initialization.rs` In 9253e1206e91f5bd7 a bunch of `gdbr-check` (for `rust-gdb`) and `gdbg-check` (for plain `gdb`) was added. But in two places the author accidentally wrote `gdbt-check` instead. This commit fixes this typo. --- tests/debuginfo/function-arg-initialization.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/debuginfo/function-arg-initialization.rs b/tests/debuginfo/function-arg-initialization.rs index 1a681c772116..d9ce6ead5f2b 100644 --- a/tests/debuginfo/function-arg-initialization.rs +++ b/tests/debuginfo/function-arg-initialization.rs @@ -26,9 +26,9 @@ // NON IMMEDIATE ARGS // gdb-command:print a -// gdbt-check:$4 = function_arg_initialization::BigStruct {a: 3, b: 4, c: 5, d: 6, e: 7, f: 8, g: 9, h: 10} +// gdb-check:$4 = function_arg_initialization::BigStruct {a: 3, b: 4, c: 5, d: 6, e: 7, f: 8, g: 9, h: 10} // gdb-command:print b -// gdbt-check:$5 = function_arg_initialization::BigStruct {a: 11, b: 12, c: 13, d: 14, e: 15, f: 16, g: 17, h: 18} +// gdb-check:$5 = function_arg_initialization::BigStruct {a: 11, b: 12, c: 13, d: 14, e: 15, f: 16, g: 17, h: 18} // gdb-command:continue // BINDING @@ -234,6 +234,9 @@ struct BigStruct { fn non_immediate_args(a: BigStruct, b: BigStruct) { zzz(); // #break + + // FIXME(#128973): Needed to avoid `` prints before #128973 has been fixed. + std::hint::black_box(|| { let _ = (a, b);}); } fn binding(a: i64, b: u64, c: f64) { From 540df3d1d999fc192473e9b6903956823bffc033 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 6 Jul 2025 16:10:11 +0300 Subject: [PATCH 222/525] Provide an option to not show derives near the ADT for "Goto Implementations" or "Implementations" codelens I don't do it by default, for three reasons: (1) it's more expensive, (2) I actually quite like seeing the derives, and they may expand to no impl/more than one impl, (3) if #19130 will ever be merged this will become even more useful. Even a config might be too much, but it was fun and easy to code so I did that. --- .../rust-analyzer/crates/hir/src/semantics.rs | 16 ++++++ .../crates/ide/src/annotations.rs | 11 +++- .../crates/ide/src/goto_implementation.rs | 53 +++++++++++++++++-- src/tools/rust-analyzer/crates/ide/src/lib.rs | 4 +- .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../crates/rust-analyzer/src/config.rs | 20 +++++-- .../rust-analyzer/src/handlers/request.rs | 14 +++-- .../docs/book/src/configuration_generated.md | 7 +++ .../rust-analyzer/editors/code/package.json | 10 ++++ 9 files changed, 122 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 62ce3daab75d..ec43442c9b74 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -2105,6 +2105,22 @@ impl<'db> SemanticsImpl<'db> { parent = parent_; } } + + pub fn impl_generated_from_derive(&self, impl_: Impl) -> Option { + let source = hir_def::src::HasSource::ast_ptr(&impl_.id.loc(self.db), self.db); + let mut file_id = source.file_id; + let adt_ast_id = loop { + let macro_call = file_id.macro_file()?; + match macro_call.loc(self.db).kind { + hir_expand::MacroCallKind::Derive { ast_id, .. } => break ast_id, + hir_expand::MacroCallKind::FnLike { ast_id, .. } => file_id = ast_id.file_id, + hir_expand::MacroCallKind::Attr { ast_id, .. } => file_id = ast_id.file_id, + } + }; + let adt_source = adt_ast_id.to_in_file_node(self.db); + self.cache(adt_source.value.syntax().ancestors().last().unwrap(), adt_source.file_id); + ToDef::to_def(self, adt_source.as_ref()) + } } // FIXME This can't be the best way to do this diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs index 36c44044bb5d..6fb8dedea47c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs +++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs @@ -9,7 +9,7 @@ use syntax::{AstNode, TextRange, ast::HasName}; use crate::{ NavigationTarget, RunnableKind, annotations::fn_references::find_all_methods, - goto_implementation::goto_implementation, + goto_implementation::{GotoImplementationConfig, goto_implementation}, navigation_target, references::{FindAllRefsConfig, find_all_refs}, runnables::{Runnable, runnables}, @@ -44,6 +44,7 @@ pub struct AnnotationConfig<'a> { pub annotate_method_references: bool, pub annotate_enum_variant_references: bool, pub location: AnnotationLocation, + pub filter_adjacent_derive_implementations: bool, pub minicore: MiniCore<'a>, } @@ -204,7 +205,12 @@ pub(crate) fn resolve_annotation( ) -> Annotation { match annotation.kind { AnnotationKind::HasImpls { pos, ref mut data } => { - *data = goto_implementation(db, pos).map(|range| range.info); + let goto_implementation_config = GotoImplementationConfig { + filter_adjacent_derive_implementations: config + .filter_adjacent_derive_implementations, + }; + *data = + goto_implementation(db, &goto_implementation_config, pos).map(|range| range.info); } AnnotationKind::HasReferences { pos, ref mut data } => { *data = find_all_refs( @@ -253,6 +259,7 @@ mod tests { annotate_enum_variant_references: true, location: AnnotationLocation::AboveName, minicore: MiniCore::default(), + filter_adjacent_derive_implementations: false, }; fn check_with_config( diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs index 875403c4e32a..0572bca44584 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs @@ -8,6 +8,10 @@ use syntax::{AstNode, SyntaxKind::*, T, ast}; use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; +pub struct GotoImplementationConfig { + pub filter_adjacent_derive_implementations: bool, +} + // Feature: Go to Implementation // // Navigates to the impl items of types. @@ -19,6 +23,7 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; // ![Go to Implementation](https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif) pub(crate) fn goto_implementation( db: &RootDatabase, + config: &GotoImplementationConfig, FilePosition { file_id, offset }: FilePosition, ) -> Option>> { let sema = Semantics::new(db); @@ -55,7 +60,19 @@ pub(crate) fn goto_implementation( .and_then(|def| { let navs = match def { Definition::Trait(trait_) => impls_for_trait(&sema, trait_), - Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)), + Definition::Adt(adt) => { + let mut impls = Impl::all_for_type(db, adt.ty(sema.db)); + if config.filter_adjacent_derive_implementations { + impls.retain(|impl_| { + sema.impl_generated_from_derive(*impl_) != Some(adt) + }); + } + impls + .into_iter() + .filter_map(|imp| imp.try_to_nav(&sema)) + .flatten() + .collect() + } Definition::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)), Definition::BuiltinType(builtin) => { impls_for_ty(&sema, builtin.ty(sema.db)) @@ -125,12 +142,24 @@ mod tests { use ide_db::FileRange; use itertools::Itertools; - use crate::fixture; + use crate::{GotoImplementationConfig, fixture}; + const TEST_CONFIG: &GotoImplementationConfig = + &GotoImplementationConfig { filter_adjacent_derive_implementations: false }; + + #[track_caller] fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + check_with_config(TEST_CONFIG, ra_fixture); + } + + #[track_caller] + fn check_with_config( + config: &GotoImplementationConfig, + #[rust_analyzer::rust_fixture] ra_fixture: &str, + ) { let (analysis, position, expected) = fixture::annotations(ra_fixture); - let navs = analysis.goto_implementation(position).unwrap().unwrap().info; + let navs = analysis.goto_implementation(config, position).unwrap().unwrap().info; let cmp = |frange: &FileRange| (frange.file_id, frange.range.start()); @@ -416,4 +445,22 @@ fn test() { "#, ); } + + #[test] + fn filter_adjacent_derives() { + check_with_config( + &GotoImplementationConfig { filter_adjacent_derive_implementations: true }, + r#" +//- minicore: clone, copy, derive + +#[derive(Clone, Copy)] +struct Foo$0; + +trait Bar {} + +impl Bar for Foo {} + // ^^^ + "#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index ece5bac6df4b..260945757348 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -86,6 +86,7 @@ pub use crate::{ file_structure::{FileStructureConfig, StructureNode, StructureNodeKind}, folding_ranges::{Fold, FoldKind}, goto_definition::GotoDefinitionConfig, + goto_implementation::GotoImplementationConfig, highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{ HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult, @@ -537,9 +538,10 @@ impl Analysis { /// Returns the impls from the symbol at `position`. pub fn goto_implementation( &self, + config: &GotoImplementationConfig, position: FilePosition, ) -> Cancellable>>> { - self.with_db(|db| goto_implementation::goto_implementation(db, position)) + self.with_db(|db| goto_implementation::goto_implementation(db, config, position)) } /// Returns the type definitions for the symbol at `position`. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index de24bc09ff0f..5e4a277f38af 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1214,6 +1214,7 @@ impl flags::AnalysisStats { annotate_method_references: false, annotate_enum_variant_references: false, location: ide::AnnotationLocation::AboveName, + filter_adjacent_derive_implementations: false, minicore: MiniCore::default(), }; for &file_id in file_ids { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6d2907ee56aa..185df4dd73f5 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -10,9 +10,9 @@ use hir::Symbol; use ide::{ AnnotationConfig, AssistConfig, CallHierarchyConfig, CallableSnippets, CompletionConfig, CompletionFieldsToResolve, DiagnosticsConfig, GenericParameterHints, GotoDefinitionConfig, - HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, - InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, - RenameConfig, Snippet, SnippetScope, SourceRootId, + GotoImplementationConfig, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, + InlayFieldsToResolve, InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, + MemoryLayoutHoverRenderKind, RenameConfig, Snippet, SnippetScope, SourceRootId, }; use ide_db::{ MiniCore, SnippetCap, @@ -98,6 +98,9 @@ config_data! { /// Code's `files.watcherExclude`. files_exclude | files_excludeDirs: Vec = vec![], + /// If this is `true`, when "Goto Implementations" and in "Implementations" lens, are triggered on a `struct` or `enum` or `union`, we filter out trait implementations that originate from `derive`s above the type. + gotoImplementations_filterAdjacentDerives: bool = false, + /// Highlight related return values while the cursor is on any `match`, `if`, or match arm /// arrow (`=>`). highlightRelated_branchExitPoints_enable: bool = true, @@ -1413,6 +1416,7 @@ pub struct LensConfig { // annotations pub location: AnnotationLocation, + pub filter_adjacent_derive_implementations: bool, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -1469,6 +1473,7 @@ impl LensConfig { annotate_enum_variant_references: self.enum_variant_refs, location: self.location.into(), minicore, + filter_adjacent_derive_implementations: self.filter_adjacent_derive_implementations, } } } @@ -2503,6 +2508,15 @@ impl Config { refs_trait: *self.lens_enable() && *self.lens_references_trait_enable(), enum_variant_refs: *self.lens_enable() && *self.lens_references_enumVariant_enable(), location: *self.lens_location(), + filter_adjacent_derive_implementations: *self + .gotoImplementations_filterAdjacentDerives(), + } + } + + pub fn goto_implementation(&self) -> GotoImplementationConfig { + GotoImplementationConfig { + filter_adjacent_derive_implementations: *self + .gotoImplementations_filterAdjacentDerives(), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 66a7a0b825f1..ab463533d70f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -849,10 +849,11 @@ pub(crate) fn handle_goto_implementation( let _p = tracing::info_span!("handle_goto_implementation").entered(); let position = try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); - let nav_info = match snap.analysis.goto_implementation(position)? { - None => return Ok(None), - Some(it) => it, - }; + let nav_info = + match snap.analysis.goto_implementation(&snap.config.goto_implementation(), position)? { + None => return Ok(None), + Some(it) => it, + }; let src = FileRange { file_id: position.file_id, range: nav_info.range }; let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) @@ -2142,7 +2143,10 @@ fn show_impl_command_link( ) -> Option { if implementations && show_references - && let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) + && let Some(nav_data) = snap + .analysis + .goto_implementation(&snap.config.goto_implementation(), *position) + .unwrap_or(None) { let uri = to_proto::url(snap, position.file_id); let line_index = snap.file_line_index(position.file_id).ok()?; diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index d768993f501f..7ec7c379c64f 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -635,6 +635,13 @@ Default: `"client"` Controls file watching implementation. +## rust-analyzer.gotoImplementations.filterAdjacentDerives {#gotoImplementations.filterAdjacentDerives} + +Default: `false` + +If this is `true`, when "Goto Implementations" and in "Implementations" lens, are triggered on a `struct` or `enum` or `union`, we filter out trait implementations that originate from `derive`s above the type. + + ## rust-analyzer.highlightRelated.branchExitPoints.enable {#highlightRelated.branchExitPoints.enable} Default: `true` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index d659421a0299..0269494da96d 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1627,6 +1627,16 @@ } } }, + { + "title": "Goto Implementations", + "properties": { + "rust-analyzer.gotoImplementations.filterAdjacentDerives": { + "markdownDescription": "If this is `true`, when \"Goto Implementations\" and in \"Implementations\" lens, are triggered on a `struct` or `enum` or `union`, we filter out trait implementations that originate from `derive`s above the type.", + "default": false, + "type": "boolean" + } + } + }, { "title": "Highlight Related", "properties": { From ae2818dc574d271a4896257e3f19e30a3c8402b4 Mon Sep 17 00:00:00 2001 From: "Shoyu Vanilla (Flint)" Date: Tue, 28 Oct 2025 15:49:38 +0900 Subject: [PATCH 223/525] fix: Canonicalize flycheck output path --- .../crates/rust-analyzer/src/flycheck.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index db6743d4e5b6..68337ddf1c9d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -445,11 +445,19 @@ impl FlycheckActor { let target_dir = target_dir.as_deref().or(ws_target_dir); Some( - target_dir - .unwrap_or( + // As `CommandHandle::spawn`'s working directory is + // rust-analyzer's working directory, which might be different + // from the flycheck's working directory, we should canonicalize + // the output directory, otherwise we might write it into the + // wrong target dir. + // If `target_dir` is an absolute path, it will replace + // `self.root` and that's an intended behavior. + self.root + .join(target_dir.unwrap_or( Utf8Path::new("target").join("rust-analyzer").as_path(), - ) - .join(format!("flycheck{}", self.id)), + )) + .join(format!("flycheck{}", self.id)) + .into(), ) } _ => None, From bd5788690b7bff71bca99da28433dacd2b036067 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 28 Oct 2025 17:58:10 +1100 Subject: [PATCH 224/525] Test that auxiliaries are built against their own directives There are probably plenty of tests that will check this incidentally, but it's convenient to have a dedicated self-test. --- tests/ui/compiletest-self-test/aux-has-props.rs | 14 ++++++++++++++ .../auxiliary/aux_with_props.rs | 6 ++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/ui/compiletest-self-test/aux-has-props.rs create mode 100644 tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs diff --git a/tests/ui/compiletest-self-test/aux-has-props.rs b/tests/ui/compiletest-self-test/aux-has-props.rs new file mode 100644 index 000000000000..73ec2e169f4f --- /dev/null +++ b/tests/ui/compiletest-self-test/aux-has-props.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ aux-build: aux_with_props.rs +//@ compile-flags: --check-cfg=cfg(this_is_aux) +//@ run-pass + +// Test that auxiliaries are built using the directives in the auxiliary file, +// and don't just accidentally use the directives of the main test file. + +extern crate aux_with_props; + +fn main() { + assert!(!cfg!(this_is_aux)); + assert!(aux_with_props::aux_directives_are_respected()); +} diff --git a/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs new file mode 100644 index 000000000000..31a5a05a7144 --- /dev/null +++ b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs @@ -0,0 +1,6 @@ +//@ edition: 2024 +//@ compile-flags: --cfg=this_is_aux + +pub fn aux_directives_are_respected() -> bool { + cfg!(this_is_aux) +} From c62794553e642ad801aaabd45e2f3d734bb35977 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 28 Oct 2025 17:58:10 +1100 Subject: [PATCH 225/525] Don't modify `testpaths` when creating aux contexts --- src/tools/compiletest/src/runtest.rs | 58 +++++++++++++--------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 16b604e9df82..fed59764a2eb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -18,7 +18,6 @@ use crate::common::{ CompareMode, Config, Debugger, FailMode, PassMode, RunFailMode, RunResult, TestMode, TestPaths, TestSuite, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, expected_output_path, incremental_dir, output_base_dir, output_base_name, - output_testname_unique, }; use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; @@ -1004,27 +1003,39 @@ impl<'test> TestCx<'test> { root_out_dir: &Utf8Path, root_testpaths: &TestPaths, kind: DocKind, + ) -> ProcRes { + self.document_inner(&self.testpaths.file, root_out_dir, root_testpaths, kind) + } + + /// Like `document`, but takes an explicit `file_to_doc` argument so that + /// it can also be used for documenting auxiliaries, in addition to + /// documenting the main test file. + fn document_inner( + &self, + file_to_doc: &Utf8Path, + root_out_dir: &Utf8Path, + root_testpaths: &TestPaths, + kind: DocKind, ) -> ProcRes { if self.props.build_aux_docs { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab); - let props_for_aux = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.compute_aux_test_paths(root_testpaths, rel_ab); + let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, stdout: self.stdout, stderr: self.stderr, props: &props_for_aux, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); // use root_testpaths here, because aux-builds should have the // same --out-dir and auxiliary directory. - let auxres = aux_cx.document(&root_out_dir, root_testpaths, kind); + let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, root_testpaths, kind); if !auxres.status.success() { return auxres; } @@ -1038,7 +1049,7 @@ impl<'test> TestCx<'test> { // actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire // test let out_dir: Cow<'_, Utf8Path> = if self.props.unique_doc_out_dir { - let file_name = self.testpaths.file.file_stem().expect("file name should not be empty"); + let file_name = file_to_doc.file_stem().expect("file name should not be empty"); let out_dir = Utf8PathBuf::from_iter([ root_out_dir, Utf8Path::new("docs"), @@ -1063,7 +1074,7 @@ impl<'test> TestCx<'test> { .arg(out_dir.as_ref()) .arg("--deny") .arg("warnings") - .arg(&self.testpaths.file) + .arg(file_to_doc) .arg("-A") .arg("internal_features") .args(&self.props.compile_flags) @@ -1195,24 +1206,14 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> TestPaths { + fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> Utf8PathBuf { let test_ab = of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab); if !test_ab.exists() { self.fatal(&format!("aux-build `{}` source not found", test_ab)) } - TestPaths { - file: test_ab, - relative_dir: of - .relative_dir - .join(self.output_testname_unique()) - .join("auxiliary") - .join(rel_ab) - .parent() - .expect("aux-build path has no parent") - .to_path_buf(), - } + test_ab } fn is_vxworks_pure_static(&self) -> bool { @@ -1369,9 +1370,8 @@ impl<'test> TestCx<'test> { aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_testpaths = self.compute_aux_test_paths(of, source_path); - let mut aux_props = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.compute_aux_test_paths(of, source_path); + let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; } @@ -1388,14 +1388,13 @@ impl<'test> TestCx<'test> { stdout: self.stdout, stderr: self.stderr, props: &aux_props, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - let input_file = &aux_testpaths.file; let mut aux_rustc = aux_cx.make_compile_args( - input_file, + &aux_path, aux_output, Emit::None, AllowUnused::No, @@ -1471,7 +1470,7 @@ impl<'test> TestCx<'test> { ); if !auxres.status.success() { self.fatal_proc_rec( - &format!("auxiliary build of {} failed to compile: ", aux_testpaths.file), + &format!("auxiliary build of {aux_path} failed to compile: "), &auxres, ); } @@ -2033,11 +2032,6 @@ impl<'test> TestCx<'test> { self.aux_output_dir_name().join("bin") } - /// Generates a unique name for the test, such as `testname.revision.mode`. - fn output_testname_unique(&self) -> Utf8PathBuf { - output_testname_unique(self.config, self.testpaths, self.safe_revision()) - } - /// The revision, ignored for incremental compilation since it wants all revisions in /// the same directory. fn safe_revision(&self) -> Option<&str> { From 6dfc82b24af1708068aaecbb0edeafea0cd28b47 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 28 Oct 2025 17:58:10 +1100 Subject: [PATCH 226/525] Remove some parameters that are always `self.testpaths` In particular, this eliminates the cryptic `of: &TestPaths` parameters. --- src/tools/compiletest/src/runtest.rs | 67 ++++++++----------- src/tools/compiletest/src/runtest/assembly.rs | 2 +- src/tools/compiletest/src/runtest/coverage.rs | 2 +- src/tools/compiletest/src/runtest/js_doc.rs | 2 +- src/tools/compiletest/src/runtest/rustdoc.rs | 2 +- .../compiletest/src/runtest/rustdoc_json.rs | 2 +- src/tools/compiletest/src/runtest/ui.rs | 2 +- 7 files changed, 35 insertions(+), 44 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index fed59764a2eb..6696662c7a09 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -562,7 +562,7 @@ impl<'test> TestCx<'test> { self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags); rustc.args(&self.props.compile_flags); - self.compose_and_run_compiler(rustc, Some(src), self.testpaths) + self.compose_and_run_compiler(rustc, Some(src)) } fn maybe_add_external_args(&self, cmd: &mut Command, args: &Vec) { @@ -993,18 +993,13 @@ impl<'test> TestCx<'test> { passes, ); - self.compose_and_run_compiler(rustc, None, self.testpaths) + self.compose_and_run_compiler(rustc, None) } /// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run. /// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths. - fn document( - &self, - root_out_dir: &Utf8Path, - root_testpaths: &TestPaths, - kind: DocKind, - ) -> ProcRes { - self.document_inner(&self.testpaths.file, root_out_dir, root_testpaths, kind) + fn document(&self, root_out_dir: &Utf8Path, kind: DocKind) -> ProcRes { + self.document_inner(&self.testpaths.file, root_out_dir, kind) } /// Like `document`, but takes an explicit `file_to_doc` argument so that @@ -1014,14 +1009,13 @@ impl<'test> TestCx<'test> { &self, file_to_doc: &Utf8Path, root_out_dir: &Utf8Path, - root_testpaths: &TestPaths, kind: DocKind, ) -> ProcRes { if self.props.build_aux_docs { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_path = self.compute_aux_test_paths(root_testpaths, rel_ab); + let aux_path = self.compute_aux_test_paths(rel_ab); let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, @@ -1033,9 +1027,7 @@ impl<'test> TestCx<'test> { }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - // use root_testpaths here, because aux-builds should have the - // same --out-dir and auxiliary directory. - let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, root_testpaths, kind); + let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, kind); if !auxres.status.success() { return auxres; } @@ -1063,7 +1055,7 @@ impl<'test> TestCx<'test> { }; let mut rustdoc = Command::new(rustdoc_path); - let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision()); + let current_dir = self.output_base_dir(); rustdoc.current_dir(current_dir); rustdoc .arg("-L") @@ -1091,7 +1083,7 @@ impl<'test> TestCx<'test> { rustdoc.arg(format!("-Clinker={}", linker)); } - self.compose_and_run_compiler(rustdoc, None, root_testpaths) + self.compose_and_run_compiler(rustdoc, None) } fn exec_compiled_test(&self) -> ProcRes { @@ -1206,9 +1198,14 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> Utf8PathBuf { - let test_ab = - of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab); + fn compute_aux_test_paths(&self, rel_ab: &str) -> Utf8PathBuf { + let test_ab = self + .testpaths + .file + .parent() + .expect("test file path has no parent") + .join("auxiliary") + .join(rel_ab); if !test_ab.exists() { self.fatal(&format!("aux-build `{}` source not found", test_ab)) } @@ -1259,13 +1256,13 @@ impl<'test> TestCx<'test> { aux_dir } - fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Utf8Path, rustc: &mut Command) { + fn build_all_auxiliary(&self, aux_dir: &Utf8Path, rustc: &mut Command) { for rel_ab in &self.props.aux.builds { - self.build_auxiliary(of, rel_ab, &aux_dir, None); + self.build_auxiliary(rel_ab, &aux_dir, None); } for rel_ab in &self.props.aux.bins { - self.build_auxiliary(of, rel_ab, &aux_dir, Some(AuxType::Bin)); + self.build_auxiliary(rel_ab, &aux_dir, Some(AuxType::Bin)); } let path_to_crate_name = |path: &str| -> String { @@ -1284,12 +1281,12 @@ impl<'test> TestCx<'test> { }; for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, None); + let aux_type = self.build_auxiliary(&aux_path, &aux_dir, None); add_extern(rustc, aux_name, aux_path, aux_type); } for proc_macro in &self.props.aux.proc_macros { - self.build_auxiliary(of, proc_macro, &aux_dir, Some(AuxType::ProcMacro)); + self.build_auxiliary(proc_macro, &aux_dir, Some(AuxType::ProcMacro)); let crate_name = path_to_crate_name(proc_macro); add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro); } @@ -1297,7 +1294,7 @@ impl<'test> TestCx<'test> { // Build any `//@ aux-codegen-backend`, and pass the resulting library // to `-Zcodegen-backend` when compiling the test file. if let Some(aux_file) = &self.props.aux.codegen_backend { - let aux_type = self.build_auxiliary(of, aux_file, aux_dir, None); + let aux_type = self.build_auxiliary(aux_file, aux_dir, None); if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) { let lib_path = aux_dir.join(&lib_name); rustc.arg(format!("-Zcodegen-backend={}", lib_path)); @@ -1307,12 +1304,7 @@ impl<'test> TestCx<'test> { /// `root_testpaths` refers to the path of the original test. the auxiliary and the test with an /// aux-build have the same `root_testpaths`. - fn compose_and_run_compiler( - &self, - mut rustc: Command, - input: Option, - root_testpaths: &TestPaths, - ) -> ProcRes { + fn compose_and_run_compiler(&self, mut rustc: Command, input: Option) -> ProcRes { if self.props.add_core_stubs { let minicore_path = self.build_minicore(); rustc.arg("--extern"); @@ -1320,7 +1312,7 @@ impl<'test> TestCx<'test> { } let aux_dir = self.aux_output_dir(); - self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc); + self.build_all_auxiliary(&aux_dir, &mut rustc); rustc.envs(self.props.rustc_env.clone()); self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); @@ -1365,12 +1357,11 @@ impl<'test> TestCx<'test> { /// If `aux_type` is `None`, then this will determine the aux-type automatically. fn build_auxiliary( &self, - of: &TestPaths, source_path: &str, aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_path = self.compute_aux_test_paths(of, source_path); + let aux_path = self.compute_aux_test_paths(source_path); let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; @@ -1401,7 +1392,7 @@ impl<'test> TestCx<'test> { LinkToAux::No, Vec::new(), ); - aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc); + aux_cx.build_all_auxiliary(&aux_dir, &mut aux_rustc); aux_rustc.envs(aux_props.rustc_env.clone()); for key in &aux_props.unset_rustc_env { @@ -2126,7 +2117,7 @@ impl<'test> TestCx<'test> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } @@ -2204,9 +2195,9 @@ impl<'test> TestCx<'test> { Vec::new(), ); let aux_dir = new_rustdoc.aux_output_dir(); - new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc); + new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc); - let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths, DocKind::Html); + let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html); if !proc_res.status.success() { writeln!(self.stderr, "failed to run nightly rustdoc"); return; diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs index 91d4f620f719..c805b4c7a59e 100644 --- a/src/tools/compiletest/src/runtest/assembly.rs +++ b/src/tools/compiletest/src/runtest/assembly.rs @@ -43,7 +43,7 @@ impl TestCx<'_> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } } diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index d0a0c960b451..5b94d9567d8f 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -197,7 +197,7 @@ impl<'test> TestCx<'test> { rustdoc_cmd.arg(&self.testpaths.file); - let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc --test failed!", &proc_res) } diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs index 93b05617e6f8..e7e078ff27d9 100644 --- a/src/tools/compiletest/src/runtest/js_doc.rs +++ b/src/tools/compiletest/src/runtest/js_doc.rs @@ -7,7 +7,7 @@ impl TestCx<'_> { if let Some(nodejs) = &self.config.nodejs { let out_dir = self.output_base_dir(); - self.document(&out_dir, &self.testpaths, DocKind::Html); + self.document(&out_dir, DocKind::Html); let file_stem = self.testpaths.file.file_stem().expect("no file stem"); let res = self.run_command_to_procres( diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 32b1823961be..a4558de5f1c0 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -11,7 +11,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Html); + let proc_res = self.document(&out_dir, DocKind::Html); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index dd7ebe9efaee..6cb0c2a04053 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -13,7 +13,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Json); + let proc_res = self.document(&out_dir, DocKind::Json); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index d683a325c866..2bbde95dba54 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -249,7 +249,7 @@ impl TestCx<'_> { rustc.arg(crate_name); } - let res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); } From 720bfff17132a6295df26d62b7db8b8262b328e4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 28 Oct 2025 17:58:10 +1100 Subject: [PATCH 227/525] Rename `compute_aux_paths` to `resolve_aux_path` This method no longer returns a `TestPaths`, so the old name is no longer appropriate. --- src/tools/compiletest/src/runtest.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 6696662c7a09..84806ffb66c7 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1015,7 +1015,7 @@ impl<'test> TestCx<'test> { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_path = self.compute_aux_test_paths(rel_ab); + let aux_path = self.resolve_aux_path(rel_ab); let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, @@ -1198,19 +1198,21 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, rel_ab: &str) -> Utf8PathBuf { - let test_ab = self + fn resolve_aux_path(&self, relative_aux_path: &str) -> Utf8PathBuf { + let aux_path = self .testpaths .file .parent() .expect("test file path has no parent") .join("auxiliary") - .join(rel_ab); - if !test_ab.exists() { - self.fatal(&format!("aux-build `{}` source not found", test_ab)) + .join(relative_aux_path); + if !aux_path.exists() { + self.fatal(&format!( + "auxiliary source file `{relative_aux_path}` not found at `{aux_path}`" + )); } - test_ab + aux_path } fn is_vxworks_pure_static(&self) -> bool { @@ -1361,7 +1363,7 @@ impl<'test> TestCx<'test> { aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_path = self.compute_aux_test_paths(source_path); + let aux_path = self.resolve_aux_path(source_path); let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; From 20e0014de01e6160ed3b8dd9f692c02118086142 Mon Sep 17 00:00:00 2001 From: Francisco Gouveia Date: Thu, 23 Oct 2025 22:26:06 +0100 Subject: [PATCH 228/525] Support f32/f64 in native function calls --- src/tools/miri/src/shims/native_lib/mod.rs | 16 ++++++++++++++-- .../tests/native-lib/pass/scalar_arguments.rs | 4 ++++ .../miri/tests/native-lib/scalar_arguments.c | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 382839ea1eb1..483da4b67b8e 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -8,10 +8,12 @@ use libffi::middle::Type as FfiType; use rustc_abi::{HasDataLayout, Size}; use rustc_data_structures::either; use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout}; -use rustc_middle::ty::{self, IntTy, Ty, UintTy}; +use rustc_middle::ty::{self, FloatTy, IntTy, Ty, UintTy}; use rustc_span::Symbol; use serde::{Deserialize, Serialize}; +use self::helpers::ToSoft; + mod ffi; #[cfg_attr( @@ -138,6 +140,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let x = unsafe { ffi::call::(fun, libffi_args) }; Scalar::from_target_usize(x.try_into().unwrap(), this) } + ty::Float(FloatTy::F32) => { + let x = unsafe { ffi::call::(fun, libffi_args) }; + Scalar::from_f32(x.to_soft()) + } + ty::Float(FloatTy::F64) => { + let x = unsafe { ffi::call::(fun, libffi_args) }; + Scalar::from_f64(x.to_soft()) + } // Functions with no declared return type (i.e., the default return) // have the output_type `Tuple([])`. ty::Tuple(t_list) if (*t_list).deref().is_empty() => { @@ -396,7 +406,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Gets the matching libffi type for a given Ty. fn ty_to_ffitype(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, FfiType> { - use rustc_abi::{AddressSpace, BackendRepr, Integer, Primitive}; + use rustc_abi::{AddressSpace, BackendRepr, Float, Integer, Primitive}; // `BackendRepr::Scalar` is also a signal to pass this type as a scalar in the ABI. This // matches what codegen does. This does mean that we support some types whose ABI is not @@ -413,6 +423,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { Primitive::Int(Integer::I16, /* signed */ false) => FfiType::u16(), Primitive::Int(Integer::I32, /* signed */ false) => FfiType::u32(), Primitive::Int(Integer::I64, /* signed */ false) => FfiType::u64(), + Primitive::Float(Float::F32) => FfiType::f32(), + Primitive::Float(Float::F64) => FfiType::f64(), Primitive::Pointer(AddressSpace::ZERO) => FfiType::pointer(), _ => throw_unsup_format!( diff --git a/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs index 9e99977a692a..231df67bb5b8 100644 --- a/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs +++ b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs @@ -17,6 +17,7 @@ extern "C" { ) -> i32; fn add_short_to_long(x: i16, y: i64) -> i64; fn get_unsigned_int() -> u32; + fn add_float(x: f32) -> f32; fn printer(); } @@ -37,6 +38,9 @@ fn main() { // test function that returns -10 as an unsigned int assert_eq!(get_unsigned_int(), (-10i32) as u32); + // test function that adds 1.5 to a f32 + assert_eq!(add_float(1.0f32), 2.5f32); + // test void function that prints from C printer(); } diff --git a/src/tools/miri/tests/native-lib/scalar_arguments.c b/src/tools/miri/tests/native-lib/scalar_arguments.c index 8cf38f74413c..10b6244bdeb4 100644 --- a/src/tools/miri/tests/native-lib/scalar_arguments.c +++ b/src/tools/miri/tests/native-lib/scalar_arguments.c @@ -30,6 +30,10 @@ EXPORT int64_t add_short_to_long(int16_t x, int64_t y) { return x + y; } +EXPORT float add_float(float x) { + return x + 1.5f; +} + // To test that functions not marked with EXPORT cannot be called by Miri. int32_t not_exported(void) { return 0; From 13834a011e0e14196a64097e6308f75f6bf6c6c3 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 28 Oct 2025 10:59:33 +0200 Subject: [PATCH 229/525] Fix handling of blocks modules that are not the root module --- .../crates/hir-def/src/item_tree/lower.rs | 28 ++++++++----------- .../crates/hir-def/src/resolver.rs | 23 ++++++++------- .../crates/hir-def/src/visibility.rs | 13 +++++---- .../crates/hir-ty/src/display.rs | 5 ++-- .../crates/hir-ty/src/tests/regression.rs | 16 +++++++++++ .../crates/hir/src/source_analyzer.rs | 14 ++++------ .../rust-analyzer/crates/ide-db/src/search.rs | 14 ++++++---- .../test_data/highlight_block_mod_items.html | 2 +- 8 files changed, 64 insertions(+), 51 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 454e06399583..db50e6585d84 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -370,18 +370,13 @@ impl<'a> Ctx<'a> { }); match &vis { RawVisibility::Public => RawVisibilityId::PUB, - RawVisibility::Module(path, explicitness) if path.segments().is_empty() => { - match (path.kind, explicitness) { - (PathKind::SELF, VisibilityExplicitness::Explicit) => { - RawVisibilityId::PRIV_EXPLICIT - } - (PathKind::SELF, VisibilityExplicitness::Implicit) => { - RawVisibilityId::PRIV_IMPLICIT - } - (PathKind::Crate, _) => RawVisibilityId::PUB_CRATE, - _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32), - } + RawVisibility::PubSelf(VisibilityExplicitness::Explicit) => { + RawVisibilityId::PRIV_EXPLICIT } + RawVisibility::PubSelf(VisibilityExplicitness::Implicit) => { + RawVisibilityId::PRIV_IMPLICIT + } + RawVisibility::PubCrate => RawVisibilityId::PUB_CRATE, _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32), } } @@ -466,10 +461,7 @@ pub(crate) fn lower_use_tree( } fn private_vis() -> RawVisibility { - RawVisibility::Module( - Interned::new(ModPath::from_kind(PathKind::SELF)), - VisibilityExplicitness::Implicit, - ) + RawVisibility::PubSelf(VisibilityExplicitness::Implicit) } pub(crate) fn visibility_from_ast( @@ -486,9 +478,11 @@ pub(crate) fn visibility_from_ast( Some(path) => path, } } - ast::VisibilityKind::PubCrate => ModPath::from_kind(PathKind::Crate), + ast::VisibilityKind::PubCrate => return RawVisibility::PubCrate, ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)), - ast::VisibilityKind::PubSelf => ModPath::from_kind(PathKind::SELF), + ast::VisibilityKind::PubSelf => { + return RawVisibility::PubSelf(VisibilityExplicitness::Explicit); + } ast::VisibilityKind::Pub => return RawVisibility::Public, }; RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 698292c2fbea..abcf0a397cdf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -1075,7 +1075,9 @@ fn resolver_for_scope_<'db>( if let Some(block) = scopes.block(scope) { let def_map = block_def_map(db, block); let local_def_map = block.lookup(db).module.only_local_def_map(db); - r = r.push_block_scope(def_map, local_def_map); + // Using `DefMap::ROOT` is okay here since inside modules other than the root, + // there can't directly be expressions. + r = r.push_block_scope(def_map, local_def_map, DefMap::ROOT); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? @@ -1108,12 +1110,9 @@ impl<'db> Resolver<'db> { self, def_map: &'db DefMap, local_def_map: &'db LocalDefMap, + module_id: LocalModuleId, ) -> Resolver<'db> { - self.push_scope(Scope::BlockScope(ModuleItemMap { - def_map, - local_def_map, - module_id: DefMap::ROOT, - })) + self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, module_id })) } fn push_expr_scope( @@ -1273,7 +1272,7 @@ impl HasResolver for ModuleId { let (mut def_map, local_def_map) = self.local_def_map(db); let mut module_id = self.local_id; - if !self.is_block_module() { + if !self.is_within_block() { return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, local_def_map, module_id }, @@ -1283,9 +1282,9 @@ impl HasResolver for ModuleId { let mut modules: SmallVec<[_; 1]> = smallvec![]; while let Some(parent) = def_map.parent() { let block_def_map = mem::replace(&mut def_map, parent.def_map(db)); - modules.push(block_def_map); - if !parent.is_block_module() { - module_id = parent.local_id; + let block_module_id = mem::replace(&mut module_id, parent.local_id); + modules.push((block_def_map, block_module_id)); + if !parent.is_within_block() { break; } } @@ -1293,8 +1292,8 @@ impl HasResolver for ModuleId { scopes: Vec::with_capacity(modules.len()), module_scope: ModuleItemMap { def_map, local_def_map, module_id }, }; - for def_map in modules.into_iter().rev() { - resolver = resolver.push_block_scope(def_map, local_def_map); + for (def_map, module_id) in modules.into_iter().rev() { + resolver = resolver.push_block_scope(def_map, local_def_map, module_id); } resolver } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index b5eb84c25f2b..948f6ed8c32b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -289,18 +289,21 @@ pub(crate) fn field_visibilities_query( pub fn visibility_from_ast( db: &dyn DefDatabase, - has_resolver: impl HasResolver, + has_resolver: impl HasResolver + HasModule, ast_vis: InFile>, ) -> Visibility { let mut span_map = None; let raw_vis = crate::item_tree::visibility_from_ast(db, ast_vis.value, &mut |range| { span_map.get_or_insert_with(|| db.span_map(ast_vis.file_id)).span_for_range(range).ctx }); - if raw_vis == RawVisibility::Public { - return Visibility::Public; + match raw_vis { + RawVisibility::PubSelf(explicitness) => { + Visibility::Module(has_resolver.module(db), explicitness) + } + RawVisibility::PubCrate => Visibility::PubCrate(has_resolver.krate(db)), + RawVisibility::Public => Visibility::Public, + RawVisibility::Module(..) => Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis), } - - Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis) } /// Resolve visibility of a type alias. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index dd1b212d4c29..0a3796687f03 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -2078,9 +2078,10 @@ pub fn write_visibility<'db>( if vis_id == module_id { // pub(self) or omitted Ok(()) - } else if root_module_id == vis_id { + } else if root_module_id == vis_id && !root_module_id.is_within_block() { write!(f, "pub(crate) ") - } else if module_id.containing_module(f.db) == Some(vis_id) { + } else if module_id.containing_module(f.db) == Some(vis_id) && !vis_id.is_block_module() + { write!(f, "pub(super) ") } else { write!(f, "pub(in ...) ") diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 7c79393e65ac..118ea88f7b6a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2506,3 +2506,19 @@ fn main() { "#, ); } + +#[test] +fn foo() { + check_types( + r#" +fn foo() { + mod my_mod { + pub type Bool = bool; + } + + let _: my_mod::Bool; + // ^ bool +} + "#, + ); +} diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 15eab14b88df..f994ed26cab6 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -1594,14 +1594,12 @@ fn resolve_hir_path_( Some(unresolved) => resolver .generic_def() .and_then(|def| { - hir_ty::attach_db(db, || { - hir_ty::associated_type_shorthand_candidates( - db, - def, - res.in_type_ns()?, - |name, _| name == unresolved.name, - ) - }) + hir_ty::associated_type_shorthand_candidates( + db, + def, + res.in_type_ns()?, + |name, _| name == unresolved.name, + ) }) .map(TypeAlias::from) .map(Into::into) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index f1d076e874d5..018c84189775 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -387,12 +387,14 @@ impl Definition { return SearchScope::reverse_dependencies(db, module.krate()); } - let vis = self.visibility(db); - if let Some(Visibility::Public) = vis { - return SearchScope::reverse_dependencies(db, module.krate()); - } - if let Some(Visibility::Module(module, _)) = vis { - return SearchScope::module_and_children(db, module.into()); + if let Some(vis) = self.visibility(db) { + return match vis { + Visibility::Module(module, _) => { + SearchScope::module_and_children(db, module.into()) + } + Visibility::PubCrate(krate) => SearchScope::krate(db, krate.into()), + Visibility::Public => SearchScope::reverse_dependencies(db, module.krate()), + }; } let range = match module_source { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index 3beda396da80..711f5344ae7d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -53,7 +53,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest<const C: usize> { field: [(); {C}] } + struct Innerest<const C: usize> { field: [(); {C}] } } } } From 4d338cbb2f01d9641f330211b3cbc7e130494da3 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 28 Oct 2025 10:27:28 +0200 Subject: [PATCH 230/525] Support memory profiling with dhat Unfortunately, this requires a custom build of r-a, and it's quite slow. --- src/tools/rust-analyzer/Cargo.lock | 31 ++++++++++++++++- .../crates/rust-analyzer/Cargo.toml | 2 ++ .../crates/rust-analyzer/src/config.rs | 11 ++++++ .../rust-analyzer/src/handlers/request.rs | 34 ++++++++++++++----- .../crates/rust-analyzer/src/lib.rs | 7 ++++ .../crates/rust-analyzer/src/main_loop.rs | 8 +++++ .../docs/book/src/configuration_generated.md | 10 ++++++ .../rust-analyzer/editors/code/package.json | 13 +++++++ .../editors/code/src/commands.ts | 27 ++------------- .../editors/code/src/snippets.ts | 4 ++- src/tools/rust-analyzer/xtask/src/dist.rs | 21 ++++++++++-- src/tools/rust-analyzer/xtask/src/flags.rs | 19 ++++++++++- 12 files changed, 148 insertions(+), 39 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 535833d9e2a9..b4754df16d09 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -418,6 +418,22 @@ dependencies = [ "syn", ] +[[package]] +name = "dhat" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827" +dependencies = [ + "backtrace", + "lazy_static", + "mintex", + "parking_lot", + "rustc-hash 1.1.0", + "serde", + "serde_json", + "thousands", +] + [[package]] name = "dirs" version = "6.0.0" @@ -1383,6 +1399,12 @@ dependencies = [ "adler2", ] +[[package]] +name = "mintex" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536" + [[package]] name = "mio" version = "1.1.0" @@ -1452,7 +1474,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -2011,6 +2033,7 @@ dependencies = [ "cargo_metadata 0.21.0", "cfg", "crossbeam-channel", + "dhat", "dirs", "dissimilar", "expect-test", @@ -2528,6 +2551,12 @@ dependencies = [ "syn", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + [[package]] name = "thread_local" version = "1.1.9" diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index c746f848b6a0..5fdab458bb8e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -53,6 +53,7 @@ semver.workspace = true memchr = "2.7.5" cargo_metadata.workspace = true process-wrap.workspace = true +dhat = { version = "0.3.3", optional = true } cfg.workspace = true hir-def.workspace = true @@ -105,6 +106,7 @@ in-rust-tree = [ "hir-ty/in-rust-tree", "load-cargo/in-rust-tree", ] +dhat = ["dep:dhat"] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6d2907ee56aa..75eacdbab355 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -378,6 +378,12 @@ config_data! { /// Internal config, path to proc-macro server executable. procMacro_server: Option = None, + /// The path where to save memory profiling output. + /// + /// **Note:** Memory profiling is not enabled by default in rust-analyzer builds, you need to build + /// from source for it. + profiling_memoryProfile: Option = None, + /// Exclude imports from find-all-references. references_excludeImports: bool = false, @@ -2165,6 +2171,11 @@ impl Config { Some(AbsPathBuf::try_from(path).unwrap_or_else(|path| self.root_path.join(path))) } + pub fn dhat_output_file(&self) -> Option { + let path = self.profiling_memoryProfile().clone()?; + Some(AbsPathBuf::try_from(path).unwrap_or_else(|path| self.root_path.join(path))) + } + pub fn ignored_proc_macros( &self, source_root: Option, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 66a7a0b825f1..528ec70cb6e9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -126,17 +126,35 @@ pub(crate) fn handle_analyzer_status( Ok(buf) } -pub(crate) fn handle_memory_usage(state: &mut GlobalState, _: ()) -> anyhow::Result { +pub(crate) fn handle_memory_usage(_state: &mut GlobalState, _: ()) -> anyhow::Result { let _p = tracing::info_span!("handle_memory_usage").entered(); - let mem = state.analysis_host.per_query_memory_usage(); - let mut out = String::new(); - for (name, bytes, entries) in mem { - format_to!(out, "{:>8} {:>6} {}\n", bytes, entries, name); + #[cfg(not(feature = "dhat"))] + { + Err(anyhow::anyhow!( + "Memory profiling is not enabled for this build of rust-analyzer.\n\n\ + To build rust-analyzer with profiling support, pass `--features dhat --profile dev-rel` to `cargo build` + when building from source, or pass `--enable-profiling` to `cargo xtask`." + )) + } + #[cfg(feature = "dhat")] + { + if let Some(dhat_output_file) = _state.config.dhat_output_file() { + let mutprofiler = crate::DHAT_PROFILER.lock().unwrap(); + let old_profiler = profiler.take(); + // Need to drop the old profiler before creating a new one. + drop(old_profiler); + *profiler = Some(dhat::Profiler::builder().file_name(&dhat_output_file).build()); + Ok(format!( + "Memory profile was saved successfully to {dhat_output_file}.\n\n\ + See https://docs.rs/dhat/latest/dhat/#viewing for how to inspect the profile." + )) + } else { + Err(anyhow::anyhow!( + "Please set `rust-analyzer.profiling.memoryProfile` to the path where you want to save the profile." + )) + } } - format_to!(out, "{:>8} Remaining\n", profile::memory_usage().allocated); - - Ok(out) } pub(crate) fn handle_view_syntax_tree( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 44af8fbddf30..6ae527abb1ff 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -82,3 +82,10 @@ macro_rules! try_default_ { }; } pub(crate) use try_default_ as try_default; + +#[cfg(feature = "dhat")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +#[cfg(feature = "dhat")] +static DHAT_PROFILER: std::sync::Mutex> = std::sync::Mutex::new(None); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index c0947b2a291e..f57e0fe15313 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -60,6 +60,14 @@ pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> { SetThreadPriority(thread, thread_priority_above_normal); } + #[cfg(feature = "dhat")] + { + if let Some(dhat_output_file) = config.dhat_output_file() { + *crate::DHAT_PROFILER.lock().unwrap() = + Some(dhat::Profiler::builder().file_name(&dhat_output_file).build()); + } + } + GlobalState::new(connection.sender, config).run(connection.receiver) } diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index d768993f501f..4f456555a2e6 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1289,6 +1289,16 @@ Default: `null` Internal config, path to proc-macro server executable. +## rust-analyzer.profiling.memoryProfile {#profiling.memoryProfile} + +Default: `null` + +The path where to save memory profiling output. + +**Note:** Memory profiling is not enabled by default in rust-analyzer builds, you need to build +from source for it. + + ## rust-analyzer.references.excludeImports {#references.excludeImports} Default: `false` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index d659421a0299..099397eafa97 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2749,6 +2749,19 @@ } } }, + { + "title": "Profiling", + "properties": { + "rust-analyzer.profiling.memoryProfile": { + "markdownDescription": "The path where to save memory profiling output.\n\n**Note:** Memory profiling is not enabled by default in rust-analyzer builds, you need to build\nfrom source for it.", + "default": null, + "type": [ + "null", + "string" + ] + } + } + }, { "title": "References", "properties": { diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts index 25b30013fa1c..16fc586d5df0 100644 --- a/src/tools/rust-analyzer/editors/code/src/commands.ts +++ b/src/tools/rust-analyzer/editors/code/src/commands.ts @@ -71,32 +71,9 @@ export function analyzerStatus(ctx: CtxInit): Cmd { } export function memoryUsage(ctx: CtxInit): Cmd { - const tdcp = new (class implements vscode.TextDocumentContentProvider { - readonly uri = vscode.Uri.parse("rust-analyzer-memory://memory"); - readonly eventEmitter = new vscode.EventEmitter(); - - provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult { - if (!vscode.window.activeTextEditor) return ""; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => { - return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)"; - }); - } - - get onDidChange(): vscode.Event { - return this.eventEmitter.event; - } - })(); - - ctx.pushExtCleanup( - vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-memory", tdcp), - ); - return async () => { - tdcp.eventEmitter.fire(tdcp.uri); - const document = await vscode.workspace.openTextDocument(tdcp.uri); - return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true); + const response = await ctx.client.sendRequest(ra.memoryUsage); + vscode.window.showInformationMessage(response); }; } diff --git a/src/tools/rust-analyzer/editors/code/src/snippets.ts b/src/tools/rust-analyzer/editors/code/src/snippets.ts index e3f43a80670a..a469a9cd1f45 100644 --- a/src/tools/rust-analyzer/editors/code/src/snippets.ts +++ b/src/tools/rust-analyzer/editors/code/src/snippets.ts @@ -24,7 +24,9 @@ export async function applySnippetWorkspaceEdit( for (const indel of edits) { assert( !(indel instanceof vscode.SnippetTextEdit), - `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`, + `bad ws edit: snippet received with multiple edits: ${JSON.stringify( + edit, + )}`, ); builder.replace(indel.range, indel.newText); } diff --git a/src/tools/rust-analyzer/xtask/src/dist.rs b/src/tools/rust-analyzer/xtask/src/dist.rs index dbfecdbe1121..1b1fb532cae9 100644 --- a/src/tools/rust-analyzer/xtask/src/dist.rs +++ b/src/tools/rust-analyzer/xtask/src/dist.rs @@ -45,11 +45,22 @@ impl flags::Dist { allocator, self.zig, self.pgo, + // Profiling requires debug information. + self.enable_profiling, )?; let release_tag = if stable { date_iso(sh)? } else { "nightly".to_owned() }; dist_client(sh, &version, &release_tag, &target)?; } else { - dist_server(sh, "0.0.0-standalone", &target, allocator, self.zig, self.pgo)?; + dist_server( + sh, + "0.0.0-standalone", + &target, + allocator, + self.zig, + self.pgo, + // Profiling requires debug information. + self.enable_profiling, + )?; } Ok(()) } @@ -92,9 +103,11 @@ fn dist_server( allocator: Malloc, zig: bool, pgo: Option, + dev_rel: bool, ) -> anyhow::Result<()> { let _e = sh.push_env("CFG_RELEASE", release); let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin"); + let _e = sh.push_env("CARGO_PROFILE_DEV_REL_LTO", "thin"); // Uncomment to enable debug info for releases. Note that: // * debug info is split on windows and macs, so it does nothing for those platforms, @@ -120,7 +133,7 @@ fn dist_server( None }; - let mut cmd = build_command(sh, command, &target_name, features); + let mut cmd = build_command(sh, command, &target_name, features, dev_rel); if let Some(profile) = pgo_profile { cmd = cmd.env("RUSTFLAGS", format!("-Cprofile-use={}", profile.to_str().unwrap())); } @@ -141,10 +154,12 @@ fn build_command<'a>( command: &str, target_name: &str, features: &[&str], + dev_rel: bool, ) -> Cmd<'a> { + let profile = if dev_rel { "dev-rel" } else { "release" }; cmd!( sh, - "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release" + "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --profile {profile}" ) } diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs index 8f70a1861893..e72d8f22e4f0 100644 --- a/src/tools/rust-analyzer/xtask/src/flags.rs +++ b/src/tools/rust-analyzer/xtask/src/flags.rs @@ -42,6 +42,10 @@ xflags::xflags! { optional --mimalloc /// Use jemalloc allocator for server. optional --jemalloc + // Enable memory profiling support. + // + // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. + optional --enable-profiling /// Install the proc-macro server. optional --proc-macro-server @@ -67,6 +71,10 @@ xflags::xflags! { optional --mimalloc /// Use jemalloc allocator for server optional --jemalloc + // Enable memory profiling support. + // + // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. + optional --enable-profiling optional --client-patch-version version: String /// Use cargo-zigbuild optional --zig @@ -125,6 +133,7 @@ pub struct Install { pub server: bool, pub mimalloc: bool, pub jemalloc: bool, + pub enable_profiling: bool, pub proc_macro_server: bool, pub dev_rel: bool, pub force_always_assert: bool, @@ -143,6 +152,7 @@ pub struct Release { pub struct Dist { pub mimalloc: bool, pub jemalloc: bool, + pub enable_profiling: bool, pub client_patch_version: Option, pub zig: bool, pub pgo: Option, @@ -280,6 +290,7 @@ pub(crate) enum Malloc { System, Mimalloc, Jemalloc, + Dhat, } impl Malloc { @@ -288,6 +299,7 @@ impl Malloc { Malloc::System => &[][..], Malloc::Mimalloc => &["--features", "mimalloc"], Malloc::Jemalloc => &["--features", "jemalloc"], + Malloc::Dhat => &["--features", "dhat"], } } } @@ -301,12 +313,15 @@ impl Install { Malloc::Mimalloc } else if self.jemalloc { Malloc::Jemalloc + } else if self.enable_profiling { + Malloc::Dhat } else { Malloc::System }; Some(ServerOpt { malloc, - dev_rel: self.dev_rel, + // Profiling requires debug information. + dev_rel: self.dev_rel || self.enable_profiling, pgo: self.pgo.clone(), force_always_assert: self.force_always_assert, }) @@ -331,6 +346,8 @@ impl Dist { Malloc::Mimalloc } else if self.jemalloc { Malloc::Jemalloc + } else if self.enable_profiling { + Malloc::Dhat } else { Malloc::System } From 3e2c614cb53e7d3797863bf497f330d02e525534 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 28 Oct 2025 15:44:34 +0100 Subject: [PATCH 231/525] Fix invalid tag closing when leaving expansion "original code" --- src/librustdoc/html/highlight.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c37736f137df..c8dbc8d32100 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -428,6 +428,27 @@ impl<'a, F: Write> TokenHandler<'a, '_, F> { } } } + + /// Used when we're done with the current expansion "original code" (ie code before expansion). + /// We close all tags inside `Class::Original` and only keep the ones that were not closed yet. + fn close_original_tag(&mut self) { + let mut classes_to_reopen = Vec::new(); + while let Some(mut class_info) = self.class_stack.open_classes.pop() { + if class_info.class == Class::Original { + while let Some(class_info) = classes_to_reopen.pop() { + self.class_stack.open_classes.push(class_info); + } + class_info.close_tag(self.out); + return; + } + class_info.close_tag(self.out); + if !class_info.pending_exit { + class_info.closing_tag = None; + classes_to_reopen.push(class_info); + } + } + panic!("Didn't find `Class::Original` to close"); + } } impl Drop for TokenHandler<'_, '_, F> { @@ -476,7 +497,9 @@ fn end_expansion<'a, W: Write>( expanded_codes: &'a [ExpandedCode], span: Span, ) -> Option<&'a ExpandedCode> { - token_handler.class_stack.exit_elem(); + // We close `Class::Original` and everything open inside it. + token_handler.close_original_tag(); + // Then we check if we have another macro expansion on the same line. let expansion = get_next_expansion(expanded_codes, token_handler.line, span); if expansion.is_none() { token_handler.close_expansion(); From 8442380278e84eed6fa50e00d35e790c4555b510 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 28 Oct 2025 15:44:52 +0100 Subject: [PATCH 232/525] Add regression test for #148184 --- .../macro/auxiliary/one-line-expand.rs | 15 +++++++++++++++ tests/rustdoc/macro/one-line-expand.rs | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/rustdoc/macro/auxiliary/one-line-expand.rs create mode 100644 tests/rustdoc/macro/one-line-expand.rs diff --git a/tests/rustdoc/macro/auxiliary/one-line-expand.rs b/tests/rustdoc/macro/auxiliary/one-line-expand.rs new file mode 100644 index 000000000000..14df0f2d4f20 --- /dev/null +++ b/tests/rustdoc/macro/auxiliary/one-line-expand.rs @@ -0,0 +1,15 @@ +//@ force-host +//@ no-prefer-dynamic +//@ compile-flags: --crate-type proc-macro + +#![crate_type = "proc-macro"] +#![crate_name = "just_some_proc"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn repro(_args: TokenStream, _input: TokenStream) -> TokenStream { + "struct Repro;".parse().unwrap() +} diff --git a/tests/rustdoc/macro/one-line-expand.rs b/tests/rustdoc/macro/one-line-expand.rs new file mode 100644 index 000000000000..ceb9521820d6 --- /dev/null +++ b/tests/rustdoc/macro/one-line-expand.rs @@ -0,0 +1,19 @@ +// Regression test for . +// It ensures that the macro expansion correctly handles its "class stack". + +//@ compile-flags: -Zunstable-options --generate-macro-expansion +//@ aux-build:one-line-expand.rs + +#![crate_name = "foo"] + +extern crate just_some_proc; + +//@ has 'src/foo/one-line-expand.rs.html' +//@ has - '//*[@class="comment"]' '//' +//@ has - '//*[@class="original"]' '#[just_some_proc::repro]' +//@ has - '//*[@class="original"]/*[@class="attr"]' '#[just_some_proc::repro]' +//@ has - '//code/*[@class="kw"]' 'struct ' + +// +#[just_some_proc::repro] +struct Repro; From 022bb60b8e170cb7c2e884cf7c4187af5ca55edb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Oct 2025 15:17:46 +0000 Subject: [PATCH 233/525] Rustup to rustc 1.93.0-nightly (adaa83897 2025-10-27) --- example/mini_core.rs | 1 - rust-toolchain | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index b522ea193716..2dd75563a34d 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -6,7 +6,6 @@ extern_types, decl_macro, rustc_attrs, - rustc_private, transparent_unions, auto_traits, freeze_impls, diff --git a/rust-toolchain b/rust-toolchain index 3bede572d2c2..0836d830186c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-10-23" +channel = "nightly-2025-10-28" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From bbedad249cd0a7723403f48b2a5fe0ce60746687 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Oct 2025 15:34:36 +0000 Subject: [PATCH 234/525] Error when combining check mode and jit mode --- src/config.rs | 2 +- src/driver/jit.rs | 2 -- src/lib.rs | 21 ++++++++++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/config.rs b/src/config.rs index d328b33a704f..31bc0374460f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ /// Configuration of cg_clif as passed in through `-Cllvm-args` and various env vars. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct BackendConfig { /// Should the crate be AOT compiled or JIT executed. /// diff --git a/src/driver/jit.rs b/src/driver/jit.rs index e35df7a5e787..9dba46363936 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -33,8 +33,6 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option, jit_args: Vec) -> ! { - // FIXME error on check mode or crate types other than bin in CodegenBackend::init() - if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); } diff --git a/src/lib.rs b/src/lib.rs index a45407497f68..1815f990fc16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,7 @@ extern crate rustc_target; extern crate rustc_driver; use std::any::Any; +use std::cell::OnceCell; use std::env; use std::sync::Arc; @@ -124,7 +125,7 @@ impl String> Drop for PrintOnPanic { } pub struct CraneliftCodegenBackend { - pub config: Option, + pub config: OnceCell, } impl CodegenBackend for CraneliftCodegenBackend { @@ -150,6 +151,15 @@ impl CodegenBackend for CraneliftCodegenBackend { sess.dcx() .fatal("`-Cinstrument-coverage` is LLVM specific and not supported by Cranelift"); } + + let config = self.config.get_or_init(|| { + BackendConfig::from_opts(&sess.opts.cg.llvm_args) + .unwrap_or_else(|err| sess.dcx().fatal(err)) + }); + + if config.jit_mode && !sess.opts.output_types.should_codegen() { + sess.dcx().fatal("JIT mode doesn't work with `cargo check`"); + } } fn target_config(&self, sess: &Session) -> TargetConfig { @@ -211,13 +221,10 @@ impl CodegenBackend for CraneliftCodegenBackend { fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); - let config = self.config.clone().unwrap_or_else(|| { - BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) - .unwrap_or_else(|err| tcx.sess.dcx().fatal(err)) - }); + let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, config.jit_args); + driver::jit::run_jit(tcx, config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -363,5 +370,5 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { /// This is the entrypoint for a hot plugged rustc_codegen_cranelift #[unsafe(no_mangle)] pub fn __rustc_codegen_backend() -> Box { - Box::new(CraneliftCodegenBackend { config: None }) + Box::new(CraneliftCodegenBackend { config: OnceCell::new() }) } From eaa91b8f04b2f7adde1db8a8c49c44543344dc6a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:05:34 +0000 Subject: [PATCH 235/525] Bunch of clippy fixes --- src/abi/mod.rs | 35 +++++++++++++++++-------------- src/abi/pass_mode.rs | 7 +------ src/base.rs | 10 ++++----- src/codegen_f16_f128.rs | 3 +-- src/common.rs | 6 +++--- src/constant.rs | 23 ++++++++------------ src/debuginfo/emit.rs | 4 ++-- src/debuginfo/gcc_except_table.rs | 9 ++++---- src/debuginfo/types.rs | 4 ++-- src/driver/aot.rs | 18 ++++++++-------- src/intrinsics/mod.rs | 6 +++--- src/intrinsics/simd.rs | 2 +- src/lib.rs | 4 ++-- src/main_shim.rs | 6 +++--- src/pretty_clif.rs | 2 +- src/unsize.rs | 2 +- src/value_and_place.rs | 8 +++---- 17 files changed, 70 insertions(+), 79 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 576fc453e790..773a134e9041 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -85,7 +85,7 @@ pub(crate) fn get_function_sig<'tcx>( clif_sig_from_fn_abi( tcx, default_call_conv, - &FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), + FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), ) } @@ -114,7 +114,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { /// Instance must be monomorphized pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef { let func_id = import_function(self.tcx, self.module, inst); - let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); + let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func); if self.clif_comments.enabled() { self.add_comment(func_ref, format!("{:?}", inst)); @@ -185,7 +185,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { ) -> &[Value] { let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); - let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); + let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); if self.clif_comments.enabled() { self.add_comment(func_ref, format!("{:?}", name)); @@ -419,7 +419,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { crate::intrinsics::codegen_llvm_intrinsic_call( fx, - &fx.tcx.symbol_name(instance).name, + fx.tcx.symbol_name(instance).name, args, ret_place, target, @@ -534,7 +534,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0].value, idx); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); (CallTarget::Indirect(sig, method), Some(ptr.get_addr(fx))) @@ -554,7 +554,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } let func = func.load_scalar(fx); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); (CallTarget::Indirect(sig, func), None) @@ -564,7 +564,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 mut call_args = return_ptr .into_iter() - .chain(first_arg_override.into_iter()) + .chain(first_arg_override) .chain( args.into_iter() .enumerate() @@ -577,7 +577,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // 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); + adjust_call_for_c_variadic(fx, fn_abi, source_info, func_ref, &mut call_args); } if fx.clif_comments.enabled() { @@ -739,7 +739,7 @@ pub(crate) fn codegen_drop<'tcx>( let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) .fn_abi_of_instance(virtual_drop, ty::List::empty()); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); codegen_call_with_unwind_action( fx, @@ -767,9 +767,12 @@ pub(crate) fn codegen_drop<'tcx>( if drop_instance.def.requires_caller_location(fx.tcx) { // Pass the caller location for `#[track_caller]`. let caller_location = fx.get_caller_location(source_info); - call_args.extend( - adjust_arg_for_abi(fx, caller_location, &fn_abi.args[1], false).into_iter(), - ); + call_args.extend(adjust_arg_for_abi( + fx, + caller_location, + &fn_abi.args[1], + false, + )); } let func_ref = fx.get_function_ref(drop_instance); @@ -816,9 +819,9 @@ pub(crate) fn codegen_call_with_unwind_action( match unwind { UnwindAction::Continue | UnwindAction::Unreachable => { let call_inst = match func_ref { - CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args), + 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) + fx.bcx.ins().call_indirect(sig, func_ptr, call_args) } }; @@ -866,10 +869,10 @@ pub(crate) fn codegen_call_with_unwind_action( match func_ref { CallTarget::Direct(func_ref) => { - fx.bcx.ins().try_call(func_ref, &call_args, exception_table); + fx.bcx.ins().try_call(func_ref, call_args, exception_table); } CallTarget::Indirect(_sig, func_ptr) => { - fx.bcx.ins().try_call_indirect(func_ptr, &call_args, exception_table); + fx.bcx.ins().try_call_indirect(func_ptr, call_args, exception_table); } } diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 7a909a740b05..44b63aa95f83 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -209,12 +209,7 @@ pub(super) fn to_casted_value<'tcx>( cast_target_to_abi_params(cast) .into_iter() .map(|(offset, param)| { - let val = ptr.offset_i64(fx, offset.bytes() as i64).load( - fx, - param.value_type, - MemFlags::new(), - ); - val + ptr.offset_i64(fx, offset.bytes() as i64).load(fx, param.value_type, MemFlags::new()) }) .collect() } diff --git a/src/base.rs b/src/base.rs index 0e95ab5de66b..0d3b38d52c8d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -266,12 +266,12 @@ fn verify_func(tcx: TyCtxt<'_>, writer: &crate::pretty_clif::CommentWriter, func tcx.prof.generic_activity("verify clif ir").run(|| { let flags = cranelift_codegen::settings::Flags::new(cranelift_codegen::settings::builder()); - match cranelift_codegen::verify_function(&func, &flags) { + match cranelift_codegen::verify_function(func, &flags) { Ok(_) => {} Err(err) => { tcx.dcx().err(format!("{:?}", err)); let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error( - &func, + func, Some(Box::new(writer)), err, ); @@ -554,7 +554,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { template, operands, *options, - targets.get(0).copied(), + targets.first().copied(), ); } TerminatorKind::UnwindTerminate(reason) => { @@ -1131,7 +1131,7 @@ fn codegen_panic_inner<'tcx>( call_conv: fx.target_config.default_call_conv, }; let func_id = fx.module.declare_function(symbol_name, Linkage::Import, &sig).unwrap(); - let func_ref = fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); + let func_ref = fx.module.declare_func_in_func(func_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(func_ref, format!("{:?}", symbol_name)); } @@ -1141,7 +1141,7 @@ fn codegen_panic_inner<'tcx>( fx.add_comment(nop_inst, format!("panic {}", symbol_name)); } - codegen_call_with_unwind_action(fx, span, CallTarget::Direct(func_ref), unwind, &args, None); + codegen_call_with_unwind_action(fx, span, CallTarget::Direct(func_ref), unwind, args, None); fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index c2406197f303..e5e5064ce140 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -75,8 +75,7 @@ pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs &[lhs, rhs], )[0]; let zero = fx.bcx.ins().iconst(CMP_RESULT_TY, 0); - let res = fx.bcx.ins().icmp(int_cc, res, zero); - res + fx.bcx.ins().icmp(int_cc, res, zero) } _ => unreachable!("{ty:?}"), } diff --git a/src/common.rs b/src/common.rs index 16adc84747ff..c7c0ffa79de7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -257,7 +257,7 @@ pub(crate) fn create_wrapper_function( .map(|param| func.dfg.append_block_param(block, param.value_type)) .collect::>(); - let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); + let callee_func_ref = module.declare_func_in_func(callee_func_id, bcx.func); let call_inst = bcx.ins().call(callee_func_ref, &args); let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error @@ -374,7 +374,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer { assert!( - size % align == 0, + size.is_multiple_of(align), "size must be a multiple of alignment (size={size}, align={align})" ); @@ -384,7 +384,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { kind: StackSlotKind::ExplicitSlot, // 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, + size: size.div_ceil(abi_align) * abi_align, align_shift: 4, }); Pointer::stack_slot(stack_slot) diff --git a/src/constant.rs b/src/constant.rs index 38b66256ea30..2b65b8290681 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -65,7 +65,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( // For a declaration the stated mutability doesn't matter. false, ); - let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("tls {:?}", def_id)); } @@ -111,7 +111,7 @@ pub(crate) fn codegen_const_value<'tcx>( ConstValue::Scalar(x) => match x { Scalar::Int(int) => { if fx.clif_type(layout.ty).is_some() { - return CValue::const_val(fx, layout, int); + CValue::const_val(fx, layout, int) } else { let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { @@ -150,7 +150,7 @@ pub(crate) fn codegen_const_value<'tcx>( alloc.inner().mutability, ); let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } @@ -159,8 +159,7 @@ pub(crate) fn codegen_const_value<'tcx>( } GlobalAlloc::Function { instance, .. } => { let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); - let local_func_id = - fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); + let local_func_id = fx.module.declare_func_in_func(func_id, fx.bcx.func); fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } GlobalAlloc::VTable(ty, dyn_ty) => { @@ -173,8 +172,7 @@ pub(crate) fn codegen_const_value<'tcx>( fx.tcx.instantiate_bound_regions_with_erased(principal) }), ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } GlobalAlloc::TypeId { .. } => { @@ -191,8 +189,7 @@ pub(crate) fn codegen_const_value<'tcx>( // For a declaration the stated mutability doesn't matter. false, ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", def_id)); } @@ -236,7 +233,7 @@ fn pointer_for_allocation<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, alloc_id: All let data_id = data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); - let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } @@ -354,7 +351,7 @@ fn data_id_for_static( Linkage::Import }; - let data_id = match module.declare_data( + match module.declare_data( symbol_name, linkage, definition_writable, @@ -365,9 +362,7 @@ fn data_id_for_static( "attempt to declare `{symbol_name}` as static, but it was already declared as function" )), Err(err) => Err::<_, _>(err).unwrap(), - }; - - data_id + } } fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 53b513ded9c4..8016c5a3005a 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -222,12 +222,12 @@ impl Writer for WriterRelocate { gimli::DW_EH_PE_absptr => { self.relocs.push(DebugReloc { offset: self.len() as u32, - size: size.into(), + size, name: DebugRelocName::Symbol(symbol), addend, kind: object::RelocationKind::Absolute, }); - self.write_udata(0, size.into()) + self.write_udata(0, size) } _ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)), }, diff --git a/src/debuginfo/gcc_except_table.rs b/src/debuginfo/gcc_except_table.rs index b8e602c76a8c..ff1c6aacd2f9 100644 --- a/src/debuginfo/gcc_except_table.rs +++ b/src/debuginfo/gcc_except_table.rs @@ -41,8 +41,7 @@ impl GccExceptTable { + self.call_sites.encoded_size() + self.actions.encoded_size() + type_info_padding) - % 4 - == 0 + .is_multiple_of(4) }; let mut type_info_padding = 0; @@ -69,9 +68,9 @@ impl GccExceptTable { // In this case we calculated the expected padding amount and used it to write the // classInfoOffset field. Assert that the expected value matched the actual value to catch // any inconsistency. - assert!(w.len() % 4 == 0, "type_info must be aligned to 4 bytes"); + assert!(w.len().is_multiple_of(4), "type_info must be aligned to 4 bytes"); } else { - while w.len() % 4 != 0 { + while !w.len().is_multiple_of(4) { w.write_u8(0)?; } } @@ -82,7 +81,7 @@ impl GccExceptTable { // exception specs (unused for rust) // align to 4 bytes - while w.len() % 4 != 0 { + while !w.len().is_multiple_of(4) { w.write_u8(0)?; } diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 0d49f32373ca..a292429cdfad 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -56,7 +56,7 @@ impl DebugContext { // ty::FnDef(..) | ty::FnPtr(..) // ty::Closure(..) // ty::Adt(def, ..) - ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components), + ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, components), // ty::Param(_) // FIXME implement remaining types and add unreachable!() to the fallback branch _ => self.placeholder_for_type(tcx, type_dbg, ty), @@ -152,7 +152,7 @@ impl DebugContext { components: &'tcx [Ty<'tcx>], ) -> UnitEntryId { let components = components - .into_iter() + .iter() .map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty))) .collect::>(); diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 286ec1bea754..760e23f2171b 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -97,8 +97,8 @@ impl OngoingCodegen { sess, &module_regular.name, &[ - ("o", &module_regular.object.as_ref().unwrap()), - ("asm.o", &module_global_asm.object.as_ref().unwrap()), + ("o", module_regular.object.as_ref().unwrap()), + ("asm.o", module_global_asm.object.as_ref().unwrap()), ], &[], ) @@ -106,7 +106,7 @@ impl OngoingCodegen { rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( sess, &module_regular.name, - &[("o", &module_regular.object.as_ref().unwrap())], + &[("o", module_regular.object.as_ref().unwrap())], &[], ) }; @@ -308,7 +308,7 @@ fn produce_final_output_artifacts( 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); + sess.dcx().emit_artifact_notification(path, descr); } }); } @@ -450,8 +450,8 @@ fn reuse_workproduct_for_cgu( tcx.sess.invocation_temp.as_deref(), ); let source_file_regular = rustc_incremental::in_incr_comp_dir_sess( - &tcx.sess, - &work_product.saved_files.get("o").expect("no saved object file in work product"), + tcx.sess, + work_product.saved_files.get("o").expect("no saved object file in work product"), ); if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) { @@ -466,7 +466,7 @@ fn reuse_workproduct_for_cgu( let obj_out_global_asm = crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm"); let source_file_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") { - let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o); + let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(tcx.sess, asm_o); if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm) { return Err(format!( @@ -684,7 +684,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { // Calculate the CGU reuse let cgu_reuse = tcx.sess.time("find_cgu_reuse", || { - cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>() + cgus.iter().map(|cgu| determine_cgu_reuse(tcx, cgu)).collect::>() }); rustc_codegen_ssa::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| { @@ -698,7 +698,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { let disable_incr_cache = disable_incr_cache(); let (todo_cgus, done_cgus) = - cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + cgus.iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { _ if disable_incr_cache => true, CguReuse::No => true, CguReuse::PreLto | CguReuse::PostLto => false, diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index eab1a506fd0e..a78c6e0a4e7a 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -3,7 +3,7 @@ macro_rules! intrinsic_args { ($fx:expr, $args:expr => ($($arg:tt),*); $intrinsic:expr) => { - #[allow(unused_parens)] + #[allow(unused_parens, clippy::unused_unit)] let ($($arg),*) = if let [$($arg),*] = $args { ($(codegen_operand($fx, &($arg).node)),*) } else { @@ -483,7 +483,7 @@ fn codegen_float_intrinsic_call<'tcx>( }; let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), lib_call_arg_param(fx.tcx, types::I32, true)]; - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; let ret_val = if intrinsic == sym::powif16 { codegen_f16_f128::f32_to_f16(fx, ret_val) } else { @@ -505,7 +505,7 @@ fn codegen_float_intrinsic_call<'tcx>( } _ => { let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect(); - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; CValue::by_val(ret_val, fx.layout_of(ty)) } }; diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 6281089ee244..70add5b84d24 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -812,7 +812,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( Endian::Big => lane_count - 1 - lane, Endian::Little => lane, }; - let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(mask_lane) as i64); + let m_lane = fx.bcx.ins().ushr_imm(m, mask_lane.cast_signed()); let m_lane = fx.bcx.ins().band_imm(m_lane, 1); let a_lane = a.value_lane(fx, lane).load_scalar(fx); let b_lane = b.value_lane(fx, lane).load_scalar(fx); diff --git a/src/lib.rs b/src/lib.rs index 1815f990fc16..f1d5eeb76dd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,8 +271,8 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { flags_builder.set("enable_verifier", enable_verifier).unwrap(); flags_builder.set("regalloc_checker", enable_verifier).unwrap(); - let mut frame_ptr = sess.target.options.frame_pointer.clone(); - frame_ptr.ratchet(sess.opts.cg.force_frame_pointers); + let frame_ptr = + { sess.target.options.frame_pointer }.ratchet(sess.opts.cg.force_frame_pointers); let preserve_frame_pointer = frame_ptr != rustc_target::spec::FramePointer::MayOmit; flags_builder .set("preserve_frame_pointers", if preserve_frame_pointer { "true" } else { "false" }) diff --git a/src/main_shim.rs b/src/main_shim.rs index bf756860b649..c3e4bf1f0c27 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -93,7 +93,7 @@ pub(crate) fn maybe_create_entry_wrapper( let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_sigpipe = bcx.ins().iconst(types::I8, sigpipe as i64); - let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); + let main_func_ref = m.declare_func_in_func(main_func_id, bcx.func); let result = if ignore_lang_start_wrapper { // ignoring #[lang = "start"] as we are running in the jit @@ -123,7 +123,7 @@ pub(crate) fn maybe_create_entry_wrapper( let report_sig = get_function_sig(tcx, m.target_config().default_call_conv, report); let report_func_id = m.declare_function(report_name, Linkage::Import, &report_sig).unwrap(); - let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func); + let report_func_ref = m.declare_func_in_func(report_func_id, bcx.func); // FIXME do proper abi handling instead of expecting the pass mode to be identical // for returns and arguments. @@ -148,7 +148,7 @@ pub(crate) fn maybe_create_entry_wrapper( let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); - let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); + let func_ref = m.declare_func_in_func(start_func_id, bcx.func); let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]); bcx.inst_results(call_inst)[0] diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 3655faf598a7..2878fa7aa298 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -312,7 +312,7 @@ impl fmt::Debug for FunctionCx<'_, '_, '_> { ::cranelift_codegen::write::decorate_function( &mut &self.clif_comments, &mut clif, - &self.bcx.func, + self.bcx.func, ) .unwrap(); writeln!(f, "\n{}", clif) diff --git a/src/unsize.rs b/src/unsize.rs index c97eb3874b02..3dbb689cccd2 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -134,7 +134,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( (ty::Pat(a, _), ty::Pat(b, _)) => { let src = src.cast_pat_ty_to_base(fx.layout_of(*a)); let dst = dst.place_transmute_type(fx, *b); - return coerce_unsized_into(fx, src, dst); + coerce_unsized_into(fx, src, dst) } (&ty::Ref(..), &ty::Ref(..)) | (&ty::Ref(..), &ty::RawPtr(..)) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index cc8e872b9aef..5b76a4cb9779 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -310,13 +310,13 @@ impl<'tcx> CValue<'tcx> { fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F16) => { - fx.bcx.ins().f16const(Ieee16::with_bits(u16::try_from(const_val).unwrap())) + fx.bcx.ins().f16const(Ieee16::with_bits(u16::from(const_val))) } ty::Float(FloatTy::F32) => { - fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap())) + fx.bcx.ins().f32const(Ieee32::with_bits(u32::from(const_val))) } ty::Float(FloatTy::F64) => { - fx.bcx.ins().f64const(Ieee64::with_bits(u64::try_from(const_val).unwrap())) + fx.bcx.ins().f64const(Ieee64::with_bits(u64::from(const_val))) } ty::Float(FloatTy::F128) => { let value = fx @@ -324,7 +324,7 @@ impl<'tcx> CValue<'tcx> { .func .dfg .constants - .insert(Ieee128::with_bits(u128::try_from(const_val).unwrap()).into()); + .insert(Ieee128::with_bits(u128::from(const_val)).into()); fx.bcx.ins().f128const(value) } _ => panic!( From ca44758e509949485e3048d9a9a0b53230caa618 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:08:46 +0000 Subject: [PATCH 236/525] Fix a bunch of clippy lints in the build system --- build_system/bench.rs | 2 +- build_system/build_backend.rs | 2 +- build_system/build_sysroot.rs | 2 +- build_system/rustc_info.rs | 14 +++++++------- build_system/tests.rs | 2 +- build_system/utils.rs | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/build_system/bench.rs b/build_system/bench.rs index 8359b7b52790..192cb499536f 100644 --- a/build_system/bench.rs +++ b/build_system/bench.rs @@ -144,7 +144,7 @@ fn hyperfine_command( } for &(name, cmd) in cmds { - if name != "" { + if !name.is_empty() { bench.arg("-n").arg(name); } bench.arg(cmd); diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index a1f19a1afd09..b9fa0ff2d94c 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -16,7 +16,7 @@ pub(crate) fn build_backend( ) -> PathBuf { let _group = LogGroup::guard("Build backend"); - let mut cmd = CG_CLIF.build(&bootstrap_host_compiler, dirs); + let mut cmd = CG_CLIF.build(bootstrap_host_compiler, dirs); let mut rustflags = rustflags_from_env("RUSTFLAGS"); rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned()); diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index c0ccf506262a..72140c651a9a 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -49,7 +49,7 @@ pub(crate) fn build_sysroot( let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc); let wrapper_path = dist_dir.join(&wrapper_name); build_cargo_wrapper_cmd - .arg(dirs.source_dir.join("scripts").join(&format!("{wrapper}.rs"))) + .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs"))) .arg("-o") .arg(&wrapper_path) .arg("-Cstrip=debuginfo"); diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs index 61d56795efa3..2fa827498de9 100644 --- a/build_system/rustc_info.rs +++ b/build_system/rustc_info.rs @@ -4,7 +4,7 @@ use std::process::{Command, Stdio}; pub(crate) fn get_host_triple(rustc: &Path) -> String { let version_info = Command::new(rustc) .stderr(Stdio::inherit()) - .args(&["--print", "host-tuple"]) + .args(["--print", "host-tuple"]) .output() .unwrap() .stdout; @@ -14,7 +14,7 @@ pub(crate) fn get_host_triple(rustc: &Path) -> String { pub(crate) fn get_toolchain_name() -> String { let active_toolchain = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["show", "active-toolchain"]) + .args(["show", "active-toolchain"]) .output() .unwrap() .stdout; @@ -27,7 +27,7 @@ pub(crate) fn get_cargo_path() -> PathBuf { } let cargo_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "cargo"]) + .args(["which", "cargo"]) .output() .unwrap() .stdout; @@ -40,7 +40,7 @@ pub(crate) fn get_rustc_path() -> PathBuf { } let rustc_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "rustc"]) + .args(["which", "rustc"]) .output() .unwrap() .stdout; @@ -53,7 +53,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf { } let rustc_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "rustdoc"]) + .args(["which", "rustdoc"]) .output() .unwrap() .stdout; @@ -63,7 +63,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf { pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf { let default_sysroot = Command::new(rustc) .stderr(Stdio::inherit()) - .args(&["--print", "sysroot"]) + .args(["--print", "sysroot"]) .output() .unwrap() .stdout; @@ -74,7 +74,7 @@ pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf { pub(crate) fn get_file_name(rustc: &Path, crate_name: &str, crate_type: &str) -> String { let file_name = Command::new(rustc) .stderr(Stdio::inherit()) - .args(&[ + .args([ "--crate-name", crate_name, "--crate-type", diff --git a/build_system/tests.rs b/build_system/tests.rs index 6dd9ebb84587..dd8cf929bc2f 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -355,7 +355,7 @@ impl<'a> TestRunner<'a> { let _guard = if !config::get_bool(config) || (is_jit_test && !self.jit_supported) - || self.skip_tests.contains(&config) + || self.skip_tests.contains(config) { eprintln!("[{tag}] {testname} (skipped)"); continue; diff --git a/build_system/utils.rs b/build_system/utils.rs index d9807155a3d5..3266aa0ce8b6 100644 --- a/build_system/utils.rs +++ b/build_system/utils.rs @@ -162,7 +162,7 @@ impl CargoProject { pub(crate) fn try_hard_link(src: impl AsRef, dst: impl AsRef) { let src = src.as_ref(); let dst = dst.as_ref(); - if let Err(_) = fs::hard_link(src, dst) { + if fs::hard_link(src, dst).is_err() { fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed } } @@ -179,7 +179,7 @@ pub(crate) fn spawn_and_wait(mut cmd: Command) { /// Create the specified directory if it doesn't exist yet and delete all contents. pub(crate) fn ensure_empty_dir(path: &Path) { fs::create_dir_all(path).unwrap(); - let read_dir = match fs::read_dir(&path) { + let read_dir = match fs::read_dir(path) { Ok(read_dir) => read_dir, Err(err) if err.kind() == io::ErrorKind::NotFound => { return; From 0ceb66838b5084cebd290565fa08b112cdad9aca Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 27 Oct 2025 18:27:20 +0200 Subject: [PATCH 237/525] Show proper async function signatures in the signature help Co-authored-by: Lukas Wirth --- .../crates/ide/src/signature_help.rs | 157 ++++++++++++++++-- 1 file changed, 144 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index e927fd57ae96..f9ec44813a6b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -175,6 +175,9 @@ fn signature_help_for_call( match callable.kind() { hir::CallableKind::Function(func) => { res.doc = func.docs(db); + if func.is_async(db) { + format_to!(res.signature, "async "); + } format_to!(res.signature, "fn {}", func.name(db).display(db, edition)); let generic_params = GenericDef::Function(func) @@ -283,13 +286,16 @@ fn signature_help_for_call( } }; match callable.kind() { - hir::CallableKind::Function(func) if callable.return_type().contains_unknown() => { - render(func.ret_type(db)) + hir::CallableKind::Function(func) => render(func.async_ret_type(db).unwrap_or_else(|| { + if callable.return_type().contains_unknown() { + func.ret_type(db) + } else { + callable.return_type() + } + })), + hir::CallableKind::Closure(_) | hir::CallableKind::FnPtr | hir::CallableKind::FnImpl(_) => { + render(callable.return_type()) } - hir::CallableKind::Function(_) - | hir::CallableKind::Closure(_) - | hir::CallableKind::FnPtr - | hir::CallableKind::FnImpl(_) => render(callable.return_type()), hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {} } Some(res) @@ -751,13 +757,7 @@ mod tests { #[track_caller] fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { - let fixture = format!( - r#" -//- minicore: sized, fn -{ra_fixture} - "# - ); - let (db, position) = position(&fixture); + let (db, position) = position(ra_fixture); let sig_help = hir::attach_db(&db, || crate::signature_help::signature_help(&db, position)); let actual = match sig_help { Some(sig_help) => { @@ -795,6 +795,7 @@ mod tests { fn test_fn_signature_two_args() { check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo($03, ); } "#, @@ -805,6 +806,7 @@ fn bar() { foo($03, ); } ); check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo(3$0, ); } "#, @@ -815,6 +817,7 @@ fn bar() { foo(3$0, ); } ); check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo(3,$0 ); } "#, @@ -825,6 +828,7 @@ fn bar() { foo(3,$0 ); } ); check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo(3, $0); } "#, @@ -839,6 +843,7 @@ fn bar() { foo(3, $0); } fn test_fn_signature_two_args_empty() { check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo($0); } "#, @@ -853,6 +858,7 @@ fn bar() { foo($0); } fn test_fn_signature_two_args_first_generics() { check( r#" +//- minicore: sized, fn fn foo(x: T, y: U) -> u32 where T: Copy + Display, U: Debug { x + y } @@ -870,6 +876,7 @@ fn bar() { foo($03, ); } fn test_fn_signature_no_params() { check( r#" +//- minicore: sized, fn fn foo() -> T where T: Copy + Display {} fn bar() { foo($0); } "#, @@ -883,6 +890,7 @@ fn bar() { foo($0); } fn test_fn_signature_for_impl() { check( r#" +//- minicore: sized, fn struct F; impl F { pub fn new() { } } fn bar() { @@ -899,6 +907,7 @@ fn bar() { fn test_fn_signature_for_method_self() { check( r#" +//- minicore: sized, fn struct S; impl S { pub fn do_it(&self) {} } @@ -917,6 +926,7 @@ fn bar() { fn test_fn_signature_for_method_with_arg() { check( r#" +//- minicore: sized, fn struct S; impl S { fn foo(&self, x: i32) {} @@ -935,6 +945,7 @@ fn main() { S.foo($0); } fn test_fn_signature_for_generic_method() { check( r#" +//- minicore: sized, fn struct S(T); impl S { fn foo(&self, x: T) {} @@ -953,6 +964,7 @@ fn main() { S(1u32).foo($0); } fn test_fn_signature_for_method_with_arg_as_assoc_fn() { check( r#" +//- minicore: sized, fn struct S; impl S { fn foo(&self, x: i32) {} @@ -971,6 +983,7 @@ fn main() { S::foo($0); } fn test_fn_signature_with_docs_simple() { check( r#" +//- minicore: sized, fn /// test // non-doc-comment fn foo(j: u32) -> u32 { @@ -994,6 +1007,7 @@ fn bar() { fn test_fn_signature_with_docs() { check( r#" +//- minicore: sized, fn /// Adds one to the number given. /// /// # Examples @@ -1031,6 +1045,7 @@ pub fn r#do() { fn test_fn_signature_with_docs_impl() { check( r#" +//- minicore: sized, fn struct addr; impl addr { /// Adds one to the number given. @@ -1073,6 +1088,7 @@ pub fn do_it() { fn test_fn_signature_with_docs_from_actix() { check( r#" +//- minicore: sized, fn trait Actor { /// Actor execution context type type Context; @@ -1106,6 +1122,7 @@ fn foo(mut r: impl WriteHandler<()>) { fn call_info_bad_offset() { check( r#" +//- minicore: sized, fn fn foo(x: u32, y: u32) -> u32 {x + y} fn bar() { foo $0 (3, ); } "#, @@ -1117,6 +1134,7 @@ fn bar() { foo $0 (3, ); } fn outside_of_arg_list() { check( r#" +//- minicore: sized, fn fn foo(a: u8) {} fn f() { foo(123)$0 @@ -1126,6 +1144,7 @@ fn f() { ); check( r#" +//- minicore: sized, fn fn foo(a: u8) {} fn f() { foo::$0() @@ -1135,6 +1154,7 @@ fn f() { ); check( r#" +//- minicore: sized, fn fn foo(a: u8) -> u8 {a} fn bar(a: u8) -> u8 {a} fn f() { @@ -1148,6 +1168,7 @@ fn f() { ); check( r#" +//- minicore: sized, fn struct Vec(T); struct Vec2(T); fn f() { @@ -1165,6 +1186,7 @@ fn f() { fn test_nested_method_in_lambda() { check( r#" +//- minicore: sized, fn struct Foo; impl Foo { fn bar(&self, _: u32) { } } @@ -1186,6 +1208,7 @@ fn main() { fn works_for_tuple_structs() { check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32); fn main() { @@ -1205,6 +1228,7 @@ fn main() { fn tuple_struct_pat() { check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32); fn main() { @@ -1224,6 +1248,7 @@ fn main() { fn tuple_struct_pat_rest() { check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16); fn main() { @@ -1239,6 +1264,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16, u8); fn main() { @@ -1254,6 +1280,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16); fn main() { @@ -1269,6 +1296,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16, u8); fn main() { @@ -1284,6 +1312,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16); fn main() { @@ -1299,6 +1328,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn /// A cool tuple struct struct S(u32, i32, f32, u16); fn main() { @@ -1318,6 +1348,7 @@ fn main() { fn generic_struct() { check( r#" +//- minicore: sized, fn struct S(T); fn main() { let s = S($0); @@ -1334,6 +1365,7 @@ fn main() { fn works_for_enum_variants() { check( r#" +//- minicore: sized, fn enum E { /// A Variant A(i32), @@ -1360,6 +1392,7 @@ fn main() { fn cant_call_struct_record() { check( r#" +//- minicore: sized, fn struct S { x: u32, y: i32 } fn main() { let s = S($0); @@ -1373,6 +1406,7 @@ fn main() { fn cant_call_enum_record() { check( r#" +//- minicore: sized, fn enum E { /// A Variant A(i32), @@ -1394,6 +1428,7 @@ fn main() { fn fn_signature_for_call_in_macro() { check( r#" +//- minicore: sized, fn macro_rules! id { ($($tt:tt)*) => { $($tt)* } } fn foo() { } id! { @@ -1410,6 +1445,7 @@ id! { fn fn_signature_for_method_call_defined_in_macro() { check( r#" +//- minicore: sized, fn macro_rules! id { ($($tt:tt)*) => { $($tt)* } } struct S; id! { @@ -1429,6 +1465,7 @@ fn test() { S.foo($0); } fn call_info_for_lambdas() { check( r#" +//- minicore: sized, fn struct S; fn foo(s: S) -> i32 { 92 } fn main() { @@ -1443,6 +1480,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn struct S; fn foo(s: S) -> i32 { 92 } fn main() { @@ -1456,6 +1494,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn struct S; fn foo(s: S) -> i32 { 92 } fn main() { @@ -1474,6 +1513,7 @@ fn main() { fn call_info_for_fn_def_over_reference() { check( r#" +//- minicore: sized, fn struct S; fn foo(s: S) -> i32 { 92 } fn main() { @@ -1492,6 +1532,7 @@ fn main() { fn call_info_for_fn_ptr() { check( r#" +//- minicore: sized, fn fn main(f: fn(i32, f64) -> char) { f(0, $0) } @@ -1507,6 +1548,7 @@ fn main(f: fn(i32, f64) -> char) { fn call_info_for_fn_impl() { check( r#" +//- minicore: sized, fn struct S; impl core::ops::FnOnce<(i32, f64)> for S { type Output = char; @@ -1524,6 +1566,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn struct S; impl core::ops::FnOnce<(i32, f64)> for S { type Output = char; @@ -1541,6 +1584,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn struct S; impl core::ops::FnOnce<(i32, f64)> for S { type Output = char; @@ -1556,6 +1600,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn struct S; impl core::ops::FnOnce<(i32, f64)> for S { type Output = char; @@ -1576,6 +1621,7 @@ fn main() { fn call_info_for_unclosed_call() { check( r#" +//- minicore: sized, fn fn foo(foo: u32, bar: u32) {} fn main() { foo($0 @@ -1588,6 +1634,7 @@ fn main() { // check with surrounding space check( r#" +//- minicore: sized, fn fn foo(foo: u32, bar: u32) {} fn main() { foo( $0 @@ -1603,6 +1650,7 @@ fn main() { fn test_multiline_argument() { check( r#" +//- minicore: sized, fn fn callee(a: u8, b: u8) {} fn main() { callee(match 0 { @@ -1613,6 +1661,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn callee(a: u8, b: u8) {} fn main() { callee(match 0 { @@ -1626,6 +1675,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn callee(a: u8, b: u8) {} fn main() { callee($0match 0 { @@ -1643,6 +1693,7 @@ fn main() { fn test_generics_simple() { check( r#" +//- minicore: sized, fn /// Option docs. enum Option { Some(T), @@ -1666,6 +1717,7 @@ fn f() { fn test_generics_on_variant() { check( r#" +//- minicore: sized, fn /// Option docs. enum Option { /// Some docs. @@ -1693,6 +1745,7 @@ fn f() { fn test_lots_of_generics() { check( r#" +//- minicore: sized, fn trait Tr {} struct S(T); @@ -1716,6 +1769,7 @@ fn f() { fn test_generics_in_trait_ufcs() { check( r#" +//- minicore: sized, fn trait Tr { fn f() {} } @@ -1739,6 +1793,7 @@ fn f() { fn test_generics_in_method_call() { check( r#" +//- minicore: sized, fn struct S; impl S { @@ -1760,6 +1815,7 @@ fn f() { fn test_generic_param_in_method_call() { check( r#" +//- minicore: sized, fn struct Foo; impl Foo { fn test(&mut self, val: V) {} @@ -1779,6 +1835,7 @@ fn sup() { fn test_generic_kinds() { check( r#" +//- minicore: sized, fn fn callee<'a, const A: u8, T, const C: u8>() {} fn f() { @@ -1792,6 +1849,7 @@ fn f() { ); check( r#" +//- minicore: sized, fn fn callee<'a, const A: u8, T, const C: u8>() {} fn f() { @@ -1809,6 +1867,7 @@ fn f() { fn test_trait_assoc_types() { check( r#" +//- minicore: sized, fn trait Trait<'a, T> { type Assoc; } @@ -1821,6 +1880,7 @@ fn f() -> impl Trait<(), $0 ); check( r#" +//- minicore: sized, fn trait Iterator { type Item; } @@ -1833,6 +1893,7 @@ fn f() -> impl Iterator<$0 ); check( r#" +//- minicore: sized, fn trait Iterator { type Item; } @@ -1845,6 +1906,7 @@ fn f() -> impl Iterator impl Tr<$0 ); check( r#" +//- minicore: sized, fn trait Tr { type A; type B; @@ -1871,6 +1934,7 @@ fn f() -> impl Tr impl Tr impl Tr impl Sub<$0 fn no_assoc_types_outside_type_bounds() { check( r#" +//- minicore: sized, fn trait Tr { type Assoc; } @@ -1938,6 +2005,7 @@ impl Tr<$0 // FIXME: Substitute type vars in impl trait (`U` -> `i8`) check( r#" +//- minicore: sized, fn trait Trait {} struct Wrap(T); fn foo(x: Wrap>) {} @@ -1956,6 +2024,7 @@ fn f() { fn fully_qualified_syntax() { check( r#" +//- minicore: sized, fn fn f() { trait A { fn foo(&self, other: Self); } A::foo(&self$0, other); @@ -1972,6 +2041,7 @@ fn f() { fn help_for_generic_call() { check( r#" +//- minicore: sized, fn fn f i32>(f: F) { f($0) } @@ -1983,6 +2053,7 @@ fn f i32>(f: F) { ); check( r#" +//- minicore: sized, fn fn f &T>(f: F) { f($0) } @@ -2004,6 +2075,7 @@ fn f &T>(f: F) { // https://github.com/rust-lang/rust/pull/146602 should fix the solver bug. check( r#" +//- minicore: sized, fn fn f() { take(2)($0); } @@ -2022,6 +2094,7 @@ fn take( fn record_literal() { check( r#" +//- minicore: sized, fn struct Strukt { t: T, u: U, @@ -2045,6 +2118,7 @@ fn f() { fn record_literal_nonexistent_field() { check( r#" +//- minicore: sized, fn struct Strukt { a: u8, } @@ -2066,6 +2140,7 @@ fn f() { fn tuple_variant_record_literal() { check( r#" +//- minicore: sized, fn enum Opt { Some(u8), } @@ -2080,6 +2155,7 @@ fn f() { ); check( r#" +//- minicore: sized, fn enum Opt { Some(u8), } @@ -2098,6 +2174,7 @@ fn f() { fn record_literal_self() { check( r#" +//- minicore: sized, fn struct S { t: u8 } impl S { fn new() -> Self { @@ -2116,6 +2193,7 @@ impl S { fn record_pat() { check( r#" +//- minicore: sized, fn struct Strukt { t: T, u: U, @@ -2139,6 +2217,7 @@ fn f() { fn test_enum_in_nested_method_in_lambda() { check( r#" +//- minicore: sized, fn enum A { A, B @@ -2162,6 +2241,7 @@ fn main() { fn test_tuple_expr_free() { check( r#" +//- minicore: sized, fn fn main() { (0$0, 1, 3); } @@ -2173,6 +2253,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { ($0 1, 3); } @@ -2184,6 +2265,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { (1, 3 $0); } @@ -2195,6 +2277,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { (1, 3 $0,); } @@ -2210,6 +2293,7 @@ fn main() { fn test_tuple_expr_expected() { check( r#" +//- minicore: sized, fn fn main() { let _: (&str, u32, u32)= ($0, 1, 3); } @@ -2222,6 +2306,7 @@ fn main() { // FIXME: Should typeck report a 4-ary tuple for the expression here? check( r#" +//- minicore: sized, fn fn main() { let _: (&str, u32, u32, u32) = ($0, 1, 3); } @@ -2233,6 +2318,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let _: (&str, u32, u32)= ($0, 1, 3, 5); } @@ -2248,6 +2334,7 @@ fn main() { fn test_tuple_pat_free() { check( r#" +//- minicore: sized, fn fn main() { let ($0, 1, 3); } @@ -2259,6 +2346,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (0$0, 1, 3); } @@ -2270,6 +2358,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let ($0 1, 3); } @@ -2281,6 +2370,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0); } @@ -2292,6 +2382,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0,); } @@ -2303,6 +2394,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0, ..); } @@ -2314,6 +2406,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3, .., $0); } @@ -2330,6 +2423,7 @@ fn main() { fn test_tuple_pat_expected() { check( r#" +//- minicore: sized, fn fn main() { let (0$0, 1, 3): (i32, i32, i32); } @@ -2341,6 +2435,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let ($0, 1, 3): (i32, i32, i32); } @@ -2352,6 +2447,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0): (i32,); } @@ -2363,6 +2459,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0, ..): (i32, i32, i32, i32); } @@ -2374,6 +2471,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3, .., $0): (i32, i32, i32); } @@ -2388,6 +2486,7 @@ fn main() { fn test_tuple_pat_expected_inferred() { check( r#" +//- minicore: sized, fn fn main() { let (0$0, 1, 3) = (1, 2 ,3); } @@ -2399,6 +2498,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let ($0 1, 3) = (1, 2, 3); } @@ -2411,6 +2511,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0) = (1,); } @@ -2422,6 +2523,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3 $0, ..) = (1, 2, 3, 4); } @@ -2433,6 +2535,7 @@ fn main() { ); check( r#" +//- minicore: sized, fn fn main() { let (1, 3, .., $0) = (1, 2, 3); } @@ -2448,6 +2551,7 @@ fn main() { fn test_tuple_generic_param() { check( r#" +//- minicore: sized, fn struct S(T); fn main() { @@ -2465,6 +2569,7 @@ fn main() { fn test_enum_generic_param() { check( r#" +//- minicore: sized, fn enum Option { Some(T), None, @@ -2485,6 +2590,7 @@ fn main() { fn test_enum_variant_generic_param() { check( r#" +//- minicore: sized, fn enum Option { Some(T), None, @@ -2505,6 +2611,7 @@ fn main() { fn test_generic_arg_with_default() { check( r#" +//- minicore: sized, fn struct S { field: T, } @@ -2521,6 +2628,7 @@ fn main() { check( r#" +//- minicore: sized, fn struct S { field: C, } @@ -2535,4 +2643,27 @@ fn main() { "#]], ); } + + #[test] + fn test_async_function() { + check( + r#" +//- minicore: sized, fn, future, result +pub async fn conn_mut(f: F) -> Result +where + F: FnOnce() -> T, +{ + Ok(f()) +} + +fn main() { + conn_mut($0) +} + "#, + expect![[r#" + async fn conn_mut T, T>(f: F) -> Result + ^^^^ + "#]], + ); + } } From 46a474bbb8e72db6c8ddeea0f06b28da9d9317b9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 28 Oct 2025 15:27:55 -0700 Subject: [PATCH 238/525] ci: add runners for vanilla LLVM 21 Ubuntu 25.10 has `llvm-21` packages that we can test with. The `Dockerfile` is otherwise the same as the `llvm-20` runners. --- .../host-x86_64/x86_64-gnu-llvm-21/Dockerfile | 66 +++++++++++++++++++ src/ci/github-actions/jobs.yml | 25 +++++++ 2 files changed, 91 insertions(+) create mode 100644 src/ci/docker/host-x86_64/x86_64-gnu-llvm-21/Dockerfile diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-21/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-21/Dockerfile new file mode 100644 index 000000000000..f0314854411f --- /dev/null +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-21/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:25.10 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + bzip2 \ + g++ \ + gcc-multilib \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-21-tools \ + llvm-21-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs \ + mingw-w64 \ + # libgccjit dependencies + flex \ + libmpfr-dev \ + libgmp-dev \ + libmpc3 \ + libmpc-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install powershell (universal package) so we can test x.ps1 on Linux +# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ + dpkg --ignore-depends=libicu72 -i powershell.deb && \ + rm -f powershell.deb + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# We are disabling CI LLVM since this builder is intentionally using a host +# LLVM, rather than the typical src/llvm-project LLVM. +ENV NO_DOWNLOAD_CI_LLVM 1 +ENV EXTERNAL_LLVM 1 + +# Using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-21 \ + --enable-llvm-link-shared \ + --set rust.randomize-layout=true \ + --set rust.thin-lto-import-instr-limit=10 + +COPY scripts/shared.sh /scripts/ + +COPY scripts/x86_64-gnu-llvm.sh /scripts/ +COPY scripts/x86_64-gnu-llvm2.sh /scripts/ +COPY scripts/x86_64-gnu-llvm3.sh /scripts/ +COPY scripts/stage_2_test_set1.sh /scripts/ +COPY scripts/stage_2_test_set2.sh /scripts/ + +ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index eeef94483fda..35cc43fa4f64 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -404,6 +404,31 @@ auto: DOCKER_SCRIPT: x86_64-gnu-llvm3.sh <<: *job-linux-4c + # The x86_64-gnu-llvm-21 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-21-1 skips tests that run in x86_64-gnu-llvm-21-{2,3}. + - name: x86_64-gnu-llvm-21-1 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-21 + DOCKER_SCRIPT: stage_2_test_set2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-21-{1,3} + - name: x86_64-gnu-llvm-21-2 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-21 + DOCKER_SCRIPT: x86_64-gnu-llvm2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-21-{1,2} + - name: x86_64-gnu-llvm-21-3 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-21 + DOCKER_SCRIPT: x86_64-gnu-llvm3.sh + <<: *job-linux-4c + - name: x86_64-gnu-nopt <<: *job-linux-4c From 1f23b4849272186b9294347c8268571e07fdcb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 29 Oct 2025 02:49:16 +0100 Subject: [PATCH 239/525] rustdoc: Properly highlight shebang and frontmatter --- src/librustdoc/html/highlight.rs | 198 ++++++++++-------- tests/rustdoc/jump-to-def/shebang.rs | 15 ++ .../rustdoc/source-code-pages/frontmatter.rs | 10 + tests/rustdoc/source-code-pages/shebang.rs | 6 + 4 files changed, 136 insertions(+), 93 deletions(-) create mode 100644 tests/rustdoc/jump-to-def/shebang.rs create mode 100644 tests/rustdoc/source-code-pages/frontmatter.rs create mode 100644 tests/rustdoc/source-code-pages/shebang.rs diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c37736f137df..81dde140fa81 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -566,52 +566,52 @@ pub(super) fn write_code( }; let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, file_span); - Classifier::new( + classify( &src, - token_handler.href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), + token_handler.href_context.as_ref().map_or(DUMMY_SP, |c| c.file_span), decoration_info, - ) - .highlight(&mut |span, highlight| match highlight { - Highlight::Token { text, class } => { - token_handler.push_token(class, Cow::Borrowed(text)); + &mut |span, highlight| match highlight { + Highlight::Token { text, class } => { + token_handler.push_token(class, Cow::Borrowed(text)); - if text == "\n" { - if current_expansion.is_none() { - current_expansion = get_expansion(&mut token_handler, expanded_codes, span); - } - if let Some(ref current_expansion) = current_expansion - && current_expansion.span.lo() == span.hi() - { - token_handler.add_expanded_code(current_expansion); - } - } else { - let mut need_end = false; - if let Some(ref current_expansion) = current_expansion { - if current_expansion.span.lo() == span.hi() { - token_handler.add_expanded_code(current_expansion); - } else if current_expansion.end_line == token_handler.line - && span.hi() >= current_expansion.span.hi() + if text == "\n" { + if current_expansion.is_none() { + current_expansion = get_expansion(&mut token_handler, expanded_codes, span); + } + if let Some(ref current_expansion) = current_expansion + && current_expansion.span.lo() == span.hi() { - need_end = true; + token_handler.add_expanded_code(current_expansion); + } + } else { + let mut need_end = false; + if let Some(ref current_expansion) = current_expansion { + if current_expansion.span.lo() == span.hi() { + token_handler.add_expanded_code(current_expansion); + } else if current_expansion.end_line == token_handler.line + && span.hi() >= current_expansion.span.hi() + { + need_end = true; + } + } + if need_end { + current_expansion = end_expansion(&mut token_handler, expanded_codes, span); } } - if need_end { - current_expansion = end_expansion(&mut token_handler, expanded_codes, span); - } } - } - Highlight::EnterSpan { class } => { - token_handler.class_stack.enter_elem( - token_handler.out, - &token_handler.href_context, - class, - None, - ); - } - Highlight::ExitSpan => { - token_handler.class_stack.exit_elem(); - } - }); + Highlight::EnterSpan { class } => { + token_handler.class_stack.enter_elem( + token_handler.out, + &token_handler.href_context, + class, + None, + ); + } + Highlight::ExitSpan => { + token_handler.class_stack.exit_elem(); + } + }, + ); } fn write_footer(playground_button: Option<&str>) -> impl Display { @@ -735,6 +735,12 @@ struct TokenIter<'a> { cursor: Cursor<'a>, } +impl<'a> TokenIter<'a> { + fn new(src: &'a str) -> Self { + Self { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) } + } +} + impl<'a> Iterator for TokenIter<'a> { type Item = (TokenKind, &'a str); fn next(&mut self) -> Option<(TokenKind, &'a str)> { @@ -843,6 +849,54 @@ fn new_span(lo: u32, text: &str, file_span: Span) -> Span { file_span.with_lo(file_lo + BytePos(lo)).with_hi(file_lo + BytePos(hi)) } +fn classify<'src>( + src: &'src str, + file_span: Span, + decoration_info: Option<&DecorationInfo>, + sink: &mut dyn FnMut(Span, Highlight<'src>), +) { + let offset = rustc_lexer::strip_shebang(src); + + if let Some(offset) = offset { + sink(DUMMY_SP, Highlight::Token { text: &src[..offset], class: Some(Class::Comment) }); + } + + let mut classifier = + Classifier::new(src, offset.unwrap_or_default(), file_span, decoration_info); + + loop { + if let Some(decs) = classifier.decorations.as_mut() { + let byte_pos = classifier.byte_pos; + let n_starts = decs.starts.iter().filter(|(i, _)| byte_pos >= *i).count(); + for (_, kind) in decs.starts.drain(0..n_starts) { + sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Decoration(kind) }); + } + + let n_ends = decs.ends.iter().filter(|i| byte_pos >= **i).count(); + for _ in decs.ends.drain(0..n_ends) { + sink(DUMMY_SP, Highlight::ExitSpan); + } + } + + if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() { + let tokens = classifier.get_full_ident_path(); + for &(token, start, end) in &tokens { + let text = &classifier.src[start..end]; + classifier.advance(token, text, sink, start as u32); + classifier.byte_pos += text.len() as u32; + } + if !tokens.is_empty() { + continue; + } + } + if let Some((token, text, before)) = classifier.next() { + classifier.advance(token, text, sink, before); + } else { + break; + } + } +} + /// Processes program tokens, classifying strings of text by highlighting /// category (`Class`). struct Classifier<'src> { @@ -857,21 +911,23 @@ struct Classifier<'src> { } impl<'src> Classifier<'src> { - /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code - /// file span which will be used later on by the `span_correspondence_map`. - fn new(src: &'src str, file_span: Span, decoration_info: Option<&DecorationInfo>) -> Self { - let tokens = - PeekIter::new(TokenIter { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) }); - let decorations = decoration_info.map(Decorations::new); + /// Takes as argument the source code to HTML-ify and the source code file span + /// which will be used later on by the `span_correspondence_map`. + fn new( + src: &'src str, + byte_pos: usize, + file_span: Span, + decoration_info: Option<&DecorationInfo>, + ) -> Self { Classifier { - tokens, + tokens: PeekIter::new(TokenIter::new(&src[byte_pos..])), in_attribute: false, in_macro: false, in_macro_nonterminal: false, - byte_pos: 0, + byte_pos: byte_pos as u32, file_span, src, - decorations, + decorations: decoration_info.map(Decorations::new), } } @@ -938,50 +994,6 @@ impl<'src> Classifier<'src> { } } - /// Exhausts the `Classifier` writing the output into `sink`. - /// - /// The general structure for this method is to iterate over each token, - /// possibly giving it an HTML span with a class specifying what flavor of - /// token is used. - fn highlight(mut self, sink: &mut dyn FnMut(Span, Highlight<'src>)) { - loop { - if let Some(decs) = self.decorations.as_mut() { - let byte_pos = self.byte_pos; - let n_starts = decs.starts.iter().filter(|(i, _)| byte_pos >= *i).count(); - for (_, kind) in decs.starts.drain(0..n_starts) { - sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Decoration(kind) }); - } - - let n_ends = decs.ends.iter().filter(|i| byte_pos >= **i).count(); - for _ in decs.ends.drain(0..n_ends) { - sink(DUMMY_SP, Highlight::ExitSpan); - } - } - - if self - .tokens - .peek() - .map(|t| matches!(t.0, TokenKind::Colon | TokenKind::Ident)) - .unwrap_or(false) - { - let tokens = self.get_full_ident_path(); - for (token, start, end) in &tokens { - let text = &self.src[*start..*end]; - self.advance(*token, text, sink, *start as u32); - self.byte_pos += text.len() as u32; - } - if !tokens.is_empty() { - continue; - } - } - if let Some((token, text, before)) = self.next() { - self.advance(token, text, sink, before); - } else { - break; - } - } - } - /// Single step of highlighting. This will classify `token`, but maybe also a couple of /// following ones as well. /// @@ -1019,6 +1031,7 @@ impl<'src> Classifier<'src> { Class::Comment } } + TokenKind::Frontmatter { .. } => Class::Comment, // Consider this as part of a macro invocation if there was a // leading identifier. TokenKind::Bang if self.in_macro => { @@ -1117,7 +1130,6 @@ impl<'src> Classifier<'src> { | TokenKind::At | TokenKind::Tilde | TokenKind::Colon - | TokenKind::Frontmatter { .. } | TokenKind::Unknown => return no_highlight(sink), TokenKind::Question => Class::QuestionMark, diff --git a/tests/rustdoc/jump-to-def/shebang.rs b/tests/rustdoc/jump-to-def/shebang.rs new file mode 100644 index 000000000000..a631762554b1 --- /dev/null +++ b/tests/rustdoc/jump-to-def/shebang.rs @@ -0,0 +1,15 @@ +#!/path/to/my/interpreter +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +// Ensure that we can successfully generate links to definitions in the presence of shebang. +// Implementation-wise, shebang is not a token that's emitted by the lexer. Instead, we need +// to offset the actual lexing which is tricky due to all the byte index and span calculations +// in the Classifier. + +fn scope() { +//@ has 'src/shebang/shebang.rs.html' +//@ has - '//a[@href="#15"]' 'function' + function(); +} + +fn function() {} diff --git a/tests/rustdoc/source-code-pages/frontmatter.rs b/tests/rustdoc/source-code-pages/frontmatter.rs new file mode 100644 index 000000000000..c352504bab2b --- /dev/null +++ b/tests/rustdoc/source-code-pages/frontmatter.rs @@ -0,0 +1,10 @@ +--- json +{"edition": "2024"} +--- +#![feature(frontmatter)] + +// Test that we highlight frontmatter as comments on source code pages. + +//@ has 'src/frontmatter/frontmatter.rs.html' +//@ has - '//pre[@class="rust"]//span[@class="comment"]' \ +// '--- json {"edition": "2024"} ---' diff --git a/tests/rustdoc/source-code-pages/shebang.rs b/tests/rustdoc/source-code-pages/shebang.rs new file mode 100644 index 000000000000..975ca3a31858 --- /dev/null +++ b/tests/rustdoc/source-code-pages/shebang.rs @@ -0,0 +1,6 @@ +#!/path/to/somewhere 0 if false "" + +// Test that we highlight shebang as comments on source code pages. + +//@ has 'src/shebang/shebang.rs.html' +//@ has - '//pre[@class="rust"]//span[@class="comment"]' '#!/path/to/somewhere 0 if false ""' From a5f07138ac19744fc283c07e278d21b61360e43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 28 Oct 2025 21:21:54 +0100 Subject: [PATCH 240/525] rustdoc: Recognize more weak keywords when highlighting Rust code --- src/librustdoc/html/highlight.rs | 80 ++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 81dde140fa81..7c22a7ab91f6 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -764,7 +764,8 @@ fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option Some(match text { "ref" | "mut" => Class::RefKeyWord, "false" | "true" => Class::Bool, - _ if Symbol::intern(text).is_reserved(|| Edition::Edition2021) => Class::KeyWord, + // FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument. + _ if Symbol::intern(text).is_reserved(|| Edition::Edition2024) => Class::KeyWord, _ => return None, }) } @@ -1201,7 +1202,7 @@ impl<'src> Classifier<'src> { }, TokenKind::GuardedStrPrefix => return no_highlight(sink), TokenKind::Ident | TokenKind::RawIdent - if self.peek_non_whitespace() == Some(TokenKind::Bang) => + if let Some((TokenKind::Bang, _)) = self.peek_non_trivia() => { self.in_macro = true; let span = new_span(before, text, file_span); @@ -1209,26 +1210,22 @@ impl<'src> Classifier<'src> { sink(span, Highlight::Token { text, class: None }); return; } - TokenKind::Ident => { - match get_real_ident_class(text, false) { - None => match text { - "Option" | "Result" => Class::PreludeTy(new_span(before, text, file_span)), - "Some" | "None" | "Ok" | "Err" => { - Class::PreludeVal(new_span(before, text, file_span)) - } - // "union" is a weak keyword and is only considered as a keyword when declaring - // a union type. - "union" if self.check_if_is_union_keyword() => Class::KeyWord, - _ if self.in_macro_nonterminal => { - self.in_macro_nonterminal = false; - Class::MacroNonTerminal - } - "self" | "Self" => Class::Self_(new_span(before, text, file_span)), - _ => Class::Ident(new_span(before, text, file_span)), - }, - Some(c) => c, - } - } + TokenKind::Ident => match get_real_ident_class(text, false) { + None => match text { + "Option" | "Result" => Class::PreludeTy(new_span(before, text, file_span)), + "Some" | "None" | "Ok" | "Err" => { + Class::PreludeVal(new_span(before, text, file_span)) + } + _ if self.is_weak_keyword(text) => Class::KeyWord, + _ if self.in_macro_nonterminal => { + self.in_macro_nonterminal = false; + Class::MacroNonTerminal + } + "self" | "Self" => Class::Self_(new_span(before, text, file_span)), + _ => Class::Ident(new_span(before, text, file_span)), + }, + Some(c) => c, + }, TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => { Class::Ident(new_span(before, text, file_span)) } @@ -1249,25 +1246,40 @@ impl<'src> Classifier<'src> { } } - fn peek(&mut self) -> Option { - self.tokens.peek().map(|(token_kind, _text)| *token_kind) + fn is_weak_keyword(&mut self, text: &str) -> bool { + // NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization), + // `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are + // too difficult or annoying to properly detect under this simple scheme. + + let matches = match text { + "auto" => |text| text == "trait", // `auto trait Trait {}` (`auto_traits`) + "pin" => |text| text == "const" || text == "mut", // `&pin mut Type` (`pin_ergonomics`) + "raw" => |text| text == "const" || text == "mut", // `&raw const local` + "safe" => |text| text == "fn" || text == "extern", // `unsafe extern { safe fn f(); }` + "union" => |_| true, // `union Untagged { field: () }` + _ => return false, + }; + matches!(self.peek_non_trivia(), Some((TokenKind::Ident, text)) if matches(text)) } - fn peek_non_whitespace(&mut self) -> Option { - while let Some((token_kind, _)) = self.tokens.peek_next() { - if *token_kind != TokenKind::Whitespace { - let token_kind = *token_kind; - self.tokens.stop_peeking(); - return Some(token_kind); + fn peek(&mut self) -> Option { + self.tokens.peek().map(|&(kind, _)| kind) + } + + fn peek_non_trivia(&mut self) -> Option<(TokenKind, &str)> { + while let Some(&token @ (kind, _)) = self.tokens.peek_next() { + if let TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } = kind + { + continue; } + self.tokens.stop_peeking(); + return Some(token); } self.tokens.stop_peeking(); None } - - fn check_if_is_union_keyword(&mut self) -> bool { - self.peek_non_whitespace().is_some_and(|kind| kind == TokenKind::Ident) - } } fn generate_link_to_def( From 0582085e6fac50865a0d7217d74ef9260f05a6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 28 Oct 2025 22:30:58 +0100 Subject: [PATCH 241/525] rustdoc: Refactor keyword highlighting and make metavars take precedence --- src/librustdoc/html/highlight.rs | 83 ++++++++++++++------------------ 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 7c22a7ab91f6..bc872573cc18 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -754,22 +754,6 @@ impl<'a> Iterator for TokenIter<'a> { } } -/// Classifies into identifier class; returns `None` if this is a non-keyword identifier. -fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option { - let ignore: &[&str] = - if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] }; - if ignore.contains(&text) { - return None; - } - Some(match text { - "ref" | "mut" => Class::RefKeyWord, - "false" | "true" => Class::Bool, - // FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument. - _ if Symbol::intern(text).is_reserved(|| Edition::Edition2024) => Class::KeyWord, - _ => return None, - }) -} - /// This iterator comes from the same idea than "Peekable" except that it allows to "peek" more than /// just the next item by using `peek_next`. The `peek` method always returns the next item after /// the current one whereas `peek_next` will return the next item after the last one peeked. @@ -787,16 +771,16 @@ impl<'a> PeekIter<'a> { Self { stored: VecDeque::new(), peek_pos: 0, iter } } /// Returns the next item after the current one. It doesn't interfere with `peek_next` output. - fn peek(&mut self) -> Option<&(TokenKind, &'a str)> { + fn peek(&mut self) -> Option<(TokenKind, &'a str)> { if self.stored.is_empty() && let Some(next) = self.iter.next() { self.stored.push_back(next); } - self.stored.front() + self.stored.front().copied() } /// Returns the next item after the last one peeked. It doesn't interfere with `peek` output. - fn peek_next(&mut self) -> Option<&(TokenKind, &'a str)> { + fn peek_next(&mut self) -> Option<(TokenKind, &'a str)> { self.peek_pos += 1; if self.peek_pos - 1 < self.stored.len() { self.stored.get(self.peek_pos - 1) @@ -806,6 +790,7 @@ impl<'a> PeekIter<'a> { } else { None } + .copied() } fn stop_peeking(&mut self) { @@ -956,15 +941,10 @@ impl<'src> Classifier<'src> { } } - if let Some((None, text)) = self.tokens.peek().map(|(token, text)| { - if *token == TokenKind::Ident { - let class = get_real_ident_class(text, true); - (class, text) - } else { - // Doesn't matter which Class we put in here... - (Some(Class::Comment), text) - } - }) { + if let Some((TokenKind::Ident, text)) = self.tokens.peek() + && let symbol = Symbol::intern(text) + && (symbol.is_path_segment_keyword() || !is_keyword(symbol)) + { // We only "add" the colon if there is an ident behind. pos += text.len() + nb; has_ident = true; @@ -1210,22 +1190,7 @@ impl<'src> Classifier<'src> { sink(span, Highlight::Token { text, class: None }); return; } - TokenKind::Ident => match get_real_ident_class(text, false) { - None => match text { - "Option" | "Result" => Class::PreludeTy(new_span(before, text, file_span)), - "Some" | "None" | "Ok" | "Err" => { - Class::PreludeVal(new_span(before, text, file_span)) - } - _ if self.is_weak_keyword(text) => Class::KeyWord, - _ if self.in_macro_nonterminal => { - self.in_macro_nonterminal = false; - Class::MacroNonTerminal - } - "self" | "Self" => Class::Self_(new_span(before, text, file_span)), - _ => Class::Ident(new_span(before, text, file_span)), - }, - Some(c) => c, - }, + TokenKind::Ident => self.classify_ident(before, text), TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => { Class::Ident(new_span(before, text, file_span)) } @@ -1246,6 +1211,27 @@ impl<'src> Classifier<'src> { } } + fn classify_ident(&mut self, before: u32, text: &'src str) -> Class { + // Macro non-terminals (meta vars) take precedence. + if self.in_macro_nonterminal { + self.in_macro_nonterminal = false; + return Class::MacroNonTerminal; + } + + let file_span = self.file_span; + let span = || new_span(before, text, file_span); + + match text { + "ref" | "mut" => Class::RefKeyWord, + "false" | "true" => Class::Bool, + "self" | "Self" => Class::Self_(span()), + "Option" | "Result" => Class::PreludeTy(span()), + "Some" | "None" | "Ok" | "Err" => Class::PreludeVal(span()), + _ if self.is_weak_keyword(text) || is_keyword(Symbol::intern(text)) => Class::KeyWord, + _ => Class::Ident(span()), + } + } + fn is_weak_keyword(&mut self, text: &str) -> bool { // NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization), // `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are @@ -1263,11 +1249,11 @@ impl<'src> Classifier<'src> { } fn peek(&mut self) -> Option { - self.tokens.peek().map(|&(kind, _)| kind) + self.tokens.peek().map(|(kind, _)| kind) } fn peek_non_trivia(&mut self) -> Option<(TokenKind, &str)> { - while let Some(&token @ (kind, _)) = self.tokens.peek_next() { + while let Some(token @ (kind, _)) = self.tokens.peek_next() { if let TokenKind::Whitespace | TokenKind::LineComment { doc_style: None } | TokenKind::BlockComment { doc_style: None, .. } = kind @@ -1282,6 +1268,11 @@ impl<'src> Classifier<'src> { } } +fn is_keyword(symbol: Symbol) -> bool { + // FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument. + symbol.is_reserved(|| Edition::Edition2024) +} + fn generate_link_to_def( out: &mut impl Write, text_s: &str, From 1fbaa24d64960410a0f58ce33a7da6d85094b607 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Wed, 29 Oct 2025 00:31:09 -0700 Subject: [PATCH 242/525] fix typo in autodiff docs --- src/doc/rustc-dev-guide/src/autodiff/internals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/autodiff/internals.md b/src/doc/rustc-dev-guide/src/autodiff/internals.md index c8e304f814ba..e381b091e898 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/internals.md +++ b/src/doc/rustc-dev-guide/src/autodiff/internals.md @@ -20,7 +20,7 @@ The detailed documentation for the `std::autodiff` module is available at [std:: Differentiable programming is used in various fields like numerical computing, [solid mechanics][ratel], [computational chemistry][molpipx], [fluid dynamics][waterlily] or for Neural Network training via Backpropagation, [ODE solver][diffsol], [differentiable rendering][libigl], [quantum computing][catalyst], and climate simulations. [ratel]: https://gitlab.com/micromorph/ratel -[molpipx]: https://arxiv.org/abs/2411.17011v +[molpipx]: https://arxiv.org/abs/2411.17011 [waterlily]: https://github.com/WaterLily-jl/WaterLily.jl [diffsol]: https://github.com/martinjrobins/diffsol [libigl]: https://github.com/alecjacobson/libigl-enzyme-example?tab=readme-ov-file#run From 5f0c7c2aae9195e8850d34d1d6f501bebf7820ad Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 29 Oct 2025 12:28:57 +0100 Subject: [PATCH 243/525] fix: Improve error recovery when parsing malformed function return types --- .../parser/src/grammar/expressions/atom.rs | 6 + .../crates/parser/src/grammar/items.rs | 8 ++ .../parser/test_data/generated/runner.rs | 8 ++ .../inline/err/closure_ret_recovery.rast | 52 ++++++++ .../parser/inline/err/closure_ret_recovery.rs | 1 + .../parser/inline/err/fn_ret_recovery.rast | 112 ++++++++++++++++++ .../parser/inline/err/fn_ret_recovery.rs | 2 + 7 files changed, 189 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rs diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index ed8a91c39c01..cde62e03238a 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -588,6 +588,12 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker { } params::param_list_closure(p); if opt_ret_type(p) { + // test_err closure_ret_recovery + // fn foo() { || -> A> { let x = 1; } } + while p.at(T![>]) { + // recover from unbalanced return type brackets + p.err_and_bump("expected a curly brace"); + } // test lambda_ret_block // fn main() { || -> i32 { 92 }(); } block_expr(p); diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs index 8e551b0b9611..c609f9383ee0 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs @@ -424,6 +424,14 @@ fn fn_(p: &mut Parser<'_>, m: Marker) { // fn bar() -> () {} opt_ret_type(p); + // test_err fn_ret_recovery + // fn foo() -> A>]) { let x = 1; } + // fn foo() -> A>]) where T: Copy { let x = 1; } + while p.at(T![')']) | p.at(T![']']) | p.at(T![>]) { + // recover from unbalanced return type brackets + p.err_and_bump("expected a curly brace"); + } + // test function_where_clause // fn foo() where T: Copy {} generic_params::opt_where_clause(p); diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 9bdbe5633033..c56eb5090cee 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -749,6 +749,10 @@ mod err { #[test] fn bad_asm_expr() { run_and_expect_errors("test_data/parser/inline/err/bad_asm_expr.rs"); } #[test] + fn closure_ret_recovery() { + run_and_expect_errors("test_data/parser/inline/err/closure_ret_recovery.rs"); + } + #[test] fn comma_after_default_values_syntax() { run_and_expect_errors("test_data/parser/inline/err/comma_after_default_values_syntax.rs"); } @@ -773,6 +777,10 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/fn_pointer_type_missing_fn.rs"); } #[test] + fn fn_ret_recovery() { + run_and_expect_errors("test_data/parser/inline/err/fn_ret_recovery.rs"); + } + #[test] fn gen_fn() { run_and_expect_errors_with_edition( "test_data/parser/inline/err/gen_fn.rs", diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rast new file mode 100644 index 000000000000..f6266510bb4f --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rast @@ -0,0 +1,52 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + CLOSURE_EXPR + PARAM_LIST + PIPE "|" + PIPE "|" + WHITESPACE " " + RET_TYPE + THIN_ARROW "->" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "A" + ERROR + R_ANGLE ">" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n" +error 18: expected a curly brace diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rs new file mode 100644 index 000000000000..7a758ec076d6 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/closure_ret_recovery.rs @@ -0,0 +1 @@ +fn foo() { || -> A> { let x = 1; } } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rast new file mode 100644 index 000000000000..0323df8bf0ff --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rast @@ -0,0 +1,112 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + RET_TYPE + THIN_ARROW "->" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "A" + ERROR + R_ANGLE ">" + ERROR + R_BRACK "]" + ERROR + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n" + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + RET_TYPE + THIN_ARROW "->" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "A" + ERROR + R_ANGLE ">" + ERROR + R_BRACK "]" + ERROR + R_PAREN ")" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + WHERE_PRED + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Copy" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "x" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n" +error 13: expected a curly brace +error 14: expected a curly brace +error 15: expected a curly brace +error 45: expected a curly brace +error 46: expected a curly brace +error 47: expected a curly brace diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rs new file mode 100644 index 000000000000..73e3d84d74e9 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_ret_recovery.rs @@ -0,0 +1,2 @@ +fn foo() -> A>]) { let x = 1; } +fn foo() -> A>]) where T: Copy { let x = 1; } From 008c60d48bbd852ecbe5c6c97e88a928bc2b2617 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 2 Aug 2025 17:26:34 +0200 Subject: [PATCH 244/525] minor: Cleanup `map_rust_child_diagnostics` a bit --- src/tools/rust-analyzer/Cargo.lock | 1 + .../crates/rust-analyzer/Cargo.toml | 1 + .../crates/rust-analyzer/src/diagnostics.rs | 5 +- .../{to_proto.rs => flycheck_to_proto.rs} | 375 +++++++++--------- .../test_data/macro_compiler_error.txt | 2 +- .../crates/rust-analyzer/src/main_loop.rs | 4 +- 6 files changed, 193 insertions(+), 195 deletions(-) rename src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/{to_proto.rs => flycheck_to_proto.rs} (88%) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 535833d9e2a9..78c0238994b0 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2047,6 +2047,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "smallvec", "stdx", "syntax", "syntax-bridge", diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index c746f848b6a0..721fae6ed5d8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -42,6 +42,7 @@ tenthash = "1.1.0" num_cpus = "1.17.0" mimalloc = { version = "0.1.46", default-features = false, optional = true } lsp-server.workspace = true +smallvec.workspace = true tracing.workspace = true tracing-subscriber.workspace = true tracing-tree.workspace = true diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs index 4bfad98b3997..4a247800af9d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs @@ -1,5 +1,5 @@ //! Book keeping for keeping diagnostics easily in sync with the client. -pub(crate) mod to_proto; +pub(crate) mod flycheck_to_proto; use std::mem; @@ -8,6 +8,7 @@ use ide::FileId; use ide_db::{FxHashMap, base_db::DbPanicContext}; use itertools::Itertools; use rustc_hash::FxHashSet; +use smallvec::SmallVec; use stdx::iter_eq_by; use triomphe::Arc; @@ -57,7 +58,7 @@ pub(crate) struct DiagnosticCollection { #[derive(Debug, Clone)] pub(crate) struct Fix { // Fixes may be triggerable from multiple ranges. - pub(crate) ranges: Vec, + pub(crate) ranges: SmallVec<[lsp_types::Range; 1]>, pub(crate) action: lsp_ext::CodeAction, } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs similarity index 88% rename from src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs rename to src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs index 3f64628de860..a6d7bcb9c70e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs @@ -4,6 +4,7 @@ use crate::flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan}; use itertools::Itertools; use rustc_hash::FxHashMap; +use smallvec::SmallVec; use stdx::format_to; use vfs::{AbsPath, AbsPathBuf}; @@ -18,12 +19,12 @@ use super::{DiagnosticsMapConfig, Fix}; fn diagnostic_severity( config: &DiagnosticsMapConfig, level: crate::flycheck::DiagnosticLevel, - code: Option, + code: Option<&crate::flycheck::DiagnosticCode>, ) -> Option { let res = match level { DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::ERROR, DiagnosticLevel::Error => lsp_types::DiagnosticSeverity::ERROR, - DiagnosticLevel::Warning => match &code { + DiagnosticLevel::Warning => match code { // HACK: special case for `warnings` rustc lint. Some(code) if config.warnings_as_hint.iter().any(|lint| { @@ -143,11 +144,11 @@ fn primary_location( fn diagnostic_related_information( config: &DiagnosticsMapConfig, workspace_root: &AbsPath, - span: &DiagnosticSpan, + span: DiagnosticSpan, snap: &GlobalStateSnapshot, ) -> Option { - let message = span.label.clone()?; - let location = location(config, workspace_root, span, snap); + let location = location(config, workspace_root, &span, snap); + let message = span.label?; Some(lsp_types::DiagnosticRelatedInformation { location, message }) } @@ -184,7 +185,7 @@ fn map_rust_child_diagnostic( rd: &crate::flycheck::Diagnostic, snap: &GlobalStateSnapshot, ) -> MappedRustChildDiagnostic { - let spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect(); + let spans: SmallVec<[&DiagnosticSpan; 1]> = rd.spans.iter().filter(|s| s.is_primary).collect(); if spans.is_empty() { // `rustc` uses these spanless children as a way to print multi-line // messages @@ -227,42 +228,37 @@ fn map_rust_child_diagnostic( message.push_str(&suggestions); } - if edit_map.is_empty() { - MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { - related: lsp_types::DiagnosticRelatedInformation { - location: location(config, workspace_root, spans[0], snap), - message, - }, - suggested_fix: None, - }) + let suggested_fix = if edit_map.is_empty() { + None } else { - MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { - related: lsp_types::DiagnosticRelatedInformation { - location: location(config, workspace_root, spans[0], snap), - message: message.clone(), + Some(Box::new(Fix { + ranges: spans + .iter() + .map(|&span| location(config, workspace_root, span, snap).range) + .collect(), + action: lsp_ext::CodeAction { + title: message.clone(), + group: None, + kind: Some(lsp_types::CodeActionKind::QUICKFIX), + edit: Some(lsp_ext::SnippetWorkspaceEdit { + // FIXME: there's no good reason to use edit_map here.... + changes: Some(edit_map), + document_changes: None, + change_annotations: None, + }), + is_preferred: Some(is_preferred), + data: None, + command: None, }, - suggested_fix: Some(Box::new(Fix { - ranges: spans - .iter() - .map(|&span| location(config, workspace_root, span, snap).range) - .collect(), - action: lsp_ext::CodeAction { - title: message, - group: None, - kind: Some(lsp_types::CodeActionKind::QUICKFIX), - edit: Some(lsp_ext::SnippetWorkspaceEdit { - // FIXME: there's no good reason to use edit_map here.... - changes: Some(edit_map), - document_changes: None, - change_annotations: None, - }), - is_preferred: Some(is_preferred), - data: None, - command: None, - }, - })), - }) - } + })) + }; + MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { + related: lsp_types::DiagnosticRelatedInformation { + location: location(config, workspace_root, spans[0], snap), + message, + }, + suggested_fix, + }) } #[derive(Debug)] @@ -284,48 +280,56 @@ pub(crate) struct MappedRustDiagnostic { /// If the diagnostic has no primary span this will return `None` pub(crate) fn map_rust_diagnostic_to_lsp( config: &DiagnosticsMapConfig, - rd: &crate::flycheck::Diagnostic, + crate::flycheck::Diagnostic { + mut message, + code: diagnostic_code, + level, + spans, + children, + rendered, + .. + }: crate::flycheck::Diagnostic, workspace_root: &AbsPath, snap: &GlobalStateSnapshot, ) -> Vec { - let primary_spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect(); + let (primary_spans, secondary_spans): ( + SmallVec<[DiagnosticSpan; 1]>, + SmallVec<[DiagnosticSpan; 1]>, + ) = spans.into_iter().partition(|s| s.is_primary); if primary_spans.is_empty() { return Vec::new(); } - let severity = diagnostic_severity(config, rd.level, rd.code.clone()); + let mut code = diagnostic_code.as_ref().map(|c| &*c.code); - let mut source = String::from("rustc"); - let mut code = rd.code.as_ref().map(|c| c.code.clone()); - - if let Some(code_val) = &code + if let Some(code_val) = code && config.check_ignore.contains(code_val) { return Vec::new(); } - if let Some(code_val) = &code { + let severity = diagnostic_severity(config, level, diagnostic_code.as_ref()); + + let mut source = "rustc"; + if let Some(code_val) = code { // See if this is an RFC #2103 scoped lint (e.g. from Clippy) - let scoped_code: Vec<&str> = code_val.split("::").collect(); - if scoped_code.len() == 2 { - source = String::from(scoped_code[0]); - code = Some(String::from(scoped_code[1])); + if let Some((s, c)) = code_val.split("::").collect_tuple() { + source = s; + code = Some(c); } } let mut needs_primary_span_label = true; let mut subdiagnostics = Vec::new(); - let mut tags = Vec::new(); - for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { + for secondary_span in secondary_spans { let related = diagnostic_related_information(config, workspace_root, secondary_span, snap); if let Some(related) = related { subdiagnostics.push(SubDiagnostic { related, suggested_fix: None }); } } - let mut message = rd.message.clone(); - for child in &rd.children { + for child in &children { let child = map_rust_child_diagnostic(config, workspace_root, child, snap); match child { MappedRustChildDiagnostic::SubDiagnostic(sub) => { @@ -340,155 +344,146 @@ pub(crate) fn map_rust_diagnostic_to_lsp( } } } + let message = message; - if let Some(code) = &rd.code { - let code = code.code.as_str(); - if matches!( - code, - "dead_code" - | "unknown_lints" - | "unreachable_code" - | "unused_attributes" - | "unused_imports" - | "unused_macros" - | "unused_variables" - ) { - tags.push(lsp_types::DiagnosticTag::UNNECESSARY); - } - - if matches!(code, "deprecated") { - tags.push(lsp_types::DiagnosticTag::DEPRECATED); + let mut tag = None; + if let Some(code) = &diagnostic_code { + match &*code.code { + "dead_code" | "unknown_lints" | "unreachable_code" | "unused_attributes" + | "unused_imports" | "unused_macros" | "unused_variables" => { + tag = Some(lsp_types::DiagnosticTag::UNNECESSARY); + } + "deprecated" => { + tag = Some(lsp_types::DiagnosticTag::DEPRECATED); + } + _ => {} } } - let code_description = match source.as_str() { - "rustc" => rustc_code_description(code.as_deref()), - "clippy" => clippy_code_description(code.as_deref()), + let code_description = match source { + "rustc" => rustc_code_description(code), + "clippy" => clippy_code_description(code), _ => None, }; + // Each primary diagnostic span may result in multiple LSP diagnostics. + let mut diagnostics = Vec::new(); - primary_spans - .iter() - .flat_map(|primary_span| { - let primary_location = primary_location(config, workspace_root, primary_span, snap); - let message = { - let mut message = message.clone(); - if needs_primary_span_label && let Some(primary_span_label) = &primary_span.label { - format_to!(message, "\n{}", primary_span_label); - } - message - }; - // Each primary diagnostic span may result in multiple LSP diagnostics. - let mut diagnostics = Vec::new(); + for primary_span in primary_spans { + let primary_location = primary_location(config, workspace_root, &primary_span, snap); + let message = { + let mut message = message.clone(); + if needs_primary_span_label && let Some(primary_span_label) = &primary_span.label { + format_to!(message, "\n{}", primary_span_label); + } + message + }; - let mut related_info_macro_calls = vec![]; + let mut related_info_macro_calls = vec![]; - // If error occurs from macro expansion, add related info pointing to - // where the error originated - // Also, we would generate an additional diagnostic, so that exact place of macro - // will be highlighted in the error origin place. - let span_stack = std::iter::successors(Some(*primary_span), |span| { - Some(&span.expansion.as_ref()?.span) - }); - for (i, span) in span_stack.enumerate() { - if is_dummy_macro_file(&span.file_name) { - continue; - } - - // First span is the original diagnostic, others are macro call locations that - // generated that code. - let is_in_macro_call = i != 0; - - let secondary_location = location(config, workspace_root, span, snap); - if secondary_location == primary_location { - continue; - } - related_info_macro_calls.push(lsp_types::DiagnosticRelatedInformation { - location: secondary_location.clone(), - message: if is_in_macro_call { - "Error originated from macro call here".to_owned() - } else { - "Actual error occurred here".to_owned() - }, - }); - // For the additional in-macro diagnostic we add the inverse message pointing to the error location in code. - let information_for_additional_diagnostic = - vec![lsp_types::DiagnosticRelatedInformation { - location: primary_location.clone(), - message: "Exact error occurred here".to_owned(), - }]; - - let diagnostic = lsp_types::Diagnostic { - range: secondary_location.range, - // downgrade to hint if we're pointing at the macro - severity: Some(lsp_types::DiagnosticSeverity::HINT), - code: code.clone().map(lsp_types::NumberOrString::String), - code_description: code_description.clone(), - source: Some(source.clone()), - message: message.clone(), - related_information: Some(information_for_additional_diagnostic), - tags: if tags.is_empty() { None } else { Some(tags.clone()) }, - data: Some(serde_json::json!({ "rendered": rd.rendered })), - }; - diagnostics.push(MappedRustDiagnostic { - url: secondary_location.uri, - diagnostic, - fix: None, - }); + // If error occurs from macro expansion, add related info pointing to + // where the error originated + // Also, we would generate an additional diagnostic, so that exact place of macro + // will be highlighted in the error origin place. + let span_stack = + std::iter::successors(Some(&primary_span), |span| Some(&span.expansion.as_ref()?.span)) + .skip(1); + for (i, span) in span_stack.enumerate() { + if is_dummy_macro_file(&span.file_name) { + continue; + } + let secondary_location = location(config, workspace_root, span, snap); + if secondary_location == primary_location { + continue; } - // Emit the primary diagnostic. - diagnostics.push(MappedRustDiagnostic { - url: primary_location.uri.clone(), - diagnostic: lsp_types::Diagnostic { - range: primary_location.range, - severity, - code: code.clone().map(lsp_types::NumberOrString::String), - code_description: code_description.clone(), - source: Some(source.clone()), - message, - related_information: { - let info = related_info_macro_calls - .iter() - .cloned() - .chain(subdiagnostics.iter().map(|sub| sub.related.clone())) - .collect::>(); - if info.is_empty() { None } else { Some(info) } - }, - tags: if tags.is_empty() { None } else { Some(tags.clone()) }, - data: Some(serde_json::json!({ "rendered": rd.rendered })), + // First span is the original diagnostic, others are macro call locations that + // generated that code. + let is_in_macro_call = i != 0; + + related_info_macro_calls.push(lsp_types::DiagnosticRelatedInformation { + location: secondary_location.clone(), + message: if is_in_macro_call { + "Error originated from macro call here".to_owned() + } else { + "Actual error occurred here".to_owned() }, + }); + // For the additional in-macro diagnostic we add the inverse message pointing to the error location in code. + let information_for_additional_diagnostic = + vec![lsp_types::DiagnosticRelatedInformation { + location: primary_location.clone(), + message: "Exact error occurred here".to_owned(), + }]; + + let diagnostic = lsp_types::Diagnostic { + range: secondary_location.range, + // downgrade to hint if we're pointing at the macro + severity: Some(lsp_types::DiagnosticSeverity::HINT), + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), + code_description: code_description.clone(), + source: Some(source.to_owned()), + message: message.clone(), + related_information: Some(information_for_additional_diagnostic), + tags: tag.clone().map(|tag| vec![tag]), + data: Some(serde_json::json!({ "rendered": rendered })), + }; + diagnostics.push(MappedRustDiagnostic { + url: secondary_location.uri, + diagnostic, fix: None, }); + } - // Emit hint-level diagnostics for all `related_information` entries such as "help"s. - // This is useful because they will show up in the user's editor, unlike - // `related_information`, which just produces hard-to-read links, at least in VS Code. - let back_ref = lsp_types::DiagnosticRelatedInformation { - location: primary_location, - message: "original diagnostic".to_owned(), - }; - for sub in &subdiagnostics { - diagnostics.push(MappedRustDiagnostic { - url: sub.related.location.uri.clone(), - fix: sub.suggested_fix.clone(), - diagnostic: lsp_types::Diagnostic { - range: sub.related.location.range, - severity: Some(lsp_types::DiagnosticSeverity::HINT), - code: code.clone().map(lsp_types::NumberOrString::String), - code_description: code_description.clone(), - source: Some(source.clone()), - message: sub.related.message.clone(), - related_information: Some(vec![back_ref.clone()]), - tags: None, // don't apply modifiers again - data: None, - }, - }); - } + // Emit the primary diagnostic. + diagnostics.push(MappedRustDiagnostic { + url: primary_location.uri.clone(), + diagnostic: lsp_types::Diagnostic { + range: primary_location.range, + severity, + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), + code_description: code_description.clone(), + source: Some(source.to_owned()), + message, + related_information: { + let info = related_info_macro_calls + .iter() + .cloned() + .chain(subdiagnostics.iter().map(|sub| sub.related.clone())) + .collect::>(); + if info.is_empty() { None } else { Some(info) } + }, + tags: tag.clone().map(|tag| vec![tag]), + data: Some(serde_json::json!({ "rendered": rendered })), + }, + fix: None, + }); - diagnostics - }) - .collect() + // Emit hint-level diagnostics for all `related_information` entries such as "help"s. + // This is useful because they will show up in the user's editor, unlike + // `related_information`, which just produces hard-to-read links, at least in VS Code. + let back_ref = lsp_types::DiagnosticRelatedInformation { + location: primary_location, + message: "original diagnostic".to_owned(), + }; + for sub in &subdiagnostics { + diagnostics.push(MappedRustDiagnostic { + url: sub.related.location.uri.clone(), + fix: sub.suggested_fix.clone(), + diagnostic: lsp_types::Diagnostic { + range: sub.related.location.range, + severity: Some(lsp_types::DiagnosticSeverity::HINT), + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), + code_description: code_description.clone(), + source: Some(source.to_owned()), + message: sub.related.message.clone(), + related_information: Some(vec![back_ref.clone()]), + tags: None, // don't apply modifiers again + data: None, + }, + }); + } + } + diagnostics } fn rustc_code_description(code: Option<&str>) -> Option { @@ -545,7 +540,7 @@ mod tests { ), ); let snap = state.snapshot(); - let mut actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root, &snap); + let mut actual = map_rust_diagnostic_to_lsp(&config, diagnostic, workspace_root, &snap); actual.iter_mut().for_each(|diag| diag.diagnostic.data = None); expect.assert_debug_eq(&actual) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt index fe5cf9b3bea7..b44569b4931d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt @@ -191,7 +191,7 @@ }, }, }, - message: "Error originated from macro call here", + message: "Actual error occurred here", }, DiagnosticRelatedInformation { location: Location { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index c0947b2a291e..7fa4c3f1f364 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -1023,9 +1023,9 @@ impl GlobalState { package_id, } => { let snap = self.snapshot(); - let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( + let diagnostics = crate::diagnostics::flycheck_to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(None), - &diagnostic, + diagnostic, &workspace_root, &snap, ); From 3a02b357d36414dca2e388e761c41c0f611bd460 Mon Sep 17 00:00:00 2001 From: "Mark Z. Ding" Date: Wed, 29 Oct 2025 09:33:38 -0400 Subject: [PATCH 245/525] Add tests to demonstrate explicit tail call bug --- .../explicit-tail-calls/become-cast-return.rs | 22 +++++++++++++++++++ .../become-indirect-return.rs | 21 ++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/explicit-tail-calls/become-cast-return.rs create mode 100644 tests/ui/explicit-tail-calls/become-indirect-return.rs diff --git a/tests/ui/explicit-tail-calls/become-cast-return.rs b/tests/ui/explicit-tail-calls/become-cast-return.rs new file mode 100644 index 000000000000..3052886d7b8f --- /dev/null +++ b/tests/ui/explicit-tail-calls/become-cast-return.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ ignore-backends: gcc +//@ known-bug: #148239 +//@ compile-flags: -Zno-codegen +#![expect(incomplete_features)] +#![feature(explicit_tail_calls)] + +#[inline(never)] +fn leaf(_: &Box) -> [u8; 1] { + [1] +} + +#[inline(never)] +fn dispatch(param: &Box) -> [u8; 1] { + become leaf(param) +} + +fn main() { + let data = Box::new(0); + let out = dispatch(&data); + assert_eq!(out, [1]); +} diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs new file mode 100644 index 000000000000..c94683d15f40 --- /dev/null +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -0,0 +1,21 @@ +//@ run-pass +//@ ignore-backends: gcc +//@ known-bug: #148239 +#![expect(incomplete_features)] +#![feature(explicit_tail_calls)] + +#[inline(never)] +fn op_dummy(_param: &Box) -> [u8; 24] { + [1; 24] +} + +#[inline(never)] +fn dispatch(param: &Box) -> [u8; 24] { + become op_dummy(param) +} + +fn main() { + let param = Box::new(0); + let result = dispatch(¶m); + assert_ne!(result, [1; 24]); // the data is not right! +} From 52959a85cca72bdacaae9793005ff7cc7af43762 Mon Sep 17 00:00:00 2001 From: "Mark Z. Ding" Date: Wed, 29 Oct 2025 09:38:56 -0400 Subject: [PATCH 246/525] Fix musttail returns for cast/indirect ABIs --- compiler/rustc_codegen_llvm/src/builder.rs | 6 +----- compiler/rustc_codegen_ssa/src/mir/block.rs | 12 +++++++++++- tests/ui/explicit-tail-calls/become-cast-return.rs | 4 +--- .../ui/explicit-tail-calls/become-indirect-return.rs | 3 +-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index c082a8230684..49d38e05c8b0 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -16,7 +16,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; -use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers, @@ -1458,10 +1457,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { match &fn_abi.ret.mode { PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(), - PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call), - mode @ PassMode::Cast { .. } => { - bug!("Encountered `PassMode::{mode:?}` during codegen") - } + PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => self.ret(call), } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e2241a77d186..0d1e27a34dc5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1063,7 +1063,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs); target.map(|target| (return_dest, target)) } - CallKind::Tail => None, + CallKind::Tail => { + if fn_abi.ret.is_indirect() { + match self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs) { + ReturnDest::Nothing => {} + _ => bug!( + "tail calls to functions with indirect returns cannot store into a destination" + ), + } + } + None + } }; // Split the rust-call tupled arguments off. diff --git a/tests/ui/explicit-tail-calls/become-cast-return.rs b/tests/ui/explicit-tail-calls/become-cast-return.rs index 3052886d7b8f..212a0ddcbca1 100644 --- a/tests/ui/explicit-tail-calls/become-cast-return.rs +++ b/tests/ui/explicit-tail-calls/become-cast-return.rs @@ -1,7 +1,5 @@ -//@ check-pass +//@ run-pass //@ ignore-backends: gcc -//@ known-bug: #148239 -//@ compile-flags: -Zno-codegen #![expect(incomplete_features)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs index c94683d15f40..7eec34f3b95c 100644 --- a/tests/ui/explicit-tail-calls/become-indirect-return.rs +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -1,6 +1,5 @@ //@ run-pass //@ ignore-backends: gcc -//@ known-bug: #148239 #![expect(incomplete_features)] #![feature(explicit_tail_calls)] @@ -17,5 +16,5 @@ fn dispatch(param: &Box) -> [u8; 24] { fn main() { let param = Box::new(0); let result = dispatch(¶m); - assert_ne!(result, [1; 24]); // the data is not right! + assert_eq!(result, [1; 24]); } From b92ed4e02b72454e6fae090a1ab5df1082087ca2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 29 Oct 2025 19:52:26 +0200 Subject: [PATCH 247/525] reflect that type and const parameter can be intermixed Also, add reference id --- tests/ui/const-generics/argument_order.rs | 8 +++++--- tests/ui/const-generics/argument_order.stderr | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/ui/const-generics/argument_order.rs b/tests/ui/const-generics/argument_order.rs index 196d9b8a1e21..f8980c9b54d7 100644 --- a/tests/ui/const-generics/argument_order.rs +++ b/tests/ui/const-generics/argument_order.rs @@ -1,15 +1,17 @@ -struct Bad { +//@ reference: items.generics.syntax.decl-order + +struct Good { arr: [u8; { N }], another: T, } -struct AlsoBad { +struct Bad { //~^ ERROR lifetime parameters must be declared prior a: &'a T, b: &'b U, } fn main() { - let _: AlsoBad<7, 'static, u32, 'static, 17, u16>; + let _: Bad<7, 'static, u32, 'static, 17, u16>; //~^ ERROR lifetime provided when a type was expected } diff --git a/tests/ui/const-generics/argument_order.stderr b/tests/ui/const-generics/argument_order.stderr index 99122c6f5e36..ef6d168d7042 100644 --- a/tests/ui/const-generics/argument_order.stderr +++ b/tests/ui/const-generics/argument_order.stderr @@ -1,14 +1,14 @@ error: lifetime parameters must be declared prior to type and const parameters - --> $DIR/argument_order.rs:6:32 + --> $DIR/argument_order.rs:8:28 | -LL | struct AlsoBad { - | -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>` +LL | struct Bad { + | -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>` error[E0747]: lifetime provided when a type was expected - --> $DIR/argument_order.rs:13:23 + --> $DIR/argument_order.rs:15:19 | -LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>; - | ^^^^^^^ +LL | let _: Bad<7, 'static, u32, 'static, 17, u16>; + | ^^^^^^^ | = note: lifetime arguments must be provided before type arguments = help: reorder the arguments: lifetimes, then type and consts: `<'a, 'b, N, T, M, U>` From 8611f0b67c7aea4c43d5a3f39b0e84a6d0950868 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Oct 2025 11:30:37 -0700 Subject: [PATCH 248/525] rustdoc: fix `--emit=dep-info` on scraped examples --- src/librustdoc/lib.rs | 2 +- src/librustdoc/scrape_examples.rs | 5 +++++ .../examples/ex.rs | 6 ++++++ .../rustdoc-scrape-examples-dep-info/rmake.rs | 19 +++++++++++++++++++ .../src/lib.rs | 3 +++ .../rmake.rs | 2 +- .../rustdoc-scrape-examples-multiple/rmake.rs | 2 +- .../rustdoc-scrape-examples-ordering/rmake.rs | 2 +- .../rustdoc-scrape-examples-remap/rmake.rs | 2 +- .../rustdoc-scrape-examples-remap/scrape.rs | 5 +++-- .../rustdoc-scrape-examples-test/rmake.rs | 2 +- .../rmake.rs | 2 +- 12 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 tests/run-make/rustdoc-scrape-examples-dep-info/examples/ex.rs create mode 100644 tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs create mode 100644 tests/run-make/rustdoc-scrape-examples-dep-info/src/lib.rs diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index dd6378b25def..c6a0682a80c4 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -896,7 +896,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { // Register the loaded external files in the source map so they show up in depinfo. // We can't load them via the source map because it gets created after we process the options. for external_path in &loaded_paths { - let _ = sess.source_map().load_file(external_path); + let _ = sess.source_map().load_binary_file(external_path); } if sess.opts.describe_lints { diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 471e966e2c24..1b3c96d82b41 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -273,6 +273,7 @@ pub(crate) fn run( bin_crate: bool, ) { let inner = move || -> Result<(), String> { + let emit_dep_info = renderopts.dep_info().is_some(); // Generates source files for examples renderopts.no_emit_shared = true; let (cx, _) = Context::init(krate, renderopts, cache, tcx, Default::default()) @@ -320,6 +321,10 @@ pub(crate) fn run( calls.encode(&mut encoder); encoder.finish().map_err(|(_path, e)| e.to_string())?; + if emit_dep_info { + rustc_interface::passes::write_dep_info(tcx); + } + Ok(()) }; diff --git a/tests/run-make/rustdoc-scrape-examples-dep-info/examples/ex.rs b/tests/run-make/rustdoc-scrape-examples-dep-info/examples/ex.rs new file mode 100644 index 000000000000..c37b8dd48853 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-dep-info/examples/ex.rs @@ -0,0 +1,6 @@ +fn main() {} + +#[test] +fn a_test() { + foobar::ok(); +} diff --git a/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs b/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs new file mode 100644 index 000000000000..7dfa6584785a --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs @@ -0,0 +1,19 @@ +//@ needs-target-std +use run_make_support::{assert_contains, rfs}; + +#[path = "../rustdoc-scrape-examples-remap/scrape.rs"] +mod scrape; + +fn main() { + scrape::scrape( + &["--scrape-tests", "--emit=dep-info"], + &["--emit=dep-info,invocation-specific"], + ); + + let content = rfs::read_to_string("foobar.d"); + assert_contains(&content, "lib.rs:"); + assert_contains(&content, "rustdoc/ex.calls:"); + + let content = rfs::read_to_string("ex.d"); + assert_contains(&content, "examples/ex.rs:"); +} diff --git a/tests/run-make/rustdoc-scrape-examples-dep-info/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-dep-info/src/lib.rs new file mode 100644 index 000000000000..93d56b7e972f --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-dep-info/src/lib.rs @@ -0,0 +1,3 @@ +//@ has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' '' + +pub fn ok() {} diff --git a/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs b/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs index 8996ff184c90..38943b663c42 100644 --- a/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs @@ -3,5 +3,5 @@ mod scrape; fn main() { - scrape::scrape(&[]); + scrape::scrape(&[], &[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-multiple/rmake.rs b/tests/run-make/rustdoc-scrape-examples-multiple/rmake.rs index 8996ff184c90..38943b663c42 100644 --- a/tests/run-make/rustdoc-scrape-examples-multiple/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-multiple/rmake.rs @@ -3,5 +3,5 @@ mod scrape; fn main() { - scrape::scrape(&[]); + scrape::scrape(&[], &[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs index 8996ff184c90..38943b663c42 100644 --- a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs @@ -3,5 +3,5 @@ mod scrape; fn main() { - scrape::scrape(&[]); + scrape::scrape(&[], &[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs b/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs index ead3920c7613..920a65d56f8e 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs @@ -2,5 +2,5 @@ mod scrape; fn main() { - scrape::scrape(&[]); + scrape::scrape(&[], &[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs index c4d7814c3c83..668cb3797fb9 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs @@ -2,7 +2,7 @@ use std::path::Path; use run_make_support::{htmldocck, rfs, rustc, rustdoc}; -pub fn scrape(extra_args: &[&str]) { +pub fn scrape(extra_args_scrape: &[&str], extra_args_doc: &[&str]) { let out_dir = Path::new("rustdoc"); let crate_name = "foobar"; let deps = rfs::read_dir("examples") @@ -27,7 +27,7 @@ pub fn scrape(extra_args: &[&str]) { .arg(&out_example) .arg("--scrape-examples-target-crate") .arg(crate_name) - .args(extra_args) + .args(extra_args_scrape) .run(); out_deps.push(out_example); } @@ -42,6 +42,7 @@ pub fn scrape(extra_args: &[&str]) { for dep in out_deps { rustdoc.arg("--with-examples").arg(dep); } + rustdoc.args(extra_args_doc); rustdoc.run(); htmldocck().arg(out_dir).arg("src/lib.rs").run(); diff --git a/tests/run-make/rustdoc-scrape-examples-test/rmake.rs b/tests/run-make/rustdoc-scrape-examples-test/rmake.rs index 0868507c4ae5..c0c4df91d517 100644 --- a/tests/run-make/rustdoc-scrape-examples-test/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-test/rmake.rs @@ -3,5 +3,5 @@ mod scrape; fn main() { - scrape::scrape(&["--scrape-tests"]); + scrape::scrape(&["--scrape-tests"], &[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-whitespace/rmake.rs b/tests/run-make/rustdoc-scrape-examples-whitespace/rmake.rs index 8996ff184c90..38943b663c42 100644 --- a/tests/run-make/rustdoc-scrape-examples-whitespace/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-whitespace/rmake.rs @@ -3,5 +3,5 @@ mod scrape; fn main() { - scrape::scrape(&[]); + scrape::scrape(&[], &[]); } From 73515c787a900c5d00917d5fd85471af8569e56c Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Wed, 22 Oct 2025 09:58:23 -0600 Subject: [PATCH 249/525] fix: Only special case single line item attribute suggestions --- compiler/rustc_errors/src/emitter.rs | 2 ++ src/tools/clippy/tests/ui/new_without_default.stderr | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9e32a85e361a..25a37c6d58f9 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2152,6 +2152,7 @@ impl HumanEmitter { let line_start = sm.lookup_char_pos(parts[0].original_span.lo()).line; let mut lines = complete.lines(); + let lines_len = lines.clone().count(); if lines.clone().next().is_none() { // Account for a suggestion to completely remove a line(s) with whitespace (#94192). let line_end = sm.lookup_char_pos(parts[0].original_span.hi()).line; @@ -2192,6 +2193,7 @@ impl HumanEmitter { if highlight_parts.len() == 1 && line.trim().starts_with("#[") && line.trim().ends_with(']') + && lines_len == 1 { is_item_attribute = true; } diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr index 1e0d5e213199..0593dbb00fb6 100644 --- a/src/tools/clippy/tests/ui/new_without_default.stderr +++ b/src/tools/clippy/tests/ui/new_without_default.stderr @@ -191,7 +191,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfg { | error: you should consider adding a `Default` implementation for `NewWith2Cfgs` @@ -212,7 +211,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWith2Cfgs { | error: you should consider adding a `Default` implementation for `NewWithExtraneous` @@ -250,7 +248,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfgAndExtraneous { | error: aborting due to 13 previous errors From 651076aaed1778a1ec60fb6036383d764c2df208 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 30 Oct 2025 04:53:23 +0000 Subject: [PATCH 250/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 292be5c7c05138d753bbd4b30db7a3f1a5c914f7. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 405e0026b305..bf33c10dd035 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -27050c0d15af664cf43ce4b0badec230e0bfcac5 +292be5c7c05138d753bbd4b30db7a3f1a5c914f7 From 7e0783f47df3ea815f5edb67930498eb3a449cf8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 07:54:24 +0100 Subject: [PATCH 251/525] alloc access tracking: print accessed range --- src/tools/miri/src/diagnostics.rs | 12 ++++++------ src/tools/miri/src/machine.rs | 14 ++++++++++---- .../miri/tests/pass/alloc-access-tracking.stderr | 8 ++++---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 0e756d89a2dc..fdbbf9a07698 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -128,7 +128,7 @@ pub enum NonHaltingDiagnostic { PoppedPointerTag(Item, String), TrackingAlloc(AllocId, Size, Align), FreedAlloc(AllocId), - AccessedAlloc(AllocId, AccessKind), + AccessedAlloc(AllocId, AllocRange, AccessKind), RejectedIsolatedOp(String), ProgressReport { block_count: u64, // how many basic blocks have been run so far @@ -673,15 +673,15 @@ impl<'tcx> MiriMachine<'tcx> { "created tag {tag:?} with {perm} at {alloc_id:?}{range:?} derived from {orig_tag:?}" ), PoppedPointerTag(item, cause) => format!("popped tracked tag for item {item:?}{cause}"), - TrackingAlloc(AllocId(id), size, align) => + TrackingAlloc(id, size, align) => format!( - "now tracking allocation of {size} bytes (alignment {align} bytes) with id {id}", + "now tracking allocation {id:?} of {size} bytes (alignment {align} bytes)", size = size.bytes(), align = align.bytes(), ), - AccessedAlloc(AllocId(id), access_kind) => - format!("{access_kind} to allocation with id {id}"), - FreedAlloc(AllocId(id)) => format!("freed allocation with id {id}"), + AccessedAlloc(id, range, access_kind) => + format!("{access_kind} at {id:?}[{}..{}]", range.start.bytes(), range.end().bytes()), + FreedAlloc(id) => format!("freed allocation {id:?}"), RejectedIsolatedOp(op) => format!("{op} was made to return an error due to isolation"), ProgressReport { .. } => format!("progress report: current operation being executed is here"), diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 4072744d175b..9c6eafbd7418 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1523,8 +1523,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { range: AllocRange, ) -> InterpResult<'tcx> { if machine.track_alloc_accesses && machine.tracked_alloc_ids.contains(&alloc_id) { - machine - .emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc(alloc_id, AccessKind::Read)); + machine.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc( + alloc_id, + range, + AccessKind::Read, + )); } // The order of checks is deliberate, to prefer reporting a data race over a borrow tracker error. match &machine.data_race { @@ -1559,8 +1562,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { range: AllocRange, ) -> InterpResult<'tcx> { if machine.track_alloc_accesses && machine.tracked_alloc_ids.contains(&alloc_id) { - machine - .emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc(alloc_id, AccessKind::Write)); + machine.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc( + alloc_id, + range, + AccessKind::Write, + )); } match &machine.data_race { GlobalDataRaceHandler::None => {} diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index 3b4dc8f5ea99..cc0cf1f277d5 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -1,4 +1,4 @@ -note: now tracking allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC +note: now tracking allocation ALLOC of 123 bytes (alignment ALIGN bytes) --> tests/pass/alloc-access-tracking.rs:LL:CC | LL | utils::miri_track_alloc(ptr); @@ -7,7 +7,7 @@ LL | utils::miri_track_alloc(ptr); = note: BACKTRACE: = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC -note: write access to allocation with id $ALLOC +note: write access at ALLOC[0..1] --> tests/pass/alloc-access-tracking.rs:LL:CC | LL | *ptr = 42; // Crucially, only a write is printed here, no read! @@ -16,7 +16,7 @@ LL | *ptr = 42; // Crucially, only a write is printed here, no read! = note: BACKTRACE: = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC -note: read access to allocation with id $ALLOC +note: read access at ALLOC[0..1] --> tests/pass/alloc-access-tracking.rs:LL:CC | LL | assert_eq!(*ptr, 42); @@ -26,7 +26,7 @@ LL | assert_eq!(*ptr, 42); = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -note: freed allocation with id $ALLOC +note: freed allocation ALLOC --> RUSTLIB/alloc/src/boxed.rs:LL:CC | LL | self.1.deallocate(From::from(ptr.cast()), layout); From 8c678cc8e01d5a5d0c38503790573e298e1ed278 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 08:24:29 +0100 Subject: [PATCH 252/525] update comment regarding disabled jobs --- src/tools/miri/.github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 3078cd35b108..27d2f4a6df30 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -31,7 +31,8 @@ jobs: os: ubuntu-24.04-arm multiarch: armhf gcc_cross: arm-linux-gnueabihf - # Disabled due to Ubuntu repo trouble + # Ubuntu mirrors are not reliable enough for these architectures + # (see ). # - host_target: riscv64gc-unknown-linux-gnu # os: ubuntu-latest # multiarch: riscv64 @@ -68,7 +69,7 @@ jobs: - name: install multiarch if: ${{ matrix.multiarch != '' }} run: | - # s390x, ppc64el, riscv64 need Ubuntu Ports to be in the mirror list + # armhf, s390x, ppc64el, riscv64 need Ubuntu Ports to be in the mirror list sudo bash -c "echo 'https://ports.ubuntu.com/ priority:4' >> /etc/apt/apt-mirrors.txt" # Add architecture sudo dpkg --add-architecture ${{ matrix.multiarch }} From 3048ef2c4b9b4110280bd3ccff53a64b9bc96ec6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 08:25:01 +0100 Subject: [PATCH 253/525] unconditionally use Duration::from_nanos_u128 --- src/tools/miri/src/clock.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/tools/miri/src/clock.rs b/src/tools/miri/src/clock.rs index dbbe741a0714..47608f873a48 100644 --- a/src/tools/miri/src/clock.rs +++ b/src/tools/miri/src/clock.rs @@ -46,21 +46,7 @@ impl Instant { InstantKind::Virtual { nanoseconds: earlier }, ) => { let duration = nanoseconds.saturating_sub(earlier); - cfg_select! { - bootstrap => { - // `Duration` does not provide a nice constructor from a `u128` of nanoseconds, - // so we have to implement this ourselves. - // It is possible for second to overflow because u64::MAX < (u128::MAX / 1e9). - // It will be saturated to u64::MAX seconds if the value after division exceeds u64::MAX. - let seconds = u64::try_from(duration / 1_000_000_000).unwrap_or(u64::MAX); - // It is impossible for nanosecond to overflow because u32::MAX > 1e9. - let nanosecond = u32::try_from(duration.wrapping_rem(1_000_000_000)).unwrap(); - Duration::new(seconds, nanosecond) - } - _ => { - Duration::from_nanos_u128(duration) - } - } + Duration::from_nanos_u128(duration) } _ => panic!("all `Instant` must be of the same kind"), } From 04eacd0e00dadcb3c7aecc83aaa4ecf18525fb5a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 07:56:56 +0100 Subject: [PATCH 254/525] document -Zmiri-backtrace; dont print backtrace when there's only one frame --- src/tools/miri/README.md | 3 ++ src/tools/miri/src/diagnostics.rs | 46 ++++++++++--------- ...ple_os_unfair_lock_assert_not_owner.stderr | 3 -- .../apple_os_unfair_lock_assert_owner.stderr | 3 -- .../apple_os_unfair_lock_move_deadlock.stderr | 3 -- .../apple_os_unfair_lock_reentrant.stderr | 3 -- .../apple_os_unfair_lock_unowned.stderr | 3 -- .../libc_pthread_cond_double_destroy.stderr | 2 - ...ibc_pthread_condattr_double_destroy.stderr | 2 - .../libc_pthread_create_too_few_args.stderr | 1 - .../libc_pthread_create_too_many_args.stderr | 1 - .../libc_pthread_join_detached.stderr | 2 - .../libc_pthread_join_joined.stderr | 2 - .../concurrency/libc_pthread_join_main.stderr | 2 - .../libc_pthread_join_multiple.stderr | 2 - .../concurrency/libc_pthread_join_self.stderr | 2 - .../libc_pthread_mutex_NULL_reentrant.stderr | 2 - .../libc_pthread_mutex_deadlock.stderr | 3 -- ...ibc_pthread_mutex_default_reentrant.stderr | 2 - .../libc_pthread_mutex_destroy_locked.stderr | 2 - .../libc_pthread_mutex_double_destroy.stderr | 2 - ...libc_pthread_mutex_normal_reentrant.stderr | 3 -- ...thread_mutex_normal_unlock_unlocked.stderr | 2 - ..._pthread_mutex_staticinit_reentrant.stderr | 2 - .../libc_pthread_mutex_wrong_owner.stderr | 2 - ...bc_pthread_mutexattr_double_destroy.stderr | 2 - ..._pthread_rwlock_destroy_read_locked.stderr | 2 - ...pthread_rwlock_destroy_write_locked.stderr | 2 - .../libc_pthread_rwlock_double_destroy.stderr | 2 - ...k_read_write_deadlock_single_thread.stderr | 3 -- ...ibc_pthread_rwlock_read_wrong_owner.stderr | 2 - ...libc_pthread_rwlock_unlock_unlocked.stderr | 2 - ..._pthread_rwlock_write_read_deadlock.stderr | 3 -- ...k_write_read_deadlock_single_thread.stderr | 3 -- ...pthread_rwlock_write_write_deadlock.stderr | 3 -- ..._write_write_deadlock_single_thread.stderr | 3 -- ...bc_pthread_rwlock_write_wrong_owner.stderr | 2 - .../libx_pthread_rwlock_moved.stderr | 2 - .../concurrency/windows_join_main.stderr | 2 - .../concurrency/windows_join_self.stderr | 3 -- .../concurrency/windows_thread_invalid.stderr | 3 -- .../miri/tests/fail-dep/libc/affinity.stderr | 2 - .../libc/aligned_alloc_size_zero_leak.stderr | 3 -- .../libc/env-set_var-data-race.stderr | 2 - .../libc/eventfd_block_read_twice.stderr | 6 +-- .../libc/eventfd_block_write_twice.stderr | 6 +-- .../libc/fcntl_fsetfl_while_blocking.stderr | 4 -- .../fail-dep/libc/fs/close_stdout.stderr | 2 - .../fail-dep/libc/fs/read_from_stdout.stderr | 2 - .../fail-dep/libc/fs/write_to_stdin.stderr | 2 - .../fail-dep/libc/libc-epoll-data-race.stderr | 2 - .../libc-read-and-uninit-premature-eof.stderr | 2 - .../libc/libc_epoll_block_two_thread.stderr | 6 +-- .../libc/libc_epoll_unsupported_fd.stderr | 2 - .../libc/malloc_zero_double_free.stderr | 2 - .../libc/malloc_zero_memory_leak.stderr | 3 -- .../tests/fail-dep/libc/memchr_null.stderr | 2 - .../tests/fail-dep/libc/memcmp_null.stderr | 2 - .../tests/fail-dep/libc/memcmp_zero.stderr | 2 - .../tests/fail-dep/libc/memcpy_zero.stderr | 2 - .../tests/fail-dep/libc/memrchr_null.stderr | 2 - .../tests/fail-dep/libc/memset_null.stderr | 2 - .../fail-dep/libc/mmap_invalid_dealloc.stderr | 2 - .../libc/mmap_use_after_munmap.stderr | 2 - .../tests/fail-dep/libc/munmap_partial.stderr | 2 - ...osix_memalign_size_zero_double_free.stderr | 2 - .../libc/posix_memalign_size_zero_leak.stderr | 3 -- .../tests/fail-dep/libc/realloc-zero.stderr | 2 - .../socketpair-close-while-blocked.stderr | 4 -- .../fail-dep/libc/socketpair-data-race.stderr | 2 - .../libc/socketpair_block_read_twice.stderr | 6 +-- .../libc/socketpair_block_write_twice.stderr | 6 +-- .../unsupported_incomplete_function.stderr | 2 - .../alloc/deallocate-bad-alignment.stderr | 2 - .../fail/alloc/deallocate-bad-size.stderr | 2 - .../tests/fail/alloc/deallocate-twice.stderr | 2 - .../fail/alloc/no_global_allocator.stderr | 2 - .../fail/alloc/reallocate-bad-size.stderr | 2 - .../fail/alloc/reallocate-change-alloc.stderr | 2 - .../fail/alloc/reallocate-dangling.stderr | 2 - .../miri/tests/fail/alloc/too_large.stderr | 2 - .../alloc/unsupported_big_alignment.stderr | 2 - ...unsupported_non_power_two_alignment.stderr | 2 - .../alias_through_mutation.stack.stderr | 2 - .../alias_through_mutation.tree.stderr | 2 - .../buggy_as_mut_slice.stack.stderr | 2 - .../buggy_as_mut_slice.tree.stderr | 2 - .../buggy_split_at_mut.tree.stderr | 2 - .../both_borrows/illegal_write1.stack.stderr | 2 - .../both_borrows/illegal_write1.tree.stderr | 2 - .../both_borrows/illegal_write5.stack.stderr | 2 - .../both_borrows/illegal_write5.tree.stderr | 2 - .../load_invalid_shr.stack.stderr | 2 - .../both_borrows/load_invalid_shr.tree.stderr | 2 - .../mut_exclusive_violation2.stack.stderr | 2 - .../mut_exclusive_violation2.tree.stderr | 2 - .../both_borrows/outdated_local.stack.stderr | 2 - .../both_borrows/outdated_local.tree.stderr | 2 - .../pass_invalid_shr.stack.stderr | 2 - .../both_borrows/pass_invalid_shr.tree.stderr | 2 - .../pass_invalid_shr_option.stack.stderr | 2 - .../pass_invalid_shr_option.tree.stderr | 2 - .../pass_invalid_shr_tuple.stack.stderr | 2 - .../pass_invalid_shr_tuple.tree.stderr | 2 - .../shr_frozen_violation2.stack.stderr | 2 - .../shr_frozen_violation2.tree.stderr | 2 - .../branchless-select-i128-pointer.stderr | 2 - src/tools/miri/tests/fail/breakpoint.stderr | 3 -- .../read_only_atomic_cmpxchg.stderr | 2 - .../read_only_atomic_load_acquire.stderr | 2 - .../read_only_atomic_load_large.stderr | 2 - .../dangling_pointer_deref.stderr | 2 - .../dangling_pointer_deref_match_never.stderr | 2 - .../dangling_pointer_offset.stderr | 2 - ...ling_pointer_project_underscore_let.stderr | 2 - ...ject_underscore_let_type_annotation.stderr | 2 - ...ng_pointer_project_underscore_match.stderr | 2 - .../dangling_primitive.stderr | 2 - .../deref-invalid-ptr.stderr | 2 - .../deref_dangling_box.stderr | 2 - .../deref_dangling_ref.stderr | 2 - .../fail/dangling_pointers/dyn_size.stderr | 2 - .../null_pointer_deref.stderr | 2 - .../null_pointer_write.stderr | 2 - .../out_of_bounds_project.stderr | 2 - .../out_of_bounds_read.stderr | 2 - .../out_of_bounds_read_neg_offset.stderr | 2 - .../out_of_bounds_write.stderr | 2 - .../dangling_pointers/stack_temporary.stderr | 2 - .../wild_pointer_deref.stderr | 2 - .../fail/data_race/alloc_read_race.stderr | 2 - .../fail/data_race/alloc_write_race.stderr | 2 - .../atomic_read_na_write_race1.stderr | 2 - .../atomic_read_na_write_race2.stderr | 2 - .../atomic_write_na_read_race1.stderr | 2 - .../atomic_write_na_read_race2.stderr | 2 - .../atomic_write_na_write_race1.stderr | 2 - .../atomic_write_na_write_race2.stderr | 2 - .../dangling_thread_async_race.stderr | 2 - .../data_race/dangling_thread_race.stderr | 2 - .../fail/data_race/dealloc_read_race1.stderr | 2 - .../fail/data_race/dealloc_read_race2.stderr | 2 - .../data_race/dealloc_read_race_stack.stderr | 2 - .../fail/data_race/dealloc_write_race1.stderr | 2 - .../fail/data_race/dealloc_write_race2.stderr | 2 - .../data_race/dealloc_write_race_stack.stderr | 2 - .../enable_after_join_to_main.stderr | 2 - .../fail/data_race/fence_after_load.stderr | 2 - .../local_variable_alloc_race.stderr | 2 - .../data_race/local_variable_read_race.stderr | 2 - .../local_variable_write_race.stderr | 2 - ...ze_read_read_write.match_first_load.stderr | 2 - ...e_read_read_write.match_second_load.stderr | 2 - .../mixed_size_read_write.read_write.stderr | 2 - .../mixed_size_read_write.write_read.stderr | 2 - .../mixed_size_write_write.fst.stderr | 2 - .../mixed_size_write_write.snd.stderr | 2 - .../fail/data_race/read_write_race.stderr | 2 - .../data_race/read_write_race_stack.stderr | 2 - .../fail/data_race/relax_acquire_race.stderr | 2 - .../fail/data_race/release_seq_race.stderr | 2 - .../release_seq_race_same_thread.stderr | 2 - .../miri/tests/fail/data_race/rmw_race.stderr | 2 - .../fail/data_race/stack_pop_race.stderr | 2 - .../fail/data_race/write_write_race.stderr | 2 - .../data_race/write_write_race_stack.stderr | 2 - .../tests/fail/dyn-call-trait-mismatch.stderr | 2 - .../fail/dyn-upcast-nop-wrong-trait.stderr | 2 - .../fail/dyn-upcast-trait-mismatch.stderr | 2 - ...m-untagged-variant-invalid-encoding.stderr | 2 - .../fail/environ-gets-deallocated.stderr | 2 - .../fail/extern-type-field-offset.stderr | 4 -- .../miri/tests/fail/extern_static.stderr | 2 - .../tests/fail/extern_static_in_const.stderr | 2 - .../fail/extern_static_wrong_size.stderr | 2 - .../arg_inplace_locals_alias.stack.stderr | 2 - .../arg_inplace_locals_alias.tree.stderr | 2 - .../arg_inplace_locals_alias_ret.stack.stderr | 2 - .../arg_inplace_locals_alias_ret.tree.stderr | 2 - .../arg_inplace_observe_after.stderr | 2 - .../fail/function_calls/check_arg_abi.stderr | 2 - .../check_arg_count_abort.stderr | 2 - .../check_arg_count_too_few_args.stderr | 2 - .../check_arg_count_too_many_args.stderr | 2 - .../function_calls/check_callback_abi.stderr | 2 - .../exported_symbol_abi_mismatch.cache.stderr | 2 - ...exported_symbol_abi_mismatch.fn_ptr.stderr | 2 - ...ported_symbol_abi_mismatch.no_cache.stderr | 2 - .../exported_symbol_bad_unwind1.stderr | 2 - ...ted_symbol_bad_unwind2.extern_block.stderr | 2 - .../exported_symbol_clashing.stderr | 2 - .../exported_symbol_shim_clashing.stderr | 2 - .../exported_symbol_wrong_arguments.stderr | 2 - .../exported_symbol_wrong_type.stderr | 2 - .../return_pointer_on_unwind.stderr | 2 - .../fail/function_calls/target_feature.stderr | 2 - .../function_calls/target_feature_wasm.stderr | 3 -- .../abi_mismatch_array_vs_struct.stderr | 2 - .../abi_mismatch_int_vs_float.stderr | 2 - .../abi_mismatch_raw_pointer.stderr | 2 - .../abi_mismatch_repr_C.stderr | 2 - .../abi_mismatch_return_type.stderr | 2 - .../abi_mismatch_simple.stderr | 2 - .../abi_mismatch_too_few_args.stderr | 2 - .../abi_mismatch_too_many_args.stderr | 2 - .../abi_mismatch_vector.stderr | 2 - .../cast_box_int_to_fn_ptr.stderr | 2 - .../cast_int_to_fn_ptr.stderr | 2 - .../function_pointers/deref_fn_ptr.stderr | 2 - .../function_pointers/execute_memory.stderr | 2 - .../function_pointers/fn_ptr_offset.stderr | 2 - .../fail/intrinsic_fallback_is_spec.stderr | 2 - .../miri/tests/fail/intrinsics/assume.stderr | 2 - .../fail/intrinsics/copy_overflow.stderr | 2 - .../fail/intrinsics/copy_overlapping.stderr | 2 - .../fail/intrinsics/copy_unaligned.stderr | 2 - .../tests/fail/intrinsics/ctlz_nonzero.stderr | 2 - .../tests/fail/intrinsics/cttz_nonzero.stderr | 2 - .../fail/intrinsics/disjoint_bitor.stderr | 2 - .../tests/fail/intrinsics/div-by-zero.stderr | 2 - .../tests/fail/intrinsics/exact_div1.stderr | 2 - .../tests/fail/intrinsics/exact_div2.stderr | 2 - .../tests/fail/intrinsics/exact_div3.stderr | 2 - .../tests/fail/intrinsics/exact_div4.stderr | 2 - .../fail/intrinsics/fast_math_both.stderr | 2 - .../fail/intrinsics/fast_math_first.stderr | 2 - .../fail/intrinsics/fast_math_result.stderr | 2 - .../fail/intrinsics/fast_math_second.stderr | 2 - .../intrinsics/float_to_int_32_inf1.stderr | 2 - .../intrinsics/float_to_int_32_infneg1.stderr | 2 - .../intrinsics/float_to_int_32_nan.stderr | 2 - .../intrinsics/float_to_int_32_nanneg.stderr | 2 - .../intrinsics/float_to_int_32_neg.stderr | 2 - .../float_to_int_32_too_big1.stderr | 2 - .../float_to_int_32_too_big2.stderr | 2 - .../float_to_int_32_too_small1.stderr | 2 - .../intrinsics/float_to_int_64_inf1.stderr | 2 - .../intrinsics/float_to_int_64_infneg1.stderr | 2 - .../intrinsics/float_to_int_64_infneg2.stderr | 2 - .../intrinsics/float_to_int_64_nan.stderr | 2 - .../intrinsics/float_to_int_64_neg.stderr | 2 - .../float_to_int_64_too_big1.stderr | 2 - .../float_to_int_64_too_big2.stderr | 2 - .../float_to_int_64_too_big3.stderr | 2 - .../float_to_int_64_too_big4.stderr | 2 - .../float_to_int_64_too_big5.stderr | 2 - .../float_to_int_64_too_big6.stderr | 2 - .../float_to_int_64_too_big7.stderr | 2 - .../float_to_int_64_too_small1.stderr | 2 - .../float_to_int_64_too_small2.stderr | 2 - .../float_to_int_64_too_small3.stderr | 2 - .../tests/fail/intrinsics/funnel_shl.stderr | 2 - .../tests/fail/intrinsics/funnel_shr.stderr | 2 - .../intrinsic_target_feature.stderr | 2 - .../ptr_metadata_uninit_slice_len.stderr | 2 - .../ptr_offset_from_different_allocs.stderr | 2 - .../ptr_offset_from_different_ints.stderr | 2 - .../intrinsics/ptr_offset_from_oob.stderr | 2 - .../ptr_offset_from_unsigned_neg.stderr | 2 - .../intrinsics/ptr_offset_int_plus_int.stderr | 2 - .../intrinsics/ptr_offset_int_plus_ptr.stderr | 2 - .../ptr_offset_out_of_bounds.stderr | 2 - .../ptr_offset_out_of_bounds_neg.stderr | 2 - .../ptr_offset_out_of_bounds_neg2.stderr | 2 - .../intrinsics/ptr_offset_overflow.stderr | 2 - .../ptr_offset_unsigned_overflow.stderr | 2 - .../tests/fail/intrinsics/rem-by-zero.stderr | 2 - .../fail/intrinsics/simd-div-by-zero.stderr | 2 - .../fail/intrinsics/simd-div-overflow.stderr | 2 - .../tests/fail/intrinsics/simd-extract.stderr | 2 - .../fail/intrinsics/simd-float-to-int.stderr | 2 - .../tests/fail/intrinsics/simd-gather.stderr | 2 - .../simd-reduce-invalid-bool.stderr | 2 - .../fail/intrinsics/simd-rem-by-zero.stderr | 2 - .../tests/fail/intrinsics/simd-scatter.stderr | 2 - .../simd-select-invalid-bool.stderr | 2 - .../fail/intrinsics/simd-shl-too-far.stderr | 2 - .../fail/intrinsics/simd-shr-too-far.stderr | 2 - .../fail/intrinsics/typed-swap-overlap.stderr | 2 - .../fail/intrinsics/unchecked_add1.stderr | 2 - .../fail/intrinsics/unchecked_add2.stderr | 2 - .../fail/intrinsics/unchecked_div1.stderr | 2 - .../fail/intrinsics/unchecked_mul1.stderr | 2 - .../fail/intrinsics/unchecked_mul2.stderr | 2 - .../fail/intrinsics/unchecked_shl.stderr | 2 - .../fail/intrinsics/unchecked_shl2.stderr | 2 - .../fail/intrinsics/unchecked_shr.stderr | 2 - .../fail/intrinsics/unchecked_sub1.stderr | 2 - .../fail/intrinsics/unchecked_sub2.stderr | 2 - .../intrinsics/uninit_uninhabited_type.stderr | 2 - .../intrinsics/write_bytes_overflow.stderr | 2 - .../tests/fail/intrinsics/zero_fn_ptr.stderr | 2 - ...ce-symbolic-alignment-extern-static.stderr | 2 - src/tools/miri/tests/fail/memleak.stderr | 3 -- .../tests/fail/modifying_constants.stderr | 2 - .../miri/tests/fail/never_match_never.stderr | 2 - .../miri/tests/fail/never_say_never.stderr | 2 - .../tests/fail/never_transmute_humans.stderr | 2 - .../overlapping_assignment_aggregate.stderr | 2 - .../fail/panic/unwind_panic_abort.stderr | 2 - .../int_copy_looses_provenance0.stderr | 2 - .../int_copy_looses_provenance1.stderr | 2 - .../int_copy_looses_provenance2.stderr | 2 - .../int_copy_looses_provenance3.stderr | 2 - .../tests/fail/provenance/mix-ptrs1.stderr | 2 - .../tests/fail/provenance/mix-ptrs2.stderr | 2 - .../pointer_partial_overwrite.stderr | 2 - .../ptr_copy_loses_partial_provenance0.stderr | 2 - .../ptr_copy_loses_partial_provenance1.stderr | 2 - .../fail/provenance/ptr_int_unexposed.stderr | 2 - .../tests/fail/provenance/ptr_invalid.stderr | 2 - .../fail/provenance/ptr_invalid_offset.stderr | 2 - .../provenance/strict_provenance_cast.stderr | 2 - src/tools/miri/tests/fail/rc_as_ptr.stderr | 2 - .../fail/read_from_trivial_switch.stderr | 2 - .../tests/fail/reading_half_a_pointer.stderr | 2 - .../shims/backtrace/bad-backtrace-decl.stderr | 2 - .../backtrace/bad-backtrace-flags.stderr | 2 - .../shims/backtrace/bad-backtrace-ptr.stderr | 2 - .../bad-backtrace-resolve-flags.stderr | 2 - .../bad-backtrace-resolve-names-flags.stderr | 2 - .../backtrace/bad-backtrace-size-flags.stderr | 2 - .../fail/shims/ctor_wrong_ret_type.stderr | 1 - .../fail/shims/input_arg_mismatch.stderr | 2 - .../non_vararg_signature_mismatch.stderr | 2 - .../fail/shims/return_type_mismatch.stderr | 2 - .../tests/fail/shims/shim_arg_size.stderr | 2 - .../vararg_caller_signature_mismatch.stderr | 2 - .../fail/shims/wrong_fixed_arg_count.stderr | 2 - .../disable_mut_does_not_merge_srw.stderr | 2 - .../stacked_borrows/exposed_only_ro.stderr | 2 - .../fnentry_invalidation.stderr | 2 - .../fnentry_invalidation2.stderr | 2 - .../stacked_borrows/illegal_dealloc1.stderr | 2 - .../fail/stacked_borrows/illegal_read1.stderr | 2 - .../fail/stacked_borrows/illegal_read2.stderr | 2 - .../fail/stacked_borrows/illegal_read3.stderr | 2 - .../fail/stacked_borrows/illegal_read4.stderr | 2 - .../fail/stacked_borrows/illegal_read5.stderr | 2 - .../fail/stacked_borrows/illegal_read6.stderr | 2 - .../fail/stacked_borrows/illegal_read7.stderr | 2 - .../fail/stacked_borrows/illegal_read8.stderr | 2 - .../illegal_read_despite_exposed1.stderr | 2 - .../illegal_read_despite_exposed2.stderr | 2 - .../stacked_borrows/illegal_write2.stderr | 2 - .../stacked_borrows/illegal_write3.stderr | 2 - .../stacked_borrows/illegal_write4.stderr | 2 - .../illegal_write_despite_exposed1.stderr | 2 - .../fail/stacked_borrows/interior_mut1.stderr | 2 - .../fail/stacked_borrows/interior_mut2.stderr | 2 - .../stacked_borrows/load_invalid_mut.stderr | 2 - .../stacked_borrows/pass_invalid_mut.stderr | 2 - .../fail/stacked_borrows/raw_tracking.stderr | 2 - .../retag_data_race_protected_read.stderr | 2 - .../shared_rw_borrows_are_weak1.stderr | 2 - .../shared_rw_borrows_are_weak2.stderr | 2 - .../static_memory_modification.stderr | 2 - .../fail/stacked_borrows/track_caller.stderr | 2 - .../transmute-is-no-escape.stderr | 2 - .../stacked_borrows/unescaped_local.stderr | 2 - .../stacked_borrows/unescaped_static.stderr | 2 - .../fail/stacked_borrows/zst_slice.stderr | 2 - .../fail/static_memory_modification1.stderr | 2 - .../fail/static_memory_modification2.stderr | 2 - .../fail/static_memory_modification3.stderr | 2 - .../tests/fail/storage-live-dead-var.stderr | 2 - .../tests/fail/storage-live-resets-var.stderr | 2 - .../tail_calls/signature-mismatch-arg.stderr | 2 - .../tests/fail/tls/tls_static_dealloc.stderr | 2 - .../miri/tests/fail/tls_static_leak.stderr | 3 -- .../tree_borrows/alternate-read-write.stderr | 2 - .../tree_borrows/cell-inside-struct.stderr | 2 - .../fail/tree_borrows/error-range.stderr | 2 - .../tree_borrows/fnentry_invalidation.stderr | 2 - .../frozen-lazy-write-to-surrounding.stderr | 2 - .../parent_read_freezes_raw_mut.stderr | 2 - .../tree_borrows/protector-write-lazy.stderr | 2 - .../reservedim_spurious_write.with.stderr | 2 - .../reservedim_spurious_write.without.stderr | 2 - .../tree_borrows/return_invalid_mut.stderr | 2 - .../miri/tests/fail/type-too-large.stderr | 3 -- .../fail/unaligned_pointers/alignment.stderr | 2 - .../atomic_unaligned.stderr | 2 - .../unaligned_pointers/dyn_alignment.stderr | 2 - .../intptrcast_alignment_check.stderr | 2 - ...romise_alignment.call_unaligned_ptr.stderr | 2 - ...romise_alignment.read_unaligned_ptr.stderr | 2 - .../promise_alignment_zero.stderr | 2 - .../unaligned_pointers/unaligned_ptr1.stderr | 2 - .../unaligned_pointers/unaligned_ptr2.stderr | 2 - .../unaligned_pointers/unaligned_ptr3.stderr | 2 - .../unaligned_pointers/unaligned_ptr4.stderr | 2 - .../unaligned_ptr_zst.stderr | 2 - .../unaligned_ref_addr_of.stderr | 2 - .../tests/fail/uninit/padding-enum.stderr | 2 - .../tests/fail/uninit/padding-pair.stderr | 2 - .../uninit/padding-struct-in-union.stderr | 2 - .../tests/fail/uninit/padding-struct.stderr | 2 - .../tests/fail/uninit/padding-union.stderr | 2 - .../tests/fail/uninit/padding-wide-ptr.stderr | 2 - .../fail/uninit/transmute-pair-uninit.stderr | 2 - .../uninit-after-aggregate-assign.stderr | 2 - .../tests/fail/uninit/uninit_byte_read.stderr | 2 - src/tools/miri/tests/fail/unreachable.stderr | 2 - .../fail/unsupported_foreign_function.stderr | 2 - .../box-custom-alloc-dangling-ptr.stderr | 2 - .../box-custom-alloc-invalid-alloc.stderr | 2 - .../cast_fn_ptr_invalid_callee_arg.stderr | 2 - .../cast_fn_ptr_invalid_callee_ret.stderr | 2 - .../cast_fn_ptr_invalid_caller_ret.stderr | 2 - .../tests/fail/validity/dangling_ref1.stderr | 2 - .../tests/fail/validity/dangling_ref2.stderr | 2 - .../tests/fail/validity/dangling_ref3.stderr | 2 - .../dyn-transmute-inner-binder.stderr | 2 - .../tests/fail/validity/invalid_bool.stderr | 2 - .../fail/validity/invalid_bool_op.stderr | 2 - .../fail/validity/invalid_bool_uninit.stderr | 2 - .../tests/fail/validity/invalid_char.stderr | 2 - .../fail/validity/invalid_char_op.stderr | 2 - .../fail/validity/invalid_char_uninit.stderr | 2 - .../fail/validity/invalid_enum_op.stderr | 2 - .../fail/validity/invalid_enum_tag.stderr | 2 - .../fail/validity/invalid_fnptr_null.stderr | 2 - .../fail/validity/invalid_fnptr_uninit.stderr | 2 - .../tests/fail/validity/invalid_int_op.stderr | 2 - .../fail/validity/invalid_wide_raw.stderr | 2 - .../match_binder_checks_validity1.stderr | 2 - .../match_binder_checks_validity2.stderr | 2 - .../miri/tests/fail/validity/nonzero.stderr | 2 - .../recursive-validity-ref-bool.stderr | 2 - .../fail/validity/ref_to_uninhabited1.stderr | 2 - .../fail/validity/ref_to_uninhabited2.stderr | 2 - .../tests/fail/validity/too-big-slice.stderr | 2 - .../fail/validity/too-big-unsized.stderr | 2 - .../validity/transmute_through_ptr.stderr | 2 - .../tests/fail/validity/uninit_float.stderr | 2 - .../tests/fail/validity/uninit_integer.stderr | 2 - .../tests/fail/validity/uninit_raw_ptr.stderr | 2 - .../wrong-dyn-trait-assoc-type.stderr | 2 - .../validity/wrong-dyn-trait-generic.stderr | 2 - .../fail/validity/wrong-dyn-trait.stderr | 2 - .../tests/fail/weak_memory/weak_uninit.stderr | 2 - .../miri/tests/fail/zst_local_oob.stderr | 2 - .../atomic_ptr_invalid_provenance.make.stderr | 2 - .../atomic_ptr_invalid_provenance.send.stderr | 2 - .../tests/genmc/fail/loom/buggy_inc.stderr | 3 -- .../fail/loom/store_buffering.genmc.stderr | 3 -- .../loom/store_buffering.non_genmc.stderr | 3 -- .../fail/simple/2w2w_weak.relaxed4.stderr | 3 -- .../fail/simple/2w2w_weak.release4.stderr | 3 -- .../fail/simple/2w2w_weak.sc3_rel1.stderr | 3 -- .../native-lib/fail/function_not_in_so.stderr | 2 - .../fail/pass_struct_expose_only_range.stderr | 4 -- .../native-lib/fail/private_function.stderr | 2 - .../fail/struct_not_extern_c.stderr | 2 - .../native-lib/fail/uninit_struct.stderr | 2 - .../miri/tests/pass/alloc-access-tracking.rs | 1 - .../tests/pass/alloc-access-tracking.stderr | 8 ---- .../miri/tests/pass/extern_types.stack.stderr | 2 - .../stacked_borrows/issue-miri-2389.stderr | 2 - 460 files changed, 32 insertions(+), 991 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 1889565cc5b6..0cbfe0e96a3f 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -292,6 +292,9 @@ Try running `cargo miri clean`. Miri adds its own set of `-Z` flags, which are usually set via the `MIRIFLAGS` environment variable. We first document the most relevant and most commonly used flags: +* `-Zmiri-backtrace=<0|1|full>` configures how Miri prints backtraces: `1` is the default, + where backtraces are printed in pruned form; `full` prints backtraces without pruning, and `0` + disables backtraces entirely. * `-Zmiri-deterministic-concurrency` makes Miri's concurrency-related behavior fully deterministic. Strictly speaking, Miri is always fully deterministic when isolation is enabled (the default mode), but this determinism is achieved by using an RNG with a fixed seed. Seemingly harmless diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index fdbbf9a07698..0acdfdd3ffe5 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -604,28 +604,30 @@ pub fn report_msg<'tcx>( } // Add backtrace - let mut backtrace_title = String::from("BACKTRACE"); - if extra_span { - write!(backtrace_title, " (of the first span)").unwrap(); - } - if let Some(thread) = thread { - let thread_name = machine.threads.get_thread_display_name(thread); - if thread_name != "main" { - // Only print thread name if it is not `main`. - write!(backtrace_title, " on thread `{thread_name}`").unwrap(); - }; - } - write!(backtrace_title, ":").unwrap(); - err.note(backtrace_title); - for (idx, frame_info) in stacktrace.iter().enumerate() { - let is_local = machine.is_local(frame_info); - // No span for non-local frames and the first frame (which is the error site). - if is_local && idx > 0 { - err.subdiagnostic(frame_info.as_note(machine.tcx)); - } else { - let sm = sess.source_map(); - let span = sm.span_to_embeddable_string(frame_info.span); - err.note(format!("{frame_info} at {span}")); + if stacktrace.len() > 1 { + let mut backtrace_title = String::from("BACKTRACE"); + if extra_span { + write!(backtrace_title, " (of the first span)").unwrap(); + } + if let Some(thread) = thread { + let thread_name = machine.threads.get_thread_display_name(thread); + if thread_name != "main" { + // Only print thread name if it is not `main`. + write!(backtrace_title, " on thread `{thread_name}`").unwrap(); + }; + } + write!(backtrace_title, ":").unwrap(); + err.note(backtrace_title); + for (idx, frame_info) in stacktrace.iter().enumerate() { + let is_local = machine.is_local(frame_info); + // No span for non-local frames and the first frame (which is the error site). + if is_local && idx > 0 { + err.subdiagnostic(frame_info.as_note(machine.tcx)); + } else { + let sm = sess.source_map(); + let span = sm.span_to_embeddable_string(frame_info.span); + err.note(format!("{frame_info} at {span}")); + } } } diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_not_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_not_owner.stderr index 27bee79177ed..46d0dd348d73 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_not_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_not_owner.stderr @@ -3,9 +3,6 @@ error: abnormal termination: called os_unfair_lock_assert_not_owner on an os_unf | LL | libc::os_unfair_lock_assert_not_owner(lock.get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/apple_os_unfair_lock_assert_not_owner.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_owner.stderr index be53ee61c4cf..7670551f8515 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_assert_owner.stderr @@ -3,9 +3,6 @@ error: abnormal termination: called os_unfair_lock_assert_owner on an os_unfair_ | LL | libc::os_unfair_lock_assert_owner(lock.get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/apple_os_unfair_lock_assert_owner.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_deadlock.stderr index d00da6d6d9f0..8e7364226ecc 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_deadlock.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | unsafe { libc::os_unfair_lock_lock(lock.get()) }; | ^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/apple_os_unfair_lock_move_deadlock.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_reentrant.stderr index 08696a9b261e..18d54360b065 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_reentrant.stderr @@ -3,9 +3,6 @@ error: abnormal termination: attempted to lock an os_unfair_lock that is already | LL | libc::os_unfair_lock_lock(lock.get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/apple_os_unfair_lock_reentrant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_unowned.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_unowned.stderr index aaeb73176bff..c69928b07258 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_unowned.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_unowned.stderr @@ -3,9 +3,6 @@ error: abnormal termination: attempted to unlock an os_unfair_lock not owned by | LL | libc::os_unfair_lock_unlock(lock.get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/apple_os_unfair_lock_unowned.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr index 6156070cf955..5c5d593ad0eb 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_cond_destroy(cond.as_mut_ptr()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr index da64970ff2e2..e34de5af167d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_condattr_destroy(attr.as_mut_ptr()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr index 4fa8a430c518..4d5a80c828cd 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr @@ -4,7 +4,6 @@ error: Undefined Behavior: calling a function with more arguments than it expect = note: (no span available) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr index d28cba140fbb..1bc79411197c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr @@ -4,7 +4,6 @@ error: Undefined Behavior: calling a function with fewer arguments than it requi = note: (no span available) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr index ffae90db2f96..618584a117e4 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_join_detached.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr index e22f4dadf3f6..a9f16a96adc2 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_join_joined.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr index 978a9bdac94d..46c9c5d3d714 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr index a73dc20360ac..8a16f82a9307 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr index e3082935c34e..dec0139bd89a 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_reentrant.stderr index 961c541c70ab..0e1caafd2956 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_reentrant.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_lock(&mut mutex as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_NULL_reentrant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr index c7c1a769cdaa..582c6f11e360 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_reentrant.stderr index 743bb1af65c1..2bf22210bf32 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_reentrant.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_lock(&mut mutex as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_default_reentrant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr index c4dce0ccc821..e6f58c88b9bb 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_destroy(&mut mutex as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr index 05db823b252b..36e6a5e44cf5 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_destroy(mutex.as_mut_ptr()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr index fa0c26f987e6..c611d0ff7b00 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | libc::pthread_mutex_lock(&mut mutex as *mut _); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr index 7db3885d3d1c..21bead1b9a91 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_unlock(&mut mutex as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_staticinit_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_staticinit_reentrant.stderr index 677955fe14d1..edbb73c43904 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_staticinit_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_staticinit_reentrant.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutex_lock(&mut mutex as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutex_staticinit_reentrant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr index 4a70e16f37f0..c7d858a444cc 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr index ee3883de36ba..73e2585deffc 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr index 163d54a02f4d..5a1f8913b897 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_rwlock_destroy(rw.get()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr index cc263552024a..6cd47ae1bae2 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_rwlock_destroy(rw.get()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr index 430398dc8fd7..f642481a683c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_rwlock_destroy(&mut lock); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr index c88d08de5556..763a52963a4d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | libc::pthread_rwlock_wrlock(rw.get()); | ^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr index 85d8e0e8572e..f1f5c50baf47 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr index fc7bd8991e69..2fdc04b72779 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_rwlock_unlock(rw.get()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr index ae8b2b936a71..d8d0ff37e410 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr index d7d9a2d3686b..4c8d3fddb97c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | libc::pthread_rwlock_rdlock(rw.get()); | ^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr index dfa9a6e25831..c9a4004ebfb3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr index 846f1e73d080..e6a4b2814d83 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | libc::pthread_rwlock_wrlock(rw.get()); | ^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr index 8161b0e72eb5..fdf4297c56ae 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr @@ -6,8 +6,6 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr index 77d99ed6b0f2..e69da4de99dd 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr @@ -6,8 +6,6 @@ LL | libc::pthread_rwlock_unlock(&mut rw2 as *mut _); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr index 3b1181c92fd9..93f800ecca33 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr @@ -4,8 +4,6 @@ error: the evaluated program deadlocked LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: the evaluated program deadlocked diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr index 6eefa2da1d81..c76da9151b35 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr @@ -3,9 +3,6 @@ error: the evaluated program deadlocked | LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/concurrency/windows_join_self.rs:LL:CC error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_thread_invalid.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_thread_invalid.stderr index 8d4b049b7402..cc950c9cd0f6 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_thread_invalid.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_thread_invalid.stderr @@ -3,9 +3,6 @@ error: abnormal termination: invalid handle 1 passed to GetThreadId | LL | let _tid = unsafe { GetThreadId(std::ptr::dangling_mut()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/concurrency/windows_thread_invalid.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/affinity.stderr b/src/tools/miri/tests/fail-dep/libc/affinity.stderr index e0b3bf16601b..bc13f0698360 100644 --- a/src/tools/miri/tests/fail-dep/libc/affinity.stderr +++ b/src/tools/miri/tests/fail-dep/libc/affinity.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; | ^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/affinity.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr b/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr index bde7f5b515e3..05b8b1290fd5 100644 --- a/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr @@ -3,9 +3,6 @@ error: memory leaked: ALLOC (C heap, size: 0, align: 2), allocated here: | LL | aligned_alloc(2, 0); | ^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/aligned_alloc_size_zero_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr index 7db2338cc874..2b10a322b0be 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr @@ -11,8 +11,6 @@ LL | env::set_var("MY_RUST_VAR", "Ferris"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/env-set_var-data-race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr index 6dd6c36ab656..4730045cfe33 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -18,22 +18,18 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC | LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr index 3154197b95ed..c0e38df98d48 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -18,22 +18,18 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC | LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr index 41cfe78540aa..e451fdb9d19f 100644 --- a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr @@ -2,16 +2,12 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs:LL:CC | LL | let _res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; | ^ this thread got stuck here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr index add7812c450d..84973ac020de 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr @@ -5,8 +5,6 @@ LL | libc::close(1); | ^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/fs/close_stdout.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr index 69dc59cd66d2..525df1099f77 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr @@ -5,8 +5,6 @@ LL | libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/fs/read_from_stdout.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr index 72f2c0e86622..9aea7fffc465 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr @@ -5,8 +5,6 @@ LL | libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/fs/write_to_stdin.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr index ae1d6887cb3c..a322de74b510 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr @@ -11,8 +11,6 @@ LL | unsafe { VAL_TWO = 51 }; | ^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/libc-epoll-data-race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr index 83119f087ff2..9d5e119d1c37 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr @@ -6,8 +6,6 @@ LL | buf.assume_init(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr index 1af44c107ff8..c3cd04c0b5e6 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -2,7 +2,6 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -25,15 +24,12 @@ error: the evaluated program deadlocked | LL | check_epoll_wait::(epfd, &[(expected_event, expected_value)], -1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_unsupported_fd.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_unsupported_fd.stderr index 2f02372472e0..321c39937179 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_unsupported_fd.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_unsupported_fd.stderr @@ -5,8 +5,6 @@ LL | let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, epfd1, & | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/libc_epoll_unsupported_fd.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/malloc_zero_double_free.stderr b/src/tools/miri/tests/fail-dep/libc/malloc_zero_double_free.stderr index 4895771acbe4..ea859947cfc9 100644 --- a/src/tools/miri/tests/fail-dep/libc/malloc_zero_double_free.stderr +++ b/src/tools/miri/tests/fail-dep/libc/malloc_zero_double_free.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | libc::free(ptr); | ^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/malloc_zero_double_free.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr b/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr index 6f3d7fa7a4f2..5da35fa4769d 100644 --- a/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr @@ -3,9 +3,6 @@ error: memory leaked: ALLOC (C heap, size: 0, align: 1), allocated here: | LL | let _ptr = libc::malloc(0); | ^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/malloc_zero_memory_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr b/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr index e6fd37880331..7dcaf30871e2 100644 --- a/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr @@ -6,8 +6,6 @@ LL | libc::memchr(ptr::null(), 0, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memchr_null.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr b/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr index a80dec23c3ac..5b212fc51e4e 100644 --- a/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr @@ -6,8 +6,6 @@ LL | libc::memcmp(ptr::null(), ptr::null(), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memcmp_null.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr index 8b114703b33e..286e6e71c4f8 100644 --- a/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr @@ -6,8 +6,6 @@ LL | libc::memcmp(ptr.cast(), ptr.cast(), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memcmp_zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr index 4c95e47fd226..3c85a0171b53 100644 --- a/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr @@ -6,8 +6,6 @@ LL | libc::memcpy(to.cast(), from.cast(), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memcpy_zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr b/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr index 1a1626814206..06523d9a5312 100644 --- a/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr @@ -6,8 +6,6 @@ LL | libc::memrchr(ptr::null(), 0, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memrchr_null.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/memset_null.stderr b/src/tools/miri/tests/fail-dep/libc/memset_null.stderr index fdc8f3a29f94..943e9694d7f7 100644 --- a/src/tools/miri/tests/fail-dep/libc/memset_null.stderr +++ b/src/tools/miri/tests/fail-dep/libc/memset_null.stderr @@ -6,8 +6,6 @@ LL | libc::memset(ptr::null_mut(), 0, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/memset_null.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr index ed9e5ebc29e7..77615c14c62f 100644 --- a/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr +++ b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr @@ -6,8 +6,6 @@ LL | libc::free(ptr); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/mmap_invalid_dealloc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr index f25e74477a52..e8569c9ea218 100644 --- a/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr +++ b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr @@ -23,8 +23,6 @@ help: ALLOC was deallocated here: | LL | libc::munmap(ptr, 4096); | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/mmap_use_after_munmap.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr b/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr index e1caf4a2dce5..84e648813167 100644 --- a/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr +++ b/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr @@ -6,8 +6,6 @@ LL | libc::munmap(ptr, 1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/munmap_partial.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr index 9e3b861998a4..4af41429adb8 100644 --- a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr +++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | libc::free(ptr); | ^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr index 4546185b13e4..699e54ba0d37 100644 --- a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr @@ -3,9 +3,6 @@ error: memory leaked: ALLOC (C heap, size: 0, align: 64), allocated here: | LL | let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/posix_memalign_size_zero_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr b/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr index 459645511467..07fdfd69207d 100644 --- a/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr +++ b/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr @@ -6,8 +6,6 @@ LL | let p2 = libc::realloc(p1, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/realloc-zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr index b85470225c69..ac2346f6062f 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr @@ -19,15 +19,11 @@ error: the evaluated program deadlocked | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr index 7fb08fe6f102..7cee4b83ba90 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr @@ -11,8 +11,6 @@ LL | unsafe { VAL = 1 }; | ^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/socketpair-data-race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr index bbd2ab1c4d8d..c599432ff13c 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -18,22 +18,18 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr index c3cc20681731..2230d99fc665 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -18,22 +18,18 @@ error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC | LL | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; | ^ this thread got stuck here - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC error: the evaluated program deadlocked | = note: this thread got stuck here = note: (no span available) - = note: BACKTRACE on thread `unnamed-ID`: + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr index 161cb383cf78..f8e8f5b46d38 100644 --- a/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr +++ b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr @@ -5,8 +5,6 @@ LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this means the program tried to do something Miri does not support; it does not indicate a bug in the program - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/unsupported_incomplete_function.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr index 11e1eaa38521..6daed4fdb656 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr @@ -6,8 +6,6 @@ LL | dealloc(x, Layout::from_size_align_unchecked(1, 2)); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/deallocate-bad-alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr index 5e0e2f2da44d..840dcc911ce9 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr @@ -6,8 +6,6 @@ LL | dealloc(x, Layout::from_size_align_unchecked(2, 1)); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/deallocate-bad-size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr index 715fe7b0f601..389c8ca32d18 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/alloc/deallocate-twice.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr index b2b688e0c9eb..75f62654cd46 100644 --- a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr +++ b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr @@ -5,8 +5,6 @@ LL | __rust_alloc(1, 1); | ^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this means the program tried to do something Miri does not support; it does not indicate a bug in the program - = note: BACKTRACE: - = note: inside `miri_start` at tests/fail/alloc/no_global_allocator.rs:LL:CC error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr index 639ed069f08b..870f62e53387 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr @@ -6,8 +6,6 @@ LL | ... let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/reallocate-bad-size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr index 16e6a5b5b090..c4d2835a5466 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | let _y = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/alloc/reallocate-change-alloc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr index e30a02ef9d76..8d94dfa1dabc 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/alloc/reallocate-dangling.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/too_large.stderr b/src/tools/miri/tests/fail/alloc/too_large.stderr index dcfaeb737a80..14fad06fc06d 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.stderr +++ b/src/tools/miri/tests/fail/alloc/too_large.stderr @@ -6,8 +6,6 @@ LL | __rust_alloc(bytes, 1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/too_large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr index 6c7ee17df35d..11d2a855ef71 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr @@ -5,8 +5,6 @@ LL | __rust_alloc(1, 1 << 30); | ^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/unsupported_big_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr index a0f853a42914..827d498e7ec9 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr @@ -6,8 +6,6 @@ LL | __rust_alloc(1, 3); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/unsupported_non_power_two_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr index 70301db0fbb5..e0fbe02edc2d 100644 --- a/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *target = 13; | ^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/alias_through_mutation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr index 95b7e99dedc7..0a24a1ef3982 100644 --- a/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *target = 13; | ^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/alias_through_mutation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr index 2e394297b0c5..b1a61b079b34 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0xc] by a Unique retag | LL | unsafe { from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr index 6588bc25df13..2537c0f94500 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | v1[1] = 5; | ^^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr index 6ef27515fcd0..45b306e8108e 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | a[1] = 5; | ^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr index 55046dbbe67c..ec25e1526008 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr @@ -11,8 +11,6 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x4] | LL | let x: *mut u32 = xref as *const _ as *mut _; | ^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/illegal_write1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr index 4ffc7a75e66d..6522ca9f02fa 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr @@ -12,8 +12,6 @@ help: the accessed tag was created here, in the initial state Frozen | LL | let xref = &*target; | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/illegal_write1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr index 4e39d9c083b6..01768cc8ae7a 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | unsafe { *xraw = 15 }; | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/illegal_write5.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr index fc5b12da70e7..4c2cb7d2f25a 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = 15 }; | ^^^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/illegal_write5.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr index e7915d93a263..31fa9767512e 100644 --- a/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/load_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr index e4bde2f7aeab..468b5ca6091b 100644 --- a/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/load_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr index 21690d6c4c28..7731a30902c4 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | let raw2 = ptr2.as_mut(); | ^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/mut_exclusive_violation2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr index c1b0821a9fee..d3198a38ba85 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *raw2 = 2; | ^^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/mut_exclusive_violation2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr b/src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr index 8c1de1a38f08..b929a9b15998 100644 --- a/src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/outdated_local.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr b/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr index 5310f8b9d099..745ff2f3b6c3 100644 --- a/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local | ^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/outdated_local.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr index 712764d25ee6..3fb56ff9d4a5 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr index 3c813d35031b..789f31159e66 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr index 5845f6d50778..c5b8de9563c3 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr @@ -19,8 +19,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr_option.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr index 4747c65ba835..2e672034dd8a 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = 42 }; // unfreeze | ^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr_option.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr index 41842daa947b..fd5ca73a7afd 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr @@ -19,8 +19,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | unsafe { *xraw0 = 42 }; // unfreeze | ^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr_tuple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr index da011cfd3f74..6d9dce948c15 100644 --- a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw0 = 42 }; // unfreeze | ^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/pass_invalid_shr_tuple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr index 39a21e60a1b5..5610cd6a7a46 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | x = 1; | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/shr_frozen_violation2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr index c680c04137bc..29739c571293 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | x = 1; | ^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/both_borrows/shr_frozen_violation2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr b/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr index 3f44ef789e95..abcaf90a1ec3 100644 --- a/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr +++ b/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr @@ -10,8 +10,6 @@ LL | | ) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/branchless-select-i128-pointer.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/breakpoint.stderr b/src/tools/miri/tests/fail/breakpoint.stderr index 1963e9c9ec14..9f3414740d6a 100644 --- a/src/tools/miri/tests/fail/breakpoint.stderr +++ b/src/tools/miri/tests/fail/breakpoint.stderr @@ -3,9 +3,6 @@ error: abnormal termination: trace/breakpoint trap | LL | core::intrinsics::breakpoint(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail/breakpoint.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr b/src/tools/miri/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr index 9010033ca70f..dc56a7b3ca02 100644 --- a/src/tools/miri/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr +++ b/src/tools/miri/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr @@ -7,8 +7,6 @@ LL | x.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed).unwrap_e | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/concurrency/read_only_atomic_cmpxchg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_acquire.stderr b/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_acquire.stderr index b9e492f89be7..dde706800259 100644 --- a/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_acquire.stderr +++ b/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_acquire.stderr @@ -8,8 +8,6 @@ LL | x.load(Ordering::Acquire); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/concurrency/read_only_atomic_load_acquire.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_large.stderr b/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_large.stderr index 1fcc88f87356..f782733761ae 100644 --- a/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_large.stderr +++ b/src/tools/miri/tests/fail/concurrency/read_only_atomic_load_large.stderr @@ -8,8 +8,6 @@ LL | x.load(Ordering::Relaxed); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/concurrency/read_only_atomic_load_large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr index 7ddb5be54251..c34783773e2e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_deref.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr index 735e90328d7d..24d7df226c0a 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr @@ -6,8 +6,6 @@ LL | match *p {} | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_deref_match_never.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr index 2b34001ddf3c..99b1cb2da233 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_offset.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let.stderr index 04ac535448b4..e8dfc7dee062 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_project_underscore_let.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let_type_annotation.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let_type_annotation.stderr index cd44f728bf62..842244c0a259 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let_type_annotation.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_let_type_annotation.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_project_underscore_let_type_annotation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_match.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_match.stderr index c49e663fd422..1236c1b54d45 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_match.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore_match.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/dangling_pointer_project_underscore_match.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr index d89f79ec1d56..354cb882fd9f 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | }; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/std/src/macros.rs:LL:CC = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr index 228c259d675d..21808abc5a42 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr @@ -6,8 +6,6 @@ LL | let _y = unsafe { &*x as *const u32 }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/deref-invalid-ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr index 8c84975a7032..0ae38c3b326f 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { addr_of_mut!(**outer) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr index 8458a35ef217..c10dc19f3626 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { addr_of_mut!(**outer) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr index 5ea0d022c3d7..74102f7e1b5e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr @@ -6,8 +6,6 @@ LL | let _ptr = unsafe { &*ptr }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/dyn_size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr index d46d2c33122a..ce373668d161 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr @@ -6,8 +6,6 @@ LL | let x: i32 = unsafe { *std::ptr::null() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/null_pointer_deref.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr index bb12031a3f2b..b4097cc808c9 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr @@ -6,8 +6,6 @@ LL | unsafe { *std::ptr::null_mut() = 0i32 }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/null_pointer_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr index bd531c94dd0f..80de6e152f09 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v = 0u32; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: this error originates in the macro `addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr index df83190c29fa..b957056ad36e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v: Vec = vec![1, 2]; | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/out_of_bounds_read.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read_neg_offset.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read_neg_offset.stderr index 5c37caa1ebf0..6cae87b759ee 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read_neg_offset.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read_neg_offset.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v: Vec = vec![1, 2]; | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/out_of_bounds_read_neg_offset.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr index 5c0485a848d3..13e83e4696cf 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let mut v: Vec = vec![1, 2]; | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/out_of_bounds_write.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr index 79cb8e9f8faa..3faff2248e40 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | let x = make_ref(&mut 0); // The temporary storing "0" is deallocated at the ";"! | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/dangling_pointers/stack_temporary.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr index 8a8dd9b8f425..6caa4f376d8a 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr @@ -6,8 +6,6 @@ LL | let x = unsafe { *p }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dangling_pointers/wild_pointer_deref.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr index 5e4a09dd0d08..d4933db2ed57 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr @@ -11,8 +11,6 @@ LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relax | ^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/alloc_read_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr index 69bfc33f3779..da7f5ed869db 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr @@ -11,8 +11,6 @@ LL | .store(Box::into_raw(Box::::new_uninit()) as *mut us | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/alloc_write_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr index 0da4914d4110..203e6a10e497 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr @@ -11,8 +11,6 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_read_na_write_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr index a30d3f749065..791dc71f9930 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr @@ -11,8 +11,6 @@ LL | atomic_ref.load(Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_read_na_write_race2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr index dad28c38c179..73d963875fb1 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr @@ -11,8 +11,6 @@ LL | atomic_ref.store(32, Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_write_na_read_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr index b2b121b3188d..066fff5e3d36 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr @@ -11,8 +11,6 @@ LL | let _val = *(c.0 as *mut usize); | ^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_write_na_read_race2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr index 2a115cb51d69..10b7d8398d9d 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr @@ -11,8 +11,6 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_write_na_write_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr index 54ad60cad1bc..bb854bc4235c 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr @@ -11,8 +11,6 @@ LL | atomic_ref.store(64, Ordering::SeqCst); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/atomic_write_na_write_race2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr index 0d026dddf815..8cecfbee9d95 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 32; | ^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dangling_thread_async_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr index 1c4e03a32575..7260776043ea 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 32; | ^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/data_race/dangling_thread_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr index 006946f3f508..c4200ea96153 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr @@ -16,8 +16,6 @@ LL | let _val = *ptr.0; | ^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_read_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr index 30d1fbbf6d82..5ab5c9655d78 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr @@ -20,8 +20,6 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ) | |_____________^ - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_read_race2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr index f80e36d4b8fb..b52e48827b4b 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr @@ -11,8 +11,6 @@ LL | *pointer.load(Ordering::Acquire) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_read_race_stack.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr index 41482e4941c1..0a574068d4e7 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr @@ -16,8 +16,6 @@ LL | *ptr.0 = 2; | ^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_write_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr index 8a337dbc77c2..9fbae21eb891 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr @@ -20,8 +20,6 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ); | |_____________^ - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_write_race2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr index e6ebd5b6278e..0c853ccb8cc1 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr @@ -11,8 +11,6 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_write_race_stack.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr index c6db02fa5ae7..a8eee1241b65 100644 --- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr +++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 32; | ^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/enable_after_join_to_main.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/fence_after_load.stderr b/src/tools/miri/tests/fail/data_race/fence_after_load.stderr index 890bacd58d4d..bf2ac30a1e3f 100644 --- a/src/tools/miri/tests/fail/data_race/fence_after_load.stderr +++ b/src/tools/miri/tests/fail/data_race/fence_after_load.stderr @@ -11,8 +11,6 @@ LL | unsafe { V = 1 } | ^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/data_race/fence_after_load.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr index ea2bf3fc9f2f..52bd7721ef22 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr @@ -11,8 +11,6 @@ LL | StorageLive(val); | ^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/local_variable_alloc_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr index 215842d1815c..969b6faadbe1 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr @@ -11,8 +11,6 @@ LL | let _val = val; | ^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/local_variable_read_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr index ce0c22561dad..0bf7dd28c0f9 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr @@ -11,8 +11,6 @@ LL | let mut val: u8 = 0; | ^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/local_variable_write_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr index ba714868d013..087f326053b5 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr @@ -13,8 +13,6 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr index 13749cc349ef..66aee703e4f3 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr @@ -13,8 +13,6 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr index 11c66554fae7..967fd45c5b36 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr @@ -13,8 +13,6 @@ LL | a8[0].load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_read_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr index 4fa08032f44d..7664c3f13e3d 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr @@ -13,8 +13,6 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_read_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr index 26eddd3f193f..7e30cf6856de 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr @@ -13,8 +13,6 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_write_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr index e0ca01456064..74bb72b986af 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr @@ -13,8 +13,6 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_write_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.stderr b/src/tools/miri/tests/fail/data_race/read_write_race.stderr index c0754f6db4c5..ce063d8c532f 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race.stderr @@ -11,8 +11,6 @@ LL | let _val = *c.0; | ^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/read_write_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr index 3f6b042de568..5ac78a2ecf6b 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr @@ -11,8 +11,6 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/read_write_race_stack.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr index fdd8971f6075..fffde0370a2a 100644 --- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr +++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 1; | ^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/relax_acquire_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr index 2ee859dc45c6..61f5501434b8 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 1; | ^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/release_seq_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr index 74b844689138..2c28ee03e786 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 1; | ^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/release_seq_race_same_thread.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.stderr b/src/tools/miri/tests/fail/data_race/rmw_race.stderr index a9a97a3a3e79..04621ff07b81 100644 --- a/src/tools/miri/tests/fail/data_race/rmw_race.stderr +++ b/src/tools/miri/tests/fail/data_race/rmw_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 1; | ^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/rmw_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr index 3ba949bf9678..130a31ebeef0 100644 --- a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr +++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr @@ -11,8 +11,6 @@ LL | let _val = unsafe { *ptr.0 }; | ^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/data_race/stack_pop_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.stderr b/src/tools/miri/tests/fail/data_race/write_write_race.stderr index 314ea608190a..03bee0060a4e 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race.stderr @@ -11,8 +11,6 @@ LL | *c.0 = 32; | ^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/write_write_race.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr index 71334019f6b7..cb2faf4ac274 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr @@ -11,8 +11,6 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/write_write_race_stack.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.stderr b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.stderr index 3cb917d39fdc..ce686cce27a5 100644 --- a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.stderr +++ b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.stderr @@ -6,8 +6,6 @@ LL | r2.method2(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dyn-call-trait-mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr b/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr index bf7fc7ed8a26..65ad97f4911b 100644 --- a/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr +++ b/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr @@ -6,8 +6,6 @@ LL | let ptr: *const (dyn fmt::Debug + Send + Sync) = unsafe { std::mem::tra | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dyn-upcast-nop-wrong-trait.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr index f5e72e6ee0f8..ecc99f405ab1 100644 --- a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr +++ b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr @@ -6,8 +6,6 @@ LL | let _err = baz_fake as *const dyn Foo; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/dyn-upcast-trait-mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr index 2099041c6ce1..e019a350ba17 100644 --- a/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr +++ b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr @@ -6,8 +6,6 @@ LL | assert!(matches!(invalid, Foo::Var2(_))); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/enum-untagged-variant-invalid-encoding.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr index fcc5a8d2c804..7bcb09bf5f21 100644 --- a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr +++ b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr @@ -6,8 +6,6 @@ LL | let _y = unsafe { *pointer }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/environ-gets-deallocated.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr index 90f104ec298d..187f14faf408 100644 --- a/src/tools/miri/tests/fail/extern-type-field-offset.stderr +++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr @@ -6,8 +6,6 @@ LL | let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; | = help: `extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code = help: try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead - = note: BACKTRACE: - = note: inside `main` at tests/fail/extern-type-field-offset.rs:LL:CC error: unsupported operation: `extern type` field does not have a known offset --> tests/fail/extern-type-field-offset.rs:LL:CC @@ -16,8 +14,6 @@ LL | let _field = &x.a; | ^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/extern-type-field-offset.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/extern_static.stderr b/src/tools/miri/tests/fail/extern_static.stderr index 5bc835cfcc0d..e4c51c0345d4 100644 --- a/src/tools/miri/tests/fail/extern_static.stderr +++ b/src/tools/miri/tests/fail/extern_static.stderr @@ -5,8 +5,6 @@ LL | let _val = std::ptr::addr_of!(FOO); | ^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/extern_static.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/extern_static_in_const.stderr b/src/tools/miri/tests/fail/extern_static_in_const.stderr index deca69060ac1..f0f0966ea8af 100644 --- a/src/tools/miri/tests/fail/extern_static_in_const.stderr +++ b/src/tools/miri/tests/fail/extern_static_in_const.stderr @@ -5,8 +5,6 @@ LL | let _val = X; | ^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/extern_static_in_const.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr index fce4ff9ad1f1..0862f9779287 100644 --- a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr +++ b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr @@ -5,8 +5,6 @@ LL | let _val = unsafe { environ }; | ^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/extern_static_wrong_size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr index 0c1100cae63d..a86c68cebd23 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr @@ -16,8 +16,6 @@ help: is this argument | LL | y.0 = 0; | ^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr index 2d9ce2aa1fb6..d62adeeb8420 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr @@ -25,8 +25,6 @@ help: the protected tag later transitioned to Unique due to a child write LL | y.0 = 0; | ^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr index fcd5b8752e7d..491d01cf4284 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr @@ -16,8 +16,6 @@ help: is this argument | LL | x | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr index 42e391b5daf0..3c1038d364bb 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr @@ -25,8 +25,6 @@ help: the protected tag later transitioned to Unique due to a child write LL | x | ^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr index 3252368ea6de..f41b6cf55882 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr @@ -6,8 +6,6 @@ LL | _observe = non_copy.0; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/arg_inplace_observe_after.rs:LL:CC Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: ALLOC (stack variable, size: 4, align: 4) { diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_abi.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_abi.stderr index 83d3e6d3d1eb..84a3c7553894 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_abi.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_abi.stderr @@ -6,8 +6,6 @@ LL | let _ = malloc(0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/check_arg_abi.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr index 739507fde0ef..5b4703ca1660 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr @@ -6,8 +6,6 @@ LL | abort(1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/check_arg_count_abort.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr index ad1dbb034764..5f81145d26af 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr @@ -6,8 +6,6 @@ LL | let _ = malloc(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/check_arg_count_too_few_args.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr index 9dae9a02a16d..3ed4aaacb8c4 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr @@ -6,8 +6,6 @@ LL | let _ = malloc(1, 2); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/check_arg_count_too_many_args.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr index cbca7e920b7b..c395af97ef3a 100644 --- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr @@ -11,8 +11,6 @@ LL | | ); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/check_callback_abi.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.cache.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.cache.stderr index 6a8f444b37c5..c1f11bcd24c5 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.cache.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.cache.stderr @@ -6,8 +6,6 @@ LL | foo(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_abi_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.fn_ptr.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.fn_ptr.stderr index 07bd5e0effca..cbc51519af69 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.fn_ptr.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.fn_ptr.stderr @@ -6,8 +6,6 @@ LL | std::mem::transmute::(foo)(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_abi_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.no_cache.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.no_cache.stderr index 6a8f444b37c5..c1f11bcd24c5 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.no_cache.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_abi_mismatch.no_cache.stderr @@ -6,8 +6,6 @@ LL | foo(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_abi_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr index afabb8572bdf..000cf645e8dd 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr @@ -11,8 +11,6 @@ LL | unsafe { unwind() } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_bad_unwind1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr index eaca0d3f0122..c260a8317757 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr @@ -11,8 +11,6 @@ LL | unsafe { nounwind() } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_clashing.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_clashing.stderr index 50ca5c611def..a4edb552517f 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_clashing.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_clashing.stderr @@ -14,8 +14,6 @@ help: then it's defined here again, in crate `exported_symbol_clashing` | LL | fn bar() {} | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/exported_symbol_clashing.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_shim_clashing.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_shim_clashing.stderr index ea3b73f87245..0e2b4da5c0a0 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_shim_clashing.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_shim_clashing.stderr @@ -12,8 +12,6 @@ LL | | LL | | unreachable!() LL | | } | |_^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/function_calls/exported_symbol_shim_clashing.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr index 6699e5fea13a..75c060ea51d4 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr @@ -6,8 +6,6 @@ LL | unsafe { foo(1) } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_wrong_arguments.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_type.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_type.stderr index 7a4f3f17f6f4..01c59a77b48c 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_type.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_type.stderr @@ -6,8 +6,6 @@ LL | unsafe { FOO() } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/exported_symbol_wrong_type.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr index 77dc2c61e260..d653ec3a069c 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr @@ -11,8 +11,6 @@ LL | dbg!(x.0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/std/src/macros.rs:LL:CC = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: diff --git a/src/tools/miri/tests/fail/function_calls/target_feature.stderr b/src/tools/miri/tests/fail/function_calls/target_feature.stderr index e80e22346631..53a02b193526 100644 --- a/src/tools/miri/tests/fail/function_calls/target_feature.stderr +++ b/src/tools/miri/tests/fail/function_calls/target_feature.stderr @@ -6,8 +6,6 @@ LL | ssse3_fn(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/target_feature.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/target_feature_wasm.stderr b/src/tools/miri/tests/fail/function_calls/target_feature_wasm.stderr index a89c59123450..869fa4715d69 100644 --- a/src/tools/miri/tests/fail/function_calls/target_feature_wasm.stderr +++ b/src/tools/miri/tests/fail/function_calls/target_feature_wasm.stderr @@ -3,9 +3,6 @@ error: abnormal termination: calling a function that requires unavailable target | LL | simd128_fn(); | ^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_calls/target_feature_wasm.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr index f793abb0b62f..56e69e846696 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr @@ -8,8 +8,6 @@ LL | g(Default::default()) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr index 3651fc9b3f7a..cbef9d27cdf9 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr @@ -8,8 +8,6 @@ LL | g(42) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_int_vs_float.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr index 88345a0688ca..cd14ea156a47 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr @@ -8,8 +8,6 @@ LL | g(&42 as *const i32) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_raw_pointer.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr index 47658395132e..0e52dc02884c 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr @@ -8,8 +8,6 @@ LL | fnptr(S1(NonZero::new(1).unwrap())); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_repr_C.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr index 28c676ad4823..ba940902c8ce 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr @@ -8,8 +8,6 @@ LL | g() = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_return_type.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr index 2ed9ac2e6dae..ab9c0e720304 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr @@ -8,8 +8,6 @@ LL | g(42) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_simple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr index a03e596bba14..06e6ccbd7bf2 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr @@ -6,8 +6,6 @@ LL | g() | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_too_few_args.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr index eb681a10e43c..d343eb8f2599 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr @@ -6,8 +6,6 @@ LL | g(42) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_too_many_args.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr index b13e8d936dbe..1176589a5f4a 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr @@ -8,8 +8,6 @@ LL | g(Default::default()) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/abi_mismatch_vector.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/cast_box_int_to_fn_ptr.stderr b/src/tools/miri/tests/fail/function_pointers/cast_box_int_to_fn_ptr.stderr index 6330f17b2b26..c1a5faca3876 100644 --- a/src/tools/miri/tests/fail/function_pointers/cast_box_int_to_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/function_pointers/cast_box_int_to_fn_ptr.stderr @@ -6,8 +6,6 @@ LL | (*g)(42) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/cast_box_int_to_fn_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/cast_int_to_fn_ptr.stderr b/src/tools/miri/tests/fail/function_pointers/cast_int_to_fn_ptr.stderr index de4c037a8b14..aed5aeead5a5 100644 --- a/src/tools/miri/tests/fail/function_pointers/cast_int_to_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/function_pointers/cast_int_to_fn_ptr.stderr @@ -6,8 +6,6 @@ LL | g(42) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/cast_int_to_fn_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr index c9144aa52980..bff57c2785ce 100644 --- a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr @@ -6,8 +6,6 @@ LL | *std::mem::transmute::(f) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/deref_fn_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/execute_memory.stderr b/src/tools/miri/tests/fail/function_pointers/execute_memory.stderr index 52d03ae1733a..3f7b80412ae1 100644 --- a/src/tools/miri/tests/fail/function_pointers/execute_memory.stderr +++ b/src/tools/miri/tests/fail/function_pointers/execute_memory.stderr @@ -6,8 +6,6 @@ LL | f() | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/execute_memory.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_pointers/fn_ptr_offset.stderr b/src/tools/miri/tests/fail/function_pointers/fn_ptr_offset.stderr index f558251bea38..e22a5090243a 100644 --- a/src/tools/miri/tests/fail/function_pointers/fn_ptr_offset.stderr +++ b/src/tools/miri/tests/fail/function_pointers/fn_ptr_offset.stderr @@ -6,8 +6,6 @@ LL | x(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/function_pointers/fn_ptr_offset.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.stderr b/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.stderr index a115aa2d5b58..2fc9a917022a 100644 --- a/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.stderr +++ b/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.stderr @@ -5,8 +5,6 @@ LL | ptr_guaranteed_cmp::<()>(std::ptr::null(), std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsic_fallback_is_spec.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/assume.stderr b/src/tools/miri/tests/fail/intrinsics/assume.stderr index 3e7ad34f54e7..23bae791ec1c 100644 --- a/src/tools/miri/tests/fail/intrinsics/assume.stderr +++ b/src/tools/miri/tests/fail/intrinsics/assume.stderr @@ -6,8 +6,6 @@ LL | std::intrinsics::assume(x > 42); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/assume.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/copy_overflow.stderr b/src/tools/miri/tests/fail/intrinsics/copy_overflow.stderr index 486b00c4d235..ac0005b9681d 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_overflow.stderr +++ b/src/tools/miri/tests/fail/intrinsics/copy_overflow.stderr @@ -6,8 +6,6 @@ LL | (&mut y as *mut i32).copy_from(&x, 1usize << (mem::size_of:: | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/copy_overflow.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr index aee22698fd19..70ff03fb1c20 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr +++ b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.stderr @@ -6,8 +6,6 @@ LL | std::intrinsics::copy_nonoverlapping(a, b, 2); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/copy_overlapping.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/copy_unaligned.stderr b/src/tools/miri/tests/fail/intrinsics/copy_unaligned.stderr index d9b41f5b0581..898df16f4bdf 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_unaligned.stderr +++ b/src/tools/miri/tests/fail/intrinsics/copy_unaligned.stderr @@ -6,8 +6,6 @@ LL | ... std::intrinsics::copy_nonoverlapping(&data[5], ptr, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/copy_unaligned.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.stderr b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.stderr index 2f766ba77437..d84d1ba5c667 100644 --- a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.stderr @@ -6,8 +6,6 @@ LL | ctlz_nonzero(0u8); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ctlz_nonzero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.stderr b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.stderr index 66d0bac7302e..37127b93d8d0 100644 --- a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.stderr @@ -6,8 +6,6 @@ LL | cttz_nonzero(0u8); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/cttz_nonzero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr index 80b27adfca8c..dbce619e47b0 100644 --- a/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr +++ b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::intrinsics::disjoint_bitor(0b01101001_u8, 0b10001110) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/disjoint_bitor.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/div-by-zero.stderr b/src/tools/miri/tests/fail/intrinsics/div-by-zero.stderr index ec83f4a96e94..40e97c01cf90 100644 --- a/src/tools/miri/tests/fail/intrinsics/div-by-zero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/div-by-zero.stderr @@ -6,8 +6,6 @@ LL | let _n = unchecked_div(1i64, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/div-by-zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div1.stderr b/src/tools/miri/tests/fail/intrinsics/exact_div1.stderr index c05dee7f6f5d..316bb6bc0a3e 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/exact_div1.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::intrinsics::exact_div(2, 0) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/exact_div1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div2.stderr b/src/tools/miri/tests/fail/intrinsics/exact_div2.stderr index 349e30d7bfd2..7d37547f07a7 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/exact_div2.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::intrinsics::exact_div(2u16, 3) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/exact_div2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div3.stderr b/src/tools/miri/tests/fail/intrinsics/exact_div3.stderr index e8292bbd4b47..1ce3cb21907a 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div3.stderr +++ b/src/tools/miri/tests/fail/intrinsics/exact_div3.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::intrinsics::exact_div(-19i8, 2) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/exact_div3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/exact_div4.stderr b/src/tools/miri/tests/fail/intrinsics/exact_div4.stderr index 9e6ccf599a1a..eb5674434b86 100644 --- a/src/tools/miri/tests/fail/intrinsics/exact_div4.stderr +++ b/src/tools/miri/tests/fail/intrinsics/exact_div4.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::intrinsics::exact_div(i64::MIN, -1) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/exact_div4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/fast_math_both.stderr b/src/tools/miri/tests/fail/intrinsics/fast_math_both.stderr index c889dd01b85a..4b9e19cc0cbf 100644 --- a/src/tools/miri/tests/fail/intrinsics/fast_math_both.stderr +++ b/src/tools/miri/tests/fail/intrinsics/fast_math_both.stderr @@ -6,8 +6,6 @@ LL | ... let _x: f32 = core::intrinsics::fsub_fast(f32::NAN, f32::NAN); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/fast_math_both.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/fast_math_first.stderr b/src/tools/miri/tests/fail/intrinsics/fast_math_first.stderr index e9c4f34ab37f..2971694076f1 100644 --- a/src/tools/miri/tests/fail/intrinsics/fast_math_first.stderr +++ b/src/tools/miri/tests/fail/intrinsics/fast_math_first.stderr @@ -6,8 +6,6 @@ LL | ... let _x: f32 = core::intrinsics::frem_fast(f32::NAN, 3.2); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/fast_math_first.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/fast_math_result.stderr b/src/tools/miri/tests/fail/intrinsics/fast_math_result.stderr index cf7198c91fdf..5f2fb137f612 100644 --- a/src/tools/miri/tests/fail/intrinsics/fast_math_result.stderr +++ b/src/tools/miri/tests/fail/intrinsics/fast_math_result.stderr @@ -6,8 +6,6 @@ LL | let _x: f32 = core::intrinsics::fdiv_fast(1.0, 0.0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/fast_math_result.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/fast_math_second.stderr b/src/tools/miri/tests/fail/intrinsics/fast_math_second.stderr index e1323b0b515a..350dad33e0e1 100644 --- a/src/tools/miri/tests/fail/intrinsics/fast_math_second.stderr +++ b/src/tools/miri/tests/fail/intrinsics/fast_math_second.stderr @@ -6,8 +6,6 @@ LL | ... let _x: f32 = core::intrinsics::fmul_fast(3.4f32, f32::INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/fast_math_second.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr index 5cce3fe85924..9cfa59086289 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f32::INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_inf1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr index 49e804a82aee..acef357633c8 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f32::NEG_INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_infneg1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr index b8cb2186eff2..0c4b312fd315 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f32::NAN); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_nan.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr index 4af308057b5e..5a10eaf6bf98 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-f32::NAN); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_nanneg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr index efdee0814b80..c5bc84b62a7e 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-1.000000001f32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_neg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr index e5663a8a5f42..8ebfbc47df5d 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(2147483648.0f32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_too_big1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr index 2aab07cd8160..bdadfb4d88ce 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::((u32::MAX - 127) as f32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_too_big2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr index dbd99d12c51e..7c18066ba907 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-2147483904.0f32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_32_too_small1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr index f3348d897196..fa4bd4c45ca8 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_inf1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr index b568408e53d3..f423431ebc93 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::NEG_INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_infneg1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr index 5faa13409b07..112644abbc01 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::NEG_INFINITY); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_infneg2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr index ed0e15828022..c8e761308896 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::NAN); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_nan.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr index 754b5d514ce2..20d3fa4c39b2 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-1.0000000000001f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_neg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr index 717475704f15..91c44eadd341 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(2147483648.0f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr index 595f427b5121..43dc95132483 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(9223372036854775808.0f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr index 0e180869370c..4bbbb418074a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(18446744073709551616.0f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr index 0dd317d4b773..00320fe1b3dd 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(u128::MAX as f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr index ac8a2a858894..f698048be5d8 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr @@ -6,8 +6,6 @@ LL | ... float_to_int_unchecked::(240282366920938463463374607431768 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big5.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr index e6e4618c13de..7f80e6f1a4d9 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::MAX); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big6.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr index b82a7f1a4c71..99c6e9f8a4ea 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(f64::MIN); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_big7.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr index 37b7cae320d7..4641e573edc7 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-2147483649.0f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_small1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr index 63050939ef9e..d2718d2bda6a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr @@ -6,8 +6,6 @@ LL | float_to_int_unchecked::(-9223372036854777856.0f64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_small2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr index c3776e221e8f..f91544de7cc9 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr @@ -6,8 +6,6 @@ LL | ... float_to_int_unchecked::(-24028236692093846346337460743176 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/float_to_int_64_too_small3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr b/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr index fc828021b132..900203d1b9b3 100644 --- a/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr +++ b/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr @@ -6,8 +6,6 @@ LL | std::intrinsics::unchecked_funnel_shl(1_u32, 2, 32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/funnel_shl.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr b/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr index 7361df1b4c7a..2b2e85f9f9b7 100644 --- a/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr @@ -6,8 +6,6 @@ LL | std::intrinsics::unchecked_funnel_shr(1_u32, 2, 32); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/funnel_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr b/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr index 11c3c85be9ce..6742bd6e1adf 100644 --- a/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr +++ b/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr @@ -6,8 +6,6 @@ LL | dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/intrinsic_target_feature.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr index 80b4c8bec0d7..d284a6f6d019 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr @@ -9,8 +9,6 @@ LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32; = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics = help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC error: Undefined Behavior: reading memory at ALLOC[0xX..0xY], but memory is uninitialized at [0xX..0xY], and this operation requires initialized memory --> tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr index 4922afc8d102..8e276ed357d8 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr @@ -6,8 +6,6 @@ LL | (&1_u8 as *const u8).offset_from(&2_u8); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr index 41567e7ec991..b583e1aa9a62 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr @@ -6,8 +6,6 @@ LL | let _ = p1.byte_offset_from(p2); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_different_ints.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr index f380416af697..3c480ac8eb5a 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr @@ -6,8 +6,6 @@ LL | ptr.wrapping_add(4).offset_from(ptr); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr index a74c697df41e..317dbcc0bdaf 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr index 6e49617839ba..d7de6f307c97 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr @@ -6,8 +6,6 @@ LL | let _val = (1 as *mut u8).offset(1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_int_plus_int.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr index ace3d61499fd..b953208d4cc5 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr @@ -6,8 +6,6 @@ LL | let _val = (1 as *mut u8).offset(ptr as isize); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_int_plus_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds.stderr index b2039a792e91..d9a7967c6b7a 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v = [0i8; 4]; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/intrinsics/ptr_offset_out_of_bounds.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg.stderr index f2e6f2b9e265..c7818784b5ff 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v = [0i8; 4]; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/intrinsics/ptr_offset_out_of_bounds_neg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg2.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg2.stderr index 495aaf8d40ee..dbbfe2454a38 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_out_of_bounds_neg2.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v = [0i8; 4]; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/intrinsics/ptr_offset_out_of_bounds_neg2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_overflow.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_overflow.stderr index 741dd91b3551..aab7aa6f8786 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_overflow.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_overflow.stderr @@ -11,8 +11,6 @@ help: ALLOC was allocated here: | LL | let v = [0i8; 4]; | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/intrinsics/ptr_offset_overflow.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_unsigned_overflow.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_unsigned_overflow.stderr index eb00c369f993..1e6ac17aaf7d 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_unsigned_overflow.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_unsigned_overflow.stderr @@ -6,8 +6,6 @@ LL | let _ = unsafe { x.byte_add(usize::MAX) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/ptr_offset_unsigned_overflow.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/rem-by-zero.stderr b/src/tools/miri/tests/fail/intrinsics/rem-by-zero.stderr index 1864efbfee58..ff52290a50a6 100644 --- a/src/tools/miri/tests/fail/intrinsics/rem-by-zero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/rem-by-zero.stderr @@ -6,8 +6,6 @@ LL | let _n = unchecked_rem(3u32, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/rem-by-zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.stderr b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.stderr index 7bea17994686..abd32d26f916 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.stderr @@ -6,8 +6,6 @@ LL | simd_div(x, y); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-div-by-zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.stderr b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.stderr index 459212a91190..d3c2e353f0a5 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.stderr @@ -6,8 +6,6 @@ LL | simd_div(x, y); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-div-overflow.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-extract.stderr b/src/tools/miri/tests/fail/intrinsics/simd-extract.stderr index bd9dafb68645..c2bf4b01f3fc 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-extract.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-extract.stderr @@ -6,8 +6,6 @@ LL | let _x: i32 = unsafe { std::intrinsics::simd::simd_extract(v, 4) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-extract.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr index 64b8e166c166..3e9a4fab03e7 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr @@ -6,8 +6,6 @@ LL | ... let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchec | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-float-to-int.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr index d70f406e45bf..0b65bbc32d28 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr @@ -6,8 +6,6 @@ LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-gather.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.stderr b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.stderr index 0d8b96b79851..95c832b920e5 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.stderr @@ -6,8 +6,6 @@ LL | simd_reduce_any(x); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-reduce-invalid-bool.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.stderr b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.stderr index c58731fab8cb..77aabccdc053 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.stderr @@ -6,8 +6,6 @@ LL | simd_rem(x, y); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-rem-by-zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr index 52032254aff5..4d1dcec3b576 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr @@ -16,8 +16,6 @@ help: ALLOC was allocated here: | LL | let mut vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/intrinsics/simd-scatter.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.stderr b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.stderr index 9a681173a17c..30f5f8218ea9 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.stderr @@ -6,8 +6,6 @@ LL | simd_select(x, x, x); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-select-invalid-bool.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.stderr b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.stderr index f1387e2c27f3..b1c3cfbc554e 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.stderr @@ -6,8 +6,6 @@ LL | simd_shl(x, y); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-shl-too-far.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.stderr b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.stderr index 3c14b7fb4a25..dd67b343b143 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.stderr @@ -6,8 +6,6 @@ LL | simd_shr(x, y); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/simd-shr-too-far.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr index fb50db74a205..5a848e53f3a7 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -6,8 +6,6 @@ LL | typed_swap_nonoverlapping(a, a); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_add1.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_add1.stderr index 649009cade96..45bd099246eb 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_add1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_add1.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { 40000u16.unchecked_add(30000) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_add1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_add2.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_add2.stderr index eec74a304ad5..e12be54df024 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_add2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_add2.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { (-30000i16).unchecked_add(-8000) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_add2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_div1.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_div1.stderr index 5f3422f19b3a..f39f39cd9350 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_div1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_div1.stderr @@ -6,8 +6,6 @@ LL | std::intrinsics::unchecked_div(i16::MIN, -1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_div1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_mul1.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_mul1.stderr index f9d5a4db9339..25b68aa5b096 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_mul1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_mul1.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { 300u16.unchecked_mul(250u16) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_mul1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_mul2.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_mul2.stderr index a2c19043f926..da7f87bed14f 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_mul2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_mul2.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { 1_000_000_000i32.unchecked_mul(-4) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_mul2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_shl.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_shl.stderr index 94d0bc0d111a..3cb6203265d0 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_shl.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_shl.stderr @@ -6,8 +6,6 @@ LL | let _n = 1i8.unchecked_shl(8); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_shl.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr index 8c79a1980b77..2a8389087ffd 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr @@ -6,8 +6,6 @@ LL | let _n = intrinsics::unchecked_shl(1i8, -1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_shl2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_shr.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_shr.stderr index 4067437bf0fa..1f7eb120d974 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_shr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_shr.stderr @@ -6,8 +6,6 @@ LL | let _n = 1i64.unchecked_shr(64); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_sub1.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_sub1.stderr index b5914137a1c0..a9b4b23896ff 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_sub1.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_sub1.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { 14u32.unchecked_sub(22) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_sub1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_sub2.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_sub2.stderr index 34227ddc051e..c03683349062 100644 --- a/src/tools/miri/tests/fail/intrinsics/unchecked_sub2.stderr +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_sub2.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { 30000i16.unchecked_sub(-7000) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/unchecked_sub2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr index 36642208afea..d0f7cc1eacc2 100644 --- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr +++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr @@ -6,8 +6,6 @@ LL | let _ = unsafe { std::mem::uninitialized::() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/write_bytes_overflow.stderr b/src/tools/miri/tests/fail/intrinsics/write_bytes_overflow.stderr index e8c23463e86c..d89adaf5fce3 100644 --- a/src/tools/miri/tests/fail/intrinsics/write_bytes_overflow.stderr +++ b/src/tools/miri/tests/fail/intrinsics/write_bytes_overflow.stderr @@ -6,8 +6,6 @@ LL | (&mut y as *mut i32).write_bytes(0u8, 1usize << (mem::size_of::() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr index 3d62d02559dd..2ee8e2898ed7 100644 --- a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr +++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr @@ -5,8 +5,6 @@ LL | let _val = *DISPATCH_QUEUE_CONCURRENT; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr index 89db0f1eb162..73ccb49c2a53 100644 --- a/src/tools/miri/tests/fail/memleak.stderr +++ b/src/tools/miri/tests/fail/memleak.stderr @@ -3,9 +3,6 @@ error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: | LL | std::mem::forget(Box::new(42)); | ^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `main` at tests/fail/memleak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/modifying_constants.stderr b/src/tools/miri/tests/fail/modifying_constants.stderr index 80026a81a571..5a84a5a2eadd 100644 --- a/src/tools/miri/tests/fail/modifying_constants.stderr +++ b/src/tools/miri/tests/fail/modifying_constants.stderr @@ -6,8 +6,6 @@ LL | *y = 42; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/modifying_constants.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/never_match_never.stderr b/src/tools/miri/tests/fail/never_match_never.stderr index c29a4f6b2d10..07073b9ae8f9 100644 --- a/src/tools/miri/tests/fail/never_match_never.stderr +++ b/src/tools/miri/tests/fail/never_match_never.stderr @@ -6,8 +6,6 @@ LL | unsafe { match (*ptr).1 {} } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/never_match_never.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/never_say_never.stderr b/src/tools/miri/tests/fail/never_say_never.stderr index c8fefa462d3f..284fd4076003 100644 --- a/src/tools/miri/tests/fail/never_say_never.stderr +++ b/src/tools/miri/tests/fail/never_say_never.stderr @@ -6,8 +6,6 @@ LL | f(x) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/never_say_never.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/never_transmute_humans.stderr b/src/tools/miri/tests/fail/never_transmute_humans.stderr index 5c968dfbaead..66d1c8574e4c 100644 --- a/src/tools/miri/tests/fail/never_transmute_humans.stderr +++ b/src/tools/miri/tests/fail/never_transmute_humans.stderr @@ -6,8 +6,6 @@ LL | std::mem::transmute::(Human) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/never_transmute_humans.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr index f2a6d326b718..0d2debccc8a6 100644 --- a/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr +++ b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr @@ -6,8 +6,6 @@ LL | _1 = (_1.0, ); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/overlapping_assignment_aggregate.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr index 289cbb43bcff..a741bcad39de 100644 --- a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr +++ b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr @@ -6,8 +6,6 @@ LL | miri_start_unwind(&mut 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/panic/unwind_panic_abort.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr index 97bda83d05a3..6f097c336d2c 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *ptr.read() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/int_copy_looses_provenance0.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr index a4d725f9ae11..f3d1d8c13dec 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *ptr.read() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/int_copy_looses_provenance1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr index f00eccf07195..837423292daa 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *ptr.read() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/int_copy_looses_provenance2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.stderr index 432d869af9b3..db559f839e85 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance3.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *ptr }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/int_copy_looses_provenance3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/mix-ptrs1.stderr b/src/tools/miri/tests/fail/provenance/mix-ptrs1.stderr index 88d75135a763..92aeb6445b4f 100644 --- a/src/tools/miri/tests/fail/provenance/mix-ptrs1.stderr +++ b/src/tools/miri/tests/fail/provenance/mix-ptrs1.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(*strange_ptr.with_addr(ptr.addr()), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/mix-ptrs2.stderr b/src/tools/miri/tests/fail/provenance/mix-ptrs2.stderr index 636378952ba5..e00e72a50c6b 100644 --- a/src/tools/miri/tests/fail/provenance/mix-ptrs2.stderr +++ b/src/tools/miri/tests/fail/provenance/mix-ptrs2.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(*ptr, 42); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr b/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr index e1d990771f25..b0f9ffb45197 100644 --- a/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr +++ b/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr @@ -6,8 +6,6 @@ LL | let x = *p; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/pointer_partial_overwrite.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance0.stderr b/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance0.stderr index 0c97c990f92a..1f3fcab1729f 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance0.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance0.stderr @@ -6,8 +6,6 @@ LL | let _val = *ptr; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/ptr_copy_loses_partial_provenance0.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance1.stderr b/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance1.stderr index c29cf2df8117..b634c403cca0 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance1.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_copy_loses_partial_provenance1.stderr @@ -6,8 +6,6 @@ LL | let _val = *ptr; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/ptr_copy_loses_partial_provenance1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr index 23c2fce84034..0068af956a5b 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(unsafe { *ptr }, 3); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/ptr_int_unexposed.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr b/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr index dffaf236bed4..bab14fe41b6e 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *xptr_invalid }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/ptr_invalid.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.stderr b/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.stderr index fab5fe0f60cd..dbb3fdf773b4 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_invalid_offset.stderr @@ -6,8 +6,6 @@ LL | let _ = unsafe { roundtrip.offset(1) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/ptr_invalid_offset.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/provenance/strict_provenance_cast.stderr b/src/tools/miri/tests/fail/provenance/strict_provenance_cast.stderr index e203911c6677..b01bd5ce5a16 100644 --- a/src/tools/miri/tests/fail/provenance/strict_provenance_cast.stderr +++ b/src/tools/miri/tests/fail/provenance/strict_provenance_cast.stderr @@ -5,8 +5,6 @@ LL | let _ptr = std::ptr::with_exposed_provenance::(addr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead - = note: BACKTRACE: - = note: inside `main` at tests/fail/provenance/strict_provenance_cast.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/rc_as_ptr.stderr b/src/tools/miri/tests/fail/rc_as_ptr.stderr index 5c6bda35af6c..d2d9d94afd44 100644 --- a/src/tools/miri/tests/fail/rc_as_ptr.stderr +++ b/src/tools/miri/tests/fail/rc_as_ptr.stderr @@ -16,8 +16,6 @@ help: ALLOC was deallocated here: | LL | drop(strong); | ^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/read_from_trivial_switch.stderr b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr index 1dcc341b7e67..85817513bc39 100644 --- a/src/tools/miri/tests/fail/read_from_trivial_switch.stderr +++ b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr @@ -6,8 +6,6 @@ LL | let &(0 | _) = bad_ref; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/read_from_trivial_switch.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/reading_half_a_pointer.stderr b/src/tools/miri/tests/fail/reading_half_a_pointer.stderr index fe2bc6da2f83..6732987b79f5 100644 --- a/src/tools/miri/tests/fail/reading_half_a_pointer.stderr +++ b/src/tools/miri/tests/fail/reading_half_a_pointer.stderr @@ -6,8 +6,6 @@ LL | let _val = *x; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/reading_half_a_pointer.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.stderr index 266e941436d7..e50fd41617a8 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.stderr @@ -6,8 +6,6 @@ LL | ... miri_resolve_frame(*frame, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-decl.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr index dd2b19003219..f0553cc04316 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr @@ -5,8 +5,6 @@ LL | miri_get_backtrace(2, std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-flags.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-ptr.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-ptr.stderr index 2274b1098aa3..bb4615dd14b5 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-ptr.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-ptr.stderr @@ -6,8 +6,6 @@ LL | miri_resolve_frame(std::ptr::null_mut(), 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr index ba9ea5ce3a46..947c42397309 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr @@ -5,8 +5,6 @@ LL | miri_resolve_frame(buf[0], 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-resolve-flags.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr index e0498586a037..de09300306be 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr @@ -5,8 +5,6 @@ LL | ... miri_resolve_frame_names(buf[0], 2, std::ptr::null_mut(), std::ptr::n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr index 5846fbb769f4..bf176fc016c3 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr @@ -5,8 +5,6 @@ LL | miri_backtrace_size(2); | ^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/backtrace/bad-backtrace-size-flags.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr index 664bfbd32db2..68c56044be88 100644 --- a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr +++ b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr @@ -6,7 +6,6 @@ error: Undefined Behavior: calling a function with return type i32 passing retur = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr index ec27fd5ebb8f..bb5468b56fc8 100644 --- a/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr @@ -8,8 +8,6 @@ LL | close(fd); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/input_arg_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr index e01ba235f896..510ffdf80cac 100644 --- a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr @@ -6,8 +6,6 @@ LL | open(c_path.as_ptr(), /* value does not matter */ 0) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/non_vararg_signature_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr index 18ff3067fa03..bf705d39a857 100644 --- a/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr @@ -8,8 +8,6 @@ LL | close(fd); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/return_type_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/shim_arg_size.stderr b/src/tools/miri/tests/fail/shims/shim_arg_size.stderr index 688272df2632..08ce069486d4 100644 --- a/src/tools/miri/tests/fail/shims/shim_arg_size.stderr +++ b/src/tools/miri/tests/fail/shims/shim_arg_size.stderr @@ -6,8 +6,6 @@ LL | memchr(std::ptr::null(), 0, 0); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/shim_arg_size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr index a7b8be9b36d9..12c5a21909ab 100644 --- a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr @@ -6,8 +6,6 @@ LL | let res = unsafe { pipe(fds.as_mut_ptr()) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr index fcec61a9e7e2..2442f051c81c 100644 --- a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr +++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr @@ -6,8 +6,6 @@ LL | open(c_path.as_ptr(), /* value does not matter */ 0) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/shims/wrong_fixed_arg_count.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/disable_mut_does_not_merge_srw.stderr b/src/tools/miri/tests/fail/stacked_borrows/disable_mut_does_not_merge_srw.stderr index 7e9fb3f3c881..32725935a230 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/disable_mut_does_not_merge_srw.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/disable_mut_does_not_merge_srw.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *base = 1; | ^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/disable_mut_does_not_merge_srw.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.stderr b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.stderr index 07662573f61c..bded2dcb8400 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.stderr @@ -6,8 +6,6 @@ LL | unsafe { *ptr = 0 }; | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/stacked_borrows/exposed_only_ro.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation.stderr b/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation.stderr index b4f82469a8b8..8e107e7f89a4 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique function-ent | LL | x.do_bad(); | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/fnentry_invalidation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation2.stderr b/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation2.stderr index ad24e0fa32dc..a1f8a36b00f9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/fnentry_invalidation2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0xc] by a Unique function-ent | LL | let _ = t.sli.as_mut_ptr(); | ^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/fnentry_invalidation2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr index 4e547e567e81..c2ef0916c030 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x1] by a write access | LL | ptr1.write(0); | ^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read1.stderr index ea9dc47460ae..99f152eb9acb 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = unsafe { *xraw }; | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read2.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read2.stderr index fec08275f107..0d959a5752b5 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a SharedReadOnly reta | LL | let shr = unsafe { &*xraw }; | ^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.stderr index 2ef951a6e9cd..6b3228bd9d93 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read3.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = unsafe { *xref1.r }; | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read4.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read4.stderr index fdf5ae4297a0..73c3da8c09fe 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read4.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read4.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = unsafe { *xraw }; // use the raw again, this invalidates xref2 *even* with the special read except for uniq refs | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read5.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read5.stderr index f1514cf49063..8b3ab12484bb 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read5.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read5.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [$HEX..$HEX] by a read access | LL | mem::forget(unsafe { ptr::read(xshr) }); // but after reading through the shared ref | ^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read5.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read6.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read6.stderr index 3deb458cf22a..8360abb71ec8 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read6.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read6.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | let x = &mut *x; // kill `raw` | ^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read6.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read7.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read7.stderr index 0ed58cf775b8..c7e6901522e9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read7.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read7.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = ptr::read(raw); | ^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read7.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read8.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read8.stderr index 7eb52d7ec3b0..be425bc8438e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read8.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read8.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *y2 += 1; | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read8.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.stderr index 3c6dbf7fdce7..065e7395f8e2 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *exposed_ptr = 0; | ^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.stderr index 630fbd2fd14f..5643226463a7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = *exposed_ptr; | ^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.stderr index 684e4ef19468..0d729dee4b8a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | drop(&mut *target); // reborrow | ^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_write2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write3.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_write3.stderr index 431dc4443d23..ef850189ec6d 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write3.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write3.stderr @@ -11,8 +11,6 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x4] | LL | let ptr = r#ref as *const _ as *mut _; // raw ptr, with raw tag | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_write3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write4.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_write4.stderr index 954deeee77db..41470d76d6fa 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write4.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write4.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | let _mut_ref: &mut i32 = unsafe { mem::transmute(raw) }; // &mut, with raw tag | ^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_write4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.stderr index 03597105e8ed..5ed9ab6da8b6 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *exposed_ptr = 0; | ^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/interior_mut1.stderr b/src/tools/miri/tests/fail/stacked_borrows/interior_mut1.stderr index 76a320a819a9..f916a5f729e7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/interior_mut1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/interior_mut1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *c.get() = UnsafeCell::new(1); // invalidates inner_shr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/interior_mut1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/interior_mut2.stderr b/src/tools/miri/tests/fail/stacked_borrows/interior_mut2.stderr index c7852d58b8e6..6f41d858cd19 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/interior_mut2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/interior_mut2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *c.get() = UnsafeCell::new(0); // now inner_shr gets invalidated | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/interior_mut2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/load_invalid_mut.stderr b/src/tools/miri/tests/fail/stacked_borrows/load_invalid_mut.stderr index ff295c4bf846..7dc406158177 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/load_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/load_invalid_mut.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/load_invalid_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_mut.stderr b/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_mut.stderr index 382343f18db4..2bf1f5faa562 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_mut.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/pass_invalid_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/raw_tracking.stderr b/src/tools/miri/tests/fail/stacked_borrows/raw_tracking.stderr index 479bc87e99c5..aef24cddf2a9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/raw_tracking.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/raw_tracking.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | let raw2 = &mut l as *mut _; // invalidates raw1 | ^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/raw_tracking.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr index 561ce3164c30..5b8f77600cd2 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr @@ -14,8 +14,6 @@ LL | unsafe { ptr.0.read() }; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/stacked_borrows/retag_data_race_protected_read.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak1.stderr b/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak1.stderr index ebeb721b76f6..24265de1ea83 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak1.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique retag | LL | shr_rw.set(1); | ^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/shared_rw_borrows_are_weak1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak2.stderr b/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak2.stderr index 79a3d391fccf..3b8aa2ee662b 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/shared_rw_borrows_are_weak2.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [$HEX..$HEX] by a Unique retag | LL | shr_rw.replace(1); | ^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/shared_rw_borrows_are_weak2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/static_memory_modification.stderr b/src/tools/miri/tests/fail/stacked_borrows/static_memory_modification.stderr index 8e517ad05edb..bca5daa73d70 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/static_memory_modification.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/static_memory_modification.stderr @@ -6,8 +6,6 @@ LL | std::mem::transmute::<&usize, &mut usize>(&X) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/stacked_borrows/static_memory_modification.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/track_caller.stderr b/src/tools/miri/tests/fail/stacked_borrows/track_caller.stderr index 6cdaa2913ea2..c60ce8b5a9b6 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/track_caller.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/track_caller.stderr @@ -16,8 +16,6 @@ help: was later invalidated at offsets [0x0..0x4] by a read access | LL | callee(xraw); | ^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/track_caller.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/transmute-is-no-escape.stderr b/src/tools/miri/tests/fail/stacked_borrows/transmute-is-no-escape.stderr index 9d454f2c1e6b..1aba064992c6 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/transmute-is-no-escape.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/transmute-is-no-escape.stderr @@ -11,8 +11,6 @@ help: was created by a SharedReadWrite retag at offsets [0x4..0x8] | LL | let raw = (&mut x[1] as *mut i32).wrapping_offset(-1); | ^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/transmute-is-no-escape.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/unescaped_local.stderr b/src/tools/miri/tests/fail/stacked_borrows/unescaped_local.stderr index 0c78dcd7c887..5dd8f11bb94c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/unescaped_local.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/unescaped_local.stderr @@ -6,8 +6,6 @@ LL | *raw = 13; | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/stacked_borrows/unescaped_local.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/unescaped_static.stderr b/src/tools/miri/tests/fail/stacked_borrows/unescaped_static.stderr index 3efd6c32c932..7f3d1dfd411f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/unescaped_static.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/unescaped_static.stderr @@ -11,8 +11,6 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x1] | LL | let ptr_to_first = &ARRAY[0] as *const u8; | ^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/unescaped_static.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr index 021f87839e86..91b320465624 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr @@ -11,8 +11,6 @@ help: would have been created here, but this is a zero-size retag ([0x0..0 | LL | assert_eq!(*s.as_ptr().add(1), 2); | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/static_memory_modification1.stderr b/src/tools/miri/tests/fail/static_memory_modification1.stderr index d4a2dca3c14a..239274e21368 100644 --- a/src/tools/miri/tests/fail/static_memory_modification1.stderr +++ b/src/tools/miri/tests/fail/static_memory_modification1.stderr @@ -6,8 +6,6 @@ LL | *std::mem::transmute::<&usize, &mut usize>(&X) = 6; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/static_memory_modification1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/static_memory_modification2.stderr b/src/tools/miri/tests/fail/static_memory_modification2.stderr index 48483ce7b29e..323358601f14 100644 --- a/src/tools/miri/tests/fail/static_memory_modification2.stderr +++ b/src/tools/miri/tests/fail/static_memory_modification2.stderr @@ -6,8 +6,6 @@ LL | transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/static_memory_modification2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/static_memory_modification3.stderr b/src/tools/miri/tests/fail/static_memory_modification3.stderr index a94a600a08a4..ca1f85065aa0 100644 --- a/src/tools/miri/tests/fail/static_memory_modification3.stderr +++ b/src/tools/miri/tests/fail/static_memory_modification3.stderr @@ -6,8 +6,6 @@ LL | transmute::<&[u8], &mut [u8]>(bs)[4] = 42; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/static_memory_modification3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/storage-live-dead-var.stderr b/src/tools/miri/tests/fail/storage-live-dead-var.stderr index d196f6164644..d33bfd79e94e 100644 --- a/src/tools/miri/tests/fail/storage-live-dead-var.stderr +++ b/src/tools/miri/tests/fail/storage-live-dead-var.stderr @@ -6,8 +6,6 @@ LL | val = 42; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/storage-live-dead-var.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/storage-live-resets-var.stderr b/src/tools/miri/tests/fail/storage-live-resets-var.stderr index 478123501ec2..b3dd4ea0e848 100644 --- a/src/tools/miri/tests/fail/storage-live-resets-var.stderr +++ b/src/tools/miri/tests/fail/storage-live-resets-var.stderr @@ -6,8 +6,6 @@ LL | _val2 = val; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/storage-live-resets-var.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr index cabea5df85dd..f5eccaeba666 100644 --- a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr @@ -8,8 +8,6 @@ LL | f(0); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: BACKTRACE: - = note: inside `main` at tests/fail/tail_calls/signature-mismatch-arg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr b/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr index a1307b7b41a8..db113b6cf457 100644 --- a/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr +++ b/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr @@ -6,8 +6,6 @@ LL | let _val = *dangling_ptr.0; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/tls/tls_static_dealloc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls_static_leak.stderr b/src/tools/miri/tests/fail/tls_static_leak.stderr index 24306cca7ffd..8f59aa8a31db 100644 --- a/src/tools/miri/tests/fail/tls_static_leak.stderr +++ b/src/tools/miri/tests/fail/tls_static_leak.stderr @@ -3,9 +3,6 @@ error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: | LL | TLS.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside closure at tests/fail/tls_static_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr b/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr index aff482abfa0c..391ed75f730e 100644 --- a/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr @@ -24,8 +24,6 @@ help: the accessed tag later transitioned to Frozen due to a foreign read LL | let _val = *x; | ^^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/alternate-read-write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/cell-inside-struct.stderr b/src/tools/miri/tests/fail/tree_borrows/cell-inside-struct.stderr index 5e43d174ed90..282dc19eea79 100644 --- a/src/tools/miri/tests/fail/tree_borrows/cell-inside-struct.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/cell-inside-struct.stderr @@ -18,8 +18,6 @@ help: the accessed tag was created here, in the initial state Cell | LL | let a = &root; | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/cell-inside-struct.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/error-range.stderr b/src/tools/miri/tests/fail/tree_borrows/error-range.stderr index 3dc120a20d23..df508317bc34 100644 --- a/src/tools/miri/tests/fail/tree_borrows/error-range.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/error-range.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | data[5] = 1; | ^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/error-range.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr index bfd6854514e5..54013b27dee3 100644 --- a/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr @@ -24,8 +24,6 @@ help: the accessed tag later transitioned to Frozen due to a reborrow (act LL | x.do_bad(); | ^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/fnentry_invalidation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/frozen-lazy-write-to-surrounding.stderr b/src/tools/miri/tests/fail/tree_borrows/frozen-lazy-write-to-surrounding.stderr index e9800468c57a..4d6146499ee8 100644 --- a/src/tools/miri/tests/fail/tree_borrows/frozen-lazy-write-to-surrounding.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/frozen-lazy-write-to-surrounding.stderr @@ -12,8 +12,6 @@ help: the accessed tag was created here, in the initial state Frozen | LL | let x = &pair.0; | ^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/frozen-lazy-write-to-surrounding.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr index 7a713abcbc45..d0cd0088c0be 100644 --- a/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr @@ -24,8 +24,6 @@ help: the accessed tag later transitioned to Frozen due to a reborrow (act LL | assert_eq!(root, 0); // Parent Read | ^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/parent_read_freezes_raw_mut.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr index 7cebd7f32a0a..6ebc2dd40e29 100644 --- a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr @@ -18,8 +18,6 @@ help: the accessed tag later transitioned to Disabled due to a protector r LL | } | ^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/protector-write-lazy.rs:LL:CC = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr index 7565fa6203f9..15365e5c8bcc 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr @@ -32,8 +32,6 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *x = 64; | ^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr index 7f791c88dde3..4065c822866c 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr @@ -32,8 +32,6 @@ help: the accessed tag later transitioned to Disabled due to a protector r LL | } | ^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr index 4b6308847bb8..76ee412d71af 100644 --- a/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr @@ -30,8 +30,6 @@ help: the conflicting tag later transitioned to Frozen due to a foreign re LL | let _val = unsafe { *xraw }; // invalidate xref for writing | ^^^^^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/return_invalid_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/type-too-large.stderr b/src/tools/miri/tests/fail/type-too-large.stderr index 8c05f3a7e0bb..8f4e465fb529 100644 --- a/src/tools/miri/tests/fail/type-too-large.stderr +++ b/src/tools/miri/tests/fail/type-too-large.stderr @@ -3,9 +3,6 @@ error: post-monomorphization error: values of the type `[u8; 2305843011361177600 | LL | _fat = [0; (1u64 << 61) as usize + (1u64 << 31) as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ post-monomorphization error occurred here - | - = note: BACKTRACE: - = note: inside `main` at tests/fail/type-too-large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr index bc344bbbf7e2..59850f9cdb7f 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr @@ -6,8 +6,6 @@ LL | *(x_ptr as *mut u32) = 42; *(x_ptr.add(1) as *mut u32) = 42; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr index a76d2f04f3f8..ac3b70fb3529 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr @@ -6,8 +6,6 @@ LL | intrinsics::atomic_load::<_, { intrinsics::AtomicOrdering::SeqCst } | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/atomic_unaligned.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr index ddd4641f7efb..0be5ef9ccf1b 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr @@ -6,8 +6,6 @@ LL | let _ptr = &*ptr; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/dyn_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr index 15fc1a768f95..1010da408c6d 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr @@ -6,8 +6,6 @@ LL | unsafe { *u16_ptr = 2 }; | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/intptrcast_alignment_check.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr index 8d31f110ef41..5e7d6f5a5ded 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr @@ -5,8 +5,6 @@ LL | unsafe { utils::miri_promise_symbolic_alignment(align8.add(1).cast( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/promise_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr index 85eec253a774..6bea0e34b648 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { align8.cast::().read() }; | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/promise_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr index 600e39907a2b..f50e94327e8c 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr @@ -5,8 +5,6 @@ LL | unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/promise_alignment_zero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr index ccf7f833a6be..07a653ae12bf 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr @@ -6,8 +6,6 @@ LL | let _x = unsafe { *x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ptr1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr index 99d26a78bf05..f0ae68aad62d 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr @@ -6,8 +6,6 @@ LL | let _x = unsafe { *x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ptr2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr index 7cdcc47455e4..9b9fbe576d4c 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr @@ -6,8 +6,6 @@ LL | let _x = unsafe { *x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ptr3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr index 0d511c532f38..e0e788c90c22 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *ptr }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ptr4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr index ebcaa460462a..d7d21c128562 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr @@ -6,8 +6,6 @@ LL | let _x = unsafe { *x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ptr_zst.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr index 86e7e73417ac..dfd6c143dfe4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr @@ -6,8 +6,6 @@ LL | let _x = unsafe { &*x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/uninit/padding-enum.stderr b/src/tools/miri/tests/fail/uninit/padding-enum.stderr index 64229ac88172..56b209d51c91 100644 --- a/src/tools/miri/tests/fail/uninit/padding-enum.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-enum.stderr @@ -6,8 +6,6 @@ LL | let _val = *c.add(padding_offset); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-enum.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/uninit/padding-pair.stderr b/src/tools/miri/tests/fail/uninit/padding-pair.stderr index 2e7a577f204a..ef7cb41cc82a 100644 --- a/src/tools/miri/tests/fail/uninit/padding-pair.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-pair.stderr @@ -6,8 +6,6 @@ LL | let v = unsafe { *z.offset(first_undef) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-pair.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr b/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr index 87a423e46657..2b0dbd38e6ed 100644 --- a/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { (foobar.foo, foobar.bar) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-struct-in-union.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/uninit/padding-struct.stderr b/src/tools/miri/tests/fail/uninit/padding-struct.stderr index 05d754625d3f..5368f94e5665 100644 --- a/src/tools/miri/tests/fail/uninit/padding-struct.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-struct.stderr @@ -6,8 +6,6 @@ LL | let _val = *c.add(1); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-struct.rs:LL:CC Uninitialized memory occurred at ALLOC[0x1..0x2], in this allocation: ALLOC (stack variable, size: 4, align: 2) { diff --git a/src/tools/miri/tests/fail/uninit/padding-union.stderr b/src/tools/miri/tests/fail/uninit/padding-union.stderr index fa07eedd8913..30d0862df39a 100644 --- a/src/tools/miri/tests/fail/uninit/padding-union.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-union.stderr @@ -6,8 +6,6 @@ LL | let _val = *c; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-union.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr index ce11320ca1bf..0203b25d4241 100644 --- a/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr @@ -6,8 +6,6 @@ LL | let _val = *c.add(mem::size_of::<*const u8>()); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/padding-wide-ptr.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/uninit/transmute-pair-uninit.stderr b/src/tools/miri/tests/fail/uninit/transmute-pair-uninit.stderr index eb049dd41ec2..adbae0840f47 100644 --- a/src/tools/miri/tests/fail/uninit/transmute-pair-uninit.stderr +++ b/src/tools/miri/tests/fail/uninit/transmute-pair-uninit.stderr @@ -6,8 +6,6 @@ LL | let v = unsafe { *z.offset(first_undef) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/transmute-pair-uninit.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr b/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr index 8086d375855e..e8deb5732a70 100644 --- a/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr @@ -6,8 +6,6 @@ LL | _val = *sptr2; // should hence be UB | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/uninit-after-aggregate-assign.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/uninit/uninit_byte_read.stderr b/src/tools/miri/tests/fail/uninit/uninit_byte_read.stderr index 5a5aa12987c5..7827ed161aed 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_byte_read.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_byte_read.stderr @@ -6,8 +6,6 @@ LL | let undef = unsafe { *v.as_ptr().add(5) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/uninit/uninit_byte_read.rs:LL:CC Uninitialized memory occurred at ALLOC[0x5..0x6], in this allocation: ALLOC (Rust heap, size: 10, align: 1) { diff --git a/src/tools/miri/tests/fail/unreachable.stderr b/src/tools/miri/tests/fail/unreachable.stderr index 4b1820c9cef9..ab8ba4a68e5f 100644 --- a/src/tools/miri/tests/fail/unreachable.stderr +++ b/src/tools/miri/tests/fail/unreachable.stderr @@ -6,8 +6,6 @@ LL | unsafe { std::hint::unreachable_unchecked() } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/unreachable.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr index 63467859ed2f..4ff9f2764902 100644 --- a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr @@ -5,8 +5,6 @@ LL | foo(); | ^^^^^ unsupported operation occurred here | = help: this means the program tried to do something Miri does not support; it does not indicate a bug in the program - = note: BACKTRACE: - = note: inside `main` at tests/fail/unsupported_foreign_function.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr b/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr index 36a318790418..b470e79232d5 100644 --- a/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr +++ b/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr @@ -6,8 +6,6 @@ LL | std::mem::transmute(b) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/box-custom-alloc-dangling-ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr b/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr index 42c4a6e851b8..d7594ab53b5d 100644 --- a/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr +++ b/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr @@ -6,8 +6,6 @@ LL | std::mem::transmute(b) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/box-custom-alloc-invalid-alloc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr index d2f75da47f1d..02e0ebe8abe6 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr @@ -6,8 +6,6 @@ LL | g(0usize as *const i32) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr index efe89c0d220a..a00d167df2f7 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr @@ -6,8 +6,6 @@ LL | f(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr index e54d7105f17b..03d6637cdb61 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr @@ -6,8 +6,6 @@ LL | let _x = g(); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/cast_fn_ptr_invalid_caller_ret.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/dangling_ref1.stderr b/src/tools/miri/tests/fail/validity/dangling_ref1.stderr index b29826a9a3b9..05467c483f63 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref1.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref1.stderr @@ -6,8 +6,6 @@ LL | let _x: &i32 = unsafe { mem::transmute(16usize) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/dangling_ref1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/dangling_ref2.stderr b/src/tools/miri/tests/fail/validity/dangling_ref2.stderr index b792fb5b944c..eb1b6e2c5804 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref2.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref2.stderr @@ -6,8 +6,6 @@ LL | let _x: &i32 = unsafe { mem::transmute(ptr) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/dangling_ref2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/dangling_ref3.stderr b/src/tools/miri/tests/fail/validity/dangling_ref3.stderr index bcc4a796a872..ec2238c8618f 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref3.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref3.stderr @@ -6,8 +6,6 @@ LL | let _x: &i32 = unsafe { mem::transmute(dangling()) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/dangling_ref3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr index 8a43534bc2d1..383c13cc2ab7 100644 --- a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr @@ -6,8 +6,6 @@ LL | let y: &dyn Trait fn(&'a ())> = unsafe { std::mem::transmute(x) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_bool.stderr b/src/tools/miri/tests/fail/validity/invalid_bool.stderr index 7135f545c520..b667449add68 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_bool.stderr @@ -6,8 +6,6 @@ LL | let _b = unsafe { std::mem::transmute::(2) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_bool.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_bool_op.stderr b/src/tools/miri/tests/fail/validity/invalid_bool_op.stderr index faac61426bb9..e2d76c6b7776 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool_op.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_bool_op.stderr @@ -6,8 +6,6 @@ LL | let _x = b == std::hint::black_box(true); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_bool_op.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr index 089fd2303e39..800bc4fc3163 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr @@ -6,8 +6,6 @@ LL | let _b = unsafe { MyUninit { init: () }.uninit }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_bool_uninit.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_char.stderr b/src/tools/miri/tests/fail/validity/invalid_char.stderr index 720c09e692d2..7f579882bea0 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char.stderr @@ -6,8 +6,6 @@ LL | let _val = match unsafe { std::mem::transmute::(-1) } { | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_char.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_char_op.stderr b/src/tools/miri/tests/fail/validity/invalid_char_op.stderr index 692d57648619..081a7816300b 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_op.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_op.stderr @@ -6,8 +6,6 @@ LL | let _x = c == 'x'; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_char_op.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr index a4a61ed86a27..de8c1f39f248 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr @@ -6,8 +6,6 @@ LL | let _b = unsafe { MyUninit { init: () }.uninit }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_char_uninit.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_op.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_op.stderr index 3dd8f650d2e8..6481f3f9170e 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_op.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_op.stderr @@ -6,8 +6,6 @@ LL | let _val = mem::discriminant(&f); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_enum_op.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr index 3056643a1916..d7f299105205 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr @@ -6,8 +6,6 @@ LL | let _f = unsafe { std::mem::transmute::(42) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_enum_tag.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr b/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr index 10cefa128650..20b2234e2ab2 100644 --- a/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr @@ -6,8 +6,6 @@ LL | let _b: fn() = unsafe { std::mem::transmute(0usize) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_fnptr_null.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr index 7e6fda25078c..513b90b5d85e 100644 --- a/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr @@ -6,8 +6,6 @@ LL | let _b = unsafe { MyUninit { init: () }.uninit }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_fnptr_uninit.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_int_op.stderr b/src/tools/miri/tests/fail/validity/invalid_int_op.stderr index 0b1915621b24..046bbcb32f79 100644 --- a/src/tools/miri/tests/fail/validity/invalid_int_op.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_int_op.stderr @@ -6,8 +6,6 @@ LL | let i = unsafe { std::mem::MaybeUninit::::uninit().assume_init() } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_int_op.rs:LL:CC Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: ALLOC (stack variable, size: 4, align: 4) { diff --git a/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr b/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr index c41766ae845a..a3c7815cf282 100644 --- a/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr @@ -6,8 +6,6 @@ LL | dbg!(S { x: unsafe { std::mem::transmute((0usize, 0usize)) } }); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/invalid_wide_raw.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr b/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr index cde972ab6a2a..0ca8bc9f9bae 100644 --- a/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr +++ b/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr @@ -6,8 +6,6 @@ LL | _x => println!("hi from the void!"), | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/match_binder_checks_validity1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr b/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr index 37625ace795f..281314e68d51 100644 --- a/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr +++ b/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr @@ -6,8 +6,6 @@ LL | _x => println!("hi from the void!"), | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/match_binder_checks_validity2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/nonzero.stderr b/src/tools/miri/tests/fail/validity/nonzero.stderr index 7be3ef46639c..e5fcdadb0d2c 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.stderr +++ b/src/tools/miri/tests/fail/validity/nonzero.stderr @@ -6,8 +6,6 @@ LL | let _x = Some(unsafe { NonZero(0) }); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/nonzero.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr b/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr index 05203802d84f..112072679ea5 100644 --- a/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr +++ b/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr @@ -6,8 +6,6 @@ LL | let xref_wrong_type: &bool = unsafe { std::mem::transmute(xref) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/recursive-validity-ref-bool.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr b/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr index 6a7cbda5ef86..f1a059175566 100644 --- a/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr +++ b/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr @@ -6,8 +6,6 @@ LL | let x: Box = transmute(&mut 42); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/ref_to_uninhabited1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr b/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr index 0cb126b2be33..4d25de46ade8 100644 --- a/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr +++ b/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr @@ -6,8 +6,6 @@ LL | let _x: &(i32, Void) = transmute(&42); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/ref_to_uninhabited2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/too-big-slice.stderr b/src/tools/miri/tests/fail/validity/too-big-slice.stderr index 3405cafc645a..9d4c34748660 100644 --- a/src/tools/miri/tests/fail/validity/too-big-slice.stderr +++ b/src/tools/miri/tests/fail/validity/too-big-slice.stderr @@ -6,8 +6,6 @@ LL | ... let _x: &[u8] = mem::transmute((ptr, usize::MAX)); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/too-big-slice.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/too-big-unsized.stderr b/src/tools/miri/tests/fail/validity/too-big-unsized.stderr index f283ab960167..6c07308d08ca 100644 --- a/src/tools/miri/tests/fail/validity/too-big-unsized.stderr +++ b/src/tools/miri/tests/fail/validity/too-big-unsized.stderr @@ -6,8 +6,6 @@ LL | ... let _x: &MySlice = mem::transmute((ptr, isize::MAX as usize)); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/too-big-unsized.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr b/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr index c30c532496dc..998ff79d3afe 100644 --- a/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr +++ b/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr @@ -6,8 +6,6 @@ LL | let y = x; // reading this ought to be enough to trigger validation | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/transmute_through_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/uninit_float.stderr b/src/tools/miri/tests/fail/validity/uninit_float.stderr index 0c859d727641..7f3c94a87874 100644 --- a/src/tools/miri/tests/fail/validity/uninit_float.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_float.stderr @@ -6,8 +6,6 @@ LL | let _val: [f32; 1] = unsafe { std::mem::uninitialized() }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/uninit_float.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/uninit_integer.stderr b/src/tools/miri/tests/fail/validity/uninit_integer.stderr index 5d31e2659ee6..a80396f7f1ce 100644 --- a/src/tools/miri/tests/fail/validity/uninit_integer.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_integer.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { std::mem::MaybeUninit::<[usize; 1]>::uninit().assum | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/uninit_integer.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr index d2e9408adbe0..946d74d35484 100644 --- a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { std::mem::MaybeUninit::<[*const u8; 1]>::uninit().a | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/uninit_raw_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr index 23d43867920a..ea77d11f1e83 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr @@ -6,8 +6,6 @@ LL | let v: Box> = unsafe { std::mem::transmute(v) } | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/wrong-dyn-trait-assoc-type.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr index c5df837a9776..f9e2f15d98f9 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr @@ -6,8 +6,6 @@ LL | let _y: *const dyn Trait = unsafe { mem::transmute(x) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/wrong-dyn-trait-generic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr index 1dcbd9c774de..47efd0b0428c 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr @@ -6,8 +6,6 @@ LL | let _y: *const dyn fmt::Debug = unsafe { mem::transmute(x) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/validity/wrong-dyn-trait.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr index 7adcb28e4bcb..99e06e7febf5 100644 --- a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr @@ -6,8 +6,6 @@ LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/fail/weak_memory/weak_uninit.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/zst_local_oob.stderr b/src/tools/miri/tests/fail/zst_local_oob.stderr index 5bb29514d9a7..4c6c1be6fd23 100644 --- a/src/tools/miri/tests/fail/zst_local_oob.stderr +++ b/src/tools/miri/tests/fail/zst_local_oob.stderr @@ -6,8 +6,6 @@ LL | let _val = unsafe { *x }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/zst_local_oob.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.make.stderr b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.make.stderr index d74fa12256bb..d866b8514c96 100644 --- a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.make.stderr +++ b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.make.stderr @@ -12,8 +12,6 @@ help: ALLOC was allocated here: | LL | let mut b = Box::new(0u64); | ^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `miri_start` at tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.rs:LL:CC note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.send.stderr b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.send.stderr index d74fa12256bb..d866b8514c96 100644 --- a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.send.stderr +++ b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.send.stderr @@ -12,8 +12,6 @@ help: ALLOC was allocated here: | LL | let mut b = Box::new(0u64); | ^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `miri_start` at tests/genmc/fail/atomics/atomic_ptr_invalid_provenance.rs:LL:CC note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr b/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr index 290cdf90a084..ad98ba6aeb9a 100644 --- a/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr @@ -4,9 +4,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/loom/buggy_inc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr b/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr index 7742790e3330..658914ba088d 100644 --- a/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr @@ -4,9 +4,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/loom/store_buffering.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr b/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr index a6c3ed7055e7..d2036d464bb5 100644 --- a/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr @@ -3,9 +3,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/loom/store_buffering.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr index 80ac7206644c..d6c66bf8f5c4 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr @@ -4,9 +4,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/simple/2w2w_weak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr index 80ac7206644c..d6c66bf8f5c4 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr @@ -4,9 +4,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/simple/2w2w_weak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr index 80ac7206644c..d6c66bf8f5c4 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr @@ -4,9 +4,6 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `miri_start` at tests/genmc/fail/simple/2w2w_weak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/fail/function_not_in_so.stderr b/src/tools/miri/tests/native-lib/fail/function_not_in_so.stderr index 632696e8249a..fd99ab53a924 100644 --- a/src/tools/miri/tests/native-lib/fail/function_not_in_so.stderr +++ b/src/tools/miri/tests/native-lib/fail/function_not_in_so.stderr @@ -5,8 +5,6 @@ LL | foo(); | ^^^^^ unsupported operation occurred here | = help: this means the program tried to do something Miri does not support; it does not indicate a bug in the program - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/function_not_in_so.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/fail/pass_struct_expose_only_range.stderr b/src/tools/miri/tests/native-lib/fail/pass_struct_expose_only_range.stderr index a8f85001c233..8ef41fce35e6 100644 --- a/src/tools/miri/tests/native-lib/fail/pass_struct_expose_only_range.stderr +++ b/src/tools/miri/tests/native-lib/fail/pass_struct_expose_only_range.stderr @@ -8,8 +8,6 @@ LL | let r = access_struct_ptr(structs[1]); = help: in particular, Miri assumes that the native call initializes all memory it has access to = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/pass_struct_expose_only_range.rs:LL:CC error: Undefined Behavior: memory access failed: attempting to access 1 byte, but got $HEX[noalloc] which is a dangling pointer (it has no provenance) --> tests/native-lib/fail/pass_struct_expose_only_range.rs:LL:CC @@ -19,8 +17,6 @@ LL | let _val = *std::ptr::with_exposed_provenance::(structs[0].ptr. | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/pass_struct_expose_only_range.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/fail/private_function.stderr b/src/tools/miri/tests/native-lib/fail/private_function.stderr index 9b32d0c381b6..0e51835b0b82 100644 --- a/src/tools/miri/tests/native-lib/fail/private_function.stderr +++ b/src/tools/miri/tests/native-lib/fail/private_function.stderr @@ -5,8 +5,6 @@ LL | not_exported(); | ^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this means the program tried to do something Miri does not support; it does not indicate a bug in the program - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/private_function.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/fail/struct_not_extern_c.stderr b/src/tools/miri/tests/native-lib/fail/struct_not_extern_c.stderr index 90e59a31da42..a9158a0c6bac 100644 --- a/src/tools/miri/tests/native-lib/fail/struct_not_extern_c.stderr +++ b/src/tools/miri/tests/native-lib/fail/struct_not_extern_c.stderr @@ -5,8 +5,6 @@ LL | unsafe { pass_struct(pass_me) }; | ^^^^^^^^^^^^^^^^^^^^ unsupported operation occurred here | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/struct_not_extern_c.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr b/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr index 0fe6ad9c77bb..9833b65b91b3 100644 --- a/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr +++ b/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr @@ -6,8 +6,6 @@ LL | unsafe { pass_struct_complex(*arg.as_ptr(), 0, 0, 0) }; | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/native-lib/fail/uninit_struct.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index 3578a4863301..7774b75d5471 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-track-alloc-accesses -//@normalize-stderr-test: "id \d+" -> "id $$ALLOC" #[path = "../utils/mod.rs"] mod utils; diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index cc0cf1f277d5..745fd89f9f54 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -3,18 +3,12 @@ note: now tracking allocation ALLOC of 123 bytes (alignment ALIGN bytes) | LL | utils::miri_track_alloc(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here - | - = note: BACKTRACE: - = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC note: write access at ALLOC[0..1] --> tests/pass/alloc-access-tracking.rs:LL:CC | LL | *ptr = 42; // Crucially, only a write is printed here, no read! | ^^^^^^^^^ tracking was triggered here - | - = note: BACKTRACE: - = note: inside `main` at tests/pass/alloc-access-tracking.rs:LL:CC note: read access at ALLOC[0..1] --> tests/pass/alloc-access-tracking.rs:LL:CC @@ -22,8 +16,6 @@ note: read access at ALLOC[0..1] LL | assert_eq!(*ptr, 42); | ^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: freed allocation ALLOC diff --git a/src/tools/miri/tests/pass/extern_types.stack.stderr b/src/tools/miri/tests/pass/extern_types.stack.stderr index bd51efeb3e3d..88825169e1cd 100644 --- a/src/tools/miri/tests/pass/extern_types.stack.stderr +++ b/src/tools/miri/tests/pass/extern_types.stack.stderr @@ -6,6 +6,4 @@ LL | let x: &Foo = unsafe { &*(ptr::without_provenance::<()>(16) as *const F | = help: `extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code = help: try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead - = note: BACKTRACE: - = note: inside `main` at tests/pass/extern_types.rs:LL:CC diff --git a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr b/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr index 8ca3c6c618ea..363f8a20f8da 100644 --- a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr +++ b/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr @@ -9,6 +9,4 @@ LL | let wildcard = &root0 as *const Cell as usize as *const Cell Date: Thu, 30 Oct 2025 13:54:46 +0400 Subject: [PATCH 255/525] Constify `ControlFlow` methods (no unstable features) --- library/core/src/ops/control_flow.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index b760a7c4e21e..e426ff7cc057 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -150,7 +150,8 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] - pub fn is_break(&self) -> bool { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn is_break(&self) -> bool { matches!(*self, ControlFlow::Break(_)) } @@ -166,7 +167,8 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] - pub fn is_continue(&self) -> bool { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn is_continue(&self) -> bool { matches!(*self, ControlFlow::Continue(_)) } @@ -257,7 +259,8 @@ impl ControlFlow { /// ``` #[inline] #[unstable(feature = "control_flow_ok", issue = "140266")] - pub fn break_ok(self) -> Result { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn break_ok(self) -> Result { match self { ControlFlow::Continue(c) => Err(c), ControlFlow::Break(b) => Ok(b), @@ -361,7 +364,8 @@ impl ControlFlow { /// ``` #[inline] #[unstable(feature = "control_flow_ok", issue = "140266")] - pub fn continue_ok(self) -> Result { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn continue_ok(self) -> Result { match self { ControlFlow::Continue(c) => Ok(c), ControlFlow::Break(b) => Err(b), From 20bddb16e0d2dc506e83d624bc713d76eeb72806 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 09:05:29 +0100 Subject: [PATCH 256/525] weak memory: fix non-atomic read clearing store buffer --- .../src/borrow_tracker/stacked_borrows/mod.rs | 4 +- .../src/borrow_tracker/tree_borrows/mod.rs | 2 +- src/tools/miri/src/concurrency/data_race.rs | 56 +++++++++---------- src/tools/miri/src/concurrency/weak_memory.rs | 8 +-- src/tools/miri/src/machine.rs | 14 ++--- .../miri/tests/pass/0weak_memory/weak.rs | 3 + .../{issue1643.rs => issue-miri-1643.rs} | 0 .../issue-miri-4655-mix-atomic-nonatomic.rs | 42 ++++++++++++++ 8 files changed, 84 insertions(+), 45 deletions(-) rename src/tools/miri/tests/pass/concurrency/{issue1643.rs => issue-miri-1643.rs} (100%) create mode 100644 src/tools/miri/tests/pass/concurrency/issue-miri-4655-mix-atomic-nonatomic.rs diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 488de363bbe0..76ede552baa2 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -749,7 +749,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { // Make sure the data race model also knows about this. // FIXME(genmc): Ensure this is still done in GenMC mode. Check for other places where GenMC may need to be informed. if let Some(data_race) = alloc_extra.data_race.as_vclocks_mut() { - data_race.write( + data_race.write_non_atomic( alloc_id, range, NaWriteType::Retag, @@ -798,7 +798,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(access, AccessKind::Read); // Make sure the data race model also knows about this. if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() { - data_race.read( + data_race.read_non_atomic( alloc_id, range, NaReadType::Retag, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 865097af1018..5c905fc161f0 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -366,7 +366,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Also inform the data race model (but only if any bytes are actually affected). if range_in_alloc.size.bytes() > 0 { if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() { - data_race.read( + data_race.read_non_atomic( alloc_id, range_in_alloc, NaReadType::Retag, diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index bc1bb93a744d..e624baab5646 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -648,18 +648,17 @@ impl MemoryCellClocks { thread_clocks.clock.index_mut(index).span = current_span; } thread_clocks.clock.index_mut(index).set_read_type(read_type); - if self.write_was_before(&thread_clocks.clock) { - // We must be ordered-after all atomic writes. - let race_free = if let Some(atomic) = self.atomic() { - atomic.write_vector <= thread_clocks.clock - } else { - true - }; - self.read.set_at_index(&thread_clocks.clock, index); - if race_free { Ok(()) } else { Err(DataRace) } - } else { - Err(DataRace) + // Check synchronization with non-atomic writes. + if !self.write_was_before(&thread_clocks.clock) { + return Err(DataRace); } + // Check synchronization with atomic writes. + if !self.atomic().is_none_or(|atomic| atomic.write_vector <= thread_clocks.clock) { + return Err(DataRace); + } + // Record this access. + self.read.set_at_index(&thread_clocks.clock, index); + Ok(()) } /// Detect races for non-atomic write operations at the current memory cell @@ -675,24 +674,21 @@ impl MemoryCellClocks { if !current_span.is_dummy() { thread_clocks.clock.index_mut(index).span = current_span; } - if self.write_was_before(&thread_clocks.clock) && self.read <= thread_clocks.clock { - let race_free = if let Some(atomic) = self.atomic() { - atomic.write_vector <= thread_clocks.clock - && atomic.read_vector <= thread_clocks.clock - } else { - true - }; - self.write = (index, thread_clocks.clock[index]); - self.write_type = write_type; - if race_free { - self.read.set_zero_vector(); - Ok(()) - } else { - Err(DataRace) - } - } else { - Err(DataRace) + // Check synchronization with non-atomic accesses. + if !(self.write_was_before(&thread_clocks.clock) && self.read <= thread_clocks.clock) { + return Err(DataRace); } + // Check synchronization with atomic accesses. + if !self.atomic().is_none_or(|atomic| { + atomic.write_vector <= thread_clocks.clock && atomic.read_vector <= thread_clocks.clock + }) { + return Err(DataRace); + } + // Record this access. + self.write = (index, thread_clocks.clock[index]); + self.write_type = write_type; + self.read.set_zero_vector(); + Ok(()) } } @@ -1201,7 +1197,7 @@ impl VClockAlloc { /// operation for which data-race detection is handled separately, for example /// atomic read operations. The `ty` parameter is used for diagnostics, letting /// the user know which type was read. - pub fn read<'tcx>( + pub fn read_non_atomic<'tcx>( &self, alloc_id: AllocId, access_range: AllocRange, @@ -1243,7 +1239,7 @@ impl VClockAlloc { /// being created or if it is temporarily disabled during a racy read or write /// operation. The `ty` parameter is used for diagnostics, letting /// the user know which type was written. - pub fn write<'tcx>( + pub fn write_non_atomic<'tcx>( &mut self, alloc_id: AllocId, access_range: AllocRange, diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 6ebade6a568a..4f6eaf3ade11 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -177,11 +177,11 @@ impl StoreBufferAlloc { Self { store_buffers: RefCell::new(RangeObjectMap::new()) } } - /// When a non-atomic access happens on a location that has been atomically accessed - /// before without data race, we can determine that the non-atomic access fully happens + /// When a non-atomic write happens on a location that has been atomically accessed + /// before without data race, we can determine that the non-atomic write fully happens /// after all the prior atomic writes so the location no longer needs to exhibit - /// any weak memory behaviours until further atomic accesses. - pub fn memory_accessed(&self, range: AllocRange, global: &DataRaceState) { + /// any weak memory behaviours until further atomic writes. + pub fn non_atomic_write(&self, range: AllocRange, global: &DataRaceState) { if !global.ongoing_action_data_race_free() { let mut buffers = self.store_buffers.borrow_mut(); let access_type = buffers.access_type(range); diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 9c6eafbd7418..33f854bee23d 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1536,14 +1536,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { genmc_ctx.memory_load(machine, ptr.addr(), range.size)?, GlobalDataRaceHandler::Vclocks(_data_race) => { let _trace = enter_trace_span!(data_race::before_memory_read); - let AllocDataRaceHandler::Vclocks(data_race, weak_memory) = &alloc_extra.data_race + let AllocDataRaceHandler::Vclocks(data_race, _weak_memory) = &alloc_extra.data_race else { unreachable!(); }; - data_race.read(alloc_id, range, NaReadType::Read, None, machine)?; - if let Some(weak_memory) = weak_memory { - weak_memory.memory_accessed(range, machine.data_race.as_vclocks_ref().unwrap()); - } + data_race.read_non_atomic(alloc_id, range, NaReadType::Read, None, machine)?; } } if let Some(borrow_tracker) = &alloc_extra.borrow_tracker { @@ -1579,9 +1576,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { else { unreachable!() }; - data_race.write(alloc_id, range, NaWriteType::Write, None, machine)?; + data_race.write_non_atomic(alloc_id, range, NaWriteType::Write, None, machine)?; if let Some(weak_memory) = weak_memory { - weak_memory.memory_accessed(range, machine.data_race.as_vclocks_ref().unwrap()); + weak_memory + .non_atomic_write(range, machine.data_race.as_vclocks_ref().unwrap()); } } } @@ -1612,7 +1610,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { GlobalDataRaceHandler::Vclocks(_global_state) => { let _trace = enter_trace_span!(data_race::before_memory_deallocation); let data_race = alloc_extra.data_race.as_vclocks_mut().unwrap(); - data_race.write( + data_race.write_non_atomic( alloc_id, alloc_range(Size::ZERO, size), NaWriteType::Deallocate, diff --git a/src/tools/miri/tests/pass/0weak_memory/weak.rs b/src/tools/miri/tests/pass/0weak_memory/weak.rs index e329bbff1aae..c5125e636001 100644 --- a/src/tools/miri/tests/pass/0weak_memory/weak.rs +++ b/src/tools/miri/tests/pass/0weak_memory/weak.rs @@ -92,6 +92,9 @@ fn initialization_write(add_fence: bool) { let j1 = spawn(move || { x.store(22, Relaxed); + // Since nobody else writes to `x`, we can non-atomically read it. + // (This tests that we do not delete the store buffer here.) + unsafe { std::ptr::from_ref(x).read() }; // Relaxed is intentional. We want to test if the thread 2 reads the initialisation write // after a relaxed write wait.store(1, Relaxed); diff --git a/src/tools/miri/tests/pass/concurrency/issue1643.rs b/src/tools/miri/tests/pass/concurrency/issue-miri-1643.rs similarity index 100% rename from src/tools/miri/tests/pass/concurrency/issue1643.rs rename to src/tools/miri/tests/pass/concurrency/issue-miri-1643.rs diff --git a/src/tools/miri/tests/pass/concurrency/issue-miri-4655-mix-atomic-nonatomic.rs b/src/tools/miri/tests/pass/concurrency/issue-miri-4655-mix-atomic-nonatomic.rs new file mode 100644 index 000000000000..fd9d3a349d2c --- /dev/null +++ b/src/tools/miri/tests/pass/concurrency/issue-miri-4655-mix-atomic-nonatomic.rs @@ -0,0 +1,42 @@ +//! This reproduces #4655 every single time +//@ compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{ptr, thread}; + +const SIZE: usize = 256; + +static mut ARRAY: [u8; SIZE] = [0; _]; +// Everything strictly less than this has been initialized by the sender. +static POS: AtomicUsize = AtomicUsize::new(0); + +fn main() { + // Sender + let th = std::thread::spawn(|| { + for i in 0..SIZE { + unsafe { ptr::write(&raw mut ARRAY[i], 1) }; + POS.store(i + 1, Ordering::Release); + + thread::yield_now(); + + // We are the only writer, so we can do non-atomic reads as well. + unsafe { (&raw const POS).cast::().read() }; + } + }); + + // Receiver + loop { + let i = POS.load(Ordering::Acquire); + + if i > 0 { + unsafe { ptr::read(&raw const ARRAY[i - 1]) }; + } + + if i == SIZE { + break; + } + + thread::yield_now(); + } + + th.join().unwrap(); +} From 851b10f4554931c88c04f060c899a66dd5b0028a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Oct 2025 10:10:00 +0100 Subject: [PATCH 257/525] add store buffer initialization sanity check that would have caught the bug --- src/tools/miri/src/concurrency/data_race.rs | 41 ++++++++++++++++--- src/tools/miri/src/concurrency/weak_memory.rs | 14 +++++-- .../miri/tests/pass/0weak_memory/weak.rs | 7 ++++ 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index e624baab5646..75c1d0f6a798 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -688,6 +688,8 @@ impl MemoryCellClocks { self.write = (index, thread_clocks.clock[index]); self.write_type = write_type; self.read.set_zero_vector(); + // This is not an atomic location any more. + self.atomic_ops = None; Ok(()) } } @@ -754,14 +756,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); this.atomic_access_check(dest, AtomicAccessType::Store)?; - // Read the previous value so we can put it in the store buffer later. - // The program didn't actually do a read, so suppress the memory access hooks. - // This is also a very special exception where we just ignore an error -- if this read - // was UB e.g. because the memory is uninitialized, we don't want to know! - let old_val = this.run_for_validation_ref(|this| this.read_scalar(dest)).discard_err(); - // Inform GenMC about the atomic store. if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() { + let old_val = this.run_for_validation_ref(|this| this.read_scalar(dest)).discard_err(); if genmc_ctx.atomic_store( this, dest.ptr().addr(), @@ -776,6 +773,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { } return interp_ok(()); } + + // Read the previous value so we can put it in the store buffer later. + let old_val = this.get_latest_nonatomic_val(dest); this.allow_data_races_mut(move |this| this.write_scalar(val, dest))?; this.validate_atomic_store(dest, atomic)?; this.buffered_atomic_write(val, dest, atomic, old_val) @@ -1536,6 +1536,35 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { ) } + /// Returns the most recent *non-atomic* value stored in the given place. + /// Errors if we don't need that (because we don't do store buffering) or if + /// the most recent value is in fact atomic. + fn get_latest_nonatomic_val(&self, place: &MPlaceTy<'tcx>) -> Result, ()> { + let this = self.eval_context_ref(); + // These cannot fail because `atomic_access_check` was done first. + let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(place.ptr(), 0).unwrap(); + let alloc_meta = &this.get_alloc_extra(alloc_id).unwrap().data_race; + if alloc_meta.as_weak_memory_ref().is_none() { + // No reason to read old value if we don't track store buffers. + return Err(()); + } + let data_race = alloc_meta.as_vclocks_ref().unwrap(); + // Only read old value if this is currently a non-atomic location. + for (_range, clocks) in data_race.alloc_ranges.borrow_mut().iter(offset, place.layout.size) + { + // If this had an atomic write that's not before the non-atomic write, that should + // already be in the store buffer. Initializing the store buffer now would use the + // wrong `sync_clock` so we better make sure that does not happen. + if clocks.atomic().is_some_and(|atomic| !(atomic.write_vector <= clocks.write())) { + return Err(()); + } + } + // The program didn't actually do a read, so suppress the memory access hooks. + // This is also a very special exception where we just ignore an error -- if this read + // was UB e.g. because the memory is uninitialized, we don't want to know! + Ok(this.run_for_validation_ref(|this| this.read_scalar(place)).discard_err()) + } + /// Generic atomic operation implementation fn validate_atomic_op( &self, diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 4f6eaf3ade11..2255e0d48174 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -223,18 +223,23 @@ impl StoreBufferAlloc { fn get_or_create_store_buffer_mut<'tcx>( &mut self, range: AllocRange, - init: Option, + init: Result, ()>, ) -> InterpResult<'tcx, &mut StoreBuffer> { let buffers = self.store_buffers.get_mut(); let access_type = buffers.access_type(range); let pos = match access_type { AccessType::PerfectlyOverlapping(pos) => pos, AccessType::Empty(pos) => { + let init = + init.expect("cannot have empty store buffer when previous write was atomic"); buffers.insert_at_pos(pos, range, StoreBuffer::new(init)); pos } AccessType::ImperfectlyOverlapping(pos_range) => { // Once we reach here we would've already checked that this access is not racy. + let init = init.expect( + "cannot have partially overlapping store buffer when previous write was atomic", + ); buffers.remove_pos_range(pos_range.clone()); buffers.insert_at_pos(pos_range.start, range, StoreBuffer::new(init)); pos_range.start @@ -490,7 +495,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let range = alloc_range(base_offset, place.layout.size); let sync_clock = data_race_clocks.sync_clock(range); - let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, Some(init))?; + let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, Ok(Some(init)))?; // The RMW always reads from the most recent store. buffer.read_from_last_store(global, threads, atomic == AtomicRwOrd::SeqCst); buffer.buffered_write( @@ -556,7 +561,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Add the given write to the store buffer. (Does not change machine memory.) /// /// `init` says with which value to initialize the store buffer in case there wasn't a store - /// buffer for this memory range before. + /// buffer for this memory range before. `Err(())` means the value is not available; + /// `Ok(None)` means the memory does not contain a valid scalar. /// /// Must be called *after* `validate_atomic_store` to ensure that `sync_clock` is up-to-date. fn buffered_atomic_write( @@ -564,7 +570,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { val: Scalar, dest: &MPlaceTy<'tcx>, atomic: AtomicWriteOrd, - init: Option, + init: Result, ()>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr(), 0)?; diff --git a/src/tools/miri/tests/pass/0weak_memory/weak.rs b/src/tools/miri/tests/pass/0weak_memory/weak.rs index c5125e636001..8d3c85186175 100644 --- a/src/tools/miri/tests/pass/0weak_memory/weak.rs +++ b/src/tools/miri/tests/pass/0weak_memory/weak.rs @@ -88,6 +88,13 @@ fn initialization_write(add_fence: bool) { check_all_outcomes([11, 22], || { let x = static_atomic(11); + if add_fence { + // For the fun of it, let's make this location atomic and non-atomic again, + // to ensure Miri updates the state properly for that. + x.store(99, Relaxed); + unsafe { std::ptr::from_ref(x).cast_mut().write(11.into()) }; + } + let wait = static_atomic(0); let j1 = spawn(move || { From 2fbb75198536302356e430fdff54f8a03463c4c2 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Thu, 30 Oct 2025 20:22:45 +0800 Subject: [PATCH 258/525] Un-shadow object bound candidate in `NormalizesTo` goal --- .../src/solve/assembly/mod.rs | 6 ++++++ .../use_object_if_empty_env.rs | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs 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 c9a42dddac42..42eb804431e4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -1143,6 +1143,12 @@ where // See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`. if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_))); + } else if matches!(goal.predicate.self_ty().kind(), ty::Dynamic(..)) { + // Object candidate may be shadowed by where-bound for the trait goal, see + // `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`. + // Trait objects always have their associated types specified so `candidates` + // won't be empty. + self.assemble_object_bound_candidates(goal, &mut candidates); } else if candidates.is_empty() { // If the trait goal has been proven by using the environment, we want to treat // aliases as rigid if there are no applicable projection bounds in the environment. diff --git a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs new file mode 100644 index 000000000000..ec3a94a97294 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +trait Trait { + type Assoc; +} + +// We have param env candidate for the trait goal but not the projection. +// Under such circumstance, consider object candidate if the self_ty is trait object. +fn foo(x: as Trait>::Assoc) -> T +where + dyn Trait: Trait, +{ + x +} + +fn main() {} From 2ac9a9a48c79437743b2f96082f6e44cf9900f79 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 31 Oct 2025 00:45:05 +0900 Subject: [PATCH 259/525] fix: Do not make false positive syntax errors on frontmatter --- .../rust-analyzer/crates/parser/src/grammar.rs | 10 ++++++++++ .../parser/test_data/generated/runner.rs | 2 ++ .../parser/inline/ok/frontmatter.rast | 18 ++++++++++++++++++ .../test_data/parser/inline/ok/frontmatter.rs | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rs diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs index 8ddf50db043a..bf8430294110 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs @@ -94,7 +94,17 @@ pub(crate) mod entry { pub(crate) fn source_file(p: &mut Parser<'_>) { let m = p.start(); + // test frontmatter + // #!/usr/bin/env cargo + // + // --- + // [dependencies] + // clap = { version = "4.2", features = ["derive"] } + // --- + // + // fn main() {} p.eat(SHEBANG); + p.eat(FRONTMATTER); items::mod_contents(p, false); m.complete(p, SOURCE_FILE); } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index c56eb5090cee..7f5ff0ec0735 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -265,6 +265,8 @@ mod ok { #[test] fn for_type() { run_and_expect_no_errors("test_data/parser/inline/ok/for_type.rs"); } #[test] + fn frontmatter() { run_and_expect_no_errors("test_data/parser/inline/ok/frontmatter.rs"); } + #[test] fn full_range_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/full_range_expr.rs"); } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rast new file mode 100644 index 000000000000..bad895929316 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rast @@ -0,0 +1,18 @@ +SOURCE_FILE + SHEBANG "#!/usr/bin/env cargo\n" + FRONTMATTER "\n---\n[dependencies]\nclap = { version = \"4.2\", features = [\"derive\"] }\n---\n" + WHITESPACE "\n" + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "main" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rs new file mode 100644 index 000000000000..1f9f7a76284c --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/frontmatter.rs @@ -0,0 +1,8 @@ +#!/usr/bin/env cargo + +--- +[dependencies] +clap = { version = "4.2", features = ["derive"] } +--- + +fn main() {} From 2a5d830bd645a72e4e41476bb039cce2896b5bb2 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Thu, 30 Oct 2025 19:19:25 +0300 Subject: [PATCH 260/525] Do not double check for already decoded expn_id to avoid races --- compiler/rustc_metadata/src/rmeta/decoder.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b895feb90624..808d9fbbc2ce 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1560,7 +1560,6 @@ impl<'a> CrateMetadataRef<'a> { } fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId { - debug_assert_eq!(ExpnId::from_hash(hash), None); let index_guess = ExpnIndex::from_u32(index_guess); let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self)); From fd378ce0b89f6d18f274a15738177c8b175c3305 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Fri, 31 Oct 2025 00:36:21 -0400 Subject: [PATCH 261/525] Fix typos, backtick errors/omissions --- .../crates/ide/src/syntax_highlighting.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 66895cb0b053..531c7e1f4d38 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -114,9 +114,9 @@ pub struct HighlightConfig<'a> { // |-----------|--------------------------------| // |operator| Emitted for general operators.| // |arithmetic| Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.| -// |bitwise| Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.| +// |bitwise| Emitted for the bitwise operators `\|`, `&`, `!`, `^`, `\|=`, `&=`, `^=`.| // |comparison| Emitted for the comparison oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.| -// |logical| Emitted for the logical operators `||`, `&&`, `!`.| +// |logical| Emitted for the logical operators `\|\|`, `&&`, `!`.| // // - For punctuation: // @@ -172,20 +172,20 @@ pub struct HighlightConfig<'a> { // |constant| Emitted for const.| // |consuming| Emitted for locals that are being consumed when use in a function call.| // |controlFlow| Emitted for control-flow related tokens, this includes th `?` operator.| -// |crateRoot| Emitted for crate names, like `serde` and `crate.| +// |crateRoot| Emitted for crate names, like `serde` and `crate`.| // |declaration| Emitted for names of definitions, like `foo` in `fn foo(){}`.| -// |defaultLibrary| Emitted for items from built-in crates (std, core, allc, test and proc_macro).| +// |defaultLibrary| Emitted for items from built-in crates (std, core, alloc, test and proc_macro).| // |documentation| Emitted for documentation comment.| // |injected| Emitted for doc-string injected highlighting like rust source blocks in documentation.| // |intraDocLink| Emitted for intra doc links in doc-string.| -// |library| Emitted for items that are defined outside of the current crae.| +// |library| Emitted for items that are defined outside of the current crate.| // |macro| Emitted for tokens inside macro call.| // |mutable| Emitted for mutable locals and statics as well as functions taking `&mut self`.| -// |public| Emitted for items that are from the current crate and are `pub.| -// |reference| Emitted for locals behind a reference and functions taking self` by reference.| -// |static| Emitted for "static" functions, also known as functions that d not take a `self` param, as well as statics and consts.| +// |public| Emitted for items that are from the current crate and are `pub`.| +// |reference| Emitted for locals behind a reference and functions taking `self` by reference.| +// |static| Emitted for "static" functions, also known as functions that do not take a `self` param, as well as statics and consts.| // |trait| Emitted for associated trait item.| -// |unsafe| Emitted for unsafe operations, like unsafe function calls, as ell as the `unsafe` token.| +// |unsafe| Emitted for unsafe operations, like unsafe function calls, as well as the `unsafe` token.| // // ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png) // ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png) From cac6f8760a6abca336a81f28e5508ebf4ca6f693 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Jul 2025 11:50:21 +0000 Subject: [PATCH 262/525] Do not emit solver errors that contain error types --- compiler/rustc_infer/src/traits/project.rs | 3 +- .../src/error_reporting/traits/mod.rs | 7 +- .../rustc_trait_selection/src/traits/mod.rs | 5 +- .../invalid_const_in_lifetime_position.rs | 5 - .../invalid_const_in_lifetime_position.stderr | 85 +--------- .../generic_const_exprs/issue-102768.rs | 5 - .../generic_const_exprs/issue-102768.stderr | 85 +--------- .../gat-in-trait-path-undeclared-lifetime.rs | 3 - ...t-in-trait-path-undeclared-lifetime.stderr | 38 +---- .../gat-trait-path-parenthesised-args.rs | 9 -- .../gat-trait-path-parenthesised-args.stderr | 145 +----------------- .../generic-associated-types/issue-67510.rs | 1 - .../issue-67510.stderr | 21 +-- .../generic-associated-types/issue-71176.rs | 4 - .../issue-71176.stderr | 73 +-------- .../missing_lifetime_args.rs | 3 - .../missing_lifetime_args.stderr | 59 +------ .../trait-path-type-error-once-implemented.rs | 5 - ...it-path-type-error-once-implemented.stderr | 85 +--------- tests/ui/layout/issue-84108.rs | 2 - tests/ui/layout/issue-84108.stderr | 23 +-- .../next-solver/issue-118950-root-region.rs | 2 - .../issue-118950-root-region.stderr | 25 +-- tests/ui/transmutability/issue-101739-1.rs | 1 - .../ui/transmutability/issue-101739-1.stderr | 11 +- 25 files changed, 35 insertions(+), 670 deletions(-) diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 9082db4f4488..9dd35b6de308 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -2,6 +2,7 @@ use rustc_data_structures::snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage}; use rustc_data_structures::undo_log::Rollback; +use rustc_macros::TypeVisitable; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty; use tracing::{debug, info}; @@ -12,7 +13,7 @@ use crate::infer::snapshot::undo_log::InferCtxtUndoLogs; pub(crate) type UndoLog<'tcx> = snapshot_map::UndoLog, ProjectionCacheEntry<'tcx>>; -#[derive(Clone)] +#[derive(Clone, TypeVisitable)] pub struct MismatchedProjectionTypes<'tcx> { pub err: ty::error::TypeError<'tcx>, } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index ded5969e83c5..58e220cfbe7d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -20,7 +20,7 @@ use rustc_infer::traits::{ PredicateObligation, SelectionError, }; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span}; use tracing::{info, instrument}; @@ -253,7 +253,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for from_expansion in [false, true] { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { - if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { + if !suppressed + && error.obligation.cause.span.from_expansion() == from_expansion + && !error.references_error() + { let guar = self.report_fulfillment_error(error); self.infcx.set_tainted_by_errors(guar); reported = Some(guar); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0f3b38ef6675..308d533e6899 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -29,6 +29,7 @@ use std::ops::ControlFlow; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; pub use rustc_infer::traits::*; +use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -75,7 +76,7 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::regions::InferCtxtRegionExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -#[derive(Debug)] +#[derive(Debug, TypeVisitable)] pub struct FulfillmentError<'tcx> { pub obligation: PredicateObligation<'tcx>, pub code: FulfillmentErrorCode<'tcx>, @@ -107,7 +108,7 @@ impl<'tcx> FulfillmentError<'tcx> { } } -#[derive(Clone)] +#[derive(Clone, TypeVisitable)] pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only /// if it is already implemented. diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs index 427c84679ba1..c3f4fd63bac7 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs @@ -4,8 +4,3 @@ trait X { fn f<'a>(arg : Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments -//~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments -//~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR trait `X` is not dyn compatible diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr index 2c25589a5531..a29cf5bf5ad9 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | +++ +error: aborting due to 2 previous errors -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/invalid_const_in_lifetime_position.rs:4:20 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs index 882b27a418e5..18a9b53cf768 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs @@ -9,11 +9,6 @@ const _: () = { fn f2<'a>(arg: Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR `X` is not dyn compatible }; fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr index 57b61006631f..8e972100173f 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | +++ +error: aborting due to 2 previous errors -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/issue-102768.rs:9:24 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-102768.rs:5:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs index b02739a7d0ac..86b164ba7d8a 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs +++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs @@ -6,7 +6,4 @@ fn main() { fn _f(arg : Box X = &'a [u32]>>) {} //~^ ERROR: use of undeclared lifetime name `'x` //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: the trait `X` is not dyn compatible } diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr index c9b46de5c33c..b77f10084c92 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr @@ -20,39 +20,7 @@ error[E0582]: binding for associated type `Y` references lifetime `'a`, which do LL | fn _f(arg : Box X = &'a [u32]>>) {} | ^^^^^^^^^^^^^^^^^ -error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: aborting due to 2 previous errors -error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:19 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'x>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0038, E0261, E0582. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0261, E0582. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index 294fb6743fbc..22f4918fb191 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -7,19 +7,10 @@ fn foo<'a>(arg: Box>) {} //~| ERROR: parenthesized generic arguments cannot be used //~| ERROR associated type takes 0 generic arguments but 1 generic argument //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR at least one trait is required - //~| ERROR: the trait `X` is not dyn compatible fn bar<'a>(arg: Box>) {} //~^ ERROR: parenthesized generic arguments cannot be used //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR: the trait `X` is not dyn compatible fn main() {} diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index e18d8198c945..23199fae28b5 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -22,7 +22,7 @@ LL + fn foo<'a>(arg: Box = &'a ()>>) {} | error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 + --> $DIR/gat-trait-path-parenthesised-args.rs:12:27 | LL | fn bar<'a>(arg: Box>) {} | ^-- @@ -60,93 +60,7 @@ LL | type Y<'a>; | ^ error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn foo<'a>(arg: Box>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^---- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn foo<'a>(arg: Box>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^---- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0224]: at least one trait is required for an object type - --> $DIR/gat-trait-path-parenthesised-args.rs:5:29 - | -LL | fn foo<'a>(arg: Box>) {} - | ^^ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-trait-path-parenthesised-args.rs:5:21 - | -LL | fn foo<'a>(arg: Box>) {} - | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 + --> $DIR/gat-trait-path-parenthesised-args.rs:12:27 | LL | fn bar<'a>(arg: Box>) {} | ^ expected 1 lifetime argument @@ -161,57 +75,6 @@ help: add missing lifetime argument LL | fn bar<'a>(arg: Box>) {} | ++ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 - | -LL | fn bar<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn bar<'a>(arg: Box>) {} - | ++ +error: aborting due to 6 previous errors -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 - | -LL | fn bar<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn bar<'a>(arg: Box>) {} - | ++ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-trait-path-parenthesised-args.rs:18:21 - | -LL | fn bar<'a>(arg: Box>) {} - | ^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 15 previous errors - -Some errors have detailed explanations: E0038, E0107, E0224. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/issue-67510.rs b/tests/ui/generic-associated-types/issue-67510.rs index 5c3150a77ed1..2db9fb82aaec 100644 --- a/tests/ui/generic-associated-types/issue-67510.rs +++ b/tests/ui/generic-associated-types/issue-67510.rs @@ -5,6 +5,5 @@ trait X { fn f(x: Box = &'a ()>>) {} //~^ ERROR: use of undeclared lifetime name `'a` //~| ERROR: use of undeclared lifetime name `'a` -//~| ERROR: the trait `X` is not dyn compatible [E0038] fn main() {} diff --git a/tests/ui/generic-associated-types/issue-67510.stderr b/tests/ui/generic-associated-types/issue-67510.stderr index f5c494788ea5..34d867621d7e 100644 --- a/tests/ui/generic-associated-types/issue-67510.stderr +++ b/tests/ui/generic-associated-types/issue-67510.stderr @@ -29,23 +29,6 @@ help: consider introducing lifetime `'a` here LL | fn f<'a>(x: Box = &'a ()>>) {} | ++++ -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/issue-67510.rs:5:13 - | -LL | fn f(x: Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-67510.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0261. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index 8ecfa93750d4..f0e162d825f9 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -9,14 +9,10 @@ impl Provider for () { struct Holder { inner: Box>, //~^ ERROR: missing generics for associated type - //~| ERROR: missing generics for associated type - //~| ERROR: missing generics for associated type - //~| ERROR: the trait `Provider` is not dyn compatible } fn main() { Holder { inner: Box::new(()), - //~^ ERROR: the trait `Provider` is not dyn compatible }; } diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index f231056a2eed..ed837f347533 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -14,75 +14,6 @@ help: add missing lifetime argument LL | inner: Box = B>>, | ++++ -error[E0107]: missing generics for associated type `Provider::A` - --> $DIR/issue-71176.rs:10:27 - | -LL | inner: Box>, - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-71176.rs:2:10 - | -LL | type A<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | inner: Box = B>>, - | ++++ +error: aborting due to 1 previous error -error[E0107]: missing generics for associated type `Provider::A` - --> $DIR/issue-71176.rs:10:27 - | -LL | inner: Box>, - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-71176.rs:2:10 - | -LL | type A<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | inner: Box = B>>, - | ++++ - -error[E0038]: the trait `Provider` is not dyn compatible - --> $DIR/issue-71176.rs:10:14 - | -LL | inner: Box>, - | ^^^^^^^^^^^^^^^^^^^ `Provider` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-71176.rs:2:10 - | -LL | trait Provider { - | -------- this trait is not dyn compatible... -LL | type A<'a>; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - = help: only type `()` implements `Provider`; consider using it directly instead. - -error[E0038]: the trait `Provider` is not dyn compatible - --> $DIR/issue-71176.rs:19:16 - | -LL | inner: Box::new(()), - | ^^^^^^^^^^^^ `Provider` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-71176.rs:2:10 - | -LL | trait Provider { - | -------- this trait is not dyn compatible... -LL | type A<'a>; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - = help: only type `()` implements `Provider`; consider using it directly instead. - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs index e0f2db5eb21e..331511ba61a4 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.rs +++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs @@ -10,9 +10,6 @@ struct Foo<'a, 'b, 'c> { fn foo<'c, 'd>(_arg: Box>) {} //~^ ERROR missing generics for associated type -//~| ERROR missing generics for associated type -//~| ERROR missing generics for associated type -//~| ERROR the trait `X` is not dyn compatible fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} //~^ ERROR struct takes 3 lifetime arguments but 2 lifetime diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr index 7b6888817f4f..1a7a2e787a1a 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr @@ -14,58 +14,8 @@ help: add missing lifetime arguments LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} | ++++++++ -error[E0107]: missing generics for associated type `X::Y` - --> $DIR/missing_lifetime_args.rs:11:32 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^ expected 2 lifetime arguments - | -note: associated type defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | type Y<'a, 'b>; - | ^ -- -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime arguments - | -LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} - | ++++++++ - -error[E0107]: missing generics for associated type `X::Y` - --> $DIR/missing_lifetime_args.rs:11:32 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^ expected 2 lifetime arguments - | -note: associated type defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | type Y<'a, 'b>; - | ^ -- -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime arguments - | -LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} - | ++++++++ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/missing_lifetime_args.rs:11:26 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a, 'b>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/missing_lifetime_args.rs:17:26 + --> $DIR/missing_lifetime_args.rs:14:26 | LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} | ^^^ -- -- supplied 2 lifetime arguments @@ -83,7 +33,7 @@ LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {} | ++++ error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing_lifetime_args.rs:20:16 + --> $DIR/missing_lifetime_args.rs:17:16 | LL | fn f<'a>(_arg: Foo<'a>) {} | ^^^ -- supplied 1 lifetime argument @@ -100,7 +50,6 @@ help: add missing lifetime arguments LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {} | ++++++++ -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs index c828691bb305..c58f9cf1dfc8 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs @@ -6,11 +6,6 @@ const _: () = { fn f2<'a>(arg : Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR the trait `X` is not dyn compatible }; fn main() {} diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index 45bca1a76287..682fa27ab5d6 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | +++ +error: aborting due to 2 previous errors -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/trait-path-type-error-once-implemented.rs:6:23 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 33884617acbf..07ff3d3c0e3e 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -8,8 +8,6 @@ static FOO: (dyn AsRef, u8) = ("hello", 42); const BAR: (&Path, [u8], usize) = ("hello", [], 42); //~^ ERROR cannot find type `Path` in this scope -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time //~| ERROR mismatched types static BAZ: ([u8], usize) = ([], 0); diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 62a6ae341fa6..08acc3d3b257 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -21,16 +21,7 @@ LL + use std::path::Path; | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:9:12 - | -LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); - | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:15:13 + --> $DIR/issue-84108.rs:13:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -38,16 +29,6 @@ LL | static BAZ: ([u8], usize) = ([], 0); = help: the trait `Sized` is not implemented for `[u8]` = note: only the last element of a tuple may have a dynamically sized type -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:9:12 - | -LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); - | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0308]: mismatched types --> $DIR/issue-84108.rs:9:45 | @@ -57,7 +38,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = note: expected slice `[u8]` found array `[_; 0]` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index fe336766891d..84e2f4c94386 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -18,7 +18,5 @@ impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} //~^ ERROR cannot find type `Missing` in this scope -//~| ERROR the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied -//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index ce4f742a3fa9..e934c5cdc749 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,30 +26,7 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:9 - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-118950-root-region.rs:8:1 - | -LL | trait ToUnit<'a> { - | ^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:47 - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^ the trait `Overlap fn(Assoc<'a, T>)>` is not implemented for `T` - | -help: consider further restricting type parameter `T` with trait `Overlap` - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap, T: Overlap fn(Assoc<'a, T>)> {} - | ++++++++++++++++++++++++++++++++++++++ - -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: E0277, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs index b801e2355404..afd8aba51ce9 100644 --- a/tests/ui/transmutability/issue-101739-1.rs +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -6,7 +6,6 @@ mod assert { pub fn is_transmutable() where Dst: TransmuteFrom, //~ ERROR cannot find type `Dst` in this scope - //~| ERROR the constant `ASSUME_ALIGNMENT` is not of type `Assume` { } } diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index b3c640a00b4c..20bc8af47f8d 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -4,15 +4,6 @@ error[E0412]: cannot find type `Dst` in this scope LL | Dst: TransmuteFrom, | ^^^ not found in this scope -error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` - --> $DIR/issue-101739-1.rs:8:14 - | -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` - | -note: required by a const generic parameter in `TransmuteFrom` - --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0412`. From e2ac9d92d9f0ce0f4a08d8376649f740c4073439 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Fri, 31 Oct 2025 20:31:49 +0800 Subject: [PATCH 263/525] Apply suggestions --- .../src/solve/assembly/mod.rs | 17 ++++++++++------- .../use_object_if_empty_env.rs | 2 ++ 2 files changed, 12 insertions(+), 7 deletions(-) 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 42eb804431e4..221593d6eadb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -454,7 +454,16 @@ where self.assemble_object_bound_candidates(goal, &mut candidates); } } - AssembleCandidatesFrom::EnvAndBounds => {} + AssembleCandidatesFrom::EnvAndBounds => { + // This is somewhat inconsistent and may make #57893 slightly easier to exploit. + // However, it matches the behavior of the old solver. See + // `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`. + if matches!(normalized_self_ty.kind(), ty::Dynamic(..)) + && !candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) + { + self.assemble_object_bound_candidates(goal, &mut candidates); + } + } } (candidates, failed_candidate_info) @@ -1143,12 +1152,6 @@ where // See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`. if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_))); - } else if matches!(goal.predicate.self_ty().kind(), ty::Dynamic(..)) { - // Object candidate may be shadowed by where-bound for the trait goal, see - // `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`. - // Trait objects always have their associated types specified so `candidates` - // won't be empty. - self.assemble_object_bound_candidates(goal, &mut candidates); } else if candidates.is_empty() { // If the trait goal has been proven by using the environment, we want to treat // aliases as rigid if there are no applicable projection bounds in the environment. diff --git a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs index ec3a94a97294..c0bd2b49117b 100644 --- a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs +++ b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Znext-solver //@ check-pass +// Regression test for trait-system-refactor-initiative#244 + trait Trait { type Assoc; } From ad20e5c4680085002719af4b5650db68ccdb0459 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 27 Oct 2025 13:51:55 +0100 Subject: [PATCH 264/525] split definition and use site hidden tys --- compiler/rustc_borrowck/src/lib.rs | 4 +- .../src/region_infer/opaque_types/mod.rs | 116 +++++++++--------- compiler/rustc_borrowck/src/root_cx.rs | 12 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../rustc_hir_analysis/src/collect/type_of.rs | 8 +- .../src/collect/type_of/opaque.rs | 52 ++++---- compiler/rustc_hir_typeck/src/opaque_types.rs | 14 ++- compiler/rustc_hir_typeck/src/writeback.rs | 28 ++--- compiler/rustc_middle/src/arena.rs | 5 +- compiler/rustc_middle/src/mir/query.rs | 9 +- compiler/rustc_middle/src/query/mod.rs | 5 +- compiler/rustc_middle/src/ty/mod.rs | 67 ++++++++-- .../rustc_middle/src/ty/typeck_results.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- 14 files changed, 188 insertions(+), 138 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a57689a45b67..054af132a52b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) { fn mir_borrowck( tcx: TyCtxt<'_>, def: LocalDefId, -) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> { +) -> Result<&FxIndexMap>, ErrorGuaranteed> { assert!(!tcx.is_typeck_child(def.to_def_id())); let (input_body, _) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); @@ -130,7 +130,7 @@ fn mir_borrowck( Err(guar) } else if input_body.should_skip() { debug!("Skipping borrowck because of injected body"); - let opaque_types = DefinitionSiteHiddenTypes(Default::default()); + let opaque_types = Default::default(); Ok(tcx.arena.alloc(opaque_types)) } else { let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 67d1d44b1e1f..2294c6381625 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -8,10 +8,10 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries}; use rustc_infer::traits::ObligationCause; use rustc_macros::extension; -use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes}; +use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ - self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef, - OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, + self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, + GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions, }; use rustc_mir_dataflow::points::DenseLocationMap; @@ -131,27 +131,26 @@ fn nll_var_to_universal_region<'tcx>( /// and errors if we end up with distinct hidden types. fn add_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, def_id: LocalDefId, - hidden_ty: OpaqueHiddenType<'tcx>, + hidden_ty: ty::DefinitionSiteHiddenType<'tcx>, ) { // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to // `(X, Y)` and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we // only know that once we convert the generic parameters to those of the opaque type. - if let Some(prev) = hidden_types.0.get_mut(&def_id) { - if prev.ty != hidden_ty.ty { - let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| { - let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); - e - }); - prev.ty = Ty::new_error(tcx, guar); + if let Some(prev) = hidden_types.get_mut(&def_id) { + if prev.ty == hidden_ty.ty { + // Pick a better span if there is one. + // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. + prev.span = prev.span.substitute_dummy(hidden_ty.span); + } else { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); + *prev = ty::DefinitionSiteHiddenType::new_error(tcx, guar); } - // Pick a better span if there is one. - // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. - prev.span = prev.span.substitute_dummy(hidden_ty.span); } else { - hidden_types.0.insert(def_id, hidden_ty); + hidden_types.insert(def_id, hidden_ty); } } @@ -181,7 +180,7 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( universal_region_relations: &Frozen>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); @@ -216,7 +215,7 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( #[instrument(level = "debug", skip_all, ret)] fn collect_defining_uses<'tcx>( rcx: &mut RegionCtxt<'_, 'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], errors: &mut Vec>, ) -> Vec> { @@ -240,7 +239,7 @@ fn collect_defining_uses<'tcx>( infcx.tcx, hidden_types, opaque_type_key.def_id, - OpaqueHiddenType::new_error(infcx.tcx, guar), + DefinitionSiteHiddenType::new_error(infcx.tcx, guar), ), _ => debug!(?non_nll_opaque_type_key, ?err, "ignoring non-defining use"), } @@ -276,7 +275,7 @@ fn collect_defining_uses<'tcx>( #[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))] fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( rcx: &RegionCtxt<'_, 'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, defining_uses: &[DefiningUse<'tcx>], errors: &mut Vec>, ) { @@ -310,14 +309,13 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( // Now that we mapped the member regions to their final value, // map the arguments of the opaque type key back to the parameters // of the opaque type definition. - let ty = infcx + let hidden_type = infcx .infer_opaque_definition_from_instantiation(opaque_type_key, hidden_type) .unwrap_or_else(|_| { - Ty::new_error_with_message( - rcx.infcx.tcx, - hidden_type.span, - "deferred invalid opaque type args", - ) + let guar = tcx + .dcx() + .span_delayed_bug(hidden_type.span, "deferred invalid opaque type args"); + DefinitionSiteHiddenType::new_error(tcx, guar) }); // Sometimes, when the hidden type is an inference variable, it can happen that @@ -325,7 +323,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( // usage of the opaque type and we can ignore it. This check is mirrored in typeck's // writeback. if !rcx.infcx.tcx.use_typing_mode_borrowck() { - if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() + if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.skip_binder().kind() && alias_ty.def_id == opaque_type_key.def_id.to_def_id() && alias_ty.args == opaque_type_key.args { @@ -357,12 +355,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( }, )); } - add_hidden_type( - tcx, - hidden_types, - opaque_type_key.def_id, - OpaqueHiddenType { span: hidden_type.span, ty }, - ); + add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type); } } @@ -495,14 +488,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( region_bound_pairs: &RegionBoundPairs<'tcx>, known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>], constraints: &mut MirTypeckRegionConstraints<'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], ) -> Vec> { let tcx = infcx.tcx; let mut errors = Vec::new(); for &(key, hidden_type) in opaque_types { - let Some(expected) = hidden_types.0.get(&key.def_id).map(|ty| EarlyBinder::bind(*ty)) - else { + let Some(expected) = hidden_types.get(&key.def_id) else { if !tcx.use_typing_mode_borrowck() { if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() && alias_ty.def_id == key.def_id.to_def_id() @@ -521,20 +513,26 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( hidden_type.span, "non-defining use in the defining scope with no defining uses", ); - add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); + add_hidden_type( + tcx, + hidden_types, + key.def_id, + DefinitionSiteHiddenType::new_error(tcx, guar), + ); continue; }; // We erase all non-member region of the opaque and need to treat these as existentials. - let expected = ty::fold_regions(tcx, expected.instantiate(tcx, key.args), |re, _dbi| { - match re.kind() { - ty::ReErased => infcx.next_nll_region_var( - NllRegionVariableOrigin::Existential { name: None }, - || crate::RegionCtxt::Existential(None), - ), - _ => re, - } - }); + let expected_ty = + ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| { + match re.kind() { + ty::ReErased => infcx.next_nll_region_var( + NllRegionVariableOrigin::Existential { name: None }, + || crate::RegionCtxt::Existential(None), + ), + _ => re, + } + }); // We now simply equate the expected with the actual hidden type. let locations = Locations::All(hidden_type.span); @@ -555,13 +553,18 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( ); // We need to normalize both types in the old solver before equatingt them. let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty); - let expected_ty = ocx.normalize(&cause, infcx.param_env, expected.ty); + let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty); ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution) }, "equating opaque types", ), ) { - add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); + add_hidden_type( + tcx, + hidden_types, + key.def_id, + DefinitionSiteHiddenType::new_error(tcx, guar), + ); } } errors @@ -677,7 +680,7 @@ impl<'tcx> InferCtxt<'tcx> { &self, opaque_type_key: OpaqueTypeKey<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>, - ) -> Result, NonDefiningUseReason<'tcx>> { + ) -> Result, NonDefiningUseReason<'tcx>> { opaque_type_has_defining_use_args( self, opaque_type_key, @@ -685,15 +688,12 @@ impl<'tcx> InferCtxt<'tcx> { DefiningScopeKind::MirBorrowck, )?; - let definition_ty = instantiated_ty - .remap_generic_params_to_declaration_params( - opaque_type_key, - self.tcx, - DefiningScopeKind::MirBorrowck, - ) - .ty; - - definition_ty.error_reported()?; + let definition_ty = instantiated_ty.remap_generic_params_to_declaration_params( + opaque_type_key, + self.tcx, + DefiningScopeKind::MirBorrowck, + ); + definition_ty.ty.skip_binder().error_reported()?; Ok(definition_ty) } } diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index 21c11e128735..c3ff8cba9472 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -17,9 +17,8 @@ use crate::region_infer::opaque_types::{ }; use crate::type_check::{Locations, constraint_conversion}; use crate::{ - ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes, - PropagatedBorrowCheckResults, borrowck_check_region_constraints, - borrowck_collect_region_constraints, + ClosureRegionRequirements, CollectRegionConstraintsResult, PropagatedBorrowCheckResults, + borrowck_check_region_constraints, borrowck_collect_region_constraints, }; /// The shared context used by both the root as well as all its nested @@ -27,7 +26,7 @@ use crate::{ pub(super) struct BorrowCheckRootCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, - hidden_types: DefinitionSiteHiddenTypes<'tcx>, + hidden_types: FxIndexMap>, /// The region constraints computed by [borrowck_collect_region_constraints]. This uses /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before /// their parents. @@ -72,7 +71,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { &self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars } - pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { + pub(super) fn finalize( + self, + ) -> Result<&'tcx FxIndexMap>, ErrorGuaranteed> + { if let Some(guar) = self.tainted_by_errors { Err(guar) } else { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 25ab91ebc9cf..b4385b5030cf 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -430,7 +430,7 @@ fn best_definition_site_of_opaque<'tcx>( .tcx .mir_borrowck(item_def_id) .ok() - .and_then(|opaque_types| opaque_types.0.get(&self.opaque_def_id)) + .and_then(|opaque_types| opaque_types.get(&self.opaque_def_id)) { ControlFlow::Break((hidden_ty.span, item_def_id)) } else { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8cbf17162e32..e93725e13613 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -345,7 +345,7 @@ pub(super) fn type_of_opaque( def_id: DefId, ) -> Result>, CyclePlaceholder> { if let Some(def_id) = def_id.as_local() { - Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + Ok(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { opaque::find_opaque_ty_constraints_for_tait( tcx, @@ -378,7 +378,7 @@ pub(super) fn type_of_opaque( DefiningScopeKind::MirBorrowck, ) } - })) + }) } else { // Foreign opaque type will go through the foreign provider // and load the type from metadata. @@ -390,7 +390,7 @@ pub(super) fn type_of_opaque_hir_typeck( tcx: TyCtxt<'_>, def_id: LocalDefId, ) -> ty::EarlyBinder<'_, Ty<'_>> { - ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck) } @@ -419,7 +419,7 @@ pub(super) fn type_of_opaque_hir_typeck( DefiningScopeKind::HirTypeck, ) } - }) + } } fn infer_placeholder_type<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 870a7b656386..03216d009c2e 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,7 +3,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, DefiningScopeKind, EarlyBinder, Ty, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::opaque_types::report_item_does_not_constrain_error; use tracing::{debug, instrument, trace}; @@ -16,7 +16,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'_> { +) -> EarlyBinder<'_, Ty<'_>> { let mut parent_def_id = def_id; while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy { // Account for `type Alias = impl Trait;` (#116031) @@ -49,7 +49,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( name: tcx.item_ident(parent_def_id.to_def_id()), what: "impl", }); - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } } @@ -76,7 +76,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait( tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'_> { +) -> EarlyBinder<'_, Ty<'_>> { let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from }; tcx.hir_walk_toplevel_module(&mut locator); @@ -94,7 +94,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait( name: tcx.item_ident(parent_def_id.to_def_id()), what: "crate", }); - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } } @@ -109,18 +109,18 @@ struct TaitConstraintLocator<'tcx> { /// with the first type that we find, and then later types are /// checked against it (we also carry the span of that first /// type). - found: Option>, + found: Option>, opaque_types_from: DefiningScopeKind, } impl<'tcx> TaitConstraintLocator<'tcx> { - fn insert_found(&mut self, hidden_ty: ty::OpaqueHiddenType<'tcx>) { + fn insert_found(&mut self, hidden_ty: ty::DefinitionSiteHiddenType<'tcx>) { if let Some(prev) = &mut self.found { if hidden_ty.ty != prev.ty { let (Ok(guar) | Err(guar)) = prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit()); - prev.ty = Ty::new_error(self.tcx, guar); + *prev = ty::DefinitionSiteHiddenType::new_error(self.tcx, guar); } } else { self.found = Some(hidden_ty); @@ -133,7 +133,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { // with the new solver. assert!(!self.tcx.next_trait_solver_globally()); let guar = report_item_does_not_constrain_error(self.tcx, item_def_id, self.def_id, None); - self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(self.tcx, guar)); } #[instrument(skip(self), level = "debug")] @@ -168,7 +168,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { hir_sig.decl.output.span(), "inferring return types and opaque types do not mix well", ); - self.found = Some(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.found = Some(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); return; } @@ -176,7 +176,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { DefiningScopeKind::HirTypeck => { let tables = tcx.typeck(item_def_id); if let Some(guar) = tables.tainted_by_errors { - self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); } else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) { self.insert_found(hidden_type); } else { @@ -184,17 +184,15 @@ impl<'tcx> TaitConstraintLocator<'tcx> { } } DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) { - Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)), + Err(guar) => self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)), Ok(hidden_types) => { - if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) { + if let Some(&hidden_type) = hidden_types.get(&self.def_id) { debug!(?hidden_type, "found constraint"); self.insert_found(hidden_type); - } else if let Err(guar) = tcx - .type_of_opaque_hir_typeck(self.def_id) - .instantiate_identity() - .error_reported() + } else if let Err(guar) = + tcx.type_of_opaque_hir_typeck(self.def_id).skip_binder().error_reported() { - self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); } else { self.non_defining_use_in_defining_scope(item_def_id); } @@ -241,7 +239,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( def_id: LocalDefId, owner_def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'tcx> { +) -> EarlyBinder<'tcx, Ty<'tcx>> { // When an opaque type is stranded, its hidden type cannot be inferred // so we should not continue. if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) { @@ -249,14 +247,14 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( let guar = tcx .dcx() .span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type"); - return Ty::new_error(tcx, guar); + return EarlyBinder::bind(Ty::new_error(tcx, guar)); } match opaque_types_from { DefiningScopeKind::HirTypeck => { let tables = tcx.typeck(owner_def_id); if let Some(guar) = tables.tainted_by_errors { - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) { hidden_ty.ty } else { @@ -267,24 +265,24 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( // so we can just make the hidden type be `!`. // For backwards compatibility reasons, we fall back to // `()` until we the diverging default is changed. - Ty::new_diverging_default(tcx) + EarlyBinder::bind(Ty::new_diverging_default(tcx)) } } DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) { Ok(hidden_types) => { - if let Some(hidden_ty) = hidden_types.0.get(&def_id) { + if let Some(hidden_ty) = hidden_types.get(&def_id) { hidden_ty.ty } else { - let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity(); - if let Err(guar) = hir_ty.error_reported() { - Ty::new_error(tcx, guar) + let hir_ty = tcx.type_of_opaque_hir_typeck(def_id); + if let Err(guar) = hir_ty.skip_binder().error_reported() { + EarlyBinder::bind(Ty::new_error(tcx, guar)) } else { assert!(!tcx.next_trait_solver_globally()); hir_ty } } } - Err(guar) => Ty::new_error(tcx, guar), + Err(guar) => EarlyBinder::bind(Ty::new_error(tcx, guar)), }, } } diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 05b5b1a8af80..b779f8b8317f 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -1,8 +1,8 @@ use rustc_hir::def::DefKind; use rustc_infer::traits::ObligationCause; use rustc_middle::ty::{ - self, DefiningScopeKind, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, TypeVisitableExt, - TypingMode, + self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueHiddenType, OpaqueTypeKey, + TypeVisitableExt, TypingMode, }; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::opaque_types::{ @@ -59,7 +59,7 @@ enum UsageKind<'tcx> { None, NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>), UnconstrainedHiddenType(OpaqueHiddenType<'tcx>), - HasDefiningUse(OpaqueHiddenType<'tcx>), + HasDefiningUse(DefinitionSiteHiddenType<'tcx>), } impl<'tcx> UsageKind<'tcx> { @@ -131,7 +131,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { continue; } - let expected = EarlyBinder::bind(ty.ty).instantiate(tcx, opaque_type_key.args); + let expected = ty.ty.instantiate(tcx, opaque_type_key.args); self.demand_eqtype(hidden_type.span, expected, hidden_type.ty); } @@ -191,7 +191,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.typeck_results .borrow_mut() .hidden_types - .insert(def_id, OpaqueHiddenType::new_error(tcx, guar)); + .insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar)); self.set_tainted_by_errors(guar); } } @@ -210,7 +210,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ) { match err { NonDefiningUseReason::Tainted(guar) => { - return UsageKind::HasDefiningUse(OpaqueHiddenType::new_error(self.tcx, guar)); + return UsageKind::HasDefiningUse(DefinitionSiteHiddenType::new_error( + self.tcx, guar, + )); } _ => return UsageKind::NonDefiningUse(opaque_type_key, hidden_type), }; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 50b6fe1ad5ec..3235aa396df4 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -21,7 +21,7 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ - self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, + self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, fold_regions, }; @@ -550,10 +550,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn visit_opaque_types_next(&mut self) { let mut fcx_typeck_results = self.fcx.typeck_results.borrow_mut(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); - for hidden_ty in fcx_typeck_results.hidden_types.values() { - assert!(!hidden_ty.has_infer()); - } - assert_eq!(self.typeck_results.hidden_types.len(), 0); self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types); } @@ -589,7 +585,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { ) { self.typeck_results.hidden_types.insert( opaque_type_key.def_id, - ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)), + ty::DefinitionSiteHiddenType::new_error(tcx, err.report(self.fcx)), ); } @@ -603,15 +599,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type) { let entry = - &mut self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap(); + self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap(); if prev.ty != hidden_type.ty { - if let Some(guar) = self.typeck_results.tainted_by_errors { - entry.ty = Ty::new_error(tcx, guar); + let guar = if let Some(guar) = self.typeck_results.tainted_by_errors { + guar } else { let (Ok(guar) | Err(guar)) = prev.build_mismatch_error(&hidden_type, tcx).map(|d| d.emit()); - entry.ty = Ty::new_error(tcx, guar); - } + guar + }; + *entry = DefinitionSiteHiddenType::new_error(tcx, guar); } // Pick a better span if there is one. @@ -627,6 +624,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .filter(|&(&def_id, hidden_ty)| { hidden_ty .ty + .instantiate_identity() .visit_with(&mut HasRecursiveOpaque { def_id, seen: Default::default(), @@ -646,7 +644,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .emit(); self.typeck_results .hidden_types - .insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) }); + .insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar)); } } @@ -1045,7 +1043,7 @@ impl<'tcx> TypeFolder> for EagerlyNormalizeConsts<'tcx> { struct HasRecursiveOpaque<'a, 'tcx> { def_id: LocalDefId, seen: FxHashSet, - opaques: &'a FxIndexMap>, + opaques: &'a FxIndexMap>, tcx: TyCtxt<'tcx>, } @@ -1063,9 +1061,7 @@ impl<'tcx> TypeVisitor> for HasRecursiveOpaque<'_, 'tcx> { if self.seen.insert(def_id) && let Some(hidden_ty) = self.opaques.get(&def_id) { - ty::EarlyBinder::bind(hidden_ty.ty) - .instantiate(self.tcx, alias_ty.args) - .visit_with(self)?; + hidden_ty.ty.instantiate(self.tcx, alias_ty.args).visit_with(self)?; } } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index feaad5bb96eb..66ee88f0e522 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -27,7 +27,10 @@ macro_rules! arena_types { rustc_middle::mir::Body<'tcx> >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, + [decode] borrowck_result: rustc_data_structures::fx::FxIndexMap< + rustc_hir::def_id::LocalDefId, + rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, + >, [] resolver: rustc_data_structures::steal::Steal<( rustc_middle::ty::ResolverAstLowering, std::sync::Arc, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 2e6c9f207e26..7629ae9817fe 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -3,16 +3,14 @@ use std::fmt::{self, Debug}; use rustc_abi::{FieldIdx, VariantIdx}; -use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::LocalDefId; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::{Span, Symbol}; use super::{ConstValue, SourceInfo}; -use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty}; +use crate::ty::{self, CoroutineArgsExt, Ty}; rustc_index::newtype_index! { #[derive(HashStable)] @@ -84,11 +82,6 @@ impl Debug for CoroutineLayout<'_> { } } -/// All the opaque types that have had their hidden type fully computed. -/// Unlike the value in `TypeckResults`, this has unerased regions. -#[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)] -pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap>); - /// The result of the `mir_const_qualif` query. /// /// Each field (except `tainted_by_errors`) corresponds to an implementer of the `Qualif` trait in diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 30d4cc8b3c8d..d59ac85ad05f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1244,7 +1244,10 @@ rustc_queries! { /// Borrow-checks the given typeck root, e.g. functions, const/static items, /// and its children, e.g. closures, inline consts. - query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { + query mir_borrowck(key: LocalDefId) -> Result< + &'tcx FxIndexMap>, + ErrorGuaranteed + > { desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 905874f05628..f0e2ffe6b19e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -798,7 +798,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { opaque_type_key: OpaqueTypeKey<'tcx>, tcx: TyCtxt<'tcx>, defining_scope_kind: DefiningScopeKind, - ) -> Self { + ) -> DefinitionSiteHiddenType<'tcx> { let OpaqueTypeKey { def_id, args } = opaque_type_key; // Use args to build up a reverse map from regions to their @@ -821,15 +821,68 @@ impl<'tcx> OpaqueHiddenType<'tcx> { // // We erase regions when doing this during HIR typeck. We manually use `fold_regions` // here as we do not want to anonymize bound variables. - let this = match defining_scope_kind { - DefiningScopeKind::HirTypeck => fold_regions(tcx, self, |_, _| tcx.lifetimes.re_erased), - DefiningScopeKind::MirBorrowck => self, + let ty = match defining_scope_kind { + DefiningScopeKind::HirTypeck => { + fold_regions(tcx, self.ty, |_, _| tcx.lifetimes.re_erased) + } + DefiningScopeKind::MirBorrowck => self.ty, }; - let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span)); + let result_ty = ty.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span)); if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) { - assert_eq!(result.ty, fold_regions(tcx, result.ty, |_, _| tcx.lifetimes.re_erased)); + assert_eq!(result_ty, fold_regions(tcx, result_ty, |_, _| tcx.lifetimes.re_erased)); } - result + DefinitionSiteHiddenType { span: self.span, ty: ty::EarlyBinder::bind(result_ty) } + } +} + +#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)] +pub struct DefinitionSiteHiddenType<'tcx> { + /// The span of the definition of the opaque type. So for example: + /// + /// ```ignore (incomplete snippet) + /// type Foo = impl Baz; + /// fn bar() -> Foo { + /// // ^^^ This is the span we are looking for! + /// } + /// ``` + /// + /// In cases where the fn returns `(impl Trait, impl Trait)` or + /// other such combinations, the result is currently + /// over-approximated, but better than nothing. + pub span: Span, + + /// The final type of the opaque. + pub ty: ty::EarlyBinder<'tcx, Ty<'tcx>>, +} + +impl<'tcx> DefinitionSiteHiddenType<'tcx> { + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> DefinitionSiteHiddenType<'tcx> { + DefinitionSiteHiddenType { + span: DUMMY_SP, + ty: ty::EarlyBinder::bind(Ty::new_error(tcx, guar)), + } + } + + pub fn build_mismatch_error( + &self, + other: &Self, + tcx: TyCtxt<'tcx>, + ) -> Result, ErrorGuaranteed> { + let self_ty = self.ty.instantiate_identity(); + let other_ty = other.ty.instantiate_identity(); + (self_ty, other_ty).error_reported()?; + // Found different concrete types for the opaque type. + let sub_diag = if self.span == other.span { + TypeMismatchReason::ConflictType { span: self.span } + } else { + TypeMismatchReason::PreviousUse { span: self.span } + }; + Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch { + self_ty, + other_ty, + other_span: other.span, + sub: sub_diag, + })) } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 20657ba8c726..c05ab540c13d 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -167,7 +167,7 @@ pub struct TypeckResults<'tcx> { /// We also store the type here, so that the compiler can use it as a hint /// for figuring out hidden types, even if they are only set in dead code /// (which doesn't show up in MIR). - pub hidden_types: FxIndexMap>, + pub hidden_types: FxIndexMap>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 0652461e9750..8df34ee941b2 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -148,7 +148,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { self.typeck_results .hidden_types .get(&key.def_id) - .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args)) + .map(|x| x.ty.instantiate(self.tcx, key.args)) } // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { From 5cbb5d0ac6afda3a643389a55a0c5d605ea42092 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 31 Oct 2025 14:53:03 +0100 Subject: [PATCH 265/525] rename `OpaqueHiddenType` --- .../src/region_infer/opaque_types/mod.rs | 20 +++++++------- .../rustc_hir_analysis/src/check/check.rs | 4 +-- compiler/rustc_hir_typeck/src/method/probe.rs | 4 +-- compiler/rustc_hir_typeck/src/opaque_types.rs | 12 ++++----- compiler/rustc_infer/src/infer/context.rs | 4 +-- compiler/rustc_infer/src/infer/mod.rs | 6 ++--- .../rustc_infer/src/infer/opaque_types/mod.rs | 8 +++--- .../src/infer/opaque_types/table.rs | 26 +++++++++++-------- .../src/infer/snapshot/undo_log.rs | 4 +-- compiler/rustc_middle/src/ty/mod.rs | 8 +++--- 10 files changed, 50 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 2294c6381625..0c4a82f3d2f3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -11,8 +11,8 @@ use rustc_macros::extension; use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, - GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, TypeVisitableExt, fold_regions, + GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, + TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions, }; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; @@ -48,7 +48,7 @@ pub(crate) enum DeferredOpaqueTypeError<'tcx> { /// The opaque type. opaque_type_key: OpaqueTypeKey<'tcx>, /// The hidden type containing the member region. - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, /// The unexpected region. member_region: Region<'tcx>, }, @@ -67,7 +67,7 @@ pub(crate) fn clone_and_resolve_opaque_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, universal_region_relations: &Frozen>, constraints: &mut MirTypeckRegionConstraints<'tcx>, -) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>) { +) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>) { let opaque_types = infcx.clone_opaque_types(); let opaque_types_storage_num_entries = infcx.inner.borrow_mut().opaque_types().num_entries(); let opaque_types = opaque_types @@ -161,7 +161,7 @@ struct DefiningUse<'tcx> { /// to interact with code outside of `rustc_borrowck`. opaque_type_key: OpaqueTypeKey<'tcx>, arg_regions: Vec, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, } /// This computes the actual hidden types of the opaque types and maps them to their @@ -181,7 +181,7 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, hidden_types: &mut FxIndexMap>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); // When computing the hidden type we need to track member constraints. @@ -216,7 +216,7 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( fn collect_defining_uses<'tcx>( rcx: &mut RegionCtxt<'_, 'tcx>, hidden_types: &mut FxIndexMap>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], errors: &mut Vec>, ) -> Vec> { let infcx = rcx.infcx; @@ -302,7 +302,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( hidden_type.span, "opaque type with non-universal region args", ); - ty::OpaqueHiddenType::new_error(tcx, guar) + ty::ProvisionalHiddenType::new_error(tcx, guar) } }; @@ -489,7 +489,7 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>], constraints: &mut MirTypeckRegionConstraints<'tcx>, hidden_types: &mut FxIndexMap>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let tcx = infcx.tcx; let mut errors = Vec::new(); @@ -679,7 +679,7 @@ impl<'tcx> InferCtxt<'tcx> { fn infer_opaque_definition_from_instantiation( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - instantiated_ty: OpaqueHiddenType<'tcx>, + instantiated_ty: ProvisionalHiddenType<'tcx>, ) -> Result, NonDefiningUseReason<'tcx>> { opaque_type_has_defining_use_args( self, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b4385b5030cf..cc6598916eec 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -493,7 +493,7 @@ fn best_definition_site_of_opaque<'tcx>( fn sanity_check_found_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, key: ty::OpaqueTypeKey<'tcx>, - mut ty: ty::OpaqueHiddenType<'tcx>, + mut ty: ty::ProvisionalHiddenType<'tcx>, ) -> Result<(), ErrorGuaranteed> { if ty.ty.is_ty_var() { // Nothing was actually constrained. @@ -529,7 +529,7 @@ fn sanity_check_found_hidden_type<'tcx>( Ok(()) } else { let span = tcx.def_span(key.def_id); - let other = ty::OpaqueHiddenType { ty: hidden_ty, span }; + let other = ty::ProvisionalHiddenType { ty: hidden_ty, span }; Err(ty.build_mismatch_error(&other, tcx)?.emit()) } } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index a3f6803c5dc2..a8457134031c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -584,8 +584,8 @@ pub(crate) fn method_autoderef_steps<'tcx>( value: query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty }, } = goal; for (key, ty) in predefined_opaques_in_body { - let prev = - infcx.register_hidden_type_in_storage(key, ty::OpaqueHiddenType { span: DUMMY_SP, ty }); + let prev = infcx + .register_hidden_type_in_storage(key, ty::ProvisionalHiddenType { span: DUMMY_SP, ty }); // It may be possible that two entries in the opaque type storage end up // with the same key after resolving contained inference variables. // diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index b779f8b8317f..18c1bf39a7c1 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -1,7 +1,7 @@ use rustc_hir::def::DefKind; use rustc_infer::traits::ObligationCause; use rustc_middle::ty::{ - self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueHiddenType, OpaqueTypeKey, + self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType, TypeVisitableExt, TypingMode, }; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; @@ -57,8 +57,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { #[derive(Copy, Clone, Debug)] enum UsageKind<'tcx> { None, - NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>), - UnconstrainedHiddenType(OpaqueHiddenType<'tcx>), + NonDefiningUse(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>), + UnconstrainedHiddenType(ProvisionalHiddenType<'tcx>), HasDefiningUse(DefinitionSiteHiddenType<'tcx>), } @@ -88,7 +88,7 @@ impl<'tcx> UsageKind<'tcx> { impl<'tcx> FnCtxt<'_, 'tcx> { fn compute_definition_site_hidden_types( &mut self, - mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, + mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>, error_on_missing_defining_use: bool, ) { for entry in opaque_types.iter_mut() { @@ -200,7 +200,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn consider_opaque_type_use( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, ) -> UsageKind<'tcx> { if let Err(err) = opaque_type_has_defining_use_args( &self, @@ -232,7 +232,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { Ok(hidden_type) => hidden_type, Err(errors) => { let guar = self.err_ctxt().report_fulfillment_errors(errors); - OpaqueHiddenType::new_error(self.tcx, guar) + ProvisionalHiddenType::new_error(self.tcx, guar) } }; let hidden_type = hidden_type.remap_generic_params_to_declaration_params( diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 5ffa7304efaf..09403513aa08 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -314,7 +314,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { ) -> Option> { self.register_hidden_type_in_storage( opaque_type_key, - ty::OpaqueHiddenType { span, ty: hidden_ty }, + ty::ProvisionalHiddenType { span, ty: hidden_ty }, ) } fn add_duplicate_opaque_type( @@ -326,7 +326,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.inner .borrow_mut() .opaque_types() - .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }) + .add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty }) } fn reset_opaque_types(&self) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f3ebfde06ab6..dc4ee0d88a06 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -28,7 +28,7 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, - GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey, + GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueTypeKey, ProvisionalHiddenType, PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, }; @@ -978,12 +978,12 @@ impl<'tcx> InferCtxt<'tcx> { } #[instrument(level = "debug", skip(self), ret)] - pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> { self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect() } #[instrument(level = "debug", skip(self), ret)] - pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> { self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect() } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 220e025c3f7d..9579abf7ec53 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -5,7 +5,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, + self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, }; use rustc_span::Span; @@ -199,7 +199,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn register_hidden_type_in_storage( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - hidden_ty: OpaqueHiddenType<'tcx>, + hidden_ty: ProvisionalHiddenType<'tcx>, ) -> Option> { self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty) } @@ -237,7 +237,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .opaque_types() - .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); + .register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span }); if let Some(prev) = prev { goals.extend( self.at(&ObligationCause::dummy_with_span(span), param_env) @@ -253,7 +253,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .opaque_types() - .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); + .register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span }); // We either equate the new hidden type with the previous entry or with the type // inferred by HIR typeck. diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index df5a66243fc1..55c00a8695fa 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -3,15 +3,15 @@ use std::ops::Deref; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::bug; -use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; +use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType, Ty}; use tracing::instrument; use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog}; #[derive(Default, Debug, Clone)] pub struct OpaqueTypeStorage<'tcx> { - opaque_types: FxIndexMap, OpaqueHiddenType<'tcx>>, - duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, + opaque_types: FxIndexMap, ProvisionalHiddenType<'tcx>>, + duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>, } /// The number of entries in the opaque type storage at a given point. @@ -35,7 +35,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub(crate) fn remove( &mut self, key: OpaqueTypeKey<'tcx>, - prev: Option>, + prev: Option>, ) { if let Some(prev) = prev { *self.opaque_types.get_mut(&key).unwrap() = prev; @@ -60,7 +60,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub(crate) fn take_opaque_types( &mut self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries)) } @@ -75,7 +75,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub fn opaque_types_added_since( &self, prev_entries: OpaqueTypeStorageEntries, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.opaque_types .iter() .skip(prev_entries.opaque_types) @@ -90,7 +90,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { /// to also consider duplicate entries. pub fn iter_lookup_table( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.opaque_types.iter().map(|(k, v)| (*k, *v)) } @@ -101,13 +101,13 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { /// accesses them. pub fn iter_duplicate_entries( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.duplicate_entries.iter().copied() } pub fn iter_opaque_types( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied()) } @@ -146,7 +146,7 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { pub fn register( &mut self, key: OpaqueTypeKey<'tcx>, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, ) -> Option> { if let Some(entry) = self.storage.opaque_types.get_mut(&key) { let prev = std::mem::replace(entry, hidden_type); @@ -158,7 +158,11 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { None } - pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) { + pub fn add_duplicate( + &mut self, + key: OpaqueTypeKey<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, + ) { self.storage.duplicate_entries.push((key, hidden_type)); self.undo_log.push(UndoLog::DuplicateOpaqueType); } diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 22c815fb87c6..c859d64133c4 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; use rustc_data_structures::{snapshot_vec as sv, unify as ut}; -use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey}; +use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType}; use tracing::debug; use crate::infer::unify_key::{ConstVidKey, RegionVidKey}; @@ -19,7 +19,7 @@ pub struct Snapshot<'tcx> { #[derive(Clone)] pub(crate) enum UndoLog<'tcx> { DuplicateOpaqueType, - OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), + OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), TypeVariables(type_variable::UndoLog<'tcx>), ConstUnificationTable(sv::UndoLog>>), IntUnificationTable(sv::UndoLog>), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f0e2ffe6b19e..2b9079da1830 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { } #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] -pub struct OpaqueHiddenType<'tcx> { +pub struct ProvisionalHiddenType<'tcx> { /// The span of this particular definition of the opaque type. So /// for example: /// @@ -767,9 +767,9 @@ pub enum DefiningScopeKind { MirBorrowck, } -impl<'tcx> OpaqueHiddenType<'tcx> { - pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> { - OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) } +impl<'tcx> ProvisionalHiddenType<'tcx> { + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> ProvisionalHiddenType<'tcx> { + ProvisionalHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) } } pub fn build_mismatch_error( From 60c230b94a8c1dcff1b72ceb0531aac457abc7d9 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Fri, 31 Oct 2025 14:14:05 -0400 Subject: [PATCH 266/525] compiler: Fix a couple issues around cargo feature unification The first was a warning: ``` Testing stage2 {rustc_parse_format} (aarch64-apple-darwin) Compiling rustc_index v0.0.0 (/Users/ci/project/compiler/rustc_index) error: extern crate `smallvec` is unused in crate `rustc_index` --> compiler/rustc_index/src/lib.rs:2:1 | 2 | #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] | ^ | = help: remove the dependency or add `use smallvec as _;` to the crate root = note: `-D unused-crate-dependencies` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_crate_dependencies)]` error: could not compile `rustc_index` (lib) due to 1 previous error ``` The second was that `type_ir_macros` didn't fully specify its dependencies: ``` Testing stage1 {rustc_type_ir_macros} (aarch64-apple-darwin) Compiling rustc_type_ir_macros v0.0.0 (/Users/jyn/src/ferrocene3/compiler/rustc_type_ir_macros) error[E0432]: unresolved import `syn::visit_mut` --> compiler/rustc_type_ir_macros/src/lib.rs:2:10 | 2 | use syn::visit_mut::VisitMut; | ^^^^^^^^^ could not find `visit_mut` in `syn` | note: found an item that was configured out --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.106/src/lib.rs:880:21 | 878 | #[cfg(feature = "visit-mut")] | --------------------- the item is gated behind the `visit-mut` feature 879 | #[cfg_attr(docsrs, doc(cfg(feature = "visit-mut")))] 880 | pub use crate::gen::visit_mut; | ^^^^^^^^^ error[E0433]: failed to resolve: could not find `visit_mut` in `syn` --> compiler/rustc_type_ir_macros/src/lib.rs:206:18 | 206 | syn::visit_mut::visit_type_path_mut(self, i); | ^^^^^^^^^ could not find `visit_mut` in `syn` | note: found an item that was configured out --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.106/src/lib.rs:880:21 | 878 | #[cfg(feature = "visit-mut")] | --------------------- the item is gated behind the `visit-mut` feature 879 | #[cfg_attr(docsrs, doc(cfg(feature = "visit-mut")))] 880 | pub use crate::gen::visit_mut; | ^^^^^^^^^ ``` --- compiler/rustc_index/Cargo.toml | 3 ++- compiler/rustc_type_ir_macros/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index e46a1a7f7606..edcd7816a60e 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" rustc_index_macros = { path = "../rustc_index_macros" } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } -smallvec = "1.8.1" +smallvec = { version = "1.8.1", optional = true } # tidy-alphabetical-end [features] @@ -17,6 +17,7 @@ default = ["nightly"] nightly = [ "dep:rustc_macros", "dep:rustc_serialize", + "dep:smallvec", "rustc_index_macros/nightly", ] rustc_randomized_layouts = [] diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index 15a555750992..14bffa403a86 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -10,6 +10,6 @@ proc-macro = true # tidy-alphabetical-start proc-macro2 = "1" quote = "1" -syn = { version = "2.0.9", features = ["full"] } +syn = { version = "2.0.9", features = ["full", "visit-mut"] } synstructure = "0.13.0" # tidy-alphabetical-end From 65aed3b6e63bc7ad9ed61785197f882bfc071089 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 31 Oct 2025 11:16:00 -0700 Subject: [PATCH 267/525] Fix test on Windows --- tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs b/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs index 7dfa6584785a..00a87477ab5e 100644 --- a/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs @@ -10,10 +10,10 @@ fn main() { &["--emit=dep-info,invocation-specific"], ); - let content = rfs::read_to_string("foobar.d"); + let content = rfs::read_to_string("foobar.d").replace(r"\", "/"); assert_contains(&content, "lib.rs:"); assert_contains(&content, "rustdoc/ex.calls:"); - let content = rfs::read_to_string("ex.d"); + let content = rfs::read_to_string("ex.d").replace(r"\", "/"); assert_contains(&content, "examples/ex.rs:"); } From d472d91a396866d58b23f84cfa555028d83eccf9 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Fri, 31 Oct 2025 18:24:10 +0000 Subject: [PATCH 268/525] address review --- compiler/rustc_hir_typeck/src/errors.rs | 11 +++-- compiler/rustc_hir_typeck/src/expr.rs | 3 +- .../let-chains-assign-add-incorrect.fixed | 36 ++++++++++++++ .../parser/let-chains-assign-add-incorrect.rs | 18 +++++-- .../let-chains-assign-add-incorrect.stderr | 47 ++++++++++--------- 5 files changed, 83 insertions(+), 32 deletions(-) create mode 100644 tests/ui/parser/let-chains-assign-add-incorrect.fixed diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 142495c7042c..0861474e5b1f 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -7,7 +7,7 @@ use rustc_ast::{AssignOpKind, Label}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, - EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, struct_span_code_err, + EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, }; use rustc_hir as hir; use rustc_hir::ExprKind; @@ -1146,13 +1146,16 @@ pub(crate) fn maybe_emit_plus_equals_diagnostic<'a>( && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &right.kind && matches!(path.res, hir::def::Res::Local(_)) { - let mut err = struct_span_code_err!( - fnctxt.dcx(), + let mut err = fnctxt.dcx().struct_span_err( assign_op.span, - E0368, "binary assignment operation `+=` cannot be used in a let chain", ); + err.span_label( + lhs_expr.span, + "you are add-assigning the right-hand side expression to the result of this let-chain", + ); + err.span_label(assign_op.span, "cannot use `+=` in a let chain"); err.span_suggestion( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1009c7927854..65a21cc210ac 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -48,6 +48,7 @@ use crate::errors::{ NoFieldOnVariant, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine, }; +use crate::op::contains_let_in_chain; use crate::{ BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, GatherLocalsVisitor, Needs, TupleArgumentsFlag, cast, fatally_break_rust, report_unexpected_variant_res, type_error_struct, @@ -1251,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Skip suggestion if LHS contains a let-chain at this would likely be spurious // cc: https://github.com/rust-lang/rust/issues/147664 - if crate::op::contains_let_in_chain(lhs) { + if contains_let_in_chain(lhs) { return; } diff --git a/tests/ui/parser/let-chains-assign-add-incorrect.fixed b/tests/ui/parser/let-chains-assign-add-incorrect.fixed new file mode 100644 index 000000000000..b1abce8bd2df --- /dev/null +++ b/tests/ui/parser/let-chains-assign-add-incorrect.fixed @@ -0,0 +1,36 @@ +//@ edition:2024 +//@ run-rustfix + +#![allow(irrefutable_let_patterns)] + +fn test_where_left_is_not_let() { + let y = 2; + if let _ = 1 && true && y == 2 {}; + //~^ ERROR expected expression, found `let` statement + //~| NOTE only supported directly in conditions of `if` and `while` expressions + //~| ERROR mismatched types + //~| NOTE expected `bool`, found integer + //~| NOTE you are add-assigning the right-hand side expression to the result of this let-chain + //~| NOTE expected because this is `bool` + //~| ERROR binary assignment operation `+=` cannot be used in a let chain + //~| NOTE cannot use `+=` in a let chain + //~| HELP you might have meant to compare with `==` instead of assigning with `+=` +} + +fn test_where_left_is_let() { + let y = 2; + if let _ = 1 && y == 2 {}; + //~^ ERROR expected expression, found `let` statement + //~| NOTE only supported directly in conditions of `if` and `while` expressions + //~| ERROR mismatched types + //~| NOTE expected `bool`, found integer + //~| NOTE you are add-assigning the right-hand side expression to the result of this let-chain + //~| ERROR binary assignment operation `+=` cannot be used in a let chain + //~| NOTE cannot use `+=` in a let chain + //~| HELP you might have meant to compare with `==` instead of assigning with `+=` +} + +fn main() { + test_where_left_is_let(); + test_where_left_is_not_let() +} diff --git a/tests/ui/parser/let-chains-assign-add-incorrect.rs b/tests/ui/parser/let-chains-assign-add-incorrect.rs index f3b497f5c183..3b2e5e93d91a 100644 --- a/tests/ui/parser/let-chains-assign-add-incorrect.rs +++ b/tests/ui/parser/let-chains-assign-add-incorrect.rs @@ -1,12 +1,16 @@ //@ edition:2024 +//@ run-rustfix + +#![allow(irrefutable_let_patterns)] fn test_where_left_is_not_let() { - let mut y = 2; - if let x = 1 && true && y += 2 {}; + let y = 2; + if let _ = 1 && true && y += 2 {}; //~^ ERROR expected expression, found `let` statement //~| NOTE only supported directly in conditions of `if` and `while` expressions //~| ERROR mismatched types //~| NOTE expected `bool`, found integer + //~| NOTE you are add-assigning the right-hand side expression to the result of this let-chain //~| NOTE expected because this is `bool` //~| ERROR binary assignment operation `+=` cannot be used in a let chain //~| NOTE cannot use `+=` in a let chain @@ -14,15 +18,19 @@ fn test_where_left_is_not_let() { } fn test_where_left_is_let() { - let mut y = 2; - if let x = 1 && y += 2 {}; + let y = 2; + if let _ = 1 && y += 2 {}; //~^ ERROR expected expression, found `let` statement //~| NOTE only supported directly in conditions of `if` and `while` expressions //~| ERROR mismatched types //~| NOTE expected `bool`, found integer + //~| NOTE you are add-assigning the right-hand side expression to the result of this let-chain //~| ERROR binary assignment operation `+=` cannot be used in a let chain //~| NOTE cannot use `+=` in a let chain //~| HELP you might have meant to compare with `==` instead of assigning with `+=` } -fn main() {} +fn main() { + test_where_left_is_let(); + test_where_left_is_not_let() +} diff --git a/tests/ui/parser/let-chains-assign-add-incorrect.stderr b/tests/ui/parser/let-chains-assign-add-incorrect.stderr index 38811e0733a5..dea8e6a1982b 100644 --- a/tests/ui/parser/let-chains-assign-add-incorrect.stderr +++ b/tests/ui/parser/let-chains-assign-add-incorrect.stderr @@ -1,58 +1,61 @@ error: expected expression, found `let` statement - --> $DIR/let-chains-assign-add-incorrect.rs:5:8 + --> $DIR/let-chains-assign-add-incorrect.rs:8:8 | -LL | if let x = 1 && true && y += 2 {}; +LL | if let _ = 1 && true && y += 2 {}; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement - --> $DIR/let-chains-assign-add-incorrect.rs:18:8 + --> $DIR/let-chains-assign-add-incorrect.rs:22:8 | -LL | if let x = 1 && y += 2 {}; +LL | if let _ = 1 && y += 2 {}; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions error[E0308]: mismatched types - --> $DIR/let-chains-assign-add-incorrect.rs:5:29 + --> $DIR/let-chains-assign-add-incorrect.rs:8:29 | -LL | if let x = 1 && true && y += 2 {}; +LL | if let _ = 1 && true && y += 2 {}; | ----------------- ^ expected `bool`, found integer | | | expected because this is `bool` -error[E0368]: binary assignment operation `+=` cannot be used in a let chain - --> $DIR/let-chains-assign-add-incorrect.rs:5:31 +error: binary assignment operation `+=` cannot be used in a let chain + --> $DIR/let-chains-assign-add-incorrect.rs:8:31 | -LL | if let x = 1 && true && y += 2 {}; - | ^^ cannot use `+=` in a let chain +LL | if let _ = 1 && true && y += 2 {}; + | ---------------------- ^^ cannot use `+=` in a let chain + | | + | you are add-assigning the right-hand side expression to the result of this let-chain | help: you might have meant to compare with `==` instead of assigning with `+=` | -LL - if let x = 1 && true && y += 2 {}; -LL + if let x = 1 && true && y == 2 {}; +LL - if let _ = 1 && true && y += 2 {}; +LL + if let _ = 1 && true && y == 2 {}; | error[E0308]: mismatched types - --> $DIR/let-chains-assign-add-incorrect.rs:18:21 + --> $DIR/let-chains-assign-add-incorrect.rs:22:21 | -LL | if let x = 1 && y += 2 {}; +LL | if let _ = 1 && y += 2 {}; | ^ expected `bool`, found integer -error[E0368]: binary assignment operation `+=` cannot be used in a let chain - --> $DIR/let-chains-assign-add-incorrect.rs:18:23 +error: binary assignment operation `+=` cannot be used in a let chain + --> $DIR/let-chains-assign-add-incorrect.rs:22:23 | -LL | if let x = 1 && y += 2 {}; - | ^^ cannot use `+=` in a let chain +LL | if let _ = 1 && y += 2 {}; + | -------------- ^^ cannot use `+=` in a let chain + | | + | you are add-assigning the right-hand side expression to the result of this let-chain | help: you might have meant to compare with `==` instead of assigning with `+=` | -LL - if let x = 1 && y += 2 {}; -LL + if let x = 1 && y == 2 {}; +LL - if let _ = 1 && y += 2 {}; +LL + if let _ = 1 && y == 2 {}; | error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0368. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. From 516a273144114fd502ae837ae9be95a5ecd372bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 29 Sep 2025 02:58:25 +0000 Subject: [PATCH 269/525] Suggest making binding `mut` on `&mut` reborrow When a binding needs to be mutably reborrowed multiple times, suggesting removing `&mut` will lead to follow up errors. Instead suggest both making the binding mutable and removing the reborrow. ``` error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable --> f14.rs:2:12 | 2 | match (&mut outer, 23) { | ^^^^^^^^^^ cannot borrow as mutable | note: the binding is already a mutable borrow --> f14.rs:1:16 | 1 | fn test(outer: &mut Option) { | ^^^^^^^^^^^^^^^^ help: consider making the binding mutable if you need to reborrow multiple times | 1 | fn test(mut outer: &mut Option) { | +++ help: if there is only one mutable reborrow, remove the `&mut` | 2 - match (&mut outer, 23) { 2 + match (outer, 23) { | ``` --- .../src/diagnostics/mutability_errors.rs | 12 ++++++++-- tests/ui/borrowck/mut-borrow-of-mut-ref.rs | 24 ++++++++++--------- .../ui/borrowck/mut-borrow-of-mut-ref.stderr | 20 +++++++++++----- tests/ui/did_you_mean/issue-31424.rs | 11 +++++---- tests/ui/did_you_mean/issue-31424.stderr | 8 +++++-- tests/ui/did_you_mean/issue-34126.rs | 6 ++--- tests/ui/did_you_mean/issue-34126.stderr | 2 +- tests/ui/nll/issue-51191.rs | 19 ++++++++------- tests/ui/nll/issue-51191.stderr | 20 +++++++++------- 9 files changed, 75 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index b4990ffc7739..6bd24122a0c7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -335,10 +335,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { LocalInfo::User(BindingForm::Var(mir::VarBindingForm { binding_mode: BindingMode(ByRef::No, Mutability::Not), opt_ty_info: Some(sp), + pat_span, .. })) => { if suggest { err.span_note(sp, "the binding is already a mutable borrow"); + err.span_suggestion_verbose( + pat_span.shrink_to_lo(), + "consider making the binding mutable if you need to reborrow \ + multiple times", + "mut ".to_string(), + Applicability::MaybeIncorrect, + ); } } _ => { @@ -356,9 +364,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // give a best effort structured suggestion. err.span_suggestion_verbose( source_info.span.with_hi(source_info.span.lo() + BytePos(5)), - "try removing `&mut` here", + "if there is only one mutable reborrow, remove the `&mut`", "", - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } else { // This can occur with things like `(&mut self).foo()`. diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs index 477a2aa48d5d..33954592bf65 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs @@ -2,22 +2,24 @@ #![crate_type = "rlib"] pub fn f(b: &mut i32) { - //~^ ERROR cannot borrow - //~| NOTE not mutable - //~| NOTE the binding is already a mutable borrow + //~^ ERROR: cannot borrow + //~| NOTE: not mutable + //~| NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times h(&mut b); - //~^ NOTE cannot borrow as mutable - //~| HELP try removing `&mut` here + //~^ NOTE: cannot borrow as mutable + //~| HELP: if there is only one mutable reborrow, remove the `&mut` g(&mut &mut b); - //~^ NOTE cannot borrow as mutable - //~| HELP try removing `&mut` here + //~^ NOTE: cannot borrow as mutable + //~| HELP: if there is only one mutable reborrow, remove the `&mut` } -pub fn g(b: &mut i32) { //~ NOTE the binding is already a mutable borrow +pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow + //~^ HELP: consider making the binding mutable if you need to reborrow multiple times h(&mut &mut b); - //~^ ERROR cannot borrow - //~| NOTE cannot borrow as mutable - //~| HELP try removing `&mut` here + //~^ ERROR: cannot borrow + //~| NOTE: cannot borrow as mutable + //~| HELP: if there is only one mutable reborrow, remove the `&mut` } pub fn h(_: &mut i32) {} diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr index f448e009b0e1..4c4a5e718393 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr @@ -15,36 +15,44 @@ note: the binding is already a mutable borrow | LL | pub fn f(b: &mut i32) { | ^^^^^^^^ -help: try removing `&mut` here +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | pub fn f(mut b: &mut i32) { + | +++ +help: if there is only one mutable reborrow, remove the `&mut` | LL - h(&mut b); LL + h(b); | -help: try removing `&mut` here +help: if there is only one mutable reborrow, remove the `&mut` | LL - g(&mut &mut b); LL + g(&mut b); | error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:17:12 + --> $DIR/mut-borrow-of-mut-ref.rs:19:12 | LL | h(&mut &mut b); | ^^^^^^ cannot borrow as mutable | note: the binding is already a mutable borrow - --> $DIR/mut-borrow-of-mut-ref.rs:16:13 + --> $DIR/mut-borrow-of-mut-ref.rs:17:13 | LL | pub fn g(b: &mut i32) { | ^^^^^^^^ -help: try removing `&mut` here +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | pub fn g(mut b: &mut i32) { + | +++ +help: if there is only one mutable reborrow, remove the `&mut` | LL - h(&mut &mut b); LL + h(&mut b); | error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:34:5 + --> $DIR/mut-borrow-of-mut-ref.rs:36:5 | LL | f.bar(); | ^ cannot borrow as mutable diff --git a/tests/ui/did_you_mean/issue-31424.rs b/tests/ui/did_you_mean/issue-31424.rs index 2821d5b9d8b3..3b3820bfc4af 100644 --- a/tests/ui/did_you_mean/issue-31424.rs +++ b/tests/ui/did_you_mean/issue-31424.rs @@ -4,17 +4,18 @@ struct Struct; impl Struct { fn foo(&mut self) { - (&mut self).bar(); //~ ERROR cannot borrow - //~^ HELP try removing `&mut` here + (&mut self).bar(); //~ ERROR: cannot borrow + //~^ HELP: try removing `&mut` here } // In this case we could keep the suggestion, but to distinguish the // two cases is pretty hard. It's an obscure case anyway. fn bar(self: &mut Self) { - //~^ WARN function cannot return without recursing - //~^^ HELP a `loop` may express intention better if this is on purpose + //~^ WARN: function cannot return without recursing + //~| HELP: a `loop` may express intention better if this is on purpose + //~| HELP: consider making the binding mutable if you need to reborrow multiple times (&mut self).bar(); //~ ERROR cannot borrow - //~^ HELP try removing `&mut` here + //~^ HELP: try removing `&mut` here } } diff --git a/tests/ui/did_you_mean/issue-31424.stderr b/tests/ui/did_you_mean/issue-31424.stderr index 8fe38bf69728..5752397098cf 100644 --- a/tests/ui/did_you_mean/issue-31424.stderr +++ b/tests/ui/did_you_mean/issue-31424.stderr @@ -28,7 +28,7 @@ LL | (&mut self).bar(); = note: `#[warn(unconditional_recursion)]` on by default error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-31424.rs:16:9 + --> $DIR/issue-31424.rs:17:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable @@ -39,10 +39,14 @@ note: the binding is already a mutable borrow LL | fn bar(self: &mut Self) { | ^^^^^^^^^ help: try removing `&mut` here - --> $DIR/issue-31424.rs:16:9 + --> $DIR/issue-31424.rs:17:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | fn bar(mut self: &mut Self) { + | +++ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/did_you_mean/issue-34126.rs b/tests/ui/did_you_mean/issue-34126.rs index 53516f4f2471..82ffadbf7d3f 100644 --- a/tests/ui/did_you_mean/issue-34126.rs +++ b/tests/ui/did_you_mean/issue-34126.rs @@ -3,9 +3,9 @@ struct Z { } impl Z { fn run(&self, z: &mut Z) { } fn start(&mut self) { - self.run(&mut self); //~ ERROR cannot borrow - //~| ERROR cannot borrow - //~| HELP try removing `&mut` here + self.run(&mut self); //~ ERROR: cannot borrow + //~| ERROR: cannot borrow + //~| HELP: if there is only one mutable reborrow, remove the `&mut` } } diff --git a/tests/ui/did_you_mean/issue-34126.stderr b/tests/ui/did_you_mean/issue-34126.stderr index 9f7920706287..ec02dfefaca1 100644 --- a/tests/ui/did_you_mean/issue-34126.stderr +++ b/tests/ui/did_you_mean/issue-34126.stderr @@ -9,7 +9,7 @@ note: the binding is already a mutable borrow | LL | fn start(&mut self) { | ^^^^^^^^^ -help: try removing `&mut` here +help: if there is only one mutable reborrow, remove the `&mut` | LL - self.run(&mut self); LL + self.run(self); diff --git a/tests/ui/nll/issue-51191.rs b/tests/ui/nll/issue-51191.rs index 836587d93b84..c0b0c5eda139 100644 --- a/tests/ui/nll/issue-51191.rs +++ b/tests/ui/nll/issue-51191.rs @@ -2,16 +2,17 @@ struct Struct; impl Struct { fn bar(self: &mut Self) { - //~^ WARN function cannot return without recursing - //~^^ HELP a `loop` may express intention better if this is on purpose + //~^ WARN: function cannot return without recursing + //~| HELP: a `loop` may express intention better if this is on purpose + //~| HELP: consider making the binding mutable if you need to reborrow multiple times (&mut self).bar(); - //~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596] - //~^^ HELP try removing `&mut` here + //~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596] + //~| HELP: try removing `&mut` here } fn imm(self) { //~ HELP consider changing this to be mutable (&mut self).bar(); - //~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596] + //~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596] } fn mtbl(mut self) { @@ -20,14 +21,14 @@ impl Struct { fn immref(&self) { (&mut self).bar(); - //~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596] - //~^^ ERROR cannot borrow data in a `&` reference as mutable [E0596] + //~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596] + //~| ERROR: cannot borrow data in a `&` reference as mutable [E0596] } fn mtblref(&mut self) { (&mut self).bar(); - //~^ ERROR cannot borrow `self` as mutable, as it is not declared as mutable [E0596] - //~^^ HELP try removing `&mut` here + //~^ ERROR: cannot borrow `self` as mutable, as it is not declared as mutable [E0596] + //~| HELP: try removing `&mut` here } } diff --git a/tests/ui/nll/issue-51191.stderr b/tests/ui/nll/issue-51191.stderr index c14056c3a834..73f8aab9d141 100644 --- a/tests/ui/nll/issue-51191.stderr +++ b/tests/ui/nll/issue-51191.stderr @@ -11,7 +11,7 @@ LL | (&mut self).bar(); = note: `#[warn(unconditional_recursion)]` on by default error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:7:9 + --> $DIR/issue-51191.rs:8:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable @@ -22,13 +22,17 @@ note: the binding is already a mutable borrow LL | fn bar(self: &mut Self) { | ^^^^^^^^^ help: try removing `&mut` here - --> $DIR/issue-51191.rs:7:9 + --> $DIR/issue-51191.rs:8:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | fn bar(mut self: &mut Self) { + | +++ error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:13:9 + --> $DIR/issue-51191.rs:14:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable @@ -39,30 +43,30 @@ LL | fn imm(mut self) { | +++ error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:22:9 + --> $DIR/issue-51191.rs:23:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/issue-51191.rs:22:9 + --> $DIR/issue-51191.rs:23:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:28:9 + --> $DIR/issue-51191.rs:29:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable | note: the binding is already a mutable borrow - --> $DIR/issue-51191.rs:27:16 + --> $DIR/issue-51191.rs:28:16 | LL | fn mtblref(&mut self) { | ^^^^^^^^^ help: try removing `&mut` here - --> $DIR/issue-51191.rs:28:9 + --> $DIR/issue-51191.rs:29:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ From 0efeec580a9cfa426e965af35747cef74d19191c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Sep 2025 23:04:50 +0000 Subject: [PATCH 270/525] Mention crate being analysized in query description "running analysis passes on this crate" -> "running analysis passes on crate `foo`" This message is displayed in cycle errors in particular, and in some cases without any spans or any other identifiable information to determine which dependency introduced the cycle. --- compiler/rustc_middle/src/query/mod.rs | 5 ++++- .../issue-24949-assoc-const-static-recursion-trait.stderr | 2 +- tests/ui/consts/const-eval/const-eval-query-stack.stderr | 2 +- tests/ui/consts/recursive-zst-static.default.stderr | 2 +- tests/ui/consts/recursive-zst-static.unleash.stderr | 2 +- tests/ui/track-diagnostics/track.stderr | 2 +- tests/ui/treat-err-as-bug/err.stderr | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 30d4cc8b3c8d..db2e252f9406 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -397,7 +397,10 @@ rustc_queries! { /// The root query triggering all analysis passes like typeck or borrowck. query analysis(key: ()) { eval_always - desc { "running analysis passes on this crate" } + desc { |tcx| + "running analysis passes on crate `{}`", + tcx.crate_name(LOCAL_CRATE), + } } /// This query checks the fulfillment of collected lint expectations. diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 317af7975aa7..8197cfcba502 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -30,7 +30,7 @@ note: ...which requires elaborating drops for ` Date: Fri, 31 Oct 2025 21:22:27 +0000 Subject: [PATCH 271/525] Change cfg_trace, cfg_attr_trace symbol values --- compiler/rustc_span/src/symbol.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c1c9fa57f85b..e3a4d261ee84 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -625,7 +625,7 @@ symbols! { cfg_accessible, cfg_attr, cfg_attr_multi, - cfg_attr_trace: "", // must not be a valid identifier + cfg_attr_trace: "", // must not be a valid identifier cfg_boolean_literals, cfg_contract_checks, cfg_doctest, @@ -646,7 +646,7 @@ symbols! { cfg_target_has_reliable_f16_f128, cfg_target_thread_local, cfg_target_vendor, - cfg_trace: "", // must not be a valid identifier + cfg_trace: "", // must not be a valid identifier cfg_ub_checks, cfg_version, cfi, From 0ba7bcfc44e4390555e4303cf47d76355de9f670 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 31 Oct 2025 16:05:48 -0700 Subject: [PATCH 272/525] Add LLVM range attributes to slice length parameters --- compiler/rustc_codegen_llvm/src/abi.rs | 22 ++++++++++++++++ tests/codegen-llvm/function-arguments.rs | 20 +++++++++++---- tests/codegen-llvm/range-attribute.rs | 22 ++++++++++++++-- tests/codegen-llvm/slice-as_chunks.rs | 2 +- tests/codegen-llvm/slice-iter-nonnull.rs | 4 +-- tests/codegen-llvm/slice-len-math.rs | 32 ++++++++++++++++++++++++ tests/codegen-llvm/slice-ref-equality.rs | 16 ++++++------ 7 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 tests/codegen-llvm/slice-len-math.rs diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 680ad98593e7..4ea0d06e26a0 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -522,6 +522,28 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { let ii = apply(b); if let BackendRepr::ScalarPair(scalar_a, scalar_b) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar_a); + let primitive_b = scalar_b.primitive(); + let scalar_b = if let rustc_abi::Primitive::Int(int, false) = primitive_b + && let ty::Ref(_, pointee_ty, _) = *arg.layout.ty.kind() + && let ty::Slice(element_ty) = *pointee_ty.kind() + && let elem_size = cx.layout_of(element_ty).size + && elem_size != rustc_abi::Size::ZERO + { + // Ideally the layout calculations would have set the range, + // but that's complicated due to cycles, so in the mean time + // we calculate and apply it here. + debug_assert!(scalar_b.is_always_valid(cx)); + let isize_max = int.signed_max() as u64; + rustc_abi::Scalar::Initialized { + value: primitive_b, + valid_range: rustc_abi::WrappingRange { + start: 0, + end: u128::from(isize_max / elem_size.bytes()), + }, + } + } else { + scalar_b + }; apply_range_attr(llvm::AttributePlace::Argument(ii), scalar_b); } } diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs index a0744e44c61e..c8aaf00442e9 100644 --- a/tests/codegen-llvm/function-arguments.rs +++ b/tests/codegen-llvm/function-arguments.rs @@ -208,17 +208,23 @@ pub fn struct_return() -> S { #[no_mangle] pub fn helper(_: usize) {} -// CHECK: @slice(ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @slice( +// CHECK-SAME: ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %_1.0, +// CHECK-SAME: [[USIZE]] noundef range({{i32 0, -2147483648|i64 0, -9223372036854775808}}) %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn slice(_: &[u8]) {} -// CHECK: @mutable_slice(ptr noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @mutable_slice( +// CHECK-SAME: ptr noalias noundef nonnull align 1 %_1.0, +// CHECK-SAME: [[USIZE]] noundef range({{i32 0, -2147483648|i64 0, -9223372036854775808}}) %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn mutable_slice(_: &mut [u8]) {} -// CHECK: @unsafe_slice(ptr noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @unsafe_slice( +// CHECK-SAME: ptr noundef nonnull align 2 %_1.0, +// CHECK-SAME: [[USIZE]] noundef range({{i32 0, 1073741824|i64 0, 4611686018427387904}}) %_1.1) // unsafe interior means this isn't actually readonly and there may be aliases ... #[no_mangle] pub fn unsafe_slice(_: &[UnsafeInner]) {} @@ -227,7 +233,9 @@ pub fn unsafe_slice(_: &[UnsafeInner]) {} #[no_mangle] pub fn raw_slice(_: *const [u8]) {} -// CHECK: @str(ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @str( +// CHECK-SAME: ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %_1.0, +// CHECK-SAME: [[USIZE]] noundef range({{i32 0, -2147483648|i64 0, -9223372036854775808}}) %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn str(_: &[u8]) {} @@ -259,7 +267,9 @@ pub fn trait_option(x: Option>) -> Option &[u16] { x diff --git a/tests/codegen-llvm/range-attribute.rs b/tests/codegen-llvm/range-attribute.rs index 865d36d47474..b057b2386e99 100644 --- a/tests/codegen-llvm/range-attribute.rs +++ b/tests/codegen-llvm/range-attribute.rs @@ -67,8 +67,26 @@ pub fn enum2_value(x: Enum2) -> Enum2 { x } -// CHECK: noundef [[USIZE]] @takes_slice(ptr {{.*}} %x.0, [[USIZE]] noundef %x.1) +// CHECK: noundef [[USIZE]] @takes_slice_4(ptr {{.*}} %x.0, [[USIZE]] noundef +// bit32-SAME: range(i32 0, [[#0x20000000]]) +// bit64-SAME: range(i64 0, [[#0x2000000000000000]]) +// CHECK-SAME: %x.1) #[no_mangle] -pub fn takes_slice(x: &[i32]) -> usize { +pub fn takes_slice_4(x: &[i32]) -> usize { + x.len() +} + +// CHECK: noundef [[USIZE]] @takes_slice_3(ptr {{.*}} %x.0, [[USIZE]] noundef +// bit32-SAME: range(i32 0, [[#0x2AAAAAAB]]) +// bit64-SAME: range(i64 0, [[#0x2AAAAAAAAAAAAAAB]]) +// CHECK-SAME: %x.1) +#[no_mangle] +pub fn takes_slice_3(x: &[[u8; 3]]) -> usize { + x.len() +} + +// CHECK: noundef [[USIZE]] @takes_zst_slice(ptr {{.*}} %x.0, [[USIZE]] noundef %x.1) +#[no_mangle] +pub fn takes_zst_slice(x: &[()]) -> usize { x.len() } diff --git a/tests/codegen-llvm/slice-as_chunks.rs b/tests/codegen-llvm/slice-as_chunks.rs index 337eb8981f6d..0f6ae21fa214 100644 --- a/tests/codegen-llvm/slice-as_chunks.rs +++ b/tests/codegen-llvm/slice-as_chunks.rs @@ -19,7 +19,7 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] { // CHECK-LABEL: @chunks4_with_remainder #[no_mangle] pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) { - // CHECK-DAG: and i64 %x.1, -4 + // CHECK-DAG: and i64 %x.1, [[#0x7FFFFFFFFFFFFFFC]] // CHECK-DAG: and i64 %x.1, 3 // CHECK-DAG: lshr // CHECK-NOT: mul diff --git a/tests/codegen-llvm/slice-iter-nonnull.rs b/tests/codegen-llvm/slice-iter-nonnull.rs index 87907e7ad0a3..280594456c93 100644 --- a/tests/codegen-llvm/slice-iter-nonnull.rs +++ b/tests/codegen-llvm/slice-iter-nonnull.rs @@ -51,7 +51,7 @@ pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&' // attribute is there, and confirms adding the assume back doesn't do anything. // CHECK-LABEL: @slice_iter_new -// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef range({{.+}}) %slice.1) #[no_mangle] pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { // CHECK-NOT: slice @@ -66,7 +66,7 @@ pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { } // CHECK-LABEL: @slice_iter_mut_new -// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef range({{.+}}) %slice.1) #[no_mangle] pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { // CHECK-NOT: slice diff --git a/tests/codegen-llvm/slice-len-math.rs b/tests/codegen-llvm/slice-len-math.rs new file mode 100644 index 000000000000..4b7a6adb22c6 --- /dev/null +++ b/tests/codegen-llvm/slice-len-math.rs @@ -0,0 +1,32 @@ +//@ compile-flags: -C opt-level=3 +#![crate_type = "lib"] + +#[no_mangle] +// CHECK-LABEL: @len_plus_ten_a +pub fn len_plus_ten_a(s: &[u8]) -> usize { + // CHECK: start: + // CHECK-NOT: add + // CHECK: %[[R:.+]] = add nuw i{{.+}} %s.1, 10 + // CHECK-NEXT: ret {{.+}} %[[R]] + s.len().wrapping_add(10) +} + +#[no_mangle] +// CHECK-LABEL: @len_plus_ten_b +pub fn len_plus_ten_b(s: &[u32]) -> usize { + // CHECK: start: + // CHECK-NOT: add + // CHECK: %[[R:.+]] = add nuw nsw i{{.+}} %s.1, 10 + // CHECK-NEXT: ret {{.+}} %[[R]] + s.len().wrapping_add(10) +} + +#[no_mangle] +// CHECK-LABEL: @len_plus_len +pub fn len_plus_len(x: &[u8], y: &[u8]) -> usize { + // CHECK: start: + // CHECK-NOT: add + // CHECK: %[[R:.+]] = add nuw i{{.+}} {{%x.1, %y.1|%y.1, %x.1}} + // CHECK-NEXT: ret {{.+}} %[[R]] + usize::wrapping_add(x.len(), y.len()) +} diff --git a/tests/codegen-llvm/slice-ref-equality.rs b/tests/codegen-llvm/slice-ref-equality.rs index 2940378da3cd..a5994c879485 100644 --- a/tests/codegen-llvm/slice-ref-equality.rs +++ b/tests/codegen-llvm/slice-ref-equality.rs @@ -42,8 +42,8 @@ pub fn is_zero_array(data: &[u8; 4]) -> bool { // equality for non-byte types also just emit a `bcmp`, not a loop. // CHECK-LABEL: @eq_slice_of_nested_u8( -// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1 -// CHECK-SAME: [[USIZE]] noundef %y.1 +// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef range({{.+}}) %x.1 +// CHECK-SAME: [[USIZE]] noundef range({{.+}}) %y.1 #[no_mangle] fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool { // CHECK: icmp eq [[USIZE]] %x.1, %y.1 @@ -54,8 +54,8 @@ fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool { } // CHECK-LABEL: @eq_slice_of_i32( -// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1 -// CHECK-SAME: [[USIZE]] noundef %y.1 +// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef range({{.+}}) %x.1 +// CHECK-SAME: [[USIZE]] noundef range({{.+}}) %y.1 #[no_mangle] fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool { // CHECK: icmp eq [[USIZE]] %x.1, %y.1 @@ -66,8 +66,8 @@ fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool { } // CHECK-LABEL: @eq_slice_of_nonzero( -// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1 -// CHECK-SAME: [[USIZE]] noundef %y.1 +// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef range({{.+}}) %x.1 +// CHECK-SAME: [[USIZE]] noundef range({{.+}}) %y.1 #[no_mangle] fn eq_slice_of_nonzero(x: &[NonZero], y: &[NonZero]) -> bool { // CHECK: icmp eq [[USIZE]] %x.1, %y.1 @@ -78,8 +78,8 @@ fn eq_slice_of_nonzero(x: &[NonZero], y: &[NonZero]) -> bool { } // CHECK-LABEL: @eq_slice_of_option_of_nonzero( -// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1 -// CHECK-SAME: [[USIZE]] noundef %y.1 +// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef range({{.+}}) %x.1 +// CHECK-SAME: [[USIZE]] noundef range({{.+}}) %y.1 #[no_mangle] fn eq_slice_of_option_of_nonzero(x: &[Option>], y: &[Option>]) -> bool { // CHECK: icmp eq [[USIZE]] %x.1, %y.1 From 61ccd539daf784d673eb9afbad6f596bf980ffdd Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 1 Nov 2025 10:20:16 +0200 Subject: [PATCH 273/525] test works in all editions --- .../temporary-lifetime-extension.edition2024.run.stdout | 1 - tests/ui/lifetimes/temporary-lifetime-extension.rs | 4 +--- ...021.run.stdout => temporary-lifetime-extension.run.stdout} | 0 3 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout rename tests/ui/lifetimes/{temporary-lifetime-extension.edition2021.run.stdout => temporary-lifetime-extension.run.stdout} (100%) diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout deleted file mode 100644 index 864372215898..000000000000 --- a/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout +++ /dev/null @@ -1 +0,0 @@ -("Hello", 1) [(("Hello", 1),)] "Hello" "Hello" "Hello" ("Hello", 1) ("Hello", 1) ("Hello", 1) diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.rs b/tests/ui/lifetimes/temporary-lifetime-extension.rs index 86c478af317c..d101aa476d06 100644 --- a/tests/ui/lifetimes/temporary-lifetime-extension.rs +++ b/tests/ui/lifetimes/temporary-lifetime-extension.rs @@ -12,9 +12,7 @@ //@ run-pass //@ check-run-results -//@ revisions: edition2021 edition2024 -//@ [edition2021] edition: 2021 -//@ [edition2024] edition: 2024 +//@ edition: 2015.. fn temp() -> (String, i32) { (String::from("Hello"), 1) diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.run.stdout similarity index 100% rename from tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout rename to tests/ui/lifetimes/temporary-lifetime-extension.run.stdout From 2044a5f51b12960ee2df64f62275bcf4598bd258 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 24 Oct 2025 17:03:26 +1100 Subject: [PATCH 274/525] Separate debugger discovery from debugger version-query --- src/tools/compiletest/src/debuggers.rs | 32 +++++++++++++------------- src/tools/compiletest/src/lib.rs | 7 +++--- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index 8afe3289fa45..93f27fb90951 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -103,22 +103,19 @@ fn find_cdb(target: &str) -> Option { } /// Returns Path to CDB -pub(crate) fn analyze_cdb( - cdb: Option, - target: &str, -) -> (Option, Option<[u16; 4]>) { +pub(crate) fn discover_cdb(cdb: Option, target: &str) -> Option { let cdb = cdb.map(Utf8PathBuf::from).or_else(|| find_cdb(target)); + cdb +} +pub(crate) fn query_cdb_version(cdb: &Utf8Path) -> Option<[u16; 4]> { let mut version = None; - if let Some(cdb) = cdb.as_ref() { - if let Ok(output) = Command::new(cdb).arg("/version").output() { - if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() { - version = extract_cdb_version(&first_line); - } + if let Ok(output) = Command::new(cdb).arg("/version").output() { + if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() { + version = extract_cdb_version(&first_line); } } - - (cdb, version) + version } pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> { @@ -132,12 +129,11 @@ pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> { Some([major, minor, patch, build]) } -/// Returns (Path to GDB, GDB Version) -pub(crate) fn analyze_gdb( +pub(crate) fn discover_gdb( gdb: Option, target: &str, android_cross_path: &Utf8Path, -) -> (Option, Option) { +) -> Option { #[cfg(not(windows))] const GDB_FALLBACK: &str = "gdb"; #[cfg(windows)] @@ -159,6 +155,10 @@ pub(crate) fn analyze_gdb( Some(ref s) => s.to_owned(), }; + Some(gdb) +} + +pub(crate) fn query_gdb_version(gdb: &str) -> Option { let mut version_line = None; if let Ok(output) = Command::new(&gdb).arg("--version").output() { if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() { @@ -168,10 +168,10 @@ pub(crate) fn analyze_gdb( let version = match version_line { Some(line) => extract_gdb_version(&line), - None => return (None, None), + None => return None, }; - (Some(gdb), version) + version } pub(crate) fn extract_gdb_version(full_version_line: &str) -> Option { diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index b524017e4dad..89f5623c1fc9 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -258,10 +258,11 @@ fn parse_config(args: Vec) -> Config { let target = opt_str2(matches.opt_str("target")); let android_cross_path = opt_path(matches, "android-cross-path"); // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! - let (cdb, cdb_version) = debuggers::analyze_cdb(matches.opt_str("cdb"), &target); + let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); + let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version); // FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config! - let (gdb, gdb_version) = - debuggers::analyze_gdb(matches.opt_str("gdb"), &target, &android_cross_path); + let gdb = debuggers::discover_gdb(matches.opt_str("gdb"), &target, &android_cross_path); + let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version); // FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config! let lldb_version = matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version); From 4220f7c90eadcf2bf5a719cf9da8895852642a55 Mon Sep 17 00:00:00 2001 From: Vitaliy Busko Date: Sat, 1 Nov 2025 15:20:57 +0700 Subject: [PATCH 275/525] confirmed success built rustc 1.91.0 + host tools for win7 --- src/doc/rustc/src/platform-support.md | 2 +- src/doc/rustc/src/platform-support/win7-windows-msvc.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 99739ee734e4..8cae44bcd074 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -439,7 +439,7 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | [`x86_64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 64-bit Windows 7 support -[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support +[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | ✓ | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [`xtensa-esp32-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32 diff --git a/src/doc/rustc/src/platform-support/win7-windows-msvc.md b/src/doc/rustc/src/platform-support/win7-windows-msvc.md index 56fe0f640166..b14424ddbf3a 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/win7-windows-msvc.md @@ -16,7 +16,8 @@ Target triples: This target supports all of core, alloc, std and test. This is automatically tested every night on private infrastructure hosted by the maintainer. Host -tools may also work, though those are not currently tested. +tools may also work, though it is not guaranteed. Last known success built +version of rustc with host tools (x86_64) is 1.91.0. Those targets follow Windows calling convention for extern "C". From 93fef455debe3ef1e5ab8d6dd06bf7f95c5dcf06 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 1 Nov 2025 02:39:55 -0700 Subject: [PATCH 276/525] Fix `wasm_import_module` attribute cross-crate This commit fixes an accidental regression from 144678 where wasm targets would now accidentally use the wrong import module map for a symbol causing a symbol to skip mangling. This can result in compilation failures when symbols are used in cross-crate situations. Closes 148347 --- compiler/rustc_symbol_mangling/src/lib.rs | 2 +- .../auxiliary/link-name-in-foreign-crate.rs | 7 ++++++ ...sm-link-name-in-foreign-crate-respected.rs | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs create mode 100644 tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index d97ee9565253..b5716b51a91c 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -228,7 +228,7 @@ fn compute_symbol_name<'tcx>( // However, we don't have the wasm import module map there yet. tcx.is_foreign_item(def_id) && tcx.sess.target.is_like_wasm - && tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&def_id.into()) + && tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id.into()) }; if !wasm_import_module_exception_force_mangling { diff --git a/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs b/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs new file mode 100644 index 000000000000..69d508518597 --- /dev/null +++ b/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs @@ -0,0 +1,7 @@ +#![no_std] + +#[link(wasm_import_module = "test")] +unsafe extern "C" { + #[link_name = "close"] + pub fn close(x: u32) -> u32; +} diff --git a/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs b/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs new file mode 100644 index 000000000000..e2ceeb8ae13e --- /dev/null +++ b/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs @@ -0,0 +1,22 @@ +//@ only-wasm32 +//@ aux-build:link-name-in-foreign-crate.rs +//@ compile-flags: --crate-type cdylib +//@ build-pass +//@ no-prefer-dynamic + +extern crate link_name_in_foreign_crate; + +// This test that the definition of a function named `close`, which collides +// with the `close` function in libc in theory, is handled correctly in +// cross-crate situations. The `link_name_in_foreign_crate` dependency declares +// `close` from a non-`env` wasm import module and then this crate attempts to +// use the symbol. This should properly ensure that the wasm module name is +// tagged as `test` and the `close` symbol, to LLD, is mangled, to avoid +// colliding with the `close` symbol in libc itself. + +#[unsafe(no_mangle)] +pub extern "C" fn foo() { + unsafe { + link_name_in_foreign_crate::close(1); + } +} From 82140c17797fc115ba625fbfd6fcebddc6e551a6 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 1 Nov 2025 13:51:02 +0000 Subject: [PATCH 277/525] Use --print host-tuple to get the host --- src/etc/rust-lldb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb index bce72f1bad69..f8f31903060c 100755 --- a/src/etc/rust-lldb +++ b/src/etc/rust-lldb @@ -4,7 +4,7 @@ set -e # Find the host triple so we can find lldb in rustlib. -host=$(rustc -vV | sed -n -e 's/^host: //p') +host=$(rustc --print host-tuple) # Find out where to look for the pretty printer Python module RUSTC_SYSROOT=$(rustc --print sysroot) From 0bd6a03edf6d0f9957aa85625232c11bf49ee164 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 31 Oct 2025 21:41:12 +0000 Subject: [PATCH 278/525] dangling ptr lint cleanup --- compiler/rustc_lint/messages.ftl | 8 +- .../ui/lint/dangling-pointers-from-locals.rs | 38 ++--- .../lint/dangling-pointers-from-locals.stderr | 152 +++++++++--------- 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 1f6a382175b7..8aa90c070acd 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -193,11 +193,11 @@ lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as i .current_use = this identifier can be confused with `{$existing_sym}` .other_use = other identifier used here -lint_dangling_pointers_from_locals = a dangling pointer will be produced because the local variable `{$local_var_name}` will be dropped - .ret_ty = return type of the {$fn_kind} is `{$ret_ty}` - .local_var = `{$local_var_name}` is part the {$fn_kind} and will be dropped at the end of the {$fn_kind} +lint_dangling_pointers_from_locals = {$fn_kind} returns a dangling pointer to dropped local variable `{$local_var_name}` + .ret_ty = return type is `{$ret_ty}` + .local_var = local variable `{$local_var_name}` is dropped at the end of the {$fn_kind} .created_at = dangling pointer created here - .note = pointers do not have a lifetime; after returning, the `{$local_var_ty}` will be deallocated at the end of the {$fn_kind} because nothing is referencing it as far as the type system is concerned + .note = a dangling pointer is safe, but dereferencing one is undefined behavior lint_dangling_pointers_from_temporaries = a dangling pointer will be produced because the temporary `{$ty}` will be dropped .label_ptr = this pointer will immediately be invalid diff --git a/tests/ui/lint/dangling-pointers-from-locals.rs b/tests/ui/lint/dangling-pointers-from-locals.rs index e321df2f4279..a274ab8582b9 100644 --- a/tests/ui/lint/dangling-pointers-from-locals.rs +++ b/tests/ui/lint/dangling-pointers-from-locals.rs @@ -8,46 +8,46 @@ const X: u8 = 5; fn simple() -> *const u8 { let x = 0; &x - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn bindings() -> *const u8 { let x = 0; let x = &x; x - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn bindings_with_return() -> *const u8 { let x = 42; let y = &x; return y; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn with_simple_cast() -> *const u8 { let x = 0u8; &x as *const u8 - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn bindings_and_casts() -> *const u8 { let x = 0u8; let x = &x as *const u8; x as *const u8 - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn return_with_complex_cast() -> *mut u8 { let mut x = 0u8; return &mut x as *mut u8 as *const u8 as *mut u8; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn with_block() -> *const u8 { let x = 0; &{ x } - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn with_many_blocks() -> *const u8 { @@ -55,7 +55,7 @@ fn with_many_blocks() -> *const u8 { { { &{ - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer { x } } } @@ -65,20 +65,20 @@ fn with_many_blocks() -> *const u8 { fn simple_return() -> *const u8 { let x = 0; return &x; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn return_mut() -> *mut u8 { let mut x = 0; return &mut x; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn const_and_flow() -> *const u8 { if false { let x = 8; return &x; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } &X // not dangling } @@ -86,20 +86,20 @@ fn const_and_flow() -> *const u8 { fn vector() -> *const Vec { let x = vec![T::default()]; &x - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn local_adt() -> *const Adt { let x = Adt(5); return &x; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn closure() -> *const u8 { let _x = || -> *const u8 { let x = 8; return &x; - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer }; &X // not dangling } @@ -111,27 +111,27 @@ fn fn_ptr() -> *const fn() -> u8 { let x = ret_u8 as fn() -> u8; &x - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn as_arg(a: Adt) -> *const Adt { &a - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn fn_ptr_as_arg(a: fn() -> u8) -> *const fn() -> u8 { &a - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn ptr_as_arg(a: *const Adt) -> *const *const Adt { &a - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn adt_as_arg(a: &Adt) -> *const &Adt { &a - //~^ WARN a dangling pointer will be produced + //~^ WARN dangling pointer } fn unit() -> *const () { diff --git a/tests/ui/lint/dangling-pointers-from-locals.stderr b/tests/ui/lint/dangling-pointers-from-locals.stderr index e1d28bf22a0c..45acc74ac34e 100644 --- a/tests/ui/lint/dangling-pointers-from-locals.stderr +++ b/tests/ui/lint/dangling-pointers-from-locals.stderr @@ -1,105 +1,105 @@ -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:10:5 | LL | fn simple() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | &x | ^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior = note: `#[warn(dangling_pointers_from_locals)]` on by default -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:17:5 | LL | fn bindings() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | let x = &x; | -- dangling pointer created here LL | x | ^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:24:12 | LL | fn bindings_with_return() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 42; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | let y = &x; | -- dangling pointer created here LL | return y; | ^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:30:5 | LL | fn with_simple_cast() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0u8; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | &x as *const u8 | --^^^^^^^^^^^^^ | | | dangling pointer created here | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:37:5 | LL | fn bindings_and_casts() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0u8; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | let x = &x as *const u8; | -- dangling pointer created here LL | x as *const u8 | ^^^^^^^^^^^^^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:43:12 | LL | fn return_with_complex_cast() -> *mut u8 { - | ------- return type of the function is `*mut u8` + | ------- return type is `*mut u8` LL | let mut x = 0u8; - | ----- `x` is part the function and will be dropped at the end of the function + | ----- local variable `x` is dropped at the end of the function LL | return &mut x as *mut u8 as *const u8 as *mut u8; | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | dangling pointer created here | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:49:5 | LL | fn with_block() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | &{ x } | ^^^^^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:57:13 | LL | fn with_many_blocks() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function ... LL | / &{ LL | | @@ -107,141 +107,141 @@ LL | | { x } LL | | } | |_____________^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:67:12 | LL | fn simple_return() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | let x = 0; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | return &x; | ^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:73:12 | LL | fn return_mut() -> *mut u8 { - | ------- return type of the function is `*mut u8` + | ------- return type is `*mut u8` LL | let mut x = 0; - | ----- `x` is part the function and will be dropped at the end of the function + | ----- local variable `x` is dropped at the end of the function LL | return &mut x; | ^^^^^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:80:16 | LL | fn const_and_flow() -> *const u8 { - | --------- return type of the function is `*const u8` + | --------- return type is `*const u8` LL | if false { LL | let x = 8; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | return &x; | ^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:88:5 | LL | fn vector() -> *const Vec { - | ------------- return type of the function is `*const Vec` + | ------------- return type is `*const Vec` LL | let x = vec![T::default()]; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | &x | ^^ | - = note: pointers do not have a lifetime; after returning, the `Vec` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:94:12 | LL | fn local_adt() -> *const Adt { - | ---------- return type of the function is `*const Adt` + | ---------- return type is `*const Adt` LL | let x = Adt(5); - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | return &x; | ^^ | - = note: pointers do not have a lifetime; after returning, the `Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: closure returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:101:16 | LL | let _x = || -> *const u8 { - | --------- return type of the closure is `*const u8` + | --------- return type is `*const u8` LL | let x = 8; - | - `x` is part the closure and will be dropped at the end of the closure + | - local variable `x` is dropped at the end of the closure LL | return &x; | ^^ | - = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated at the end of the closure because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `x` will be dropped +warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:113:5 | LL | fn fn_ptr() -> *const fn() -> u8 { - | ----------------- return type of the function is `*const fn() -> u8` + | ----------------- return type is `*const fn() -> u8` ... LL | let x = ret_u8 as fn() -> u8; - | - `x` is part the function and will be dropped at the end of the function + | - local variable `x` is dropped at the end of the function LL | &x | ^^ | - = note: pointers do not have a lifetime; after returning, the `fn() -> u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `a` will be dropped +warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:118:5 | LL | fn as_arg(a: Adt) -> *const Adt { - | - ---------- return type of the function is `*const Adt` + | - ---------- return type is `*const Adt` | | - | `a` is part the function and will be dropped at the end of the function + | local variable `a` is dropped at the end of the function LL | &a | ^^ | - = note: pointers do not have a lifetime; after returning, the `Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `a` will be dropped +warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:123:5 | LL | fn fn_ptr_as_arg(a: fn() -> u8) -> *const fn() -> u8 { - | - ----------------- return type of the function is `*const fn() -> u8` + | - ----------------- return type is `*const fn() -> u8` | | - | `a` is part the function and will be dropped at the end of the function + | local variable `a` is dropped at the end of the function LL | &a | ^^ | - = note: pointers do not have a lifetime; after returning, the `fn() -> u8` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `a` will be dropped +warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:128:5 | LL | fn ptr_as_arg(a: *const Adt) -> *const *const Adt { - | - ----------------- return type of the function is `*const *const Adt` + | - ----------------- return type is `*const *const Adt` | | - | `a` is part the function and will be dropped at the end of the function + | local variable `a` is dropped at the end of the function LL | &a | ^^ | - = note: pointers do not have a lifetime; after returning, the `*const Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior -warning: a dangling pointer will be produced because the local variable `a` will be dropped +warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:133:5 | LL | fn adt_as_arg(a: &Adt) -> *const &Adt { - | - ----------- return type of the function is `*const &Adt` + | - ----------- return type is `*const &Adt` | | - | `a` is part the function and will be dropped at the end of the function + | local variable `a` is dropped at the end of the function LL | &a | ^^ | - = note: pointers do not have a lifetime; after returning, the `&Adt` will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned + = note: a dangling pointer is safe, but dereferencing one is undefined behavior warning: 19 warnings emitted From 599c3799471e68f2ddf2cb5dd55caa4fb0c2095e Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 1 Nov 2025 18:50:01 +0200 Subject: [PATCH 279/525] Fix building with DHAT Maybe we need to check it on CI? --- .../rust-analyzer/crates/rust-analyzer/src/handlers/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index ad06a1d6c01f..dfe98878613e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -140,7 +140,7 @@ pub(crate) fn handle_memory_usage(_state: &mut GlobalState, _: ()) -> anyhow::Re #[cfg(feature = "dhat")] { if let Some(dhat_output_file) = _state.config.dhat_output_file() { - let mutprofiler = crate::DHAT_PROFILER.lock().unwrap(); + let mut profiler = crate::DHAT_PROFILER.lock().unwrap(); let old_profiler = profiler.take(); // Need to drop the old profiler before creating a new one. drop(old_profiler); From e23c1551a736b76108406bac0a658949d34f17a3 Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Tue, 30 Sep 2025 22:35:30 +0200 Subject: [PATCH 280/525] implement VecDeque extend_front and prepend, add tests --- .../alloc/src/collections/vec_deque/mod.rs | 84 +++++++++++++++- .../src/collections/vec_deque/spec_extend.rs | 95 +++++++++++++++++++ library/alloc/src/lib.rs | 1 + library/alloctests/tests/vec_deque.rs | 43 +++++++++ 4 files changed, 222 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index dc5aaa872603..fc0220022dbb 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -52,7 +52,7 @@ pub use self::iter::Iter; mod iter; -use self::spec_extend::SpecExtend; +use self::spec_extend::{SpecExtend, SpecExtendFront}; mod spec_extend; @@ -179,6 +179,21 @@ impl VecDeque { self.len += 1; } + /// Prepends an element to the buffer. + /// + /// # Safety + /// + /// May only be called if `deque.len() < deque.capacity()` + #[inline] + unsafe fn push_front_unchecked(&mut self, element: T) { + self.head = self.wrap_sub(self.head, 1); + // SAFETY: Because of the precondition, it's guaranteed that there is space + // in the logical array before the first element (where self.head is now). + unsafe { self.buffer_write(self.head, element) }; + // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`. + self.len += 1; + } + /// Moves an element out of the buffer #[inline] unsafe fn buffer_read(&mut self, off: usize) -> T { @@ -2122,6 +2137,73 @@ impl VecDeque { unsafe { self.buffer_write(self.to_physical_idx(len), value) } } + /// Prepends all contents of the iterator to the front of the deque. + /// The order of the contents is preserved. + /// + /// To get behavior like [`append`][VecDeque::append] where elements are moved + /// from the other collection to this one, use `self.prepend(other.drain(..))`. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// deque.prepend([1, 2, 3]); + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + /// + /// Move values between collections like [`append`][VecDeque::append] does but prepend to the front: + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque1 = VecDeque::from([4, 5, 6]); + /// let mut deque2 = VecDeque::from([1, 2, 3]); + /// deque1.prepend(deque2.drain(..)); + /// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]); + /// assert!(deque2.is_empty()); + /// ``` + #[unstable(feature = "deque_extend_front", issue = "146975")] + #[track_caller] + pub fn prepend>(&mut self, other: I) { + self.extend_front(other.into_iter().rev()) + } + + /// Prepends all contents of the iterator to the front of the deque, + /// as if [`push_front`][VecDeque::push_front] was called repeatedly with + /// the values yielded by the iterator. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// deque.extend_front([3, 2, 1]); + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + /// + /// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly: + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// for v in [3, 2, 1] { + /// deque.push_front(v); + /// } + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + #[unstable(feature = "deque_extend_front", issue = "146975")] + #[track_caller] + pub fn extend_front>(&mut self, iter: I) { + >::spec_extend_front(self, iter.into_iter()); + } + #[inline] fn is_contiguous(&self) -> bool { // Do the calculation like this to avoid overflowing if len + head > usize::MAX diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index 6c2199135e08..3e830d2afe67 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -1,3 +1,5 @@ +#[cfg(not(test))] +use core::iter::Rev; use core::iter::TrustedLen; use core::slice; @@ -114,3 +116,96 @@ where } } } + +// Specialization trait used for VecDeque::extend_front +pub(super) trait SpecExtendFront { + #[track_caller] + fn spec_extend_front(&mut self, iter: I); +} + +impl SpecExtendFront for VecDeque +where + I: Iterator, +{ + #[track_caller] + default fn spec_extend_front(&mut self, mut iter: I) { + // This function should be the moral equivalent of: + // + // for item in iter { + // self.push_front(item); + // } + + while let Some(element) = iter.next() { + let (lower, _) = iter.size_hint(); + self.reserve(lower.saturating_add(1)); + + // SAFETY: We just reserved space for at least one element. + unsafe { self.push_front_unchecked(element) }; + + // Inner loop to avoid repeatedly calling `reserve`. + while self.len < self.capacity() { + let Some(element) = iter.next() else { + return; + }; + // SAFETY: The loop condition guarantees that `self.len() < self.capacity()`. + unsafe { self.push_front_unchecked(element) }; + } + } + } +} + +#[cfg(not(test))] +impl SpecExtendFront> for VecDeque { + #[track_caller] + fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { + let slice = iterator.as_mut_slice(); + slice.reverse(); + unsafe { prepend(self, slice) }; + iterator.forget_remaining_elements(); + } +} + +#[cfg(not(test))] +impl SpecExtendFront>> for VecDeque { + #[track_caller] + fn spec_extend_front(&mut self, iterator: Rev>) { + let mut iterator = iterator.into_inner(); + unsafe { prepend(self, iterator.as_slice()) }; + iterator.forget_remaining_elements(); + } +} + +// impl SpecExtendFront>> for VecDeque +// where +// T: Copy, +// { +// #[track_caller] +// fn spec_extend_front(&mut self, _iter: Copied>) { +// // unsafe { prepend(self, slice) }; +// // reverse in place? +// } +// } + +// impl SpecExtendFront>>> for VecDeque +// where +// T: Copy, +// { +// #[track_caller] +// fn spec_extend_front(&mut self, iter: Rev>>) { +// unsafe { prepend(self, iter.into_inner().it.as_slice()) }; +// } +// } + +/// # Safety +/// +/// `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +#[cfg(not(test))] +unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { + deque.reserve(slice.len()); + + unsafe { + deque.head = deque.wrap_sub(deque.head, slice.len()); + deque.copy_slice(deque.head, slice); + deque.len += slice.len(); + } +} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 786f88c29ef4..81feb1cfc3f2 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -134,6 +134,7 @@ #![feature(ptr_alignment_type)] #![feature(ptr_internals)] #![feature(ptr_metadata)] +#![feature(rev_into_inner)] #![feature(set_ptr_value)] #![feature(sized_type_properties)] #![feature(slice_from_ptr_range)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 0a4a0e0cac4d..6442ee536fb5 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -2081,3 +2081,46 @@ fn test_extend_and_prepend_from_within() { v.extend_from_within(..); assert_eq!(v.iter().map(|s| &**s).collect::(), "123123123123"); } + +#[test] +fn test_extend_front() { + let mut v = VecDeque::new(); + v.extend_front(0..3); + assert_eq!(v, [2, 1, 0]); + v.extend_front(3..6); + assert_eq!(v, [5, 4, 3, 2, 1, 0]); + v.prepend([1; 4]); + assert_eq!(v, [1, 1, 1, 1, 5, 4, 3, 2, 1, 0]); + + let mut v = VecDeque::with_capacity(8); + let cap = v.capacity(); + v.extend(0..4); + v.truncate_front(2); + v.extend_front(4..8); + assert_eq!(v.as_slices(), ([7, 6].as_slice(), [5, 4, 2, 3].as_slice())); + assert_eq!(v.capacity(), cap); + + let mut v = VecDeque::new(); + v.extend_front([]); + v.extend_front(None); + v.extend_front(vec![]); + v.prepend([]); + v.prepend(None); + v.prepend(vec![]); + assert_eq!(v.capacity(), 0); + v.extend_front(Some(123)); + assert_eq!(v, [123]); +} + +#[test] +fn test_extend_front_specialization() { + let mut v = VecDeque::with_capacity(4); + v.prepend(vec![1, 2, 3]); + assert_eq!(v, [1, 2, 3]); + v.pop_front(); + v.prepend((-4..2).collect::>()); + assert_eq!(v, (-4..=3).collect::>()); + v.clear(); + v.extend_front(vec![1, 2, 3]); + assert_eq!(v, [3, 2, 1]); +} From f39fb70fb996b7949a0d5f9b3fde1270df689286 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 1 Nov 2025 14:13:33 -0400 Subject: [PATCH 281/525] Update tests after fixing ICEs --- tests/crashes/129209.rs | 11 --------- tests/crashes/131295.rs | 9 ------- tests/crashes/139738.rs | 3 --- .../parent_generics_of_nested_in_default.rs | 6 +++++ ...arent_generics_of_nested_in_default.stderr | 24 +++++++++++++++++++ 5 files changed, 30 insertions(+), 23 deletions(-) delete mode 100644 tests/crashes/129209.rs delete mode 100644 tests/crashes/131295.rs delete mode 100644 tests/crashes/139738.rs create mode 100644 tests/ui/const-generics/parent_generics_of_nested_in_default.rs create mode 100644 tests/ui/const-generics/parent_generics_of_nested_in_default.stderr diff --git a/tests/crashes/129209.rs b/tests/crashes/129209.rs deleted file mode 100644 index 249fa41552eb..000000000000 --- a/tests/crashes/129209.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#129209 - -impl< - const N: usize = { - static || { - Foo([0; X]); - } - }, - > PartialEq for True -{ -} diff --git a/tests/crashes/131295.rs b/tests/crashes/131295.rs deleted file mode 100644 index f31d6bc324a2..000000000000 --- a/tests/crashes/131295.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #131295 - -#![feature(generic_const_exprs)] - -async fn foo<'a>() -> [(); { - let _y: &'a (); - 4 - }] { -} diff --git a/tests/crashes/139738.rs b/tests/crashes/139738.rs deleted file mode 100644 index c0e7307de6c3..000000000000 --- a/tests/crashes/139738.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ known-bug: #139738 -#![feature(generic_const_exprs)] -fn b<'a>() -> impl IntoIterator<[(); (|_: &'a u8| 0, 0).1]> {} diff --git a/tests/ui/const-generics/parent_generics_of_nested_in_default.rs b/tests/ui/const-generics/parent_generics_of_nested_in_default.rs new file mode 100644 index 000000000000..25dc416fc1fd --- /dev/null +++ b/tests/ui/const-generics/parent_generics_of_nested_in_default.rs @@ -0,0 +1,6 @@ +impl Tr {} +//~^ ERROR cannot find type `Tr` +//~| ERROR cannot find value `B` +//~| ERROR defaults for generic parameters are not allowed here + +fn main() {} diff --git a/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr new file mode 100644 index 000000000000..24e05482a1a9 --- /dev/null +++ b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr @@ -0,0 +1,24 @@ +error[E0412]: cannot find type `Tr` in this scope + --> $DIR/parent_generics_of_nested_in_default.rs:1:36 + | +LL | impl Tr {} + | ^^ not found in this scope + +error[E0425]: cannot find value `B` in this scope + --> $DIR/parent_generics_of_nested_in_default.rs:1:30 + | +LL | impl Tr {} + | - ^ help: a const parameter with a similar name exists: `A` + | | + | similarly named const parameter `A` defined here + +error: defaults for generic parameters are not allowed here + --> $DIR/parent_generics_of_nested_in_default.rs:1:6 + | +LL | impl Tr {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. From 973ab7d08f6075b833aba0d8f96c28710b1cdfa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Nov 2025 18:23:19 +0000 Subject: [PATCH 282/525] Make "add param to inner item" suggestion verbose ``` error[E0401]: can't use generic parameters from outer item --> $DIR/enum-definition-with-outer-generic-parameter-5997.rs:3:16 | LL | fn f() -> bool { | - type parameter from outer item LL | enum E { V(Z) } | ^ use of generic parameter from outer item | help: try introducing a local generic parameter here | LL | enum E { V(Z) } | +++ ``` --- compiler/rustc_resolve/src/errors.rs | 7 +++- .../early/const-param-from-outer-fn.stderr | 6 +++- tests/ui/delegation/target-expr.stderr | 9 +++-- tests/ui/error-codes/E0401.stderr | 17 +++++---- ...n-with-outer-generic-parameter-5997.stderr | 9 +++-- ...eneric-params-nested-fn-scope-error.stderr | 18 ++++++---- tests/ui/generics/issue-98432.stderr | 9 +++-- tests/ui/resolve/bad-type-env-capture.stderr | 9 +++-- ...m-in-const-item.generic_const_items.stderr | 24 ++++++++----- tests/ui/resolve/issue-3021-c.stderr | 18 ++++++---- tests/ui/resolve/issue-3214.stderr | 6 +++- ...resolve-type-param-in-item-in-trait.stderr | 36 ++++++++++++------- tests/ui/type/type-arg-out-of-scope.stderr | 18 ++++++---- 13 files changed, 126 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index f0ea97ba8a0c..3465c7fb1647 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -47,7 +47,12 @@ pub(crate) enum GenericParamsFromOuterItemLabel { } #[derive(Subdiagnostic)] -#[suggestion(resolve_suggestion, code = "{snippet}", applicability = "maybe-incorrect")] +#[suggestion( + resolve_suggestion, + code = "{snippet}", + applicability = "maybe-incorrect", + style = "verbose" +)] pub(crate) struct GenericParamsFromOuterItemSugg { #[primary_span] pub(crate) span: Span, diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr index faba4ce10a1b..0f7c7fbc6be0 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -4,9 +4,13 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - const parameter from outer item LL | fn bar() -> u32 { - | - help: try introducing a local generic parameter here: `` LL | X | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar() -> u32 { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index f5556bf9f451..8bb25ad9e96e 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -3,11 +3,14 @@ error[E0401]: can't use generic parameters from outer item | LL | fn bar(_: T) { | - type parameter from outer item -LL | reuse Trait::static_method { - | - help: try introducing a local generic parameter here: `T,` -LL | +... LL | let _ = T::Default(); | ^^^^^^^^^^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | reuse Trait::static_methodT, { + | ++ error[E0434]: can't capture dynamic environment in a fn item --> $DIR/target-expr.rs:26:17 diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index 5d6878620c89..fedb064c6bea 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -4,9 +4,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bfnr, W: Fn()>(y: T) { - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `T,` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bfnr, W: Fn()>(y: T) { + | ++ error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:9:16 @@ -14,11 +17,13 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item ... -LL | fn baz $DIR/E0401.rs:22:25 diff --git a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr index aea0f049b07d..cded8ce31961 100644 --- a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr +++ b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr @@ -4,9 +4,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn f() -> bool { | - type parameter from outer item LL | enum E { V(Z) } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | enum E { V(Z) } + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr index 7fd1069c651f..8c3b65d1edea 100644 --- a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr +++ b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr @@ -4,9 +4,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(v: Vec) -> U { | - type parameter from outer item LL | fn bar(w: [U]) -> U { - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar(w: [U]) -> U { + | +++ error[E0401]: can't use generic parameters from outer item --> $DIR/generic-params-nested-fn-scope-error.rs:5:23 @@ -14,9 +17,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(v: Vec) -> U { | - type parameter from outer item LL | fn bar(w: [U]) -> U { - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar(w: [U]) -> U { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/generics/issue-98432.stderr b/tests/ui/generics/issue-98432.stderr index 2b09d43960f6..f20f779d884c 100644 --- a/tests/ui/generics/issue-98432.stderr +++ b/tests/ui/generics/issue-98432.stderr @@ -5,9 +5,12 @@ LL | impl Struct { | - type parameter from outer item LL | const CONST: fn() = || { LL | struct _Obligation where T:; - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | struct _Obligation where T:; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/bad-type-env-capture.stderr b/tests/ui/resolve/bad-type-env-capture.stderr index 3f9bc9149c24..272672beb4fb 100644 --- a/tests/ui/resolve/bad-type-env-capture.stderr +++ b/tests/ui/resolve/bad-type-env-capture.stderr @@ -4,9 +4,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - type parameter from outer item LL | fn bar(b: T) { } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar(b: T) { } + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr index 60aa94038c3a..3852b84fee2e 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -4,11 +4,13 @@ error[E0401]: can't use generic parameters from outer item LL | fn outer() { // outer function | - type parameter from outer item LL | const K: u32 = T::C; - | - ^^^^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^^^^ use of generic parameter from outer item | = note: a `const` is a separate item from the item that contains it +help: try introducing a local generic parameter here + | +LL | const K: u32 = T::C; + | +++ error[E0401]: can't use generic parameters from outer item --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24 @@ -17,11 +19,13 @@ LL | impl Tr for T { // outer impl block | - type parameter from outer item LL | const C: u32 = { LL | const I: u32 = T::C; - | - ^^^^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^^^^ use of generic parameter from outer item | = note: a `const` is a separate item from the item that contains it +help: try introducing a local generic parameter here + | +LL | const I: u32 = T::C; + | +++ error[E0401]: can't use generic parameters from outer item --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20 @@ -29,11 +33,13 @@ error[E0401]: can't use generic parameters from outer item LL | struct S(U32<{ // outer struct | - type parameter from outer item LL | const _: u32 = T::C; - | - ^^^^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^^^^ use of generic parameter from outer item | = note: a `const` is a separate item from the item that contains it +help: try introducing a local generic parameter here + | +LL | const _: u32 = T::C; + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/issue-3021-c.stderr b/tests/ui/resolve/issue-3021-c.stderr index 537bbaf7b6a5..dcbaf2afd10c 100644 --- a/tests/ui/resolve/issue-3021-c.stderr +++ b/tests/ui/resolve/issue-3021-c.stderr @@ -3,22 +3,28 @@ error[E0401]: can't use generic parameters from outer item | LL | fn siphash() { | - type parameter from outer item -LL | -LL | trait U { - | - help: try introducing a local generic parameter here: `` +... LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | trait U { + | +++ error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash() { | - type parameter from outer item -LL | -LL | trait U { - | - help: try introducing a local generic parameter here: `` +... LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | trait U { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-3214.stderr b/tests/ui/resolve/issue-3214.stderr index 1c64fdc1711f..5e5872f2a5fb 100644 --- a/tests/ui/resolve/issue-3214.stderr +++ b/tests/ui/resolve/issue-3214.stderr @@ -4,9 +4,13 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - type parameter from outer item LL | struct Foo { - | - help: try introducing a local generic parameter here: `` LL | x: T, | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | struct Foo { + | +++ error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-3214.rs:6:22 diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 1ab56fdc5044..086418df7a25 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -3,11 +3,14 @@ error[E0401]: can't use generic parameters from outer item | LL | trait TraitA { | - type parameter from outer item -LL | fn outer(&self) { -LL | enum Foo { - | - help: try introducing a local generic parameter here: `A,` +... LL | Variance(A) | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | enum Foo { + | ++ error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 @@ -16,9 +19,12 @@ LL | trait TraitB { | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo(A); - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `A,` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | struct Foo(A); + | ++ error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 @@ -27,9 +33,12 @@ LL | trait TraitC { | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo { a: A } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `A,` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | struct Foo { a: A } + | ++ error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 @@ -38,9 +47,12 @@ LL | trait TraitD { | - type parameter from outer item LL | fn outer(&self) { LL | fn foo(a: A) { } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `A,` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn foo(a: A) { } + | ++ error: aborting due to 4 previous errors diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr index fcaaca1770f6..f4fbcdac53b6 100644 --- a/tests/ui/type/type-arg-out-of-scope.stderr +++ b/tests/ui/type/type-arg-out-of-scope.stderr @@ -4,9 +4,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bar(f: Box T>) { } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar(f: Box T>) { } + | +++ error[E0401]: can't use generic parameters from outer item --> $DIR/type-arg-out-of-scope.rs:2:35 @@ -14,9 +17,12 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bar(f: Box T>) { } - | - ^ use of generic parameter from outer item - | | - | help: try introducing a local generic parameter here: `` + | ^ use of generic parameter from outer item + | +help: try introducing a local generic parameter here + | +LL | fn bar(f: Box T>) { } + | +++ error: aborting due to 2 previous errors From f6938709c8aef58ade5577ae8ff77fbcb99d0845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Nov 2025 18:29:46 +0000 Subject: [PATCH 283/525] Point at inner item when using outer item type param ``` error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:4:39 | LL | fn foo(x: T) { | - type parameter from outer item LL | fn bfnr, W: Fn()>(y: T) { | ---- ^ use of generic parameter from outer item | | | generic parameter used in this inner function | help: try introducing a local generic parameter here | LL | fn bfnr, W: Fn()>(y: T) { | ++ ``` --- compiler/rustc_resolve/messages.ftl | 5 ++++ compiler/rustc_resolve/src/diagnostics.rs | 7 ++++++ compiler/rustc_resolve/src/errors.rs | 10 ++++++++ compiler/rustc_resolve/src/ident.rs | 25 ++++++++++++++++++- compiler/rustc_resolve/src/late.rs | 15 +++++++---- compiler/rustc_resolve/src/lib.rs | 2 +- tests/ui/delegation/target-expr.stderr | 4 ++- tests/ui/error-codes/E0401.stderr | 16 ++++++++---- ...n-with-outer-generic-parameter-5997.stderr | 4 ++- ...eneric-params-nested-fn-scope-error.stderr | 8 ++++-- tests/ui/generics/issue-98432.stderr | 4 ++- tests/ui/resolve/bad-type-env-capture.stderr | 4 ++- ...om-outer-item-in-const-item.default.stderr | 12 ++++++--- ...m-in-const-item.generic_const_items.stderr | 12 ++++++--- tests/ui/resolve/issue-12796.stderr | 9 ++++--- tests/ui/resolve/issue-3021-c.stderr | 8 ++++-- tests/ui/resolve/issue-3214.stderr | 1 + ...65025-extern-static-parent-generics.stderr | 13 ++++++---- ...e-65035-static-with-parent-generics.stderr | 17 ++++++++----- ...resolve-type-param-in-item-in-trait.stderr | 16 +++++++++--- tests/ui/resolve/use-self-in-inner-fn.rs | 1 + tests/ui/resolve/use-self-in-inner-fn.stderr | 9 ++++--- .../static-generic-param-soundness.stderr | 4 ++- tests/ui/type/type-arg-out-of-scope.stderr | 8 ++++-- 24 files changed, 162 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 5bf90d2637df..d462ff589f0d 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -180,6 +180,11 @@ resolve_generic_params_from_outer_item_const = a `const` is a separate item from resolve_generic_params_from_outer_item_const_param = const parameter from outer item +resolve_generic_params_from_outer_item_inner_item = {$is_self -> + [true] `Self` + *[false] generic parameter + } used in this inner {$descr} + resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl` resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 236ab1f09d35..f302da356e1e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -557,6 +557,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { outer_res, has_generic_params, def_kind, + item, ) => { use errs::GenericParamsFromOuterItemLabel as Label; let static_or_const = match def_kind { @@ -575,6 +576,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { sugg: None, static_or_const, is_self, + item: item.map(|(span, descr)| errs::GenericParamsFromOuterItemInnerItem { + span, + descr, + }), }; let sm = self.tcx.sess.source_map(); @@ -2506,6 +2511,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &ribs[ns_to_try], ignore_binding, + None, ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Some(binding), @@ -2556,6 +2562,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &ribs[ValueNS], ignore_binding, + None, ) } else { None diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 3465c7fb1647..5c5938a3260e 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -24,6 +24,16 @@ pub(crate) struct GenericParamsFromOuterItem { #[subdiagnostic] pub(crate) static_or_const: Option, pub(crate) is_self: bool, + #[subdiagnostic] + pub(crate) item: Option, +} + +#[derive(Subdiagnostic)] +#[label(resolve_generic_params_from_outer_item_inner_item)] +pub(crate) struct GenericParamsFromOuterItemInnerItem { + #[primary_span] + pub(crate) span: Span, + pub(crate) descr: String, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2a195c8068da..4856b1e7cf97 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -12,7 +12,9 @@ use tracing::{debug, instrument}; use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use crate::imports::{Import, NameResolution}; -use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind}; +use crate::late::{ + ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind, +}; use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy, @@ -295,6 +297,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: Option, ribs: &[Rib<'ra>], ignore_binding: Option>, + diag_metadata: Option<&DiagMetadata<'_>>, ) -> Option> { assert!(ns == TypeNS || ns == ValueNS); let orig_ident = ident; @@ -326,6 +329,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|finalize| finalize.path_span), *original_rib_ident_def, ribs, + diag_metadata, ))); } else if let RibKind::Block(Some(module)) = rib.kind && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted( @@ -1193,6 +1197,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: Option, original_rib_ident_def: Ident, all_ribs: &[Rib<'ra>], + diag_metadata: Option<&DiagMetadata<'_>>, ) -> Res { debug!("validate_res_from_ribs({:?})", res); let ribs = &all_ribs[rib_index + 1..]; @@ -1391,12 +1396,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; if let Some(span) = finalize { + let item = if let Some(diag_metadata) = diag_metadata + && let Some(current_item) = diag_metadata.current_item + { + let span = current_item + .kind + .ident() + .map(|i| i.span) + .unwrap_or(current_item.span); + Some((span, current_item.kind.descr().to_string())) + } else { + None + }; self.report_error( span, ResolutionError::GenericParamsFromOuterItem( res, has_generic_params, def_kind, + item, ), ); } @@ -1472,6 +1490,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { res, has_generic_params, def_kind, + None, ), ); } @@ -1501,6 +1520,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, None, ignore_import, + None, ) } #[instrument(level = "debug", skip(self))] @@ -1522,6 +1542,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, ignore_binding, ignore_import, + None, ) } @@ -1535,6 +1556,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ribs: Option<&PerNS>>>, ignore_binding: Option>, ignore_import: Option>, + diag_metadata: Option<&DiagMetadata<'_>>, ) -> PathResult<'ra> { let mut module = None; let mut module_had_parse_errors = false; @@ -1675,6 +1697,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize, &ribs[ns], ignore_binding, + diag_metadata, ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Ok(binding), diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e3051dc38eca..198fef0cd630 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -667,7 +667,7 @@ pub(crate) struct UnnecessaryQualification<'ra> { } #[derive(Default, Debug)] -struct DiagMetadata<'ast> { +pub(crate) struct DiagMetadata<'ast> { /// The current trait's associated items' ident, used for diagnostic suggestions. current_trait_assoc_items: Option<&'ast [Box]>, @@ -678,7 +678,7 @@ struct DiagMetadata<'ast> { current_self_item: Option, /// The current trait (used to suggest). - current_item: Option<&'ast Item>, + pub(crate) current_item: Option<&'ast Item>, /// When processing generic arguments and encountering an unresolved ident not found, /// suggest introducing a type or const param depending on the context. @@ -885,6 +885,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc TypeNS, Some(Finalize::new(ty.id, ty.span)), None, + None, ) .map_or(Res::Err, |d| d.res()); self.r.record_partial_res(ty.id, PartialRes::new(res)); @@ -1457,6 +1458,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { None, &self.ribs[ns], None, + None, ) } @@ -1466,6 +1468,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ns: Namespace, finalize: Option, ignore_binding: Option>, + diag_metadata: Option<&crate::late::DiagMetadata<'_>>, ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, @@ -1474,6 +1477,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { finalize, &self.ribs[ns], ignore_binding, + diag_metadata, ) } @@ -1493,6 +1497,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { Some(&self.ribs), None, None, + Some(&self.diag_metadata), ) } @@ -2551,8 +2556,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { report_error(self, ns); } Some(LexicalScopeBinding::Item(binding)) => { - if let Some(LexicalScopeBinding::Res(..)) = - self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding)) + if let Some(LexicalScopeBinding::Res(..)) = self + .resolve_ident_in_lexical_scope(ident, ns, None, Some(binding), None) { report_error(self, ns); } @@ -5105,7 +5110,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // use the type namespace let ns = if i + 1 == path.len() { ns } else { TypeNS }; let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?; - let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?; + let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None, None)?; (res == binding.res()).then_some((seg, binding)) }); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f6a4f59cb339..c7f5ec76c075 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -241,7 +241,7 @@ struct BindingError { #[derive(Debug)] enum ResolutionError<'ra> { /// Error E0401: can't use type or const parameters from outer item. - GenericParamsFromOuterItem(Res, HasGenericParams, DefKind), + GenericParamsFromOuterItem(Res, HasGenericParams, DefKind, Option<(Span, String)>), /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. NameAlreadyUsedInParameterList(Ident, Span), diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index 8bb25ad9e96e..f2e6c331193f 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -3,7 +3,9 @@ error[E0401]: can't use generic parameters from outer item | LL | fn bar(_: T) { | - type parameter from outer item -... +LL | reuse Trait::static_method { + | ------------- generic parameter used in this inner delegated function +LL | LL | let _ = T::Default(); | ^^^^^^^^^^ use of generic parameter from outer item | diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index fedb064c6bea..8daaf09df159 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bfnr, W: Fn()>(y: T) { - | ^ use of generic parameter from outer item + | ---- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | @@ -17,6 +19,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item ... +LL | fn baz Iterator for A { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn helper(sel: &Self) -> u8 { - | ^^^^ - | | - | use of `Self` from outer item - | refer to the type directly here instead + | ------ ^^^^ + | | | + | | use of `Self` from outer item + | | refer to the type directly here instead + | `Self` used in this inner function error: aborting due to 3 previous errors diff --git a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr index cded8ce31961..fb2d2f247b65 100644 --- a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr +++ b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn f() -> bool { | - type parameter from outer item LL | enum E { V(Z) } - | ^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item + | | + | generic parameter used in this inner enum | help: try introducing a local generic parameter here | diff --git a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr index 8c3b65d1edea..f809740ed381 100644 --- a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr +++ b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(v: Vec) -> U { | - type parameter from outer item LL | fn bar(w: [U]) -> U { - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | @@ -17,7 +19,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(v: Vec) -> U { | - type parameter from outer item LL | fn bar(w: [U]) -> U { - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | diff --git a/tests/ui/generics/issue-98432.stderr b/tests/ui/generics/issue-98432.stderr index f20f779d884c..a1efee78cb7d 100644 --- a/tests/ui/generics/issue-98432.stderr +++ b/tests/ui/generics/issue-98432.stderr @@ -5,7 +5,9 @@ LL | impl Struct { | - type parameter from outer item LL | const CONST: fn() = || { LL | struct _Obligation where T:; - | ^ use of generic parameter from outer item + | ----------- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner struct | help: try introducing a local generic parameter here | diff --git a/tests/ui/resolve/bad-type-env-capture.stderr b/tests/ui/resolve/bad-type-env-capture.stderr index 272672beb4fb..c565997ca2a2 100644 --- a/tests/ui/resolve/bad-type-env-capture.stderr +++ b/tests/ui/resolve/bad-type-env-capture.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - type parameter from outer item LL | fn bar(b: T) { } - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr index fbb9ede8aa17..bc67e9dce4e3 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn outer() { // outer function | - type parameter from outer item LL | const K: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it @@ -15,7 +17,9 @@ LL | impl Tr for T { // outer impl block | - type parameter from outer item LL | const C: u32 = { LL | const I: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it @@ -25,7 +29,9 @@ error[E0401]: can't use generic parameters from outer item LL | struct S(U32<{ // outer struct | - type parameter from outer item LL | const _: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr index 3852b84fee2e..3959d117c7c9 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn outer() { // outer function | - type parameter from outer item LL | const K: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here @@ -19,7 +21,9 @@ LL | impl Tr for T { // outer impl block | - type parameter from outer item LL | const C: u32 = { LL | const I: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here @@ -33,7 +37,9 @@ error[E0401]: can't use generic parameters from outer item LL | struct S(U32<{ // outer struct | - type parameter from outer item LL | const _: u32 = T::C; - | ^^^^ use of generic parameter from outer item + | - ^^^^ use of generic parameter from outer item + | | + | generic parameter used in this inner constant item | = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here diff --git a/tests/ui/resolve/issue-12796.stderr b/tests/ui/resolve/issue-12796.stderr index 2305971303a7..b5828c6f5fc8 100644 --- a/tests/ui/resolve/issue-12796.stderr +++ b/tests/ui/resolve/issue-12796.stderr @@ -2,10 +2,11 @@ error[E0401]: can't use `Self` from outer item --> $DIR/issue-12796.rs:3:22 | LL | fn inner(_: &Self) { - | ^^^^ - | | - | use of `Self` from outer item - | can't use `Self` here + | ----- ^^^^ + | | | + | | use of `Self` from outer item + | | can't use `Self` here + | `Self` used in this inner function error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-3021-c.stderr b/tests/ui/resolve/issue-3021-c.stderr index dcbaf2afd10c..8c554fd1b97d 100644 --- a/tests/ui/resolve/issue-3021-c.stderr +++ b/tests/ui/resolve/issue-3021-c.stderr @@ -3,7 +3,9 @@ error[E0401]: can't use generic parameters from outer item | LL | fn siphash() { | - type parameter from outer item -... +LL | +LL | trait U { + | - generic parameter used in this inner trait LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item | @@ -17,7 +19,9 @@ error[E0401]: can't use generic parameters from outer item | LL | fn siphash() { | - type parameter from outer item -... +LL | +LL | trait U { + | - generic parameter used in this inner trait LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item | diff --git a/tests/ui/resolve/issue-3214.stderr b/tests/ui/resolve/issue-3214.stderr index 5e5872f2a5fb..ab12676bdd80 100644 --- a/tests/ui/resolve/issue-3214.stderr +++ b/tests/ui/resolve/issue-3214.stderr @@ -4,6 +4,7 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - type parameter from outer item LL | struct Foo { + | --- generic parameter used in this inner struct LL | x: T, | ^ use of generic parameter from outer item | diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr index ca32147d1976..2d21ed0155a7 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr @@ -1,11 +1,14 @@ error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65025-extern-static-parent-generics.rs:3:28 | -LL | unsafe fn foo() { - | - type parameter from outer item -LL | extern "C" { -LL | static baz: *const A; - | ^ use of generic parameter from outer item +LL | unsafe fn foo() { + | - type parameter from outer item +LL | / extern "C" { +LL | | static baz: *const A; + | | ^ use of generic parameter from outer item +LL | | +LL | | } + | |_____- generic parameter used in this inner extern block | = note: a `static` is a separate item from the item that contains it diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr index 98ffb4567f16..869e1729cb85 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -1,11 +1,14 @@ error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:3:26 | -LL | fn f() { - | - type parameter from outer item -LL | extern "C" { -LL | static a: *const T; - | ^ use of generic parameter from outer item +LL | fn f() { + | - type parameter from outer item +LL | / extern "C" { +LL | | static a: *const T; + | | ^ use of generic parameter from outer item +LL | | +LL | | } + | |_____- generic parameter used in this inner extern block | = note: a `static` is a separate item from the item that contains it @@ -15,7 +18,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn g() { | - type parameter from outer item LL | static a: *const T = Default::default(); - | ^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item + | | + | generic parameter used in this inner static item | = note: a `static` is a separate item from the item that contains it diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 086418df7a25..00aa645688e7 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -3,7 +3,9 @@ error[E0401]: can't use generic parameters from outer item | LL | trait TraitA { | - type parameter from outer item -... +LL | fn outer(&self) { +LL | enum Foo { + | --- generic parameter used in this inner enum LL | Variance(A) | ^ use of generic parameter from outer item | @@ -19,7 +21,9 @@ LL | trait TraitB { | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo(A); - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner struct | help: try introducing a local generic parameter here | @@ -33,7 +37,9 @@ LL | trait TraitC { | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo { a: A } - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner struct | help: try introducing a local generic parameter here | @@ -47,7 +53,9 @@ LL | trait TraitD { | - type parameter from outer item LL | fn outer(&self) { LL | fn foo(a: A) { } - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs index 62f9dc5664ff..ed64ee885271 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.rs +++ b/tests/ui/resolve/use-self-in-inner-fn.rs @@ -6,6 +6,7 @@ impl A { fn peach(this: &Self) { //~^ ERROR can't use `Self` from outer item //~| NOTE use of `Self` from outer item + //~| NOTE `Self` used in this inner function //~| NOTE refer to the type directly here instead } } diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 9c388df8bc20..645875f6e726 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -5,10 +5,11 @@ LL | impl A { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn peach(this: &Self) { - | ^^^^ - | | - | use of `Self` from outer item - | refer to the type directly here instead + | ----- ^^^^ + | | | + | | use of `Self` from outer item + | | refer to the type directly here instead + | `Self` used in this inner function error: aborting due to 1 previous error diff --git a/tests/ui/statics/static-generic-param-soundness.stderr b/tests/ui/statics/static-generic-param-soundness.stderr index 47554c7fcb0f..72f65e2bac7c 100644 --- a/tests/ui/statics/static-generic-param-soundness.stderr +++ b/tests/ui/statics/static-generic-param-soundness.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - type parameter from outer item LL | static a: Bar = Bar::What; - | ^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item + | | + | generic parameter used in this inner static item | = note: a `static` is a separate item from the item that contains it diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr index f4fbcdac53b6..3d8850ebccea 100644 --- a/tests/ui/type/type-arg-out-of-scope.stderr +++ b/tests/ui/type/type-arg-out-of-scope.stderr @@ -4,7 +4,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bar(f: Box T>) { } - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | @@ -17,7 +19,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo(x: T) { | - type parameter from outer item LL | fn bar(f: Box T>) { } - | ^ use of generic parameter from outer item + | --- ^ use of generic parameter from outer item + | | + | generic parameter used in this inner function | help: try introducing a local generic parameter here | From 901664a7ddfd26eca1efc03d9e5781d163d3f510 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 14 Oct 2025 02:03:54 +0100 Subject: [PATCH 284/525] setup canonical normalization for const norm --- compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/traits/query.rs | 6 +- .../src/traits/query/normalize.rs | 180 ++++++++++-------- .../src/normalize_projection_ty.rs | 31 +-- 5 files changed, 125 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index feaad5bb96eb..cdf85b82ae72 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -44,7 +44,7 @@ macro_rules! arena_types { rustc_middle::traits::query::DropckOutlivesResult<'tcx> > >, - [] normalize_canonicalized_projection_ty: + [] normalize_canonicalized_projection: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::traits::query::NormalizationResult<'tcx> diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 30d4cc8b3c8d..4dae00c02ccf 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2411,7 +2411,7 @@ rustc_queries! { /// Do not call this query directly: Invoke `normalize` instead. /// /// - query normalize_canonicalized_projection_ty( + query normalize_canonicalized_projection( goal: CanonicalAliasGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, @@ -2439,7 +2439,7 @@ rustc_queries! { /// Do not call this query directly: Invoke `normalize` instead. /// /// - query normalize_canonicalized_inherent_projection_ty( + query normalize_canonicalized_inherent_projection( goal: CanonicalAliasGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index c5cd7c54e4e8..9f3bc0ec43e6 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -66,7 +66,7 @@ pub mod type_op { } pub type CanonicalAliasGoal<'tcx> = - CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTerm<'tcx>>>; pub type CanonicalMethodAutoderefStepsGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, MethodAutoderefSteps<'tcx>>>; @@ -192,11 +192,11 @@ pub struct MethodAutoderefBadTy<'tcx> { pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, } -/// Result of the `normalize_canonicalized_{{,inherent_}projection,free}_ty` queries. +/// Result of the `normalize_canonicalized_{{,inherent_}projection,free}` queries. #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct NormalizationResult<'tcx> { /// Result of the normalization. - pub normalized_ty: Ty<'tcx>, + pub normalized_term: ty::Term<'tcx>, } /// Outlives bounds are relationships between generic parameters, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index c6eb0caee1a6..02438b24ca7f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -1,9 +1,10 @@ //! Code for the 'normalization' query. This consists of a wrapper //! which folds deeply, invoking the underlying -//! `normalize_canonicalized_projection_ty` query when it encounters projections. +//! `normalize_canonicalized_projection` query when it encounters projections. use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_hir::def::DefKind; use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; @@ -255,76 +256,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { } } - ty::Projection | ty::Inherent | ty::Free => { - // See note in `rustc_trait_selection::traits::project` - - let infcx = self.infcx; - let tcx = infcx.tcx; - // Just an optimization: When we don't have escaping bound vars, - // we don't need to replace them with placeholders. - let (data, maps) = if data.has_escaping_bound_vars() { - let (data, mapped_regions, mapped_types, mapped_consts) = - BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - (data, Some((mapped_regions, mapped_types, mapped_consts))) - } else { - (data, None) - }; - let data = data.try_fold_with(self)?; - - let mut orig_values = OriginalQueryValues::default(); - let c_data = infcx.canonicalize_query(self.param_env.and(data), &mut orig_values); - debug!("QueryNormalizer: c_data = {:#?}", c_data); - debug!("QueryNormalizer: orig_values = {:#?}", orig_values); - let result = match kind { - ty::Projection => tcx.normalize_canonicalized_projection_ty(c_data), - ty::Free => tcx.normalize_canonicalized_free_alias(c_data), - ty::Inherent => tcx.normalize_canonicalized_inherent_projection_ty(c_data), - kind => unreachable!("did not expect {kind:?} due to match arm above"), - }?; - // We don't expect ambiguity. - if !result.value.is_proven() { - // Rustdoc normalizes possibly not well-formed types, so only - // treat this as a bug if we're not in rustdoc. - if !tcx.sess.opts.actually_rustdoc { - tcx.dcx() - .delayed_bug(format!("unexpected ambiguity: {c_data:?} {result:?}")); - } - return Err(NoSolution); - } - let InferOk { value: result, obligations } = infcx - .instantiate_query_response_and_region_obligations( - self.cause, - self.param_env, - &orig_values, - result, - )?; - debug!("QueryNormalizer: result = {:#?}", result); - debug!("QueryNormalizer: obligations = {:#?}", obligations); - self.obligations.extend(obligations); - let res = if let Some((mapped_regions, mapped_types, mapped_consts)) = maps { - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - result.normalized_ty, - ) - } else { - result.normalized_ty - }; - // `tcx.normalize_canonicalized_projection_ty` may normalize to a type that - // still has unevaluated consts, so keep normalizing here if that's the case. - // Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer - // of type and we need to continue folding it to reveal the TAIT behind it. - if res != ty - && (res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) || kind == ty::Free) - { - res.try_fold_with(self)? - } else { - res - } - } + ty::Projection | ty::Inherent | ty::Free => self + .try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), data.def_id, data.args))? + .expect_type(), }; self.cache.insert(ty, res); @@ -339,12 +273,22 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { return Ok(constant); } - let constant = crate::traits::with_replaced_escaping_bound_vars( - self.infcx, - &mut self.universes, - constant, - |constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env), - ); + let uv = match constant.kind() { + ty::ConstKind::Unevaluated(uv) => uv, + _ => return constant.try_super_fold_with(self), + }; + + let constant = match self.cx().def_kind(uv.def) { + DefKind::AnonConst => crate::traits::with_replaced_escaping_bound_vars( + self.infcx, + &mut self.universes, + constant, + |constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env), + ), + _ => self + .try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), uv.def, uv.args))? + .expect_const(), + }; debug!(?constant, ?self.param_env); constant.try_super_fold_with(self) } @@ -361,3 +305,85 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { } } } + +impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> { + fn try_fold_free_or_assoc( + &mut self, + term: ty::AliasTerm<'tcx>, + ) -> Result, NoSolution> { + let infcx = self.infcx; + let tcx = infcx.tcx; + // Just an optimization: When we don't have escaping bound vars, + // we don't need to replace them with placeholders. + let (term, maps) = if term.has_escaping_bound_vars() { + let (term, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, term); + (term, Some((mapped_regions, mapped_types, mapped_consts))) + } else { + (term, None) + }; + let term = term.try_fold_with(self)?; + + let mut orig_values = OriginalQueryValues::default(); + let c_term = infcx.canonicalize_query(self.param_env.and(term), &mut orig_values); + debug!("QueryNormalizer: c_term = {:#?}", c_term); + debug!("QueryNormalizer: orig_values = {:#?}", orig_values); + let result = match term.kind(tcx) { + ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { + tcx.normalize_canonicalized_projection(c_term) + } + ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => { + tcx.normalize_canonicalized_free_alias(c_term) + } + ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => { + tcx.normalize_canonicalized_inherent_projection(c_term) + } + kind @ (ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::UnevaluatedConst) => { + unreachable!("did not expect {kind:?} due to match arm above") + } + }?; + // We don't expect ambiguity. + if !result.value.is_proven() { + // Rustdoc normalizes possibly not well-formed types, so only + // treat this as a bug if we're not in rustdoc. + if !tcx.sess.opts.actually_rustdoc { + tcx.dcx().delayed_bug(format!("unexpected ambiguity: {c_term:?} {result:?}")); + } + return Err(NoSolution); + } + let InferOk { value: result, obligations } = infcx + .instantiate_query_response_and_region_obligations( + self.cause, + self.param_env, + &orig_values, + result, + )?; + debug!("QueryNormalizer: result = {:#?}", result); + debug!("QueryNormalizer: obligations = {:#?}", obligations); + self.obligations.extend(obligations); + let res = if let Some((mapped_regions, mapped_types, mapped_consts)) = maps { + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + result.normalized_term, + ) + } else { + result.normalized_term + }; + // `tcx.normalize_canonicalized_projection` may normalize to a type that + // still has unevaluated consts, so keep normalizing here if that's the case. + // Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer + // of type and we need to continue folding it to reveal the TAIT behind it. + if res != term.to_term(tcx) + && (res.as_type().map_or(false, |t| t.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)) + || term.kind(tcx) == ty::AliasTermKind::FreeTy) + { + res.try_fold_with(self) + } else { + Ok(res) + } + } +} diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index db871d4b0aaa..fd5795c0fbcc 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -12,18 +12,18 @@ use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { - normalize_canonicalized_projection_ty, + normalize_canonicalized_projection, normalize_canonicalized_free_alias, - normalize_canonicalized_inherent_projection_ty, + normalize_canonicalized_inherent_projection, ..*p }; } -fn normalize_canonicalized_projection_ty<'tcx>( +fn normalize_canonicalized_projection<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalAliasGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> { - debug!("normalize_canonicalized_projection_ty(goal={:#?})", goal); + debug!("normalize_canonicalized_projection(goal={:#?})", goal); tcx.infer_ctxt().enter_canonical_trait_query( &goal, @@ -32,7 +32,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = PredicateObligations::new(); - let answer = traits::normalize_projection_term( + let normalized_term = traits::normalize_projection_term( selcx, param_env, goal.into(), @@ -61,10 +61,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( return Err(NoSolution); } - // FIXME(associated_const_equality): All users of normalize_canonicalized_projection_ty - // expected a type, but there is the possibility it could've been a const now. - // Maybe change it to a Term later? - Ok(NormalizationResult { normalized_ty: answer.expect_type() }) + Ok(NormalizationResult { normalized_term }) }, ) } @@ -89,17 +86,21 @@ fn normalize_canonicalized_free_alias<'tcx>( }, ); ocx.register_obligations(obligations); - let normalized_ty = tcx.type_of(goal.def_id).instantiate(tcx, goal.args); - Ok(NormalizationResult { normalized_ty }) + let normalized_term = if goal.kind(tcx).is_type() { + tcx.type_of(goal.def_id).instantiate(tcx, goal.args).into() + } else { + todo!() + }; + Ok(NormalizationResult { normalized_term }) }, ) } -fn normalize_canonicalized_inherent_projection_ty<'tcx>( +fn normalize_canonicalized_inherent_projection<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalAliasGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> { - debug!("normalize_canonicalized_inherent_projection_ty(goal={:#?})", goal); + debug!("normalize_canonicalized_inherent_projection(goal={:#?})", goal); tcx.infer_ctxt().enter_canonical_trait_query( &goal, @@ -107,7 +108,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = PredicateObligations::new(); - let answer = traits::normalize_inherent_projection( + let normalized_term = traits::normalize_inherent_projection( selcx, param_env, goal.into(), @@ -117,7 +118,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( ); ocx.register_obligations(obligations); - Ok(NormalizationResult { normalized_ty: answer.expect_type() }) + Ok(NormalizationResult { normalized_term }) }, ) } From 838684b11a0c40ca1c1bae2a06ccf4a924798d58 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 14 Oct 2025 03:21:02 +0100 Subject: [PATCH 285/525] add ConstArgKind::Error --- compiler/rustc_hir/src/hir.rs | 3 +++ compiler/rustc_hir/src/intravisit.rs | 1 + compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 1 + compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +++- 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ac7ad669b461..f20b49ab5a06 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -474,6 +474,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { match self.kind { ConstArgKind::Path(path) => path.span(), ConstArgKind::Anon(anon) => anon.span, + ConstArgKind::Error(span, _) => span, ConstArgKind::Infer(span, _) => span, } } @@ -490,6 +491,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// However, in the future, we'll be using it for all of those. Path(QPath<'hir>), Anon(&'hir AnonConst), + /// Error const + Error(Span, ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes /// [`GenericArg::Infer`] is used instead. Infer(Span, Unambig), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 232178ee403a..ce2936a60dbe 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1058,6 +1058,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( match kind { ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), + ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important } } 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 c1eb277b1380..8ea4af9e1761 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2242,6 +2242,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), + hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 12d981396c8a..a5fd60be6335 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1131,6 +1131,7 @@ impl<'a> State<'a> { match &const_arg.kind { ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), + ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), ConstArgKind::Infer(..) => self.word("_"), } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f47e349ac391..60db5a276a9b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1428,7 +1428,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { && match tcx.hir_node_by_def_id(local_id) { hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind { // Skip encoding defs for these as they should not have had a `DefId` created - hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, + hir::ConstArgKind::Error(..) + | hir::ConstArgKind::Path(..) + | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, }, _ => false, From 471f2ba64ed769013f87986bc5340d9edeecc3f0 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 7 Sep 2025 22:05:59 +0530 Subject: [PATCH 286/525] library: std: sys: net: uefi: tcp: Implement write_vectored - A working vectored write implementation for TCP4. - Also introduces a small helper UefiBox intended to be used with heap allocated UEFI DSTs. - Tested on OVMF Signed-off-by: Ayush Singh --- .../std/src/sys/net/connection/uefi/mod.rs | 5 +- .../std/src/sys/net/connection/uefi/tcp.rs | 12 +++- .../std/src/sys/net/connection/uefi/tcp4.rs | 69 +++++++++++++++---- library/std/src/sys/pal/uefi/helpers.rs | 37 ++++++++++ 4 files changed, 107 insertions(+), 16 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 004f6d413a1f..d76e3e576f33 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -82,12 +82,11 @@ impl TcpStream { } pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result { - // FIXME: UEFI does support vectored write, so implement that. - crate::io::default_write_vectored(|b| self.write(b), buf) + self.inner.write_vectored(buf, self.write_timeout()?) } pub fn is_write_vectored(&self) -> bool { - false + true } pub fn peer_addr(&self) -> io::Result { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index aac97007bbfe..16283e64fb35 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -1,5 +1,5 @@ use super::tcp4; -use crate::io; +use crate::io::{self, IoSlice}; use crate::net::SocketAddr; use crate::ptr::NonNull; use crate::sys::{helpers, unsupported}; @@ -28,6 +28,16 @@ impl Tcp { } } + pub(crate) fn write_vectored( + &self, + buf: &[IoSlice<'_>], + timeout: Option, + ) -> io::Result { + match self { + Self::V4(client) => client.write_vectored(buf, timeout), + } + } + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { match self { Self::V4(client) => client.read(buf, timeout), diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index 75862ff247b4..ba0424454d73 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -1,7 +1,7 @@ use r_efi::efi::{self, Status}; use r_efi::protocols::tcp4; -use crate::io; +use crate::io::{self, IoSlice}; use crate::net::SocketAddrV4; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicBool, Ordering}; @@ -108,11 +108,7 @@ impl Tcp4 { } pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { - let evt = unsafe { self.create_evt() }?; - let completion_token = - tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX); - let fragment = tcp4::FragmentData { fragment_length: data_len, fragment_buffer: buf.as_ptr().cast::().cast_mut(), @@ -125,14 +121,63 @@ impl Tcp4 { fragment_table: [fragment], }; - let protocol = self.protocol.as_ptr(); - let mut token = tcp4::IoToken { - completion_token, - packet: tcp4::IoTokenPacket { - tx_data: (&raw mut tx_data).cast::>(), - }, + self.write_inner((&raw mut tx_data).cast(), timeout).map(|_| data_len as usize) + } + + pub(crate) fn write_vectored( + &self, + buf: &[IoSlice<'_>], + timeout: Option, + ) -> io::Result { + let mut data_length = 0u32; + let mut fragment_count = 0u32; + + // Calculate how many IoSlice in buf can be transmitted. + for i in buf { + // IoSlice length is always <= u32::MAX in UEFI. + match data_length + .checked_add(u32::try_from(i.as_slice().len()).expect("value is stored as a u32")) + { + Some(x) => data_length = x, + None => break, + } + fragment_count += 1; + } + + let tx_data_size = size_of::>() + + size_of::() * (fragment_count as usize); + let mut tx_data = helpers::UefiBox::::new(tx_data_size)?; + tx_data.write(tcp4::TransmitData { + push: r_efi::efi::Boolean::FALSE, + urgent: r_efi::efi::Boolean::FALSE, + data_length, + fragment_count, + fragment_table: [], + }); + unsafe { + // SAFETY: IoSlice and FragmentData are guaranteed to have same layout. + crate::ptr::copy_nonoverlapping( + buf.as_ptr().cast(), + (*tx_data.as_mut_ptr()).fragment_table.as_mut_ptr(), + fragment_count as usize, + ); }; + self.write_inner(tx_data.as_mut_ptr(), timeout).map(|_| data_length as usize) + } + + fn write_inner( + &self, + tx_data: *mut tcp4::TransmitData, + timeout: Option, + ) -> io::Result<()> { + let evt = unsafe { self.create_evt() }?; + let completion_token = + tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; + + let protocol = self.protocol.as_ptr(); + let mut token = tcp4::IoToken { completion_token, packet: tcp4::IoTokenPacket { tx_data } }; + let r = unsafe { ((*protocol).transmit)(protocol, &mut token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); @@ -143,7 +188,7 @@ impl Tcp4 { if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) } else { - Ok(data_len as usize) + Ok(()) } } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index c0d69c3e0029..852e0d6b051b 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -12,6 +12,7 @@ use r_efi::efi::{self, Guid}; use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell}; +use crate::alloc::Layout; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; use crate::marker::PhantomData; @@ -769,3 +770,39 @@ pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Addres pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr { crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3]) } + +/// This type is intended for use with ZSTs. Since such types are unsized, a reference to such types +/// is not valid in Rust. Thus, only pointers should be used when interacting with such types. +pub(crate) struct UefiBox { + inner: NonNull, + size: usize, +} + +impl UefiBox { + pub(crate) fn new(len: usize) -> io::Result { + assert!(len >= size_of::()); + // UEFI always expects types to be 8 byte aligned. + let layout = Layout::from_size_align(len, 8).unwrap(); + let ptr = unsafe { crate::alloc::alloc(layout) }; + + match NonNull::new(ptr.cast()) { + Some(inner) => Ok(Self { inner, size: len }), + None => Err(io::Error::new(io::ErrorKind::OutOfMemory, "Allocation failed")), + } + } + + pub(crate) fn write(&mut self, data: T) { + unsafe { self.inner.write(data) } + } + + pub(crate) fn as_mut_ptr(&mut self) -> *mut T { + self.inner.as_ptr().cast() + } +} + +impl Drop for UefiBox { + fn drop(&mut self) { + let layout = Layout::from_size_align(self.size, 8).unwrap(); + unsafe { crate::alloc::dealloc(self.inner.as_ptr().cast(), layout) }; + } +} From 0515aa5a3e1952dbe3a8cc21b779d93f6b8c550a Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 14 Oct 2025 02:52:59 +0100 Subject: [PATCH 287/525] mgca: Add ConstArg representation for const items --- compiler/rustc_ast/src/ast.rs | 21 ++++++++- compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/src/item.rs | 44 ++++++++--------- compiler/rustc_ast_lowering/src/lib.rs | 27 +++++++++++ .../rustc_ast_passes/src/ast_validation.rs | 6 +-- .../rustc_ast_pretty/src/pprust/state/item.rs | 8 ++-- .../src/alloc_error_handler.rs | 2 +- .../src/global_allocator.rs | 2 +- .../src/proc_macro_harness.rs | 4 +- compiler/rustc_builtin_macros/src/test.rs | 4 +- compiler/rustc_expand/src/build.rs | 8 +++- compiler/rustc_hir/src/hir.rs | 47 +++++++++++++------ compiler/rustc_hir/src/intravisit.rs | 20 ++++++-- compiler/rustc_hir_analysis/src/collect.rs | 3 +- .../rustc_hir_analysis/src/collect/type_of.rs | 24 +++++----- compiler/rustc_hir_analysis/src/lib.rs | 14 ++++-- compiler/rustc_hir_pretty/src/lib.rs | 17 +++++-- compiler/rustc_hir_typeck/src/pat.rs | 6 +-- compiler/rustc_lint/src/context.rs | 6 +-- compiler/rustc_lint/src/unused.rs | 29 +++++++----- compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_parse/src/parser/item.rs | 43 +++++++++++------ compiler/rustc_passes/src/reachable.rs | 8 ++-- compiler/rustc_resolve/src/late.rs | 42 ++++++++++++----- src/librustdoc/clean/mod.rs | 20 +++++--- .../clippy/clippy_utils/src/ast_utils/mod.rs | 12 ++--- 26 files changed, 278 insertions(+), 141 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 430ffded2e87..45a873109161 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3746,10 +3746,29 @@ pub struct ConstItem { pub ident: Ident, pub generics: Generics, pub ty: Box, - pub expr: Option>, + pub body: Option, pub define_opaque: Option>, } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum ConstItemRhs { + TypeConst(AnonConst), + Body(Box), +} + +impl ConstItemRhs { + pub fn span(&self) -> Span { + self.expr().span + } + + pub fn expr(&self) -> &Expr { + match self { + ConstItemRhs::TypeConst(anon_const) => &anon_const.value, + ConstItemRhs::Body(expr) => expr, + } + } +} + // Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum ItemKind { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d850698f47b0..36ade9115893 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -422,6 +422,7 @@ macro_rules! common_visitor_and_walkers { Closure, Const, ConstItem, + ConstItemRhs, Defaultness, Delegation, DelegationMac, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 177f33c0d8f1..5cb5149e2875 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -170,15 +170,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::Static(box ast::StaticItem { ident, - ty: t, + ty, safety: _, mutability: m, expr: e, define_opaque, }) => { let ident = self.lower_ident(*ident); - let (ty, body_id) = - self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy); + let ty = + self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); + let body_id = self.lower_const_body(span, e.as_deref()); self.lower_define_opaque(hir_id, define_opaque); hir::ItemKind::Static(*m, ident, ty, body_id) } @@ -186,21 +187,24 @@ impl<'hir> LoweringContext<'_, 'hir> { ident, generics, ty, - expr, + body, define_opaque, .. }) => { let ident = self.lower_ident(*ident); - let (generics, (ty, body_id)) = self.lower_generics( + let (generics, (ty, body)) = self.lower_generics( generics, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy) + let ty = this + .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); + let body = this.lower_const_item_rhs(attrs, body.as_ref(), span); + (ty, body) }, ); self.lower_define_opaque(hir_id, &define_opaque); - hir::ItemKind::Const(ident, generics, ty, body_id) + hir::ItemKind::Const(ident, generics, ty, body) } ItemKind::Fn(box Fn { sig: FnSig { decl, header, span: fn_sig_span }, @@ -462,17 +466,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_const_item( - &mut self, - ty: &Ty, - span: Span, - body: Option<&Expr>, - impl_trait_position: ImplTraitPosition, - ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { - let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position)); - (ty, self.lower_const_body(span, body)) - } - #[instrument(level = "debug", skip(self))] fn lower_use_tree( &mut self, @@ -807,7 +800,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ident, generics, ty, - expr, + body, define_opaque, .. }) => { @@ -818,14 +811,15 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x))); - + let body = body + .as_ref() + .map(|body| this.lower_const_item_rhs(attrs, Some(body), i.span)); hir::TraitItemKind::Const(ty, body) }, ); if define_opaque.is_some() { - if expr.is_some() { + if body.is_some() { self.lower_define_opaque(hir_id, &define_opaque); } else { self.dcx().span_err( @@ -835,7 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - (*ident, generics, kind, expr.is_some()) + (*ident, generics, kind, body.is_some()) } AssocItemKind::Fn(box Fn { sig, ident, generics, body: None, define_opaque, .. @@ -1025,7 +1019,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ident, generics, ty, - expr, + body, define_opaque, .. }) => ( @@ -1037,8 +1031,8 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = this.lower_const_body(i.span, expr.as_deref()); this.lower_define_opaque(hir_id, &define_opaque); + let body = this.lower_const_item_rhs(attrs, body.as_ref(), i.span); hir::ImplItemKind::Const(ty, body) }, ), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd458ab1ea70..a0d6ca41842f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2330,6 +2330,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) } + fn lower_const_item_rhs( + &mut self, + attrs: &[hir::Attribute], + rhs: Option<&ConstItemRhs>, + span: Span, + ) -> hir::ConstItemRhs<'hir> { + match rhs { + Some(ConstItemRhs::TypeConst(anon)) => { + hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg(anon)) + } + None if attr::contains_name(attrs, sym::type_const) => { + let const_arg = ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Error( + DUMMY_SP, + self.dcx().span_delayed_bug(DUMMY_SP, "no block"), + ), + }; + hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg)) + } + Some(ConstItemRhs::Body(body)) => { + hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body))) + } + None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)), + } + } + /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_anon_const`]. fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 6b218f34363d..ca3a20c296f3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1239,9 +1239,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } }); } - ItemKind::Const(box ConstItem { defaultness, expr, .. }) => { + ItemKind::Const(box ConstItem { defaultness, body, .. }) => { self.check_defaultness(item.span, *defaultness); - if expr.is_none() { + if body.is_none() { self.dcx().emit_err(errors::ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1581,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let AssocCtxt::Impl { .. } = ctxt { match &item.kind { - AssocItemKind::Const(box ConstItem { expr: None, .. }) => { + AssocItemKind::Const(box ConstItem { body: None, .. }) => { self.dcx().emit_err(errors::AssocConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 294d03a83b16..6db19285f273 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -210,7 +210,7 @@ impl<'a> State<'a> { ident, generics, ty, - expr, + body, define_opaque, }) => { self.print_item_const( @@ -218,7 +218,7 @@ impl<'a> State<'a> { None, generics, ty, - expr.as_deref(), + body.as_ref().map(|ct| ct.expr()), &item.vis, ast::Safety::Default, *defaultness, @@ -566,7 +566,7 @@ impl<'a> State<'a> { ident, generics, ty, - expr, + body, define_opaque, }) => { self.print_item_const( @@ -574,7 +574,7 @@ impl<'a> State<'a> { None, generics, ty, - expr.as_deref(), + body.as_ref().map(|ct| ct.expr()), vis, ast::Safety::Default, *defaultness, diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 40946f3b2791..e5d9d2080c08 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -43,7 +43,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); + let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index c968353504e1..e69f0838f22e 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -47,7 +47,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); + let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 6ac3e17503d0..e30d506a31b9 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -385,9 +385,9 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.attr_nested_word(sym::allow, sym::deprecated, span), ]); - let block = cx.expr_block( + let block = ast::ConstItemRhs::Body(cx.expr_block( cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), - ); + )); let anon_constant = cx.item_const( span, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 7a189ee1f4d0..21fd4689b9aa 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -289,7 +289,7 @@ pub(crate) fn expand_test_or_bench( ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), define_opaque: None, // test::TestDescAndFn { - expr: Some( + body: Some(ast::ConstItemRhs::Body( cx.expr_struct( sp, test_path("TestDescAndFn"), @@ -371,7 +371,7 @@ pub(crate) fn expand_test_or_bench( field("testfn", test_fn), // } ], ), // } - ), + )), } .into(), ), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 55541cdf4d7e..f8497dea9f4b 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -104,6 +104,10 @@ impl<'a> ExtCtxt<'a> { } } + pub fn anon_const_block(&self, b: Box) -> Box { + Box::new(self.anon_const(b.span, ast::ExprKind::Block(b, None))) + } + pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst { self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) } @@ -722,7 +726,7 @@ impl<'a> ExtCtxt<'a> { span: Span, ident: Ident, ty: Box, - expr: Box, + body: ast::ConstItemRhs, ) -> Box { let defaultness = ast::Defaultness::Final; self.item( @@ -735,7 +739,7 @@ impl<'a> ExtCtxt<'a> { // FIXME(generic_const_items): Pass the generics as a parameter. generics: ast::Generics::default(), ty, - expr: Some(expr), + body: Some(body), define_opaque: None, } .into(), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f20b49ab5a06..870c5de47acc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -403,6 +403,21 @@ impl<'hir> PathSegment<'hir> { } } +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub enum ConstItemRhs<'hir> { + Body(BodyId), + TypeConst(&'hir ConstArg<'hir>), +} + +impl<'hir> ConstItemRhs<'hir> { + pub fn hir_id(&self) -> HirId { + match self { + ConstItemRhs::Body(body_id) => body_id.hir_id, + ConstItemRhs::TypeConst(ct_arg) => ct_arg.hir_id, + } + } +} + /// A constant that enters the type system, used for arguments to const generics (e.g. array lengths). /// /// These are distinct from [`AnonConst`] as anon consts in the type system are not allowed @@ -3079,7 +3094,7 @@ impl<'hir> TraitItem<'hir> { } expect_methods_self_kind! { - expect_const, (&'hir Ty<'hir>, Option), + expect_const, (&'hir Ty<'hir>, Option>), TraitItemKind::Const(ty, body), (ty, *body); expect_fn, (&FnSig<'hir>, &TraitFn<'hir>), @@ -3104,7 +3119,7 @@ pub enum TraitFn<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). - Const(&'hir Ty<'hir>, Option), + Const(&'hir Ty<'hir>, Option>), /// An associated function with an optional body. Fn(FnSig<'hir>, TraitFn<'hir>), /// An associated type with (possibly empty) bounds and optional concrete @@ -3173,9 +3188,9 @@ impl<'hir> ImplItem<'hir> { } expect_methods_self_kind! { - expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body); - expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); - expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; + expect_const, (&'hir Ty<'hir>, ConstItemRhs<'hir>), ImplItemKind::Const(ty, body), (ty, *body); + expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); + expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; } } @@ -3184,7 +3199,7 @@ impl<'hir> ImplItem<'hir> { pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. - Const(&'hir Ty<'hir>, BodyId), + Const(&'hir Ty<'hir>, ConstItemRhs<'hir>), /// An associated function implementation with the given signature and body. Fn(FnSig<'hir>, BodyId), /// An associated type. @@ -4113,8 +4128,8 @@ impl<'hir> Item<'hir> { expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId), ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body); - expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId), - ItemKind::Const(ident, generics, ty, body), (*ident, generics, ty, *body); + expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>), + ItemKind::Const(ident, generics, ty, ct_arg), (*ident, generics, ty, *ct_arg); expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId), ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body); @@ -4285,7 +4300,7 @@ pub enum ItemKind<'hir> { /// A `static` item. Static(Mutability, Ident, &'hir Ty<'hir>, BodyId), /// A `const` item. - Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId), + Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>), /// A function declaration. Fn { sig: FnSig<'hir>, @@ -4523,17 +4538,18 @@ impl<'hir> OwnerNode<'hir> { OwnerNode::Item(Item { kind: ItemKind::Static(_, _, _, body) - | ItemKind::Const(_, _, _, body) + | ItemKind::Const(.., ConstItemRhs::Body(body)) | ItemKind::Fn { body, .. }, .. }) | OwnerNode::TraitItem(TraitItem { kind: - TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + TraitItemKind::Fn(_, TraitFn::Provided(body)) + | TraitItemKind::Const(_, Some(ConstItemRhs::Body(body))), .. }) | OwnerNode::ImplItem(ImplItem { - kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, ConstItemRhs::Body(body)), .. }) => Some(*body), _ => None, @@ -4784,7 +4800,7 @@ impl<'hir> Node<'hir> { Node::Item(Item { owner_id, kind: - ItemKind::Const(_, _, _, body) + ItemKind::Const(.., ConstItemRhs::Body(body)) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. }, .. @@ -4792,12 +4808,13 @@ impl<'hir> Node<'hir> { | Node::TraitItem(TraitItem { owner_id, kind: - TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)), + TraitItemKind::Const(.., Some(ConstItemRhs::Body(body))) + | TraitItemKind::Fn(_, TraitFn::Provided(body)), .. }) | Node::ImplItem(ImplItem { owner_id, - kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body), + kind: ImplItemKind::Const(.., ConstItemRhs::Body(body)) | ImplItemKind::Fn(_, body), .. }) => Some((owner_id.def_id, *body)), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ce2936a60dbe..57d4ffe28bd6 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -369,6 +369,10 @@ pub trait Visitor<'v>: Sized { walk_ty(self, t) } + fn visit_const_item_rhs(&mut self, c: ConstItemRhs<'v>) -> Self::Result { + walk_const_item_rhs(self, c) + } + /// All consts are treated as ambiguous consts for the purposes of hir visiting in /// order to ensure that visitors can handle infer vars without it being too error-prone. /// @@ -551,7 +555,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_ty_unambig(typ)); - try_visit!(visitor.visit_nested_body(body)); + try_visit!(visitor.visit_const_item_rhs(body)); } ItemKind::Fn { ident, sig, generics, body: body_id, .. } => { try_visit!(visitor.visit_ident(ident)); @@ -1036,6 +1040,16 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) - V::Result::output() } +pub fn walk_const_item_rhs<'v, V: Visitor<'v>>( + visitor: &mut V, + ct_rhs: ConstItemRhs<'v>, +) -> V::Result { + match ct_rhs { + ConstItemRhs::Body(body_id) => visitor.visit_nested_body(body_id), + ConstItemRhs::TypeConst(const_arg) => visitor.visit_const_arg_unambig(const_arg), + } +} + pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>( visitor: &mut V, const_arg: &'v ConstArg<'v>, @@ -1221,7 +1235,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>( match *kind { TraitItemKind::Const(ref ty, default) => { try_visit!(visitor.visit_ty_unambig(ty)); - visit_opt!(visitor, visit_nested_body, default); + visit_opt!(visitor, visit_const_item_rhs, default); } TraitItemKind::Fn(ref sig, TraitFn::Required(param_idents)) => { try_visit!(visitor.visit_fn_decl(sig.decl)); @@ -1276,7 +1290,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( match *kind { ImplItemKind::Const(ref ty, body) => { try_visit!(visitor.visit_ty_unambig(ty)); - visitor.visit_nested_body(body) + visitor.visit_const_item_rhs(body) } ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn( FnKind::Method(impl_item.ident, sig), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1386070e3d9b..d6ce5d80c045 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1524,6 +1524,7 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin let const_arg_id = tcx.parent_hir_id(hir_id); match tcx.hir_node(const_arg_id) { hir::Node::ConstArg(_) => { + let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id)); if tcx.features().generic_const_exprs() { ty::AnonConstKind::GCE } else if tcx.features().min_generic_const_args() { @@ -1531,7 +1532,7 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin } else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Repeat(_, repeat_count), .. - }) = tcx.hir_node(tcx.parent_hir_id(const_arg_id)) + }) = parent_hir_node && repeat_count.hir_id == const_arg_id { ty::AnonConstKind::RepeatExprCount diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8cbf17162e32..f44899a323d8 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -158,13 +158,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - TraitItemKind::Const(ty, body_id) => body_id - .and_then(|body_id| { + TraitItemKind::Const(ty, body) => body + .and_then(|ct_arg| { ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( icx.lowerer(), def_id, - body_id, + ct_arg.hir_id(), ty.span, item.ident, "associated constant", @@ -183,12 +183,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - ImplItemKind::Const(ty, body_id) => { + ImplItemKind::Const(ty, ct_arg) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, - body_id, + ct_arg.hir_id(), ty.span, item.ident, "associated constant", @@ -212,7 +212,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ infer_placeholder_type( icx.lowerer(), def_id, - body_id, + body_id.hir_id, ty.span, ident, "static variable", @@ -229,12 +229,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } } } - ItemKind::Const(ident, _, ty, body_id) => { + ItemKind::Const(ident, _, ty, body) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, - body_id, + body.hir_id(), ty.span, ident, "constant", @@ -425,13 +425,13 @@ pub(super) fn type_of_opaque_hir_typeck( fn infer_placeholder_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, - body_id: hir::BodyId, + hir_id: HirId, span: Span, item_ident: Ident, kind: &'static str, ) -> Ty<'tcx> { let tcx = cx.tcx(); - let ty = tcx.typeck(def_id).node_type(body_id.hir_id); + let ty = tcx.typeck(def_id).node_type(hir_id); // If this came from a free `const` or `static mut?` item, // then the user may have written e.g. `const A = 42;`. @@ -459,7 +459,7 @@ fn infer_placeholder_type<'tcx>( ); } else { with_forced_trimmed_paths!(err.span_note( - tcx.hir_body(body_id).value.span, + tcx.hir_span(hir_id), format!("however, the inferred type `{ty}` cannot be named"), )); } @@ -495,7 +495,7 @@ fn infer_placeholder_type<'tcx>( ); } else { with_forced_trimmed_paths!(diag.span_note( - tcx.hir_body(body_id).value.span, + tcx.hir_span(hir_id), format!("however, the inferred type `{ty}` cannot be named"), )); } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 6659aff71110..120600492138 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -91,13 +91,16 @@ mod variance; pub use errors::NoVariantNamed; use rustc_abi::{CVariadicStatus, ExternAbi}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::lints::DelayedLint; -use rustc_hir::{self as hir}; -use rustc_middle::middle; +use rustc_hir::{ + find_attr, {self as hir}, +}; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, Const, Ty, TyCtxt}; +use rustc_middle::ty::{Const, Ty, TyCtxt}; +use rustc_middle::{middle, ty}; use rustc_session::parse::feature_err; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits; @@ -227,7 +230,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.ensure_ok().eval_static_initializer(item_def_id); check::maybe_check_static_with_link_section(tcx, item_def_id); } - DefKind::Const if !tcx.generics_of(item_def_id).own_requires_monomorphization() => { + DefKind::Const + if !tcx.generics_of(item_def_id).own_requires_monomorphization() + && !find_attr!(tcx.get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) => + { // FIXME(generic_const_items): Passing empty instead of identity args is fishy but // seems to be fine for now. Revisit this! let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty()); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index a5fd60be6335..6903c859929b 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -523,17 +523,17 @@ impl<'a> State<'a> { ident: Ident, generics: &hir::Generics<'_>, ty: &hir::Ty<'_>, - default: Option, + default: Option>, ) { self.word_space("const"); self.print_ident(ident); self.print_generic_params(generics.params); self.word_space(":"); self.print_type(ty); - if let Some(expr) = default { + if let Some(ct_rhs) = default { self.space(); self.word_space("="); - self.ann.nested(self, Nested::Body(expr)); + self.print_const_item_rhs(ct_rhs); } self.print_where_clause(generics); self.word(";") @@ -616,7 +616,7 @@ impl<'a> State<'a> { self.word(";"); self.end(cb); } - hir::ItemKind::Const(ident, generics, ty, expr) => { + hir::ItemKind::Const(ident, generics, ty, rhs) => { let (cb, ib) = self.head("const"); self.print_ident(ident); self.print_generic_params(generics.params); @@ -626,7 +626,7 @@ impl<'a> State<'a> { self.end(ib); self.word_space("="); - self.ann.nested(self, Nested::Body(expr)); + self.print_const_item_rhs(rhs); self.print_where_clause(generics); self.word(";"); self.end(cb); @@ -1127,6 +1127,13 @@ impl<'a> State<'a> { self.ann.nested(self, Nested::Body(constant.body)) } + fn print_const_item_rhs(&mut self, ct_rhs: hir::ConstItemRhs<'_>) { + match ct_rhs { + hir::ConstItemRhs::Body(body_id) => self.ann.nested(self, Nested::Body(body_id)), + hir::ConstItemRhs::TypeConst(const_arg) => self.print_const_arg(const_arg), + } + } + fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d14463e44a03..d204a3c731ae 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1490,13 +1490,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { if let Some(def_id) = opt_def_id && let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Const(_, _, _, body_id), + kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. })) = self.tcx.hir_get_if_local(def_id) - && let hir::Node::Expr(expr) = self.tcx.hir_node(body_id.hir_id) + && let hir::Node::Expr(expr) = self.tcx.hir_node(ct_rhs.hir_id()) && hir::is_range_literal(expr) { - let span = self.tcx.hir_span(body_id.hir_id); + let span = self.tcx.hir_span(ct_rhs.hir_id()); if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) { e.span_suggestion_verbose( ident.span, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index a3dd3c53ece7..68fcf73cec51 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -978,9 +978,9 @@ impl<'tcx> LateContext<'tcx> { .. }) => *init, hir::Node::Item(item) => match item.kind { - hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => { - Some(self.tcx.hir_body(body_id).value) - } + // FIXME(mgca): figure out how to handle ConstArgKind::Path (or don't but add warning in docs here) + hir::ItemKind::Const(.., hir::ConstItemRhs::Body(body_id)) + | hir::ItemKind::Static(.., body_id) => Some(self.tcx.hir_body(body_id).value), _ => None, }, _ => None, diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 533ab6705309..cb3d09a08c05 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1032,19 +1032,22 @@ trait UnusedDelimLint { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { use ast::ItemKind::*; - if let Const(box ast::ConstItem { expr: Some(expr), .. }) - | Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind - { - self.check_unused_delims_expr( - cx, - expr, - UnusedDelimsCtx::AssignedValue, - false, - None, - None, - false, - ); - } + let expr = if let Const(box ast::ConstItem { body: Some(body), .. }) = &item.kind { + body.expr() + } else if let Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind { + expr + } else { + return; + }; + self.check_unused_delims_expr( + cx, + expr, + UnusedDelimsCtx::AssignedValue, + false, + None, + None, + false, + ); } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 60db5a276a9b..fd73dbde14c5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1350,6 +1350,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool { fn should_encode_const(def_kind: DefKind) -> bool { match def_kind { + // FIXME(mgca): should we remove Const and AssocConst here? DefKind::Const | DefKind::AssocConst | DefKind::AnonConst | DefKind::InlineConst => true, DefKind::Struct diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 4bb0d05c4f37..9bc6e991d63f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -6,7 +6,9 @@ use rustc_ast::ast::*; use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::util::case::Case; -use rustc_ast::{self as ast}; +use rustc_ast::{ + attr, {self as ast}, +}; use rustc_ast_pretty::pprust; use rustc_errors::codes::*; use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err}; @@ -255,13 +257,13 @@ impl<'a> Parser<'a> { } else { self.recover_const_mut(const_span); self.recover_missing_kw_before_item()?; - let (ident, generics, ty, expr) = self.parse_const_item()?; + let (ident, generics, ty, body) = self.parse_const_item(attrs)?; ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ident, generics, ty, - expr, + body, define_opaque: None, })) } @@ -1010,12 +1012,13 @@ impl<'a> Parser<'a> { define_opaque, }) => { self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span }); + let body = expr.map(ConstItemRhs::Body); AssocItemKind::Const(Box::new(ConstItem { defaultness: Defaultness::Final, ident, generics: Generics::default(), ty, - expr, + body, define_opaque, })) } @@ -1249,7 +1252,7 @@ impl<'a> Parser<'a> { let kind = match ForeignItemKind::try_from(kind) { Ok(kind) => kind, Err(kind) => match kind { - ItemKind::Const(box ConstItem { ident, ty, expr, .. }) => { + ItemKind::Const(box ConstItem { ident, ty, body, .. }) => { let const_span = Some(span.with_hi(ident.span.lo())) .filter(|span| span.can_be_used_for_suggestions()); self.dcx().emit_err(errors::ExternItemCannotBeConst { @@ -1260,7 +1263,10 @@ impl<'a> Parser<'a> { ident, ty, mutability: Mutability::Not, - expr, + expr: body.map(|b| match b { + ConstItemRhs::TypeConst(anon_const) => anon_const.value, + ConstItemRhs::Body(expr) => expr, + }), safety: Safety::Default, define_opaque: None, })) @@ -1431,7 +1437,8 @@ impl<'a> Parser<'a> { /// ``` fn parse_const_item( &mut self, - ) -> PResult<'a, (Ident, Generics, Box, Option>)> { + attrs: &[Attribute], + ) -> PResult<'a, (Ident, Generics, Box, Option)> { let ident = self.parse_ident_or_underscore()?; let mut generics = self.parse_generics()?; @@ -1458,7 +1465,15 @@ impl<'a> Parser<'a> { let before_where_clause = if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() }; - let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None }; + let body = if self.eat(exp!(Eq)) { + if attr::contains_name(attrs, sym::type_const) { + Some(ConstItemRhs::TypeConst(self.parse_expr_anon_const()?)) + } else { + Some(ConstItemRhs::Body(self.parse_expr()?)) + } + } else { + None + }; let after_where_clause = self.parse_where_clause()?; @@ -1466,18 +1481,18 @@ impl<'a> Parser<'a> { // Users may be tempted to write such code if they are still used to the deprecated // where-clause location on type aliases and associated types. See also #89122. if before_where_clause.has_where_token - && let Some(expr) = &expr + && let Some(body) = &body { self.dcx().emit_err(errors::WhereClauseBeforeConstBody { span: before_where_clause.span, name: ident.span, - body: expr.span, + body: body.span(), sugg: if !after_where_clause.has_where_token { - self.psess.source_map().span_to_snippet(expr.span).ok().map(|body| { + self.psess.source_map().span_to_snippet(body.span()).ok().map(|body_s| { errors::WhereClauseBeforeConstBodySugg { left: before_where_clause.span.shrink_to_lo(), - snippet: body, - right: before_where_clause.span.shrink_to_hi().to(expr.span), + snippet: body_s, + right: before_where_clause.span.shrink_to_hi().to(body.span()), } }) } else { @@ -1515,7 +1530,7 @@ impl<'a> Parser<'a> { self.expect_semi()?; - Ok((ident, generics, ty, expr)) + Ok((ident, generics, ty, body)) } /// We were supposed to parse `":" $ty` but the `:` or the type was missing. diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 74f689228b7d..e6a97eb83add 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -217,7 +217,7 @@ impl<'tcx> ReachableContext<'tcx> { // We can't figure out which value the constant will evaluate to. In // lieu of that, we have to consider everything mentioned in the const // initializer reachable, since it *may* end up in the final value. - Err(ErrorHandled::TooGeneric(_)) => self.visit_nested_body(init), + Err(ErrorHandled::TooGeneric(_)) => self.visit_const_item_rhs(init), // If there was an error evaluating the const, nothing can be reachable // via it, and anyway compilation will fail. Err(ErrorHandled::Reported(..)) => {} @@ -253,8 +253,8 @@ impl<'tcx> ReachableContext<'tcx> { | hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(body_id)) - | hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) => { + hir::TraitItemKind::Const(_, Some(body)) => self.visit_const_item_rhs(body), + hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) => { self.visit_nested_body(body_id); } hir::TraitItemKind::Type(..) => {} @@ -262,7 +262,7 @@ impl<'tcx> ReachableContext<'tcx> { } Node::ImplItem(impl_item) => match impl_item.kind { hir::ImplItemKind::Const(_, body) => { - self.visit_nested_body(body); + self.visit_const_item_rhs(body); } hir::ImplItemKind::Fn(_, body) => { if recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id()) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e3051dc38eca..e27a4e7da793 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2699,7 +2699,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if let Some(expr) = expr { // We already forbid generic params because of the above item rib, // so it doesn't matter whether this is a trivial constant. - this.resolve_const_body(expr, Some((ident, ConstantItemKind::Static))); + this.resolve_static_body(expr, Some((ident, ConstantItemKind::Static))); } }); self.resolve_define_opaques(define_opaque); @@ -2709,7 +2709,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, ref generics, ref ty, - ref expr, + ref body, ref define_opaque, .. }) => { @@ -2734,8 +2734,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this| this.visit_ty(ty), ); - if let Some(expr) = expr { - this.resolve_const_body(expr, Some((ident, ConstantItemKind::Const))); + if let Some(body) = body { + this.resolve_const_item_rhs( + body, + Some((ident, ConstantItemKind::Const)), + ); } }, ); @@ -3053,7 +3056,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AssocItemKind::Const(box ast::ConstItem { generics, ty, - expr, + body, define_opaque, .. }) => { @@ -3075,13 +3078,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. - if let Some(expr) = expr { + if let Some(body) = body { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.resolve_const_body(expr, None); + this.resolve_const_item_rhs(body, None); } }, ) @@ -3258,7 +3261,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, generics, ty, - expr, + body, define_opaque, .. }) => { @@ -3300,13 +3303,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_generics(generics); this.visit_ty(ty); - if let Some(expr) = expr { + if let Some(body) = body { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.resolve_const_body(expr, None); + this.resolve_const_item_rhs(body, None); } }, ) @@ -3516,7 +3519,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); } - fn resolve_const_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) { + fn resolve_static_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) { self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { this.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, item, |this| { this.visit_expr(expr) @@ -3524,6 +3527,23 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }) } + fn resolve_const_item_rhs( + &mut self, + rhs: &'ast ConstItemRhs, + item: Option<(Ident, ConstantItemKind)>, + ) { + self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| match rhs { + ConstItemRhs::TypeConst(anon_const) => { + this.resolve_anon_const(anon_const, AnonConstKind::ConstArg(IsRepeatExpr::No)); + } + ConstItemRhs::Body(expr) => { + this.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, item, |this| { + this.visit_expr(expr) + }); + } + }) + } + fn resolve_delegation(&mut self, delegation: &'ast Delegation) { self.smart_resolve_path( delegation.id, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 725869c6caf5..33247fa855d9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -308,13 +308,21 @@ pub(crate) fn clean_precise_capturing_arg( pub(crate) fn clean_const<'tcx>( constant: &hir::ConstArg<'tcx>, + // Used for mgca representation of const item bodies. + parent_if_item_body: Option, _cx: &mut DocContext<'tcx>, ) -> ConstantKind { match &constant.kind { hir::ConstArgKind::Path(qpath) => { ConstantKind::Path { path: qpath_to_string(qpath).into() } } - hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, + hir::ConstArgKind::Anon(anon) => { + if let Some(def_id) = parent_if_item_body { + ConstantKind::Local { def_id, body: anon.body } + } else { + ConstantKind::Anonymous { body: anon.body } + } + } hir::ConstArgKind::Infer(..) => ConstantKind::Infer, } } @@ -1194,7 +1202,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Const(ty, Some(default)) => { ProvidedAssocConstItem(Box::new(Constant { generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), - kind: ConstantKind::Local { def_id: local_did, body: default }, + kind: clean_const(default, Some(local_did), cx), type_: clean_ty(ty, cx), })) } @@ -1244,7 +1252,7 @@ pub(crate) fn clean_impl_item<'tcx>( let inner = match impl_.kind { hir::ImplItemKind::Const(ty, expr) => ImplAssocConstItem(Box::new(Constant { generics: clean_generics(impl_.generics, cx), - kind: ConstantKind::Local { def_id: local_did, body: expr }, + kind: clean_const(expr, Some(local_did), cx), type_: clean_ty(ty, cx), })), hir::ImplItemKind::Fn(ref sig, body) => { @@ -2516,7 +2524,7 @@ fn clean_generic_args<'tcx>( hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)), hir::GenericArg::Const(ct) => { - GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), cx))) + GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), None, cx))) } hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) @@ -2785,10 +2793,10 @@ fn clean_maybe_renamed_item<'tcx>( mutability, expr: Some(body_id), }), - ItemKind::Const(_, generics, ty, body_id) => ConstantItem(Box::new(Constant { + ItemKind::Const(_, generics, ty, body) => ConstantItem(Box::new(Constant { generics: clean_generics(generics, cx), type_: clean_ty(ty, cx), - kind: ConstantKind::Local { body: body_id, def_id }, + kind: clean_const(body, Some(def_id), cx), })), ItemKind::TyAlias(_, generics, ty) => { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 839b46325b5e..f5e61e365c57 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -358,7 +358,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: li, generics: lg, ty: lt, - expr: le, + body: lb, define_opaque: _, }), Const(box ConstItem { @@ -366,7 +366,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: ri, generics: rg, ty: rt, - expr: re, + body: rb, define_opaque: _, }), ) => { @@ -374,7 +374,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && eq_expr_opt(le.as_deref(), re.as_deref()) + && both(lb.as_deref(), rb.as_deref(), |l, r| eq_anon_const(l, r)) }, ( Fn(box ast::Fn { @@ -612,7 +612,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: li, generics: lg, ty: lt, - expr: le, + body: lb, define_opaque: _, }), Const(box ConstItem { @@ -620,7 +620,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: ri, generics: rg, ty: rt, - expr: re, + body: rb, define_opaque: _, }), ) => { @@ -628,7 +628,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && eq_expr_opt(le.as_deref(), re.as_deref()) + && both(lb.as_deref(), rb.as_deref(), |l, r| eq_anon_const(l, r)) }, ( Fn(box ast::Fn { From 8fdd34713dc02907cd6c601cfc62315ff8d59406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Nov 2025 19:09:56 +0000 Subject: [PATCH 288/525] Point at inner item on E0401 generated by hir_typeck ``` error[E0401]: can't reference `Self` constructor from outer item --> $DIR/do-not-ice-on-note_and_explain.rs:6:13 | LL | impl A { | ------------ the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference LL | fn d() { LL | fn d() { | - `Self` used in this inner item LL | Self(1) | ^^^^ help: replace `Self` with the actual type: `A` ``` --- compiler/rustc_hir_typeck/messages.ftl | 2 ++ compiler/rustc_hir_typeck/src/errors.rs | 11 +++++++++++ compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 11 +++++++++++ .../malformed/do-not-ice-on-note_and_explain.stderr | 4 +++- tests/ui/self/self-ctor-nongeneric.stderr | 6 +++++- tests/ui/self/self-ctor.stderr | 6 +++++- .../ice-index-out-of-bounds-issue-117446.stderr | 3 +++ 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 1ed0756fdd6a..bb705dce6a4b 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -262,6 +262,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o .label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference .suggestion = replace `Self` with the actual type +hir_typeck_self_ctor_from_outer_item_inner_item = `Self` used in this inner item + hir_typeck_slicing_suggestion = consider slicing here hir_typeck_struct_expr_non_exhaustive = diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index d15d092b7d3d..2ed3a542bae8 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -978,6 +978,15 @@ pub(crate) struct SelfCtorFromOuterItem { pub impl_span: Span, #[subdiagnostic] pub sugg: Option, + #[subdiagnostic] + pub item: Option, +} + +#[derive(Subdiagnostic)] +#[label(hir_typeck_self_ctor_from_outer_item_inner_item)] +pub(crate) struct InnerItem { + #[primary_span] + pub span: Span, } #[derive(LintDiagnostic)] @@ -987,6 +996,8 @@ pub(crate) struct SelfCtorFromOuterItemLint { pub impl_span: Span, #[subdiagnostic] pub sugg: Option, + #[subdiagnostic] + pub item: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index f4e65b42cd42..38586c844445 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1094,11 +1094,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: path_span, name: self.tcx.item_name(def.did()).to_ident_string(), }); + let item = match self + .tcx + .hir_node_by_def_id(self.tcx.hir_get_parent_item(hir_id).def_id) + { + hir::Node::Item(item) => Some(errors::InnerItem { + span: item.kind.ident().map(|i| i.span).unwrap_or(item.span), + }), + _ => None, + }; if ty.raw.has_param() { let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem { span: path_span, impl_span: tcx.def_span(impl_def_id), sugg, + item, }); return (Ty::new_error(self.tcx, guar), res); } else { @@ -1109,6 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { errors::SelfCtorFromOuterItemLint { impl_span: tcx.def_span(impl_def_id), sugg, + item, }, ); } diff --git a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr index 11a8c01e4909..63de7099797c 100644 --- a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr +++ b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr @@ -3,7 +3,9 @@ error[E0401]: can't reference `Self` constructor from outer item | LL | impl A { | ------------ the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference -... +LL | fn d() { +LL | fn d() { + | - `Self` used in this inner item LL | Self(1) | ^^^^ help: replace `Self` with the actual type: `A` diff --git a/tests/ui/self/self-ctor-nongeneric.stderr b/tests/ui/self/self-ctor-nongeneric.stderr index b53ecbe55b59..c3ae7df2ad25 100644 --- a/tests/ui/self/self-ctor-nongeneric.stderr +++ b/tests/ui/self/self-ctor-nongeneric.stderr @@ -5,7 +5,9 @@ LL | impl S0 { | ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference LL | fn foo() { LL | const C: S0 = Self(0); - | ^^^^ help: replace `Self` with the actual type: `S0` + | - ^^^^ help: replace `Self` with the actual type: `S0` + | | + | `Self` used in this inner item | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124186 @@ -17,6 +19,8 @@ warning: can't reference `Self` constructor from outer item LL | impl S0 { | ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference ... +LL | fn bar() -> S0 { + | --- `Self` used in this inner item LL | Self(0) | ^^^^ help: replace `Self` with the actual type: `S0` | diff --git a/tests/ui/self/self-ctor.stderr b/tests/ui/self/self-ctor.stderr index 0cb22baaa1a0..b8dfd324c3f3 100644 --- a/tests/ui/self/self-ctor.stderr +++ b/tests/ui/self/self-ctor.stderr @@ -5,7 +5,9 @@ LL | impl S0 { | ------------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference LL | fn foo() { LL | const C: S0 = Self(0); - | ^^^^ help: replace `Self` with the actual type: `S0` + | - ^^^^ help: replace `Self` with the actual type: `S0` + | | + | `Self` used in this inner item error[E0401]: can't reference `Self` constructor from outer item --> $DIR/self-ctor.rs:8:13 @@ -13,6 +15,8 @@ error[E0401]: can't reference `Self` constructor from outer item LL | impl S0 { | ------------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference ... +LL | fn bar() -> S0 { + | --- `Self` used in this inner item LL | Self(0) | ^^^^ help: replace `Self` with the actual type: `S0` diff --git a/tests/ui/traits/ice-index-out-of-bounds-issue-117446.stderr b/tests/ui/traits/ice-index-out-of-bounds-issue-117446.stderr index ad33a70ed3bb..2e75003c49b8 100644 --- a/tests/ui/traits/ice-index-out-of-bounds-issue-117446.stderr +++ b/tests/ui/traits/ice-index-out-of-bounds-issue-117446.stderr @@ -24,6 +24,9 @@ error[E0401]: can't reference `Self` constructor from outer item LL | impl<'a, T> Foo<'a> for Repeated { | ----------------------------------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference ... +LL | fn inner(value: Option<()>) -> Repeated { + | ----- `Self` used in this inner item +LL | match value { LL | _ => Self(unimplemented!()), | ^^^^ help: replace `Self` with the actual type: `Repeated` From 44ece2e9cef484368cfef98f0e287e5a6d1011dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Nov 2025 19:21:27 +0000 Subject: [PATCH 289/525] Point at inner item when using outer const param ``` error[E0401]: can't use generic parameters from outer item --> $DIR/const-param-from-outer-fn.rs:3:9 | LL | fn foo() { | - const parameter from outer item LL | fn bar() -> u32 { | --- generic parameter used in this inner function LL | X | ^ use of generic parameter from outer item | help: try introducing a local generic parameter here | LL | fn bar() -> u32 { | +++ ``` --- compiler/rustc_resolve/src/ident.rs | 14 ++++++++++++- .../early/const-param-from-outer-fn.stderr | 1 + ...e-65035-static-with-parent-generics.stderr | 21 ++++++++++++------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 4856b1e7cf97..2abf129e9456 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1484,13 +1484,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // This was an attempt to use a const parameter outside its scope. if let Some(span) = finalize { + let item = if let Some(diag_metadata) = diag_metadata + && let Some(current_item) = diag_metadata.current_item + { + let span = current_item + .kind + .ident() + .map(|i| i.span) + .unwrap_or(current_item.span); + Some((span, current_item.kind.descr().to_string())) + } else { + None + }; self.report_error( span, ResolutionError::GenericParamsFromOuterItem( res, has_generic_params, def_kind, - None, + item, ), ); } diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr index 0f7c7fbc6be0..3c25dff41aa2 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -4,6 +4,7 @@ error[E0401]: can't use generic parameters from outer item LL | fn foo() { | - const parameter from outer item LL | fn bar() -> u32 { + | --- generic parameter used in this inner function LL | X | ^ use of generic parameter from outer item | diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr index 869e1729cb85..b22bfb719bd5 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -27,11 +27,14 @@ LL | static a: *const T = Default::default(); error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:15:24 | -LL | fn h() { - | - const parameter from outer item -LL | extern "C" { -LL | static a: [u8; N]; - | ^ use of generic parameter from outer item +LL | fn h() { + | - const parameter from outer item +LL | / extern "C" { +LL | | static a: [u8; N]; + | | ^ use of generic parameter from outer item +LL | | +LL | | } + | |_____- generic parameter used in this inner extern block | = note: a `static` is a separate item from the item that contains it @@ -41,7 +44,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn i() { | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item + | | + | generic parameter used in this inner static item | = note: a `static` is a separate item from the item that contains it @@ -51,7 +56,9 @@ error[E0401]: can't use generic parameters from outer item LL | fn i() { | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item + | | + | generic parameter used in this inner static item | = note: a `static` is a separate item from the item that contains it From 86d755618be25e3b03d16f0c13bdc51d4c2de2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Nov 2025 19:55:35 +0000 Subject: [PATCH 290/525] Pass `DiagMetadata` through in more cases --- compiler/rustc_resolve/src/diagnostics.rs | 7 ++++--- compiler/rustc_resolve/src/ident.rs | 1 + compiler/rustc_resolve/src/late.rs | 12 +++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f302da356e1e..4a5d304f49bf 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -40,7 +40,7 @@ use crate::errors::{ MaybeMissingMacroRulesName, }; use crate::imports::{Import, ImportKind}; -use crate::late::{PatternSource, Rib}; +use crate::late::{DiagMetadata, PatternSource, Rib}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize, ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, @@ -2406,6 +2406,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module: Option>, failed_segment_idx: usize, ident: Ident, + diag_metadata: Option<&DiagMetadata<'_>>, ) -> (String, Option) { let is_last = failed_segment_idx == path.len() - 1; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; @@ -2511,7 +2512,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &ribs[ns_to_try], ignore_binding, - None, + diag_metadata, ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Some(binding), @@ -2562,7 +2563,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &ribs[ValueNS], ignore_binding, - None, + diag_metadata, ) } else { None diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2abf129e9456..2ab024df9a20 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1835,6 +1835,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module, segment_idx, ident, + diag_metadata, ) }, ); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 198fef0cd630..3d79b94c25e7 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -885,7 +885,6 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc TypeNS, Some(Finalize::new(ty.id, ty.span)), None, - None, ) .map_or(Res::Err, |d| d.res()); self.r.record_partial_res(ty.id, PartialRes::new(res)); @@ -1458,7 +1457,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { None, &self.ribs[ns], None, - None, + Some(&self.diag_metadata), ) } @@ -1468,7 +1467,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ns: Namespace, finalize: Option, ignore_binding: Option>, - diag_metadata: Option<&crate::late::DiagMetadata<'_>>, ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, @@ -1477,7 +1475,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { finalize, &self.ribs[ns], ignore_binding, - diag_metadata, + Some(&self.diag_metadata), ) } @@ -2556,8 +2554,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { report_error(self, ns); } Some(LexicalScopeBinding::Item(binding)) => { - if let Some(LexicalScopeBinding::Res(..)) = self - .resolve_ident_in_lexical_scope(ident, ns, None, Some(binding), None) + if let Some(LexicalScopeBinding::Res(..)) = + self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding)) { report_error(self, ns); } @@ -5110,7 +5108,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // use the type namespace let ns = if i + 1 == path.len() { ns } else { TypeNS }; let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?; - let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None, None)?; + let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?; (res == binding.res()).then_some((seg, binding)) }); From e9f360330d86f8ffd9cee7c71a83b12027d436d7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 25 Oct 2025 20:42:50 +1100 Subject: [PATCH 291/525] Only pass debugger-related flags for `debuginfo` tests --- src/bootstrap/src/core/build_steps/test.rs | 60 ++++++++++++---------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e1b3ff92a07b..9a6b47bdf3a1 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2078,27 +2078,43 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--python").arg(builder.python()); - if let Some(ref gdb) = builder.config.gdb { - cmd.arg("--gdb").arg(gdb); + // FIXME(#148099): Currently we set these Android-related flags in all + // modes, even though they should only be needed in "debuginfo" mode, + // because the GDB-discovery code in compiletest currently assumes that + // `--android-cross-path` is always set for Android targets. + cmd.arg("--adb-path").arg("adb"); + cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); + if target.contains("android") && !builder.config.dry_run() { + // Assume that cc for this target comes from the android sysroot + cmd.arg("--android-cross-path") + .arg(builder.cc(target).parent().unwrap().parent().unwrap()); + } else { + cmd.arg("--android-cross-path").arg(""); } - let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); - let lldb_version = command(&lldb_exe) - .allow_failure() - .arg("--version") - .run_capture(builder) - .stdout_if_ok() - .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); - if let Some(ref vers) = lldb_version { - cmd.arg("--lldb-version").arg(vers); - let lldb_python_dir = command(&lldb_exe) + if mode == "debuginfo" { + if let Some(ref gdb) = builder.config.gdb { + cmd.arg("--gdb").arg(gdb); + } + + let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); + let lldb_version = command(&lldb_exe) .allow_failure() - .arg("-P") - .run_capture_stdout(builder) + .arg("--version") + .run_capture(builder) .stdout_if_ok() - .map(|p| p.lines().next().expect("lldb Python dir not found").to_string()); - if let Some(ref dir) = lldb_python_dir { - cmd.arg("--lldb-python-dir").arg(dir); + .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); + if let Some(ref vers) = lldb_version { + cmd.arg("--lldb-version").arg(vers); + let lldb_python_dir = command(&lldb_exe) + .allow_failure() + .arg("-P") + .run_capture_stdout(builder) + .stdout_if_ok() + .map(|p| p.lines().next().expect("lldb Python dir not found").to_string()); + if let Some(ref dir) = lldb_python_dir { + cmd.arg("--lldb-python-dir").arg(dir); + } } } @@ -2332,16 +2348,6 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.env("RUST_TEST_TMPDIR", builder.tempdir()); - cmd.arg("--adb-path").arg("adb"); - cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); - if target.contains("android") && !builder.config.dry_run() { - // Assume that cc for this target comes from the android sysroot - cmd.arg("--android-cross-path") - .arg(builder.cc(target).parent().unwrap().parent().unwrap()); - } else { - cmd.arg("--android-cross-path").arg(""); - } - if builder.config.cmd.rustfix_coverage() { cmd.arg("--rustfix-coverage"); } From bcfbd7401d76b6c3455376e584402cc2a6b22dce Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 25 Oct 2025 20:34:51 +1100 Subject: [PATCH 292/525] Extract some discovery code for debuginfo tests into submodules --- src/bootstrap/src/core/build_steps/test.rs | 42 +++++++-------------- src/bootstrap/src/core/debuggers/android.rs | 24 ++++++++++++ src/bootstrap/src/core/debuggers/gdb.rs | 13 +++++++ src/bootstrap/src/core/debuggers/lldb.rs | 32 ++++++++++++++++ src/bootstrap/src/core/debuggers/mod.rs | 10 +++++ src/bootstrap/src/core/mod.rs | 1 + 6 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 src/bootstrap/src/core/debuggers/android.rs create mode 100644 src/bootstrap/src/core/debuggers/gdb.rs create mode 100644 src/bootstrap/src/core/debuggers/lldb.rs create mode 100644 src/bootstrap/src/core/debuggers/mod.rs diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9a6b47bdf3a1..57dedcccf98c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -29,6 +29,7 @@ use crate::core::builder::{ }; use crate::core::config::TargetSelection; use crate::core::config::flags::{Subcommand, get_completion, top_level_help}; +use crate::core::debuggers; use crate::utils::build_stamp::{self, BuildStamp}; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{ @@ -38,8 +39,6 @@ use crate::utils::helpers::{ use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify}; -const ADB_TEST_DIR: &str = "/data/local/tmp/work"; - /// Runs `cargo test` on various internal tools used by bootstrap. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateBootstrap { @@ -2082,39 +2081,24 @@ Please disable assertions with `rust.debug-assertions = false`. // modes, even though they should only be needed in "debuginfo" mode, // because the GDB-discovery code in compiletest currently assumes that // `--android-cross-path` is always set for Android targets. - cmd.arg("--adb-path").arg("adb"); - cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); - if target.contains("android") && !builder.config.dry_run() { - // Assume that cc for this target comes from the android sysroot - cmd.arg("--android-cross-path") - .arg(builder.cc(target).parent().unwrap().parent().unwrap()); - } else { - cmd.arg("--android-cross-path").arg(""); + if let Some(debuggers::Android { adb_path, adb_test_dir, android_cross_path }) = + debuggers::discover_android(builder, target) + { + cmd.arg("--adb-path").arg(adb_path); + cmd.arg("--adb-test-dir").arg(adb_test_dir); + cmd.arg("--android-cross-path").arg(android_cross_path); } if mode == "debuginfo" { - if let Some(ref gdb) = builder.config.gdb { + if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder) { cmd.arg("--gdb").arg(gdb); } - let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); - let lldb_version = command(&lldb_exe) - .allow_failure() - .arg("--version") - .run_capture(builder) - .stdout_if_ok() - .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); - if let Some(ref vers) = lldb_version { - cmd.arg("--lldb-version").arg(vers); - let lldb_python_dir = command(&lldb_exe) - .allow_failure() - .arg("-P") - .run_capture_stdout(builder) - .stdout_if_ok() - .map(|p| p.lines().next().expect("lldb Python dir not found").to_string()); - if let Some(ref dir) = lldb_python_dir { - cmd.arg("--lldb-python-dir").arg(dir); - } + if let Some(debuggers::Lldb { lldb_version, lldb_python_dir }) = + debuggers::discover_lldb(builder) + { + cmd.arg("--lldb-version").arg(lldb_version); + cmd.arg("--lldb-python-dir").arg(lldb_python_dir); } } diff --git a/src/bootstrap/src/core/debuggers/android.rs b/src/bootstrap/src/core/debuggers/android.rs new file mode 100644 index 000000000000..b1ad9ca555fb --- /dev/null +++ b/src/bootstrap/src/core/debuggers/android.rs @@ -0,0 +1,24 @@ +use std::path::PathBuf; + +use crate::core::builder::Builder; +use crate::core::config::TargetSelection; + +pub(crate) struct Android { + pub(crate) adb_path: &'static str, + pub(crate) adb_test_dir: &'static str, + pub(crate) android_cross_path: PathBuf, +} + +pub(crate) fn discover_android(builder: &Builder<'_>, target: TargetSelection) -> Option { + let adb_path = "adb"; + // See . + let adb_test_dir = "/data/local/tmp/work"; + + let android_cross_path = if target.contains("android") && !builder.config.dry_run() { + builder.cc(target).parent().unwrap().parent().unwrap().to_owned() + } else { + PathBuf::new() + }; + + Some(Android { adb_path, adb_test_dir, android_cross_path }) +} diff --git a/src/bootstrap/src/core/debuggers/gdb.rs b/src/bootstrap/src/core/debuggers/gdb.rs new file mode 100644 index 000000000000..ddad0909e4f0 --- /dev/null +++ b/src/bootstrap/src/core/debuggers/gdb.rs @@ -0,0 +1,13 @@ +use std::path::Path; + +use crate::core::builder::Builder; + +pub(crate) struct Gdb<'a> { + pub(crate) gdb: &'a Path, +} + +pub(crate) fn discover_gdb<'a>(builder: &'a Builder<'_>) -> Option> { + let gdb = builder.config.gdb.as_deref()?; + + Some(Gdb { gdb }) +} diff --git a/src/bootstrap/src/core/debuggers/lldb.rs b/src/bootstrap/src/core/debuggers/lldb.rs new file mode 100644 index 000000000000..66ab45573d6b --- /dev/null +++ b/src/bootstrap/src/core/debuggers/lldb.rs @@ -0,0 +1,32 @@ +use std::path::PathBuf; + +use crate::core::builder::Builder; +use crate::utils::exec::command; + +pub(crate) struct Lldb { + pub(crate) lldb_version: String, + pub(crate) lldb_python_dir: String, +} + +pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option { + // FIXME(#148361): We probably should not be picking up whatever arbitrary + // lldb happens to be in the user's path, and instead require some kind of + // explicit opt-in or configuration. + let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); + + let lldb_version = command(&lldb_exe) + .allow_failure() + .arg("--version") + .run_capture(builder) + .stdout_if_ok() + .and_then(|v| if v.trim().is_empty() { None } else { Some(v) })?; + + let lldb_python_dir = command(&lldb_exe) + .allow_failure() + .arg("-P") + .run_capture_stdout(builder) + .stdout_if_ok() + .map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?; + + Some(Lldb { lldb_version, lldb_python_dir }) +} diff --git a/src/bootstrap/src/core/debuggers/mod.rs b/src/bootstrap/src/core/debuggers/mod.rs new file mode 100644 index 000000000000..011ce4081a43 --- /dev/null +++ b/src/bootstrap/src/core/debuggers/mod.rs @@ -0,0 +1,10 @@ +//! Code for discovering debuggers and debugger-related configuration, so that +//! it can be passed to compiletest when running debuginfo tests. + +pub(crate) use self::android::{Android, discover_android}; +pub(crate) use self::gdb::{Gdb, discover_gdb}; +pub(crate) use self::lldb::{Lldb, discover_lldb}; + +mod android; +mod gdb; +mod lldb; diff --git a/src/bootstrap/src/core/mod.rs b/src/bootstrap/src/core/mod.rs index 9e18d6704d4f..f27a09c81c55 100644 --- a/src/bootstrap/src/core/mod.rs +++ b/src/bootstrap/src/core/mod.rs @@ -1,6 +1,7 @@ pub(crate) mod build_steps; pub(crate) mod builder; pub(crate) mod config; +pub(crate) mod debuggers; pub(crate) mod download; pub(crate) mod metadata; pub(crate) mod sanity; From b9e127a830df680e2f117064376dfd876c0b8ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ila=C3=AF=20Deutel?= <10098207+ilai-deutel@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:46:35 -0400 Subject: [PATCH 293/525] Fix documentation for std::panic::update_hook * `set_hook` expects a boxed function * Missing closing delimiter for the closure --- library/std/src/panicking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index b7be869c4eb4..9af3e5f63ffb 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -215,10 +215,10 @@ pub fn take_hook() -> Box) + 'static + Sync + Send> { /// /// // Equivalent to /// // let prev = panic::take_hook(); -/// // panic::set_hook(move |info| { +/// // panic::set_hook(Box::new(move |info| { /// // println!("..."); /// // prev(info); -/// // ); +/// // })); /// panic::update_hook(move |prev, info| { /// println!("Print custom message and execute panic handler as usual"); /// prev(info); From 365798d36e6d6f0eca0f3a0b47725f6b4421275b Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 2 Nov 2025 13:33:12 +0800 Subject: [PATCH 294/525] Fix missing other assoc items for generate_blanket_trait_impl - And migrate `edit_in_place::Indent` to `edit::AstNodeEdit`, because edit_in_place use ted Example --- ```rust trait $0Foo { type X: Sync; fn foo(&self, x: Self::X) -> T; fn print_foo(&self) { println!("{}", self.foo()); } } ``` **Before this PR** ```rust impl Foo for $0T1 { fn foo(&self, x: Self::X) -> T { todo!() } } ``` **After this PR** ```rust impl Foo for $0T1 { type X: Sync; fn foo(&self, x: Self::X) -> T { todo!() } } ``` --- .../handlers/generate_blanket_trait_impl.rs | 113 +++++++++++++++--- 1 file changed, 97 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index c25b0bbe7cea..b0fa9e6b3ebb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs @@ -13,7 +13,7 @@ use syntax::{ AstNode, ast::{ self, AssocItem, BlockExpr, GenericParam, HasAttrs, HasGenericParams, HasName, - HasTypeBounds, HasVisibility, edit_in_place::Indent, make, + HasTypeBounds, HasVisibility, edit::AstNodeEdit, make, }, syntax_editor::Position, }; @@ -75,7 +75,7 @@ pub(crate) fn generate_blanket_trait_impl( |builder| { let mut edit = builder.make_editor(traitd.syntax()); let namety = make::ty_path(make::path_from_text(&name.text())); - let trait_where_clause = traitd.where_clause().map(|it| it.clone_for_update()); + let trait_where_clause = traitd.where_clause().map(|it| it.reset_indent()); let bounds = traitd.type_bound_list().and_then(exlucde_sized); let is_unsafe = traitd.unsafe_token().is_some(); let thisname = this_name(&traitd); @@ -90,10 +90,6 @@ pub(crate) fn generate_blanket_trait_impl( let trait_gen_args = traitd.generic_param_list().map(|param_list| param_list.to_generic_args()); - if let Some(ref where_clause) = trait_where_clause { - where_clause.reindent_to(0.into()); - } - let impl_ = make::impl_trait( cfg_attrs(&traitd), is_unsafe, @@ -112,20 +108,19 @@ pub(crate) fn generate_blanket_trait_impl( if let Some(trait_assoc_list) = traitd.assoc_item_list() { let assoc_item_list = impl_.get_or_create_assoc_item_list(); - for method in trait_assoc_list.assoc_items() { - let AssocItem::Fn(method) = method else { - continue; + for item in trait_assoc_list.assoc_items() { + let item = match item { + ast::AssocItem::Fn(method) if method.body().is_none() => { + todo_fn(&method, ctx.config).into() + } + ast::AssocItem::Const(_) | ast::AssocItem::TypeAlias(_) => item, + _ => continue, }; - if method.body().is_some() { - continue; - } - let f = todo_fn(&method, ctx.config).clone_for_update(); - f.indent(1.into()); - assoc_item_list.add_item(AssocItem::Fn(f)); + assoc_item_list.add_item(item.reset_indent().indent(1.into())); } } - impl_.indent(indent); + let impl_ = impl_.indent(indent); edit.insert_all( Position::after(traitd.syntax()), @@ -506,6 +501,41 @@ impl Foo for $0I { ); } + #[test] + fn test_gen_blanket_other_assoc_items() { + check_assist( + generate_blanket_trait_impl, + r#" +trait $0Foo { + type Item; + + const N: usize; + + fn foo(&self); +} +"#, + r#" +trait Foo { + type Item; + + const N: usize; + + fn foo(&self); +} + +impl Foo for $0T { + type Item; + + const N: usize; + + fn foo(&self) { + todo!() + } +} +"#, + ); + } + #[test] fn test_gen_blanket_indent() { check_assist( @@ -739,6 +769,49 @@ mod foo { } } } +} + "#, + ); + check_assist( + generate_blanket_trait_impl, + r#" +mod foo { + mod bar { + trait $0Foo { + type Item: Bar< + Self, + >; + + const N: Baz< + Self, + >; + } + } +} + "#, + r#" +mod foo { + mod bar { + trait Foo { + type Item: Bar< + Self, + >; + + const N: Baz< + Self, + >; + } + + impl Foo for $0T { + type Item: Bar< + Self, + >; + + const N: Baz< + Self, + >; + } + } } "#, ); @@ -824,6 +897,8 @@ impl Foo for $0T1 where Self::Owned: Default, { + type X: Sync; + fn foo(&self, x: Self::X) -> T { todo!() } @@ -871,6 +946,8 @@ where Self: ToOwned, Self::Owned: Default, { + type X: Sync; + fn foo(&self, x: Self::X) -> T { todo!() } @@ -906,6 +983,8 @@ trait Foo { } impl Foo for $0T1 { + type X: Sync; + fn foo(&self, x: Self::X) -> T { todo!() } @@ -941,6 +1020,8 @@ trait Foo { } impl Foo for $0T { + type X: Sync; + fn foo(&self, x: Self::X) -> i32 { todo!() } From 9e4ec2acc782dea54c71430b5de5281cc77eb4ad Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 28 Oct 2025 13:27:21 +0000 Subject: [PATCH 295/525] clippy fixes and code simplification --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 36 +++++++++---------- .../src/fn_ctxt/arg_matrix.rs | 36 +++++++------------ .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 21 ++++------- .../src/fn_ctxt/suggestions.rs | 12 +++---- .../rustc_hir_typeck/src/gather_locals.rs | 2 +- compiler/rustc_hir_typeck/src/loops.rs | 17 ++++----- compiler/rustc_index/src/bit_set.rs | 2 +- .../src/impossible_predicates.rs | 8 ++--- compiler/rustc_mir_transform/src/inline.rs | 2 +- 9 files changed, 56 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 837328e379ca..854202c31270 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -94,20 +94,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let find_param_matching = |matches: &dyn Fn(ParamTerm) -> bool| { predicate_args.iter().find_map(|arg| { - arg.walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.kind() - && let ty::Param(param_ty) = *ty.kind() - && matches(ParamTerm::Ty(param_ty)) - { - Some(arg) - } else if let ty::GenericArgKind::Const(ct) = arg.kind() - && let ty::ConstKind::Param(param_ct) = ct.kind() - && matches(ParamTerm::Const(param_ct)) - { - Some(arg) - } else { - None + arg.walk().find(|arg| match arg.kind() { + ty::GenericArgKind::Type(ty) if let ty::Param(param_ty) = ty.kind() => { + matches(ParamTerm::Ty(*param_ty)) } + ty::GenericArgKind::Const(ct) + if let ty::ConstKind::Param(param_ct) = ct.kind() => + { + matches(ParamTerm::Const(param_ct)) + } + _ => false, }) }) }; @@ -162,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .flatten() { - if self.point_at_path_if_possible(error, def_id, param, &qpath) { + if self.point_at_path_if_possible(error, def_id, param, qpath) { return true; } } @@ -194,7 +190,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args, ) => { if let Some(param) = predicate_self_type_to_point_at - && self.point_at_path_if_possible(error, callee_def_id, param, &qpath) + && self.point_at_path_if_possible(error, callee_def_id, param, qpath) { return true; } @@ -225,7 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .flatten() { - if self.point_at_path_if_possible(error, callee_def_id, param, &qpath) { + if self.point_at_path_if_possible(error, callee_def_id, param, qpath) { return true; } } @@ -543,10 +539,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// - `blame_specific_*` means that the function will recursively traverse the expression, - /// looking for the most-specific-possible span to blame. + /// looking for the most-specific-possible span to blame. /// /// - `point_at_*` means that the function will only go "one level", pointing at the specific - /// expression mentioned. + /// expression mentioned. /// /// `blame_specific_arg_if_possible` will find the most-specific expression anywhere inside /// the provided function call expression, and mark it as responsible for the fulfillment @@ -609,6 +605,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { * - want `Vec: Copy` * - because `Option>: Copy` needs `Vec: Copy` because `impl Copy for Option` * - because `(Option, bool)` needs `Option>: Copy` because `impl Copy for (A, B)` + * * then if you pass in `(Some(vec![1, 2, 3]), false)`, this helper `point_at_specific_expr_if_possible` * will find the expression `vec![1, 2, 3]` as the "most blameable" reason for this missing constraint. * @@ -749,6 +746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// - expr: `(Some(vec![1, 2, 3]), false)` /// - param: `T` /// - in_ty: `(Option, bool)` + /// /// we would drill until we arrive at `vec![1, 2, 3]`. /// /// If successful, we return `Ok(refined_expr)`. If unsuccessful, we return `Err(partially_refined_expr`), @@ -1016,7 +1014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .variant_with_id(variant_def_id) .fields .iter() - .map(|field| field.ty(self.tcx, *in_ty_adt_generic_args)) + .map(|field| field.ty(self.tcx, in_ty_adt_generic_args)) .enumerate() .filter(|(_index, field_type)| find_param_in_ty((*field_type).into(), param)), ) else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index f6298adf2ebb..16f0a7dbc6f3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -174,7 +174,7 @@ impl<'tcx> ArgMatrix<'tcx> { return Some(Issue::Missing(next_unmatched_idx)); } // If we eliminate the last column, any left-over inputs are extra - if mat[i].len() == 0 { + if mat[i].is_empty() { return Some(Issue::Extra(next_unmatched_idx)); } @@ -187,28 +187,18 @@ impl<'tcx> ArgMatrix<'tcx> { continue; } - let mut useless = true; - let mut unsatisfiable = true; - if is_arg { - for j in 0..ii.len() { - // If we find at least one input this argument could satisfy - // this argument isn't unsatisfiable - if matches!(mat[j][i], Compatibility::Compatible) { - unsatisfiable = false; - break; - } - } - } - if is_input { - for j in 0..ai.len() { - // If we find at least one argument that could satisfy this input - // this input isn't useless - if matches!(mat[i][j], Compatibility::Compatible) { - useless = false; - break; - } - } - } + // If this argument can satisfy some input, then this argument is satisfiable + let unsatisfiable = if is_arg { + !mat.iter().take(ii.len()).any(|c| matches!(c[i], Compatibility::Compatible)) + } else { + true + }; + // If this input can be satisfied by some argument, then this input is useful + let useless = if is_input { + !mat[i].iter().take(ai.len()).any(|c| matches!(c, Compatibility::Compatible)) + } else { + true + }; match (is_input, is_arg, useless, unsatisfiable) { // If an argument is unsatisfied, and the input in its position is useless diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 0cbdd86768a6..127f2c676391 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -777,10 +777,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => bug!("unexpected type: {:?}", ty.normalized), }, - Res::Def( - DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy, - _, - ) + Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() { Some(adt) if !adt.is_enum() => { @@ -868,7 +865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let decl_ty = self.local_ty(decl.span, decl.hir_id); // Type check the initializer. - if let Some(ref init) = decl.init { + if let Some(init) = decl.init { let init_ty = self.check_decl_initializer(decl.hir_id, decl.pat, init); self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, init_ty); } @@ -932,7 +929,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Ignore for now. hir::StmtKind::Item(_) => {} - hir::StmtKind::Expr(ref expr) => { + hir::StmtKind::Expr(expr) => { // Check with expected type of `()`. self.check_expr_has_type_or_error(expr, self.tcx.types.unit, |err| { if self.is_next_stmt_expr_continuation(stmt.hir_id) @@ -1766,10 +1763,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let params = params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?; debug_assert_eq!(params.len(), fn_inputs.len()); - Some(( - fn_inputs.zip(params.iter().map(|param| FnParam::Param(param))).collect(), - generics, - )) + Some((fn_inputs.zip(params.iter().map(FnParam::Param)).collect(), generics)) } (None, Some(params)) => { let params = @@ -2632,7 +2626,7 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { suggestions: Vec<(Span, String)>, suggestion_text: SuggestionText, ) -> Option { - let suggestion_text = match suggestion_text { + match suggestion_text { SuggestionText::None => None, SuggestionText::Provide(plural) => { Some(format!("provide the argument{}", if plural { "s" } else { "" })) @@ -2648,8 +2642,7 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { SuggestionText::Swap => Some("swap these arguments".to_string()), SuggestionText::Reorder => Some("reorder these arguments".to_string()), SuggestionText::DidYouMean => Some("did you mean".to_string()), - }; - suggestion_text + } } fn arguments_formatting(&self, suggestion_span: Span) -> ArgumentsFormatting { @@ -2947,7 +2940,7 @@ impl<'a, 'b, 'tcx> ArgsCtxt<'a, 'b, 'tcx> { .fn_ctxt .typeck_results .borrow() - .expr_ty_adjusted_opt(*expr) + .expr_ty_adjusted_opt(expr) .unwrap_or_else(|| Ty::new_misc_error(self.call_ctxt.fn_ctxt.tcx)); ( self.call_ctxt.fn_ctxt.resolve_vars_if_possible(ty), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 28bd3e7e8d5b..1d16c3af7fb7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1132,7 +1132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .collect::>(); - if all_matching_bounds_strs.len() == 0 { + if all_matching_bounds_strs.is_empty() { return; } @@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty = *inner_expected_ty; } (hir::ExprKind::Block(blk, _), _, _) => { - self.suggest_block_to_brackets(diag, *blk, expr_ty, expected_ty); + self.suggest_block_to_brackets(diag, blk, expr_ty, expected_ty); break true; } _ => break false, @@ -1463,7 +1463,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = expr .span - .find_ancestor_not_from_extern_macro(&self.tcx.sess.source_map()) + .find_ancestor_not_from_extern_macro(self.tcx.sess.source_map()) .unwrap_or(expr.span); let mut sugg = if self.precedence(expr) >= ExprPrecedence::Unambiguous { @@ -2144,7 +2144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = expr .span - .find_ancestor_not_from_extern_macro(&self.tcx.sess.source_map()) + .find_ancestor_not_from_extern_macro(self.tcx.sess.source_map()) .unwrap_or(expr.span); err.span_suggestion_verbose(span.shrink_to_hi(), msg, sugg, Applicability::HasPlaceholders); true @@ -2257,7 +2257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let src_map = tcx.sess.source_map(); let suggestion = if src_map.is_multiline(expr.span) { - let indentation = src_map.indentation_before(span).unwrap_or_else(String::new); + let indentation = src_map.indentation_before(span).unwrap_or_default(); format!("\n{indentation}/* {suggestion} */") } else { // If the entire expr is on a single line @@ -2289,7 +2289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if `expr` is contained in array of two elements if let hir::Node::Expr(array_expr) = self.tcx.parent_hir_node(expr.hir_id) && let hir::ExprKind::Array(elements) = array_expr.kind - && let [first, second] = &elements[..] + && let [first, second] = elements && second.hir_id == expr.hir_id { // Span between the two elements of the array diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index f1d6476a0f36..85c8400f227b 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { /// again during type checking by querying [`FnCtxt::local_ty`] for the same hir_id. fn declare(&mut self, decl: Declaration<'tcx>) { let local_ty = match decl.ty { - Some(ref ty) => { + Some(ty) => { let o_ty = self.fcx.lower_ty(ty); let c_ty = self.fcx.infcx.canonicalize_user_type_annotation( diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index acfa5c473aac..799e82ec13b8 100644 --- a/compiler/rustc_hir_typeck/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs @@ -147,7 +147,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { } } } - hir::ExprKind::Loop(ref b, _, source, _) => { + hir::ExprKind::Loop(b, _, source, _) => { let cx = match self.is_loop_match(e, b) { Some(labeled_block) => LoopMatch { labeled_block }, None => Loop(source), @@ -155,9 +155,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { self.with_context(cx, |v| v.visit_block(b)); } - hir::ExprKind::Closure(&hir::Closure { - ref fn_decl, body, fn_decl_span, kind, .. - }) => { + hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, kind, .. }) => { let cx = match kind { hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(kind, source)) => { Coroutine { coroutine_span: fn_decl_span, kind, source } @@ -167,16 +165,16 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { self.visit_fn_decl(fn_decl); self.with_context(cx, |v| v.visit_nested_body(body)); } - hir::ExprKind::Block(ref b, Some(_label)) => { + hir::ExprKind::Block(b, Some(_label)) => { self.with_context(LabeledBlock, |v| v.visit_block(b)); } - hir::ExprKind::Block(ref b, None) + hir::ExprKind::Block(b, None) if matches!(self.cx_stack.last(), Some(&Fn) | Some(&ConstBlock)) => { self.with_context(Normal, |v| v.visit_block(b)); } hir::ExprKind::Block( - ref b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. }, + b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. }, None, ) if matches!( self.cx_stack.last(), @@ -431,10 +429,7 @@ impl<'hir> CheckLoopVisitor<'hir> { // Accept either `state = expr` or `state = expr;`. let loop_body_expr = match body.stmts { - [] => match body.expr { - Some(expr) => expr, - None => return None, - }, + [] => body.expr?, [single] if body.expr.is_none() => match single.kind { hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => expr, _ => return None, diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 96e85fdb10a6..a9bdf597e128 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1409,7 +1409,7 @@ impl BitMatrix { BitMatrix { num_rows, num_columns, - words: iter::repeat(&row.words).take(num_rows).flatten().cloned().collect(), + words: iter::repeat_n(&row.words, num_rows).flatten().cloned().collect(), marker: PhantomData, } } diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index 883ee32bdec9..71e4d5581ddc 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -20,11 +20,11 @@ //! parameters, so this filtering serves two purposes: //! //! 1. We skip evaluating any predicates that we would -//! never be able prove are unsatisfiable (e.g. `` +//! never be able prove are unsatisfiable (e.g. `` //! 2. We avoid trying to normalize predicates involving generic -//! parameters (e.g. `::MyItem`). This can confuse -//! the normalization code (leading to cycle errors), since -//! it's usually never invoked in this way. +//! parameters (e.g. `::MyItem`). This can confuse +//! the normalization code (leading to cycle errors), since +//! it's usually never invoked in this way. use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind}; use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt}; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index dc6088849bf5..7e1dd76f903d 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -635,7 +635,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. - if !validate_types(tcx, inliner.typing_env(), &callee_body, &caller_body).is_empty() { + if !validate_types(tcx, inliner.typing_env(), &callee_body, caller_body).is_empty() { debug!("failed to validate callee body"); return Err("implementation limitation -- callee body failed validation"); } From 76066d7949257a4b7f73b2b67d6d3a9c5c1a8919 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 2 Nov 2025 15:59:21 +0800 Subject: [PATCH 296/525] test: remove `tests/run-make/fmt-write-bloat/` This test suffers from multiple issues that make it very, very difficult to fix, and even if fixed, it would still be too fragile. For some background context, this test tries to check that the optimization introduced in [PR-78122] is not regressed. The optimization is for eliding `usize` formatting machinery and padding code from the final binary. Previously, writing any `fmt::Arguments` would cause the `usize` formatting and padding machinery to be included in the final binary since indexing used in `fmt::write` generates code using `panic_bounds_check` (that prints the index and length). Those bounds check are never hit, since `fmt::Arguments` never contain any out-of-bounds indicies. The `Makefile` version of `fmt-write-bloat` was ported to the present `rmake.rs` test infra in [PR-128147]. However, this PR just tries to maintain the original test logic. The original test, it turns out, already have multiple limitations: - It only runs on non-Windows, since the `no_std` test of the original version tries to link against a `libc`. [PR-128807] worked around this by using a substitute name. We re-enabled this test in [PR-142841], but it turns out the assertions are too weak, it will even vacuously pass for no symbols at all. - In [PR-143669], we tried to make this test more robust by comparing the set of expected versus unexpected panic-related symbols, subject to if std was built with debug assertions. However, in working on [PR-143669], we've come to realize that this test is fundamentally very fragile: - The set of panic symbols depend on whether the standard library was built with or without debug assertions. - Different platforms often have different sets of panic machinery modules, functions and paths, and thus different sets of panic symbols. For instance, x86_64 msvc and i686 msvc have different panic codepaths. - This comes back to the way the test is trying to gauge the absence of panic symbols -- it tries to look for symbol substring matches for "known" panic symbols. This is fundamentally fragile, because the test is trying to peek into the symbols of the resultant binary post-linking, based on fuzzy matches (the symbols are mangled as well). Based on this assessment, we determined that we should remove this test. This is not intended to exclude the possibility of reintroducing a more robust version of this test. For instance, we could consider some kind of more controllable post-link "end product" integration codegen test suite. [PR-78122]: https://github.com/rust-lang/rust/pull/78122 [PR-128147]: https://github.com/rust-lang/rust/pull/128147 [PR-128807]: https://github.com/rust-lang/rust/pull/128807 [PR-142841]: https://github.com/rust-lang/rust/pull/142841 [PR-143669]: https://github.com/rust-lang/rust/pull/143669 --- tests/run-make/fmt-write-bloat/main.rs | 32 ---------------------- tests/run-make/fmt-write-bloat/rmake.rs | 35 ------------------------- 2 files changed, 67 deletions(-) delete mode 100644 tests/run-make/fmt-write-bloat/main.rs delete mode 100644 tests/run-make/fmt-write-bloat/rmake.rs diff --git a/tests/run-make/fmt-write-bloat/main.rs b/tests/run-make/fmt-write-bloat/main.rs deleted file mode 100644 index b50461c0a027..000000000000 --- a/tests/run-make/fmt-write-bloat/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![feature(lang_items)] -#![no_main] -#![no_std] - -use core::fmt; -use core::fmt::Write; - -#[cfg_attr(not(windows), link(name = "c"))] -extern "C" {} - -struct Dummy; - -impl fmt::Write for Dummy { - #[inline(never)] - fn write_str(&mut self, _: &str) -> fmt::Result { - Ok(()) - } -} - -#[no_mangle] -extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int { - let _ = writeln!(Dummy, "Hello World"); - 0 -} - -#[lang = "eh_personality"] -fn eh_personality() {} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { - loop {} -} diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs deleted file mode 100644 index b7f18b384cb0..000000000000 --- a/tests/run-make/fmt-write-bloat/rmake.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Before #78122, writing any `fmt::Arguments` would trigger the inclusion of `usize` formatting -//! and padding code in the resulting binary, because indexing used in `fmt::write` would generate -//! code using `panic_bounds_check`, which prints the index and length. -//! -//! These bounds checks are not necessary, as `fmt::Arguments` never contains any out-of-bounds -//! indexes. The test is a `run-make` test, because it needs to check the result after linking. A -//! codegen or assembly test doesn't check the parts that will be pulled in from `core` by the -//! linker. -//! -//! In this test, we try to check that the `usize` formatting and padding code are not present in -//! the final binary by checking that panic symbols such as `panic_bounds_check` are **not** -//! present. -//! -//! Some CI jobs try to run faster by disabling debug assertions (through setting -//! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of -//! additional `usize` formatting and padding related symbols. - -//@ ignore-cross-compile - -use run_make_support::artifact_names::bin_name; -use run_make_support::env::std_debug_assertions_enabled; -use run_make_support::rustc; -use run_make_support::symbols::object_contains_any_symbol_substring; - -fn main() { - rustc().input("main.rs").opt().run(); - // panic machinery identifiers, these should not appear in the final binary - let mut panic_syms = vec!["panic_bounds_check", "Debug"]; - if std_debug_assertions_enabled() { - // if debug assertions are allowed, we need to allow these, - // otherwise, add them to the list of symbols to deny. - panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]); - } - assert!(!object_contains_any_symbol_substring(bin_name("main"), &panic_syms)); -} From 72c9762f500ec24b017506d01427594f34bce250 Mon Sep 17 00:00:00 2001 From: "Mark Z. Ding" Date: Sun, 2 Nov 2025 03:45:10 -0500 Subject: [PATCH 297/525] Fix CI failure by ignoring wasm target and cross compile run --- tests/ui/explicit-tail-calls/become-cast-return.rs | 2 ++ tests/ui/explicit-tail-calls/become-indirect-return.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/ui/explicit-tail-calls/become-cast-return.rs b/tests/ui/explicit-tail-calls/become-cast-return.rs index 212a0ddcbca1..d4cdcbf3a011 100644 --- a/tests/ui/explicit-tail-calls/become-cast-return.rs +++ b/tests/ui/explicit-tail-calls/become-cast-return.rs @@ -1,5 +1,7 @@ //@ run-pass //@ ignore-backends: gcc +//@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1 +//@ ignore-cross-compile #![expect(incomplete_features)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs index 7eec34f3b95c..b1e552bca029 100644 --- a/tests/ui/explicit-tail-calls/become-indirect-return.rs +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -1,5 +1,7 @@ //@ run-pass //@ ignore-backends: gcc +//@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1 +//@ ignore-cross-compile #![expect(incomplete_features)] #![feature(explicit_tail_calls)] From 625b6f5844555c315d90081c5e542bcc2b82cc71 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 2 Nov 2025 17:29:24 +0800 Subject: [PATCH 298/525] TypeId: make unstable layout/size explicit Or worded differently, explicitly remark non-stable-guarantee of `TypeId` layout and size. --- library/core/src/any.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 3ab95438c3ff..655ec4dff309 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -611,6 +611,15 @@ impl dyn Any + Send + Sync { /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! /// +/// # Layout +/// +/// Like other [`Rust`-representation][repr-rust] types, `TypeId`'s size and layout are unstable. +/// In particular, this means that you cannot rely on the size and layout of `TypeId` remaining the +/// same between Rust releases; they are subject to change without prior notice between Rust +/// releases. +/// +/// [repr-rust]: https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.rust.unspecified +/// /// # Danger of Improper Variance /// /// You might think that subtyping is impossible between two static types, From d3473f0741a8b5c8a60b5f54a6b0a898bec27d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 2 Nov 2025 11:03:31 +0100 Subject: [PATCH 299/525] Generalize branch references to HEAD --- .github/ISSUE_TEMPLATE/tracking_issue.md | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/post-merge.yml | 2 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- library/core/src/intrinsics/mod.rs | 10 ++-- src/bootstrap/src/lib.rs | 2 +- src/ci/github-actions/jobs.yml | 2 +- src/ci/run.sh | 2 +- .../src/appendix/code-index.md | 2 +- .../rustc-dev-guide/src/appendix/humorust.md | 2 +- src/doc/rustc-dev-guide/src/attributes.md | 2 +- .../src/backend/updating-llvm.md | 2 +- .../src/borrow_check/region_inference.md | 2 +- .../bootstrapping/how-bootstrap-does-it.md | 10 ++-- .../bootstrapping/what-bootstrapping-does.md | 10 ++-- .../src/building/prerequisites.md | 2 +- .../rustc-dev-guide/src/building/suggested.md | 12 ++-- .../rustc-dev-guide/src/compiler-debugging.md | 4 +- src/doc/rustc-dev-guide/src/compiler-src.md | 58 +++++++++---------- src/doc/rustc-dev-guide/src/compiler-team.md | 2 +- .../src/const-eval/interpret.md | 6 +- src/doc/rustc-dev-guide/src/contributing.md | 6 +- src/doc/rustc-dev-guide/src/external-repos.md | 2 +- .../rustc-dev-guide/src/getting-started.md | 2 +- src/doc/rustc-dev-guide/src/git.md | 2 +- .../rustc-dev-guide/src/guides/editions.md | 4 +- .../rustc-dev-guide/src/incrcomp-debugging.md | 2 +- src/doc/rustc-dev-guide/src/licenses.md | 4 +- .../src/llvm-coverage-instrumentation.md | 10 ++-- .../rustc-dev-guide/src/macro-expansion.md | 2 +- .../src/mir/drop-elaboration.md | 6 +- .../rustc-dev-guide/src/mir/optimizations.md | 4 +- .../src/notification-groups/about.md | 2 +- src/doc/rustc-dev-guide/src/overview.md | 10 ++-- .../src/panic-implementation.md | 2 +- .../src/profile-guided-optimization.md | 4 +- .../rustc-dev-guide/src/rustdoc-internals.md | 22 +++---- .../rustdoc-gui-test-suite.md | 2 +- .../rustdoc-json-test-suite.md | 6 +- .../rustdoc-internals/rustdoc-test-suite.md | 2 +- .../src/rustdoc-internals/search.md | 2 +- src/doc/rustc-dev-guide/src/rustdoc.md | 4 +- src/doc/rustc-dev-guide/src/sanitizers.md | 4 +- src/doc/rustc-dev-guide/src/serialization.md | 4 +- .../rustc-dev-guide/src/solve/opaque-types.md | 2 +- .../src/solve/significant-changes.md | 2 +- .../src/stabilization_guide.md | 8 +-- .../src/test-implementation.md | 2 +- src/doc/rustc-dev-guide/src/tests/adding.md | 2 +- src/doc/rustc-dev-guide/src/tests/ci.md | 10 ++-- .../rustc-dev-guide/src/tests/compiletest.md | 32 +++++----- .../rustc-dev-guide/src/tests/directives.md | 10 ++-- src/doc/rustc-dev-guide/src/tests/docker.md | 8 +-- src/doc/rustc-dev-guide/src/tests/intro.md | 8 +-- src/doc/rustc-dev-guide/src/tests/minicore.md | 2 +- src/doc/rustc-dev-guide/src/tests/running.md | 12 ++-- src/doc/rustc-dev-guide/src/tests/ui.md | 10 ++-- src/doc/rustc-dev-guide/src/tracing.md | 2 +- src/doc/rustc-dev-guide/src/traits/chalk.md | 2 +- .../src/traits/goals-and-clauses.md | 2 +- src/doc/rustc-dev-guide/src/ty-fold.md | 2 +- .../rustc-dev-guide/src/unsafety-checking.md | 2 +- src/doc/rustc-dev-guide/src/walkthrough.md | 2 +- src/doc/rustc/book.toml | 4 +- src/doc/rustc/src/codegen-options/index.md | 2 +- src/doc/rustc/src/contributing.md | 2 +- src/doc/rustc/src/exploit-mitigations.md | 2 +- .../armeb-unknown-linux-gnueabi.md | 2 +- src/doc/rustc/src/target-tier-policy.md | 6 +- src/doc/rustdoc/book.toml | 2 +- .../write-documentation/what-to-include.md | 2 +- src/doc/unstable-book/book.toml | 4 +- .../src/compiler-flags/codegen-backend.md | 2 +- .../src/language-features/lang-items.md | 4 +- src/etc/lldb_providers.py | 2 +- src/etc/natvis/libstd.natvis | 4 +- src/librustdoc/lib.rs | 4 +- .../rustc-std-workspace-alloc/Cargo.toml | 2 +- .../rustc-std-workspace-core/Cargo.toml | 2 +- .../rustc-std-workspace-std/Cargo.toml | 2 +- .../infrastructure/changelog_update.md | 2 +- .../src/disallowed_script_idents.rs | 2 +- src/tools/clippy/src/driver.rs | 4 +- src/tools/miri/src/shims/io_error.rs | 4 +- src/tools/nix-dev-shell/x/default.nix | 2 +- .../macro_expansion_tests/mbe/meta_syntax.rs | 2 +- .../crates/ide-db/src/generated/lints.rs | 4 +- .../docs/book/src/non_cargo_based_projects.md | 2 +- src/tools/rustfmt/Configurations.md | 2 +- src/tools/rustfmt/Contributing.md | 2 +- src/tools/rustfmt/src/closures.rs | 2 +- 92 files changed, 222 insertions(+), 222 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index aedc15a54c27..6def803b269e 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -50,7 +50,7 @@ for larger features an implementation could be broken up into multiple PRs. [stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr [doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs [nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/main/nightly-style-procedure.md -[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide +[Style Guide]: https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide ### Unresolved Questions $DIR/return-via-stack.rs:25:46 + --> $DIR/return-via-stack.rs:24:46 | LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { | ^^^^^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:30:46 + --> $DIR/return-via-stack.rs:29:46 | LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:35:46 + --> $DIR/return-via-stack.rs:34:46 | LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:40:46 + --> $DIR/return-via-stack.rs:39:46 | LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:47:46 + --> $DIR/return-via-stack.rs:46:46 | LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { | ^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:53:48 + --> $DIR/return-via-stack.rs:52:48 | LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { | ^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:59:48 + --> $DIR/return-via-stack.rs:58:48 | LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { | ^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:76:54 + --> $DIR/return-via-stack.rs:75:54 | LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:81:51 + --> $DIR/return-via-stack.rs:80:51 | LL | pub extern "cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs index aff632fa2879..32e6c92dc6cb 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ revisions: x86 aarch64 thumb7 // //@[x86] compile-flags: --target x86_64-unknown-linux-gnu diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs index cc7e2199ca91..0a6565e37fc7 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm diff --git a/tests/ui/compiletest-self-test/minicore-smoke-test.rs b/tests/ui/compiletest-self-test/minicore-smoke-test.rs index ec879f2852e1..0d43d45e2d65 100644 --- a/tests/ui/compiletest-self-test/minicore-smoke-test.rs +++ b/tests/ui/compiletest-self-test/minicore-smoke-test.rs @@ -3,7 +3,7 @@ //! This test is duplicated between ui/codegen/assembly because they have different runtest //! codepaths. -//@ add-core-stubs +//@ add-minicore //@ check-pass //@ compile-flags: --target=x86_64-unknown-linux-gnu //@ needs-llvm-components: x86 diff --git a/tests/ui/deriving/deriving-with-helper.rs b/tests/ui/deriving/deriving-with-helper.rs index df98bb6beb9f..8b468fade754 100644 --- a/tests/ui/deriving/deriving-with-helper.rs +++ b/tests/ui/deriving/deriving-with-helper.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ check-pass //@ compile-flags: --crate-type=lib diff --git a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs index 4e9096f949ba..164bc1b5c29d 100644 --- a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: avr //@ compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ ignore-backends: gcc diff --git a/tests/ui/feature-gates/feature-gate-abi-custom.rs b/tests/ui/feature-gates/feature-gate-abi-custom.rs index 312b6230b743..ca0b8337bbb7 100644 --- a/tests/ui/feature-gates/feature-gate-abi-custom.rs +++ b/tests/ui/feature-gates/feature-gate-abi-custom.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-asm-support #![no_core] #![feature(no_core, lang_items)] diff --git a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs index 60bf69f597cc..4971fcb6cb5b 100644 --- a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: msp430 //@ compile-flags: --target=msp430-none-elf --crate-type=rlib #![no_core] diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs index 7953352329ea..2bb5f969cf98 100644 --- a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: riscv //@ compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib //@ ignore-backends: gcc diff --git a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs index 0abdf0c5309b..2bfe03b89110 100644 --- a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib #![no_core] diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs index bafd3643788e..8e7f27e25cc5 100644 --- a/tests/ui/feature-gates/feature-gate-abi.rs +++ b/tests/ui/feature-gates/feature-gate-abi.rs @@ -1,5 +1,5 @@ // gate-test-intrinsics -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --crate-type=rlib #![feature(no_core, lang_items)] diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs index 148efea208c7..d442c9317f64 100644 --- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs +++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs @@ -1,5 +1,5 @@ //@ revisions: HOST AMDGPU NVPTX -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --crate-type=rlib //@[AMDGPU] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx1100 //@[AMDGPU] needs-llvm-components: amdgpu diff --git a/tests/ui/feature-gates/feature-gate-abi_ptx.rs b/tests/ui/feature-gates/feature-gate-abi_ptx.rs index 329e8e124494..7f5935a54683 100644 --- a/tests/ui/feature-gates/feature-gate-abi_ptx.rs +++ b/tests/ui/feature-gates/feature-gate-abi_ptx.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: nvptx //@ compile-flags: --target=nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs index 3e8ebd4f9f0b..450a4f40beb0 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target mips-unknown-linux-gnu //@ needs-llvm-components: mips //@ ignore-backends: gcc diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs index 15d6d4731c8f..7794bdc30b34 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target s390x-unknown-linux-gnu //@ needs-llvm-components: systemz //@ ignore-backends: gcc diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.rs b/tests/ui/feature-gates/feature-gate-vectorcall.rs index 1811357d1bcb..8c397e9fc36f 100644 --- a/tests/ui/feature-gates/feature-gate-vectorcall.rs +++ b/tests/ui/feature-gates/feature-gate-vectorcall.rs @@ -1,5 +1,5 @@ // gate-test-abi_vectorcall -//@ add-core-stubs +//@ add-minicore //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib //@ ignore-backends: gcc diff --git a/tests/ui/force-inlining/asm.rs b/tests/ui/force-inlining/asm.rs index 2b5f87c59d35..d48af8253d83 100644 --- a/tests/ui/force-inlining/asm.rs +++ b/tests/ui/force-inlining/asm.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ build-fail //@ compile-flags: --crate-type=lib --target thumbv4t-none-eabi //@ needs-llvm-components: arm diff --git a/tests/ui/layout/hexagon-enum.rs b/tests/ui/layout/hexagon-enum.rs index 22a1d5d10f30..517c1cb3d5cf 100644 --- a/tests/ui/layout/hexagon-enum.rs +++ b/tests/ui/layout/hexagon-enum.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target hexagon-unknown-linux-musl //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: hexagon diff --git a/tests/ui/layout/reprc-power-alignment.rs b/tests/ui/layout/reprc-power-alignment.rs index c8a6aa86a508..639e21782351 100644 --- a/tests/ui/layout/reprc-power-alignment.rs +++ b/tests/ui/layout/reprc-power-alignment.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags: --target powerpc64-ibm-aix //@ needs-llvm-components: powerpc -//@ add-core-stubs +//@ add-minicore //@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/layout/thumb-enum.rs b/tests/ui/layout/thumb-enum.rs index 1b516f05ec6f..d65822b4647a 100644 --- a/tests/ui/layout/thumb-enum.rs +++ b/tests/ui/layout/thumb-enum.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabihf //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: arm diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs index b8c75d24f492..cbbf772e7f59 100644 --- a/tests/ui/layout/too-big-with-padding.rs +++ b/tests/ui/layout/too-big-with-padding.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ build-fail //@ compile-flags: --target i686-unknown-linux-gnu --crate-type lib //@ needs-llvm-components: x86 diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs index 4340703e106d..1eaa00f7397c 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 //@ ignore-backends: gcc diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs index a03fb53c687b..823748035a85 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 //@ ignore-backends: gcc diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs index adcacc89e748..e1f7e03d0594 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 //@ ignore-backends: gcc diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs index 79aa16b98563..929e09a271ac 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 //@ ignore-backends: gcc diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs index 0b82165f5752..82b6066edcdb 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target aarch64-pc-windows-msvc //@ needs-llvm-components: aarch64 //@ ignore-backends: gcc diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs index 9ccc9ce4fdb8..58f0a74e674d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target x86_64-pc-windows-msvc //@ compile-flags: --crate-type lib --emit link //@ needs-llvm-components: x86 diff --git a/tests/ui/mir/checks_without_panic_impl.rs b/tests/ui/mir/checks_without_panic_impl.rs index 11ab50a5f9af..f4624fedd0c8 100644 --- a/tests/ui/mir/checks_without_panic_impl.rs +++ b/tests/ui/mir/checks_without_panic_impl.rs @@ -2,7 +2,7 @@ // does not prevent crates without a panic_impl from compiling. // See rust-lang/rust#109996 -//@ add-core-stubs +//@ add-minicore //@ build-pass //@ compile-flags: -Cdebug-assertions=yes diff --git a/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs index 295876fec527..89f5b402ea44 100644 --- a/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs +++ b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs @@ -1,6 +1,6 @@ //@ compile-flags:-C panic=unwind //@ no-prefer-dynamic -//@ add-core-stubs +//@ add-minicore #![crate_type = "rlib"] #![feature(no_core)] diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs index 78977c60be98..918394b2d32d 100644 --- a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs +++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs @@ -2,7 +2,7 @@ //@ aux-build:needs-abort.rs //@ compile-flags:-Cpanic=immediate-abort -Zunstable-options //@ no-prefer-dynamic -//@ add-core-stubs +//@ add-minicore //@ core-stubs-compile-flags: -Cpanic=immediate-abort -Zunstable-options #![feature(no_core)] diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs index 1c5f597a3f99..070262ca9ec1 100644 --- a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs +++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs @@ -2,7 +2,7 @@ //@ aux-build:needs-immediate-abort.rs //@ compile-flags:-C panic=abort //@ no-prefer-dynamic -//@ add-core-stubs +//@ add-minicore //@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs index 24d521230d49..9cdb7a0ed1dd 100644 --- a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs +++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs @@ -2,7 +2,7 @@ //@ needs-unwind //@ aux-build:needs-immediate-abort.rs //@ no-prefer-dynamic -//@ add-core-stubs +//@ add-minicore //@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs index 5aec028a46cf..6f3f7202016a 100644 --- a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs +++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs @@ -2,7 +2,7 @@ //@ aux-build:needs-unwind-immediate-abort.rs //@ compile-flags:-C panic=immediate-abort -Zunstable-options //@ no-prefer-dynamic -//@ add-core-stubs +//@ add-minicore //@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index b0f402554b81..f981ea23ee24 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ build-pass //@ revisions: avr msp430 // diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index 048e74c177ca..81f313646c7c 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -9,7 +9,7 @@ use minicore::*; // See also: repr-c-int-dead-variants.rs -//@ add-core-stubs +//@ add-minicore //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" diff --git a/tests/ui/repr/repr_align_greater_usize.rs b/tests/ui/repr/repr_align_greater_usize.rs index 7bbf0b29b2eb..d8eb03ef9525 100644 --- a/tests/ui/repr/repr_align_greater_usize.rs +++ b/tests/ui/repr/repr_align_greater_usize.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ revisions: msp430 aarch32 //@[msp430] needs-llvm-components: msp430 //@[msp430] compile-flags: --target=msp430-none-elf diff --git a/tests/ui/sanitizer/cfg-kasan.rs b/tests/ui/sanitizer/cfg-kasan.rs index 0f4560888935..2d934357adfe 100644 --- a/tests/ui/sanitizer/cfg-kasan.rs +++ b/tests/ui/sanitizer/cfg-kasan.rs @@ -1,7 +1,7 @@ // Verifies that when compiling with -Zsanitizer=kernel-address, // the `#[cfg(sanitize = "address")]` attribute is configured. -//@ add-core-stubs +//@ add-minicore //@ check-pass //@ compile-flags: -Zsanitizer=kernel-address //@ revisions: aarch64 riscv64imac riscv64gc x86_64 diff --git a/tests/ui/sanitizer/cfg.rs b/tests/ui/sanitizer/cfg.rs index 42b1d3c5e1f9..70914dcf9361 100644 --- a/tests/ui/sanitizer/cfg.rs +++ b/tests/ui/sanitizer/cfg.rs @@ -1,7 +1,7 @@ // Verifies that when compiling with -Zsanitizer=option, // the `#[cfg(sanitize = "option")]` attribute is configured. -//@ add-core-stubs +//@ add-minicore //@ check-pass //@ revisions: address cfi kcfi leak memory thread //@compile-flags: -Ctarget-feature=-crt-static diff --git a/tests/ui/static/static_sized_requirement.rs b/tests/ui/static/static_sized_requirement.rs index a0f4759112ca..644a6969fa56 100644 --- a/tests/ui/static/static_sized_requirement.rs +++ b/tests/ui/static/static_sized_requirement.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ check-pass #![feature(no_core)] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs index a604a8588858..8449b8ce0928 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type=lib //@ compile-flags: --target=aarch64-unknown-none-softfloat //@ needs-llvm-components: aarch64 -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] #![deny(aarch64_softfloat_neon)] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs index aab2be7a3669..20b82d2b1fb5 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs @@ -7,7 +7,7 @@ //@[riscv] compile-flags: --target=riscv32e-unknown-none-elf //@[riscv] needs-llvm-components: riscv //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core, riscv_target_feature, x87_target_feature)] #![no_core] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index ee932dac26a0..d3d2d6f62ec3 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -10,7 +10,7 @@ //@[riscv] core-stubs-compile-flags: -Ctarget-feature=-d //@[riscv] needs-llvm-components: riscv //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core, riscv_target_feature)] #![no_core] diff --git a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs index e5fe9d15c7b1..688f51dad58c 100644 --- a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs @@ -6,7 +6,7 @@ //@ compile-flags: -Ctarget-feature=-x87 //@ build-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/abi-required-target-feature-attribute.rs b/tests/ui/target-feature/abi-required-target-feature-attribute.rs index 747c00e48eac..b2d2c95313d2 100644 --- a/tests/ui/target-feature/abi-required-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-required-target-feature-attribute.rs @@ -4,7 +4,7 @@ //@ needs-llvm-components: x86 //@ build-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core, x87_target_feature)] #![no_core] diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs index 3b4bdb87a422..47b7abd50deb 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs @@ -17,7 +17,7 @@ // Remove some LLVM warnings that only show up sometimes. //@ normalize-stderr: "\n[^\n]*(target-abi|lp64f)[^\n]*" -> "" //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 9ea24c19f085..2e10c0e6e690 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -4,7 +4,7 @@ //@ [aarch64-sve2] compile-flags: -Ctarget-feature=-neon,+sve2 --target=aarch64-unknown-linux-gnu //@ [aarch64-sve2] needs-llvm-components: aarch64 //@ build-pass -//@ add-core-stubs +//@ add-minicore #![no_core] #![crate_type = "rlib"] #![feature(intrinsics, rustc_attrs, no_core, staged_api)] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs index 975cf3e56289..c787e747788d 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs @@ -2,7 +2,7 @@ //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core, riscv_target_feature)] #![no_core] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs index 1570c8e22251..ff9d38cc0a9d 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs @@ -2,7 +2,7 @@ //@ compile-flags: --target=riscv64gc-unknown-linux-gnu --crate-type=lib //@ needs-llvm-components: riscv //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core, riscv_target_feature)] #![no_core] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs index 7e7d7fd256fd..9457d1d2edb4 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs @@ -1,7 +1,7 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib //@ needs-llvm-components: x86 //@ check-pass -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] #![allow(unexpected_cfgs)] diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index d2c5f14f1b6c..71dedda94bc3 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -2,7 +2,7 @@ //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs index b61e83c562bf..db1a7b817bb8 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -3,7 +3,7 @@ //@ needs-llvm-components: riscv //@ check-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] #![allow(unexpected_cfgs)] diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs index f0f77700451f..e1f576bb6d89 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -5,7 +5,7 @@ // For now this is just a warning. //@ build-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index 5cb3997b2e55..ad6d3ee6dfa9 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -5,7 +5,7 @@ // For now this is just a warning. //@ build-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/inline-always.rs b/tests/ui/target-feature/inline-always.rs index 17ffcf4255ff..c1334bb6016b 100644 --- a/tests/ui/target-feature/inline-always.rs +++ b/tests/ui/target-feature/inline-always.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ build-pass //@ compile-flags: --crate-type=lib //@ revisions: aarch64 diff --git a/tests/ui/target-feature/no-llvm-leaks.rs b/tests/ui/target-feature/no-llvm-leaks.rs index 707e53f7b37d..fa72c88ead02 100644 --- a/tests/ui/target-feature/no-llvm-leaks.rs +++ b/tests/ui/target-feature/no-llvm-leaks.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ revisions: aarch64 x86-64 //@ [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 diff --git a/tests/ui/target-feature/retpoline-target-feature-flag.rs b/tests/ui/target-feature/retpoline-target-feature-flag.rs index ed3d030e69f3..182b5b86520c 100644 --- a/tests/ui/target-feature/retpoline-target-feature-flag.rs +++ b/tests/ui/target-feature/retpoline-target-feature-flag.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ revisions: by_flag by_feature1 by_feature2 by_feature3 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib //@ needs-llvm-components: x86 diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs index 691be0949c63..5e46ea8adf64 100644 --- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs +++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs @@ -4,7 +4,7 @@ // For now this is just a warning. //@ build-pass //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index 020c3b187bd0..af151e5520fc 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -12,7 +12,7 @@ //@ [four] build-pass //@ [four] compile-flags: -C target-feature=-paca,+pacg -C target-feature=+paca //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. //@ core-stubs-compile-flags: -C target-feature=-pacg,-paca #![feature(no_core)] diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 9cf6eb953bd0..1b8e34221d79 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -4,7 +4,7 @@ //@[paca] compile-flags: -Ctarget-feature=+paca //@[pacg] compile-flags: -Ctarget-feature=+pacg //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. //@ core-stubs-compile-flags: -C target-feature=-pacg,-paca #![feature(no_core)] diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 821a3b802a7d..14631411d89f 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -4,7 +4,7 @@ //@[paca] compile-flags: -Ctarget-feature=+paca //@[pacg] compile-flags: -Ctarget-feature=+pacg //@ ignore-backends: gcc -//@ add-core-stubs +//@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. //@ core-stubs-compile-flags: -C target-feature=-pacg,-paca diff --git a/tests/ui/target-feature/tied-features.rs b/tests/ui/target-feature/tied-features.rs index 1c3b171a8e1d..f83c09ef1e38 100644 --- a/tests/ui/target-feature/tied-features.rs +++ b/tests/ui/target-feature/tied-features.rs @@ -1,8 +1,7 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 //@ ignore-backends: gcc -//@ add-core-stubs #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/tied-features.stderr b/tests/ui/target-feature/tied-features.stderr index 6a2c909e2d8d..b6a97fbbe9d9 100644 --- a/tests/ui/target-feature/tied-features.stderr +++ b/tests/ui/target-feature/tied-features.stderr @@ -1,5 +1,5 @@ error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:13:5 + --> $DIR/tied-features.rs:12:5 | LL | #[target_feature(enable = "pacg")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[target_feature(enable = "pacg")] = help: add the missing features in a `target_feature` attribute error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:25:1 + --> $DIR/tied-features.rs:24:1 | LL | #[target_feature(enable = "paca")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #[target_feature(enable = "paca")] = help: add the missing features in a `target_feature` attribute error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:38:1 + --> $DIR/tied-features.rs:37:1 | LL | #[target_feature(enable = "paca")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 97d8f3e5bdd84bfa93c2a69ba5c895139a232f7e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 2 Nov 2025 10:45:15 +0100 Subject: [PATCH 307/525] also rename core-stubs-compile-flags to minicore-compile-flags --- src/tools/compiletest/src/directives.rs | 10 +++++----- .../compiletest/src/directives/directive_names.rs | 2 +- src/tools/compiletest/src/runtest.rs | 2 +- .../ui/panic-runtime/need-abort-got-immediate-abort.rs | 2 +- .../ui/panic-runtime/need-immediate-abort-got-abort.rs | 2 +- .../panic-runtime/need-immediate-abort-got-unwind.rs | 2 +- .../panic-runtime/need-unwind-got-immediate-abort.rs | 2 +- .../abi-incompatible-target-feature-flag-enable.rs | 2 +- tests/ui/target-feature/tied-features-cli.rs | 2 +- .../target-feature/tied-features-no-implication-1.rs | 2 +- .../ui/target-feature/tied-features-no-implication.rs | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 6e4ba2b9f32e..f25294d8d198 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -202,7 +202,7 @@ pub(crate) struct TestProps { /// that don't otherwise want/need `-Z build-std`. pub add_minicore: bool, /// Add these flags to the build of `minicore`. - pub core_stubs_compile_flags: Vec, + pub minicore_compile_flags: Vec, /// Whether line annotatins are required for the given error kind. pub dont_require_annotations: HashSet, /// Whether pretty printers should be disabled in gdb. @@ -255,7 +255,7 @@ mod directives { pub const FILECHECK_FLAGS: &'static str = "filecheck-flags"; pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg"; pub const ADD_MINICORE: &'static str = "add-minicore"; - pub const CORE_STUBS_COMPILE_FLAGS: &'static str = "core-stubs-compile-flags"; + pub const MINICORE_COMPILE_FLAGS: &'static str = "minicore-compile-flags"; pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers"; pub const COMPARE_OUTPUT_BY_LINES: &'static str = "compare-output-by-lines"; } @@ -312,7 +312,7 @@ impl TestProps { filecheck_flags: vec![], no_auto_check_cfg: false, add_minicore: false, - core_stubs_compile_flags: vec![], + minicore_compile_flags: vec![], dont_require_annotations: Default::default(), disable_gdb_pretty_printers: false, compare_output_by_lines: false, @@ -604,7 +604,7 @@ impl TestProps { self.update_add_minicore(ln, config); if let Some(flags) = - config.parse_name_value_directive(ln, CORE_STUBS_COMPILE_FLAGS) + config.parse_name_value_directive(ln, MINICORE_COMPILE_FLAGS) { let flags = split_flags(&flags); for flag in &flags { @@ -612,7 +612,7 @@ impl TestProps { panic!("you must use `//@ edition` to configure the edition"); } } - self.core_stubs_compile_flags.extend(flags); + self.minicore_compile_flags.extend(flags); } if let Some(err_kind) = diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index ad8eb41ef2a7..44bf9611064a 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -19,7 +19,6 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "check-test-line-numbers-match", "compare-output-by-lines", "compile-flags", - "core-stubs-compile-flags", "disable-gdb-pretty-printers", "doc-flags", "dont-check-compiler-stderr", @@ -141,6 +140,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "min-lldb-version", "min-llvm-version", "min-system-llvm-version", + "minicore-compile-flags", "needs-asm-support", "needs-backends", "needs-crate-type", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8b8031d58574..8b776f7e9289 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1341,7 +1341,7 @@ impl<'test> TestCx<'test> { rustc.args(&["--crate-type", "rlib"]); rustc.arg("-Cpanic=abort"); - rustc.args(self.props.core_stubs_compile_flags.clone()); + rustc.args(self.props.minicore_compile_flags.clone()); let res = self.compose_and_run(rustc, self.config.compile_lib_path.as_path(), None, None); if !res.status.success() { diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs index 918394b2d32d..b3f7c96bd054 100644 --- a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs +++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs @@ -3,7 +3,7 @@ //@ compile-flags:-Cpanic=immediate-abort -Zunstable-options //@ no-prefer-dynamic //@ add-minicore -//@ core-stubs-compile-flags: -Cpanic=immediate-abort -Zunstable-options +//@ minicore-compile-flags: -Cpanic=immediate-abort -Zunstable-options #![feature(no_core)] #![no_std] diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs index 070262ca9ec1..a86391101f52 100644 --- a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs +++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs @@ -3,7 +3,7 @@ //@ compile-flags:-C panic=abort //@ no-prefer-dynamic //@ add-minicore -//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort +//@ minicore-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] #![no_std] diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs index 9cdb7a0ed1dd..7e1031da4ad2 100644 --- a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs +++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs @@ -3,7 +3,7 @@ //@ aux-build:needs-immediate-abort.rs //@ no-prefer-dynamic //@ add-minicore -//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort +//@ minicore-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] #![no_std] diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs index 6f3f7202016a..a60ca012b7a4 100644 --- a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs +++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs @@ -3,7 +3,7 @@ //@ compile-flags:-C panic=immediate-abort -Zunstable-options //@ no-prefer-dynamic //@ add-minicore -//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort +//@ minicore-compile-flags: -Zunstable-options -Cpanic=immediate-abort #![feature(no_core)] #![no_std] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index d3d2d6f62ec3..0cdaf3358d25 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -7,7 +7,7 @@ //@[x86] needs-llvm-components: x86 //@[riscv] compile-flags: --target=riscv32e-unknown-none-elf -Ctarget-feature=+d // FIXME(#147881): *disable* the feature again for minicore as otherwise that will fail to build. -//@[riscv] core-stubs-compile-flags: -Ctarget-feature=-d +//@[riscv] minicore-compile-flags: -Ctarget-feature=-d //@[riscv] needs-llvm-components: riscv //@ ignore-backends: gcc //@ add-minicore diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index af151e5520fc..ffa38721c7da 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -14,7 +14,7 @@ //@ ignore-backends: gcc //@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. -//@ core-stubs-compile-flags: -C target-feature=-pacg,-paca +//@ minicore-compile-flags: -C target-feature=-pacg,-paca #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 1b8e34221d79..326da8b8dcf3 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -6,7 +6,7 @@ //@ ignore-backends: gcc //@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. -//@ core-stubs-compile-flags: -C target-feature=-pacg,-paca +//@ minicore-compile-flags: -C target-feature=-pacg,-paca #![feature(no_core)] #![no_core] diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 14631411d89f..9543065bbf92 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -6,7 +6,7 @@ //@ ignore-backends: gcc //@ add-minicore // FIXME(#147881): *disable* the features again for minicore as otherwise that will fail to build. -//@ core-stubs-compile-flags: -C target-feature=-pacg,-paca +//@ minicore-compile-flags: -C target-feature=-pacg,-paca #![feature(no_core)] #![no_core] From 4e17091cf8507fab5f85a7e8773e0f07e0e5fe25 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sun, 2 Nov 2025 14:43:48 +0000 Subject: [PATCH 308/525] add enum to address lifetime with colon problem --- .../src/error_reporting/infer/region.rs | 45 ++++++++++++++----- .../missing-param-but-has-colon-144215.rs | 9 ++++ .../missing-param-but-has-colon-144215.stderr | 17 +++++++ 3 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 tests/ui/generics/missing-param-but-has-colon-144215.rs create mode 100644 tests/ui/generics/missing-param-but-has-colon-144215.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 0765434d3c43..e225656af852 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -774,20 +774,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // instead we suggest `T: 'a + 'b` in that case. let hir_generics = self.tcx.hir_get_generics(scope).unwrap(); let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) { - Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)), + Some((span, open_paren_sp)) => { + Some((span, LifetimeSuggestion::NeedsPlus(open_paren_sp))) + } // If `param` corresponds to `Self`, no usable suggestion span. None if generics.has_self && param.index == 0 => None, None => { + let mut colon_flag = false; let span = if let Some(param) = hir_generics.params.iter().find(|param| param.def_id == def_id) && let ParamName::Plain(ident) = param.name { - ident.span.shrink_to_hi() + if let Some(sp) = param.colon_span { + colon_flag = true; + sp.shrink_to_hi() + } else { + ident.span.shrink_to_hi() + } } else { let span = self.tcx.def_span(def_id); span.shrink_to_hi() }; - Some((span, false, None)) + match colon_flag { + true => Some((span, LifetimeSuggestion::HasColon)), + false => Some((span, LifetimeSuggestion::NeedsColon)), + } } }; (scope, sugg_span) @@ -811,17 +822,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut suggs = vec![]; let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs); - if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span + if let Some((sp, suggestion_type)) = type_param_sugg_span && suggestion_scope == type_scope { - let suggestion = - if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") }; - - if let Some(open_paren_sp) = open_paren_sp { - suggs.push((open_paren_sp, "(".to_string())); - suggs.push((sp, format!("){suggestion}"))); - } else { - suggs.push((sp, suggestion)) + match suggestion_type { + LifetimeSuggestion::NeedsPlus(open_paren_sp) => { + let suggestion = format!(" + {lt_name}"); + if let Some(open_paren_sp) = open_paren_sp { + suggs.push((open_paren_sp, "(".to_string())); + suggs.push((sp, format!("){suggestion}"))); + } else { + suggs.push((sp, suggestion)); + } + } + LifetimeSuggestion::NeedsColon => suggs.push((sp, format!(": {lt_name}"))), + LifetimeSuggestion::HasColon => suggs.push((sp, format!(" {lt_name}"))), } } else if let GenericKind::Alias(ref p) = bound_kind && let ty::Projection = p.kind(self.tcx) @@ -1056,6 +1071,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } +enum LifetimeSuggestion { + NeedsPlus(Option), + NeedsColon, + HasColon, +} + pub(super) fn note_and_explain_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, diff --git a/tests/ui/generics/missing-param-but-has-colon-144215.rs b/tests/ui/generics/missing-param-but-has-colon-144215.rs new file mode 100644 index 000000000000..31a9dd49e5c6 --- /dev/null +++ b/tests/ui/generics/missing-param-but-has-colon-144215.rs @@ -0,0 +1,9 @@ +//! Regression test for + +#[rustfmt::skip] +struct S(&'static T); +//~^ ERROR the parameter type `T` may not live long enough +//~| HELP consider adding an explicit lifetime bound +//~| SUGGESTION 'static + +fn main() {} diff --git a/tests/ui/generics/missing-param-but-has-colon-144215.stderr b/tests/ui/generics/missing-param-but-has-colon-144215.stderr new file mode 100644 index 000000000000..bf6cee035e2e --- /dev/null +++ b/tests/ui/generics/missing-param-but-has-colon-144215.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/missing-param-but-has-colon-144215.rs:4:14 + | +LL | struct S(&'static T); + | ^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the reference type `&'static T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound + | +LL | struct S(&'static T); + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0310`. From c962b95a16e8766c3b6f39399d60536459381222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Nov 2025 19:58:24 +0000 Subject: [PATCH 309/525] review comments --- compiler/rustc_resolve/src/diagnostics.rs | 10 +++++----- compiler/rustc_resolve/src/ident.rs | 20 ++++++++++---------- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 7 ++++++- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 4a5d304f49bf..bc41ffc63c3c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -553,12 +553,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { resolution_error: ResolutionError<'ra>, ) -> Diag<'_> { match resolution_error { - ResolutionError::GenericParamsFromOuterItem( + ResolutionError::GenericParamsFromOuterItem { outer_res, has_generic_params, def_kind, - item, - ) => { + inner_item, + } => { use errs::GenericParamsFromOuterItemLabel as Label; let static_or_const = match def_kind { DefKind::Static { .. } => { @@ -576,9 +576,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { sugg: None, static_or_const, is_self, - item: item.map(|(span, descr)| errs::GenericParamsFromOuterItemInnerItem { + item: inner_item.map(|(span, kind)| errs::GenericParamsFromOuterItemInnerItem { span, - descr, + descr: kind.descr().to_string(), }), }; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2ab024df9a20..278c0fe35b7d 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1404,18 +1404,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .ident() .map(|i| i.span) .unwrap_or(current_item.span); - Some((span, current_item.kind.descr().to_string())) + Some((span, current_item.kind.clone())) } else { None }; self.report_error( span, - ResolutionError::GenericParamsFromOuterItem( - res, + ResolutionError::GenericParamsFromOuterItem { + outer_res: res, has_generic_params, def_kind, - item, - ), + inner_item: item, + }, ); } return Res::Err; @@ -1492,18 +1492,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .ident() .map(|i| i.span) .unwrap_or(current_item.span); - Some((span, current_item.kind.descr().to_string())) + Some((span, current_item.kind.clone())) } else { None }; self.report_error( span, - ResolutionError::GenericParamsFromOuterItem( - res, + ResolutionError::GenericParamsFromOuterItem { + outer_res: res, has_generic_params, def_kind, - item, - ), + inner_item: item, + }, ); } return Res::Err; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3d79b94c25e7..7bc5943123c1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -677,7 +677,7 @@ pub(crate) struct DiagMetadata<'ast> { /// The current self item if inside an ADT (used for better errors). current_self_item: Option, - /// The current trait (used to suggest). + /// The current item being evaluated (used for suggestions and more detail in errors). pub(crate) current_item: Option<&'ast Item>, /// When processing generic arguments and encountering an unresolved ident not found, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c7f5ec76c075..6b671df433b3 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -241,7 +241,12 @@ struct BindingError { #[derive(Debug)] enum ResolutionError<'ra> { /// Error E0401: can't use type or const parameters from outer item. - GenericParamsFromOuterItem(Res, HasGenericParams, DefKind, Option<(Span, String)>), + GenericParamsFromOuterItem { + outer_res: Res, + has_generic_params: HasGenericParams, + def_kind: DefKind, + inner_item: Option<(Span, ast::ItemKind)>, + }, /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. NameAlreadyUsedInParameterList(Ident, Span), From f171c41a837120c4ba12c9e1567dd44ad46894ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Nov 2025 20:05:48 +0000 Subject: [PATCH 310/525] Do not suggest adding type param to fn delegation --- compiler/rustc_resolve/src/diagnostics.rs | 12 ++++++++---- tests/ui/delegation/target-expr.stderr | 5 ----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index bc41ffc63c3c..3020ecb6e711 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -576,9 +576,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { sugg: None, static_or_const, is_self, - item: inner_item.map(|(span, kind)| errs::GenericParamsFromOuterItemInnerItem { - span, - descr: kind.descr().to_string(), + item: inner_item.as_ref().map(|(span, kind)| { + errs::GenericParamsFromOuterItemInnerItem { + span: *span, + descr: kind.descr().to_string(), + } }), }; @@ -613,7 +615,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } }; - if let HasGenericParams::Yes(span) = has_generic_params { + if let HasGenericParams::Yes(span) = has_generic_params + && !matches!(inner_item, Some((_, ItemKind::Delegation(..)))) + { let name = self.tcx.item_name(def_id); let (span, snippet) = if span.is_empty() { let snippet = format!("<{name}>"); diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index f2e6c331193f..edd1a584eab2 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -8,11 +8,6 @@ LL | reuse Trait::static_method { LL | LL | let _ = T::Default(); | ^^^^^^^^^^ use of generic parameter from outer item - | -help: try introducing a local generic parameter here - | -LL | reuse Trait::static_methodT, { - | ++ error[E0434]: can't capture dynamic environment in a fn item --> $DIR/target-expr.rs:26:17 From cb0a70558132eb7ea3e240402d0f62b7b852ee22 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Wed, 24 Sep 2025 20:53:11 -0400 Subject: [PATCH 311/525] std_detect: Support run-time detection on OpenBSD using elf_aux_info --- library/std_detect/README.md | 4 +- library/std_detect/src/detect/mod.rs | 5 +- .../src/detect/os/openbsd/auxvec.rs | 54 +++++++++++++++++++ .../std_detect/src/detect/os/openbsd/mod.rs | 21 ++++++++ .../src/detect/os/openbsd/powerpc.rs | 21 ++++++++ library/std_detect/tests/cpu-detection.rs | 7 ++- 6 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 library/std_detect/src/detect/os/openbsd/auxvec.rs create mode 100644 library/std_detect/src/detect/os/openbsd/mod.rs create mode 100644 library/std_detect/src/detect/os/openbsd/powerpc.rs diff --git a/library/std_detect/README.md b/library/std_detect/README.md index edc90d319a1d..177848dec104 100644 --- a/library/std_detect/README.md +++ b/library/std_detect/README.md @@ -66,10 +66,12 @@ crate from working on applications in which `std` is not available. * FreeBSD: * `arm32`, `powerpc64`: `std_detect` supports these on FreeBSD by querying ELF - auxiliary vectors using `sysctl`. + auxiliary vectors using `elf_aux_info`. * `arm64`: run-time feature detection is implemented by directly querying `mrs`. * OpenBSD: + * `powerpc64`: `std_detect` supports these on OpenBSD by querying ELF auxiliary + vectors using `elf_aux_info`. * `arm64`: run-time feature detection is implemented by querying `sysctl`. * Windows: diff --git a/library/std_detect/src/detect/mod.rs b/library/std_detect/src/detect/mod.rs index 2bc6e9a24db9..ae6fb2ab3727 100644 --- a/library/std_detect/src/detect/mod.rs +++ b/library/std_detect/src/detect/mod.rs @@ -61,11 +61,12 @@ cfg_select! { #[path = "os/freebsd/mod.rs"] mod os; } - all(target_os = "openbsd", target_arch = "aarch64", feature = "libc") => { + all(target_os = "openbsd", feature = "libc") => { #[allow(dead_code)] // we don't use code that calls the mrs instruction. + #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] mod aarch64; - #[path = "os/openbsd/aarch64.rs"] + #[path = "os/openbsd/mod.rs"] mod os; } all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")) => { diff --git a/library/std_detect/src/detect/os/openbsd/auxvec.rs b/library/std_detect/src/detect/os/openbsd/auxvec.rs new file mode 100644 index 000000000000..7a1efb2265d4 --- /dev/null +++ b/library/std_detect/src/detect/os/openbsd/auxvec.rs @@ -0,0 +1,54 @@ +//! Parses ELF auxiliary vectors. +#![cfg_attr( + any(target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64"), + allow(dead_code) +)] + +/// Cache HWCAP bitfields of the ELF Auxiliary Vector. +/// +/// If an entry cannot be read all the bits in the bitfield are set to zero. +/// This should be interpreted as all the features being disabled. +#[derive(Debug, Copy, Clone)] +pub(crate) struct AuxVec { + pub hwcap: usize, + pub hwcap2: usize, +} + +/// ELF Auxiliary Vector +/// +/// The auxiliary vector is a memory region in a running ELF program's stack +/// composed of (key: usize, value: usize) pairs. +/// +/// The keys used in the aux vector are platform dependent. For OpenBSD, they are +/// defined in [machine/elf.h][elfh]. The hardware capabilities of a given CPU +/// can be queried with the `AT_HWCAP` and `AT_HWCAP2` keys. +/// +/// Note that run-time feature detection is not invoked for features that can +/// be detected at compile-time. +/// +/// [elf.h]: https://github.com/openbsd/src/blob/master/sys/arch/arm64/include/elf.h +/// [elf.h]: https://github.com/openbsd/src/blob/master/sys/arch/powerpc64/include/elf.h +pub(crate) fn auxv() -> Result { + let hwcap = archauxv(libc::AT_HWCAP); + let hwcap2 = archauxv(libc::AT_HWCAP2); + // Zero could indicate that no features were detected, but it's also used to + // indicate an error. In particular, on many platforms AT_HWCAP2 will be + // legitimately zero, since it contains the most recent feature flags. + if hwcap != 0 || hwcap2 != 0 { + return Ok(AuxVec { hwcap, hwcap2 }); + } + Err(()) +} + +/// Tries to read the `key` from the auxiliary vector. +fn archauxv(key: libc::c_int) -> usize { + const OUT_LEN: libc::c_int = core::mem::size_of::() as libc::c_int; + let mut out: libc::c_ulong = 0; + unsafe { + let res = + libc::elf_aux_info(key, &mut out as *mut libc::c_ulong as *mut libc::c_void, OUT_LEN); + // If elf_aux_info fails, `out` will be left at zero (which is the proper default value). + debug_assert!(res == 0 || out == 0); + } + out as usize +} diff --git a/library/std_detect/src/detect/os/openbsd/mod.rs b/library/std_detect/src/detect/os/openbsd/mod.rs new file mode 100644 index 000000000000..ebfdbd5e6bcf --- /dev/null +++ b/library/std_detect/src/detect/os/openbsd/mod.rs @@ -0,0 +1,21 @@ +//! Run-time feature detection on OpenBSD + +mod auxvec; + +cfg_select! { + target_arch = "aarch64" => { + mod aarch64; + pub(crate) use self::aarch64::detect_features; + } + target_arch = "powerpc64" => { + mod powerpc; + pub(crate) use self::powerpc::detect_features; + } + _ => { + use crate::detect::cache; + /// Performs run-time feature detection. + pub(crate) fn detect_features() -> cache::Initializer { + cache::Initializer::default() + } + } +} diff --git a/library/std_detect/src/detect/os/openbsd/powerpc.rs b/library/std_detect/src/detect/os/openbsd/powerpc.rs new file mode 100644 index 000000000000..dd98ab2a3f76 --- /dev/null +++ b/library/std_detect/src/detect/os/openbsd/powerpc.rs @@ -0,0 +1,21 @@ +//! Run-time feature detection for PowerPC on OpenBSD. + +use super::auxvec; +use crate::detect::{Feature, cache}; + +pub(crate) fn detect_features() -> cache::Initializer { + let mut value = cache::Initializer::default(); + let enable_feature = |value: &mut cache::Initializer, f, enable| { + if enable { + value.set(f as u32); + } + }; + + if let Ok(auxv) = auxvec::auxv() { + enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); + enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); + enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); + return value; + } + value +} diff --git a/library/std_detect/tests/cpu-detection.rs b/library/std_detect/tests/cpu-detection.rs index 0c4fa57f2b46..f46a914aae15 100644 --- a/library/std_detect/tests/cpu-detection.rs +++ b/library/std_detect/tests/cpu-detection.rs @@ -320,8 +320,11 @@ fn powerpc_linux() { } #[test] -#[cfg(all(target_arch = "powerpc64", any(target_os = "linux", target_os = "freebsd"),))] -fn powerpc64_linux_or_freebsd() { +#[cfg(all( + target_arch = "powerpc64", + any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"), +))] +fn powerpc64_linux_or_bsd() { println!("altivec: {}", is_powerpc64_feature_detected!("altivec")); println!("vsx: {}", is_powerpc64_feature_detected!("vsx")); println!("power8: {}", is_powerpc64_feature_detected!("power8")); From 528137f97240dab08ed1da076d2634c114b39ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 18 Jul 2025 22:51:15 +0000 Subject: [PATCH 312/525] Point at non-const trait impl when encountering unmet `[const]` bound When encountering an unmet `Ty: [const] Trait` bound, if `Trait` is `#[const_trait]` and there's an `impl Trait for Ty` point at it. If local, suggest `impl const Trait for Ty`, otherwise just point at it. ``` error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied --> $DIR/assoc-type.rs:37:16 | LL | type Bar = NonConstAdd; | ^^^^^^^^^^^ | note: required by a bound in `Foo::Bar` --> $DIR/assoc-type.rs:33:15 | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` help: make the `impl` of trait `Add` `const` | LL | impl const Add for NonConstAdd { | +++++ ``` ``` error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied --> tests/ui/traits/const-traits/call-generic-method-fail.rs:5:5 | 5 | *t == *t | ^^^^^^^^ | note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/const_ptr.rs:1590:1 | 1590 | impl PartialEq for *const T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/mut_ptr.rs:2011:1 | 2011 | impl PartialEq for *mut T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` --- .../traits/fulfillment_errors.rs | 28 +++++++++++++++++++ tests/ui/consts/const_cmp_type_id.stderr | 3 ++ .../const-traits/assoc-type.current.stderr | 4 +++ .../const-traits/assoc-type.next.stderr | 4 +++ .../const-traits/call-const-closure.stderr | 5 ++++ .../call-const-trait-method-fail.stderr | 5 ++++ .../call-generic-method-fail.stderr | 5 ++++ .../call-generic-method-nonconst.stderr | 4 +++ .../const-closure-trait-method-fail.stderr | 5 ++++ .../const-default-method-bodies.stderr | 5 ++++ .../const-drop-fail-2.precise.stderr | 4 +++ .../const-drop-fail-2.stock.stderr | 4 +++ .../const-traits/const-opaque.no.stderr | 9 ++++++ .../const-traits/cross-crate.gatednc.stderr | 6 ++++ ...-method-body-is-const-body-checking.stderr | 4 +++ ...-method-body-is-const-same-trait-ck.stderr | 5 ++++ .../item-bound-entailment-fails.stderr | 4 +++ .../const-traits/minicore-deref-fail.stderr | 5 ++++ .../const-traits/minicore-fn-fail.stderr | 4 +++ .../no-explicit-const-params.stderr | 5 ++++ .../specializing-constness-2.stderr | 5 ++++ .../const-traits/super-traits-fail.stderr | 5 ++++ 22 files changed, 128 insertions(+) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 03d43977df96..d2f2c92dda08 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -839,6 +839,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) { diag.downgrade_to_delayed_bug(); } + for candidate in self.find_similar_impl_candidates(trait_ref) { + let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue }; + let impl_did = candidate.impl_def_id; + let trait_did = candidate.trait_ref.def_id; + let impl_span = self.tcx.def_span(impl_did); + let trait_name = self.tcx.item_name(trait_did); + + if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) { + if let Some(impl_did) = impl_did.as_local() + && let item = self.tcx.hir_expect_item(impl_did) + && let hir::ItemKind::Impl(item) = item.kind + && let Some(of_trait) = item.of_trait + { + // trait is const, impl is local and not const + diag.span_suggestion_verbose( + of_trait.trait_ref.path.span.shrink_to_lo(), + format!("make the `impl` of trait `{trait_name}` `const`"), + "const ".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + diag.span_note( + impl_span, + format!("trait `{trait_name}` is implemented but not `const`"), + ); + } + } + } diag } diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr index 62a1677c0d93..b991b6af08cc 100644 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `TypeId: const PartialOrd` is not satisfied | LL | let _a = TypeId::of::() < TypeId::of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: trait `PartialOrd` is implemented but not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/assoc-type.current.stderr b/tests/ui/traits/const-traits/assoc-type.current.stderr index 1e58efeedeea..7fe086550f1c 100644 --- a/tests/ui/traits/const-traits/assoc-type.current.stderr +++ b/tests/ui/traits/const-traits/assoc-type.current.stderr @@ -9,6 +9,10 @@ note: required by a bound in `Foo::Bar` | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` +help: make the `impl` of trait `Add` `const` + | +LL | impl const Add for NonConstAdd { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/assoc-type.next.stderr b/tests/ui/traits/const-traits/assoc-type.next.stderr index 1e58efeedeea..7fe086550f1c 100644 --- a/tests/ui/traits/const-traits/assoc-type.next.stderr +++ b/tests/ui/traits/const-traits/assoc-type.next.stderr @@ -9,6 +9,10 @@ note: required by a bound in `Foo::Bar` | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` +help: make the `impl` of trait `Add` `const` + | +LL | impl const Add for NonConstAdd { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-const-closure.stderr b/tests/ui/traits/const-traits/call-const-closure.stderr index 4bb8b2e9777e..9de22759c200 100644 --- a/tests/ui/traits/const-traits/call-const-closure.stderr +++ b/tests/ui/traits/const-traits/call-const-closure.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `(): [const] Bar` is not satisfied | LL | (const || ().foo())(); | ^^^ + | +help: make the `impl` of trait `Bar` `const` + | +LL | impl const Bar for () { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr index 4aaf53344c90..c6f93629379a 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `u32: [const] Plus` is not satisfied | LL | a.plus(b) | ^ + | +help: make the `impl` of trait `Plus` `const` + | +LL | impl const Plus for u32 { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-generic-method-fail.stderr b/tests/ui/traits/const-traits/call-generic-method-fail.stderr index a2fba141f7b8..6e75730b9b51 100644 --- a/tests/ui/traits/const-traits/call-generic-method-fail.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-fail.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied | LL | *t == *t | ^^^^^^^^ + | +note: trait `PartialEq` is implemented but not `const` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: trait `PartialEq` is implemented but not `const` + --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr index 9c1e0fee9e71..b2ec41182a83 100644 --- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr @@ -11,6 +11,10 @@ note: required by a bound in `equals_self` | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^^^ required by this bound in `equals_self` +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for S { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr index fddd8d10bccc..faacc8651244 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `(): const Tr` is not satisfied | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the `impl` of trait `Tr` `const` + | +LL | impl const Tr for () { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr index 03ca6f1d5115..22b6a9b5613a 100644 --- a/tests/ui/traits/const-traits/const-default-method-bodies.stderr +++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `NonConstImpl: [const] ConstDefaultFn` is not sati | LL | NonConstImpl.a(); | ^ + | +help: make the `impl` of trait `ConstDefaultFn` `const` + | +LL | impl const ConstDefaultFn for NonConstImpl { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr index c2309ea6e122..48c8852a7b8d 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr @@ -16,6 +16,10 @@ note: required by a bound in `check` | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^^ required by this bound in `check` +help: make the `impl` of trait `A` `const` + | +LL | impl const A for NonTrivialDrop {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr index c2309ea6e122..48c8852a7b8d 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr @@ -16,6 +16,10 @@ note: required by a bound in `check` | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^^ required by this bound in `check` +help: make the `impl` of trait `A` `const` + | +LL | impl const A for NonTrivialDrop {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr index acf19ba96ab3..591b81f97674 100644 --- a/tests/ui/traits/const-traits/const-opaque.no.stderr +++ b/tests/ui/traits/const-traits/const-opaque.no.stderr @@ -11,12 +11,21 @@ note: required by a bound in `bar` | LL | const fn bar(t: T) -> impl [const] Foo { | ^^^^^^^^^^^ required by this bound in `bar` +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for () { + | +++++ error[E0277]: the trait bound `(): const Foo` is not satisfied --> $DIR/const-opaque.rs:33:12 | LL | opaque.method(); | ^^^^^^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for () { + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr index 1da519151182..fe45ff188efb 100644 --- a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `cross_crate::NonConst: [const] cross_crate::MyTra | LL | NonConst.func(); | ^^^^ + | +note: trait `MyTrait` is implemented but not `const` + --> $DIR/auxiliary/cross-crate.rs:12:1 + | +LL | impl MyTrait for NonConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr index 2e236cecfb47..3ce646ec5027 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr +++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr @@ -9,6 +9,10 @@ note: required by a bound in `foo` | LL | const fn foo() where T: [const] Tr {} | ^^^^^^^^^^ required by this bound in `foo` +help: make the `impl` of trait `Tr` `const` + | +LL | impl const Tr for () {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr index 2dc2d4846174..f473a687efcb 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `(): [const] Tr` is not satisfied | LL | ().a() | ^ + | +help: make the `impl` of trait `Tr` `const` + | +LL | impl const Tr for () {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr index 8e5894a32966..3c150c77a691 100644 --- a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr +++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr @@ -9,6 +9,10 @@ note: required by a bound in `Foo::Assoc` | LL | type Assoc: [const] Bar | ^^^^^^^^^^^ required by this bound in `Foo::Assoc` +help: make the `impl` of trait `Bar` `const` + | +LL | impl const Bar for N where T: Bar {} + | +++++ error[E0277]: the trait bound `T: [const] Bar` is not satisfied --> $DIR/item-bound-entailment-fails.rs:24:21 diff --git a/tests/ui/traits/const-traits/minicore-deref-fail.stderr b/tests/ui/traits/const-traits/minicore-deref-fail.stderr index 4329b235756b..e6c087cb9d82 100644 --- a/tests/ui/traits/const-traits/minicore-deref-fail.stderr +++ b/tests/ui/traits/const-traits/minicore-deref-fail.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `Ty: [const] minicore::Deref` is not satisfied | LL | *Ty; | ^^^ + | +help: make the `impl` of trait `Deref` `const` + | +LL | impl const Deref for Ty { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/minicore-fn-fail.stderr b/tests/ui/traits/const-traits/minicore-fn-fail.stderr index c02a067774b5..eb840d421f48 100644 --- a/tests/ui/traits/const-traits/minicore-fn-fail.stderr +++ b/tests/ui/traits/const-traits/minicore-fn-fail.stderr @@ -11,6 +11,10 @@ note: required by a bound in `call_indirect` | LL | const fn call_indirect(t: &T) { t() } | ^^^^^^^^^^^^ required by this bound in `call_indirect` +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for () {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/no-explicit-const-params.stderr index 6955e9ab2985..47fa65b2479b 100644 --- a/tests/ui/traits/const-traits/no-explicit-const-params.stderr +++ b/tests/ui/traits/const-traits/no-explicit-const-params.stderr @@ -59,6 +59,11 @@ error[E0277]: the trait bound `(): const Bar` is not satisfied | LL | <() as Bar>::bar(); | ^^ + | +help: make the `impl` of trait `Bar` `const` + | +LL | impl const Bar for () { + | +++++ error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr index 850e6939daeb..2a34cd1c4f82 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `T: [const] A` is not satisfied | LL | ::a(); | ^ + | +help: make the `impl` of trait `A` `const` + | +LL | impl const A for T { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr index e19aa30cf95c..3010a5df0c31 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail.stderr @@ -3,6 +3,11 @@ error[E0277]: the trait bound `S: [const] Foo` is not satisfied | LL | impl const Bar for S {} | ^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for S { + | +++++ error: aborting due to 1 previous error From a08bdffb21b0493488da82fd3ad7aa8a6a6128ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jul 2025 00:40:03 +0000 Subject: [PATCH 313/525] Point at non-const trait when using them in const context Point at trait and associated item when that associated item is used in a const context. Suggest making the trait `#[const_trait]`. ``` error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant functions --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:26:8 | LL | ().foo(); | ^^^^^ | note: method `foo` is not const because trait `Trait` is not const --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:13:1 | LL | trait Trait { | ^^^^^^^^^^^ this trait is not const LL | fn foo(self); | ------------- this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Trait` const | LL + #[const_trait] LL | trait Trait { | ``` --- .../rustc_const_eval/src/check_consts/ops.rs | 62 ++++++++++++++++--- tests/ui/asm/non-const.stderr | 5 ++ tests/ui/borrowck/issue-64453.stderr | 2 + tests/ui/consts/const-call.stderr | 5 ++ tests/ui/consts/const-eval/format.stderr | 2 + .../const-extern-fn-call-extern-fn.stderr | 10 +++ .../consts/const-fn-not-safe-for-const.stderr | 5 ++ .../ui/consts/control-flow/issue-46843.stderr | 5 ++ tests/ui/consts/issue-16538.stderr | 5 ++ tests/ui/consts/issue-32829-2.stderr | 15 +++++ tests/ui/consts/issue-43105.stderr | 5 ++ tests/ui/consts/mir_check_nonconst.stderr | 5 ++ tests/ui/error-codes/E0015.stderr | 5 ++ tests/ui/explicit-tail-calls/constck.stderr | 10 +++ tests/ui/resolve/issue-39559-2.stderr | 24 +++++++ .../static-vec-repeat-not-constant.stderr | 5 ++ .../statics/check-values-constraints.stderr | 7 +++ .../const-check-fns-in-const-impl.stderr | 5 ++ ...nline-incorrect-early-bound-in-ctfe.stderr | 12 ++++ .../ui/traits/const-traits/issue-79450.stderr | 2 + .../ui/traits/const-traits/issue-88155.stderr | 12 ++++ .../super-traits-fail-2.nn.stderr | 12 ++++ .../super-traits-fail-2.ny.stderr | 12 ++++ .../super-traits-fail-3.nnn.stderr | 12 ++++ .../super-traits-fail-3.nny.stderr | 12 ++++ .../super-traits-fail-3.ynn.stderr | 12 ++++ .../super-traits-fail-3.yny.stderr | 12 ++++ .../typeck_type_placeholder_item.stderr | 19 ++++++ 28 files changed, 291 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 79e32dcf105c..f2eeaebdae6a 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -1,9 +1,10 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use hir::{ConstContext, LangItem}; -use rustc_errors::Diag; use rustc_errors::codes::*; +use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; @@ -352,13 +353,58 @@ fn build_error_for_const_call<'tcx>( non_or_conditionally, }) } - _ => ccx.dcx().create_err(errors::NonConstFnCall { - span, - def_descr: ccx.tcx.def_descr(callee), - def_path_str: ccx.tcx.def_path_str_with_args(callee, args), - kind: ccx.const_kind(), - non_or_conditionally, - }), + _ => { + let def_descr = ccx.tcx.def_descr(callee); + let mut err = ccx.dcx().create_err(errors::NonConstFnCall { + span, + def_descr, + def_path_str: ccx.tcx.def_path_str_with_args(callee, args), + kind: ccx.const_kind(), + non_or_conditionally, + }); + let def_kind = ccx.tcx.def_kind(callee); + if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn = def_kind { + let parent = ccx.tcx.parent(callee); + if let DefKind::Trait = ccx.tcx.def_kind(parent) + && !ccx.tcx.is_const_trait(parent) + { + let assoc_span = ccx.tcx.def_span(callee); + let assoc_name = ccx.tcx.item_name(callee); + let mut span: MultiSpan = ccx.tcx.def_span(parent).into(); + span.push_span_label(assoc_span, format!("this {def_descr} is not const")); + let trait_descr = ccx.tcx.def_descr(parent); + let trait_span = ccx.tcx.def_span(parent); + let trait_name = ccx.tcx.item_name(parent); + span.push_span_label(trait_span, format!("this {trait_descr} is not const")); + err.span_note( + span, + format!( + "{def_descr} `{assoc_name}` is not const because {trait_descr} \ + `{trait_name}` is not const", + ), + ); + let indentation = ccx + .tcx + .sess + .source_map() + .indentation_before(trait_span) + .unwrap_or_default(); + err.span_suggestion_verbose( + trait_span.shrink_to_lo(), + format!("consider making trait `{trait_name}` const"), + format!("#[const_trait]\n{indentation}"), + Applicability::MachineApplicable, + ); + } + } else if ccx.tcx.constness(callee) != hir::Constness::Const { + let name = ccx.tcx.item_name(callee); + err.span_note( + ccx.tcx.def_span(callee), + format!("{def_descr} `{name}` is not const"), + ); + } + err + } }; err.note(format!( diff --git a/tests/ui/asm/non-const.stderr b/tests/ui/asm/non-const.stderr index eac4fe841bff..d7a901ba20ee 100644 --- a/tests/ui/asm/non-const.stderr +++ b/tests/ui/asm/non-const.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `non_const_fn` in constants LL | global_asm!("/* {} */", const non_const_fn(0)); | ^^^^^^^^^^^^^^^ | +note: function `non_const_fn` is not const + --> $DIR/non-const.rs:8:1 + | +LL | fn non_const_fn(x: i32) -> i32 { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 8ec9a10f09f4..29a7363705cd 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -4,6 +4,8 @@ error[E0015]: cannot call non-const function `format` in statics LL | static settings_dir: String = format!(""); | ^^^^^^^^^^^ | +note: function `format` is not const + --> $SRC_DIR/alloc/src/fmt.rs:LL:COL = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-call.stderr b/tests/ui/consts/const-call.stderr index b9dcf5addb51..cc80f73d0bb6 100644 --- a/tests/ui/consts/const-call.stderr +++ b/tests/ui/consts/const-call.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `f` in constants LL | let _ = [0; f(2)]; | ^^^^ | +note: function `f` is not const + --> $DIR/const-call.rs:1:1 + | +LL | fn f(x: usize) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index bd50ac0bf411..ea191eb5c098 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -21,6 +21,8 @@ error[E0015]: cannot call non-const function `_print` in constant functions LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ | +note: function `_print` is not const + --> $SRC_DIR/std/src/io/stdio.rs:LL:COL = 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) diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr index 1fa881cf42b6..ac0d344d8f48 100644 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr +++ b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `regular_in_block` in constant func LL | regular_in_block(); | ^^^^^^^^^^^^^^^^^^ | +note: function `regular_in_block` is not const + --> $DIR/const-extern-fn-call-extern-fn.rs:2:5 + | +LL | fn regular_in_block(); + | ^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `regular` in constant functions @@ -12,6 +17,11 @@ error[E0015]: cannot call non-const function `regular` in constant functions LL | regular(); | ^^^^^^^^^ | +note: function `regular` is not const + --> $DIR/const-extern-fn-call-extern-fn.rs:12:1 + | +LL | extern "C" fn regular() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index e8f0566e73dd..8fd27df5367e 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `random` in constant functions LL | random() | ^^^^^^^^ | +note: function `random` is not const + --> $DIR/const-fn-not-safe-for-const.rs:5:1 + | +LL | fn random() -> u32 { + | ^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/control-flow/issue-46843.stderr b/tests/ui/consts/control-flow/issue-46843.stderr index 42eb035647c0..46b2a6bf1fd3 100644 --- a/tests/ui/consts/control-flow/issue-46843.stderr +++ b/tests/ui/consts/control-flow/issue-46843.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `non_const` in constants LL | pub const Q: i32 = match non_const() { | ^^^^^^^^^^^ | +note: function `non_const` is not const + --> $DIR/issue-46843.rs:6:1 + | +LL | fn non_const() -> Thing { + | ^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index 8bd11541a7df..fd97b4360a46 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `Y::foo` in statics LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: function `foo` is not const + --> $DIR/issue-16538.rs:6:5 + | +LL | pub fn foo(value: *const X) -> *const X { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr index eedd9d34e550..b201454866ed 100644 --- a/tests/ui/consts/issue-32829-2.stderr +++ b/tests/ui/consts/issue-32829-2.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `invalid` in constants LL | invalid(); | ^^^^^^^^^ | +note: function `invalid` is not const + --> $DIR/issue-32829-2.rs:68:1 + | +LL | fn invalid() {} + | ^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `invalid` in statics @@ -12,6 +17,11 @@ error[E0015]: cannot call non-const function `invalid` in statics LL | invalid(); | ^^^^^^^^^ | +note: function `invalid` is not const + --> $DIR/issue-32829-2.rs:68:1 + | +LL | fn invalid() {} + | ^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` @@ -21,6 +31,11 @@ error[E0015]: cannot call non-const function `invalid` in statics LL | invalid(); | ^^^^^^^^^ | +note: function `invalid` is not const + --> $DIR/issue-32829-2.rs:68:1 + | +LL | fn invalid() {} + | ^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr index c030c0f5fcde..7ec0a2b73afc 100644 --- a/tests/ui/consts/issue-43105.stderr +++ b/tests/ui/consts/issue-43105.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `xyz` in constants LL | const NUM: u8 = xyz(); | ^^^^^ | +note: function `xyz` is not const + --> $DIR/issue-43105.rs:1:1 + | +LL | fn xyz() -> u8 { 42 } + | ^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr index e930fa2103d5..bb0940ee789b 100644 --- a/tests/ui/consts/mir_check_nonconst.stderr +++ b/tests/ui/consts/mir_check_nonconst.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `bar` in statics LL | static foo: Foo = bar(); | ^^^^^ | +note: function `bar` is not const + --> $DIR/mir_check_nonconst.rs:4:1 + | +LL | fn bar() -> Foo { + | ^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/error-codes/E0015.stderr b/tests/ui/error-codes/E0015.stderr index 0c983d284349..bc457aefaecb 100644 --- a/tests/ui/error-codes/E0015.stderr +++ b/tests/ui/error-codes/E0015.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `create_some` in constants LL | const FOO: Option = create_some(); | ^^^^^^^^^^^^^ | +note: function `create_some` is not const + --> $DIR/E0015.rs:1:1 + | +LL | fn create_some() -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/constck.stderr b/tests/ui/explicit-tail-calls/constck.stderr index c223d273b383..2fc2fb7f9338 100644 --- a/tests/ui/explicit-tail-calls/constck.stderr +++ b/tests/ui/explicit-tail-calls/constck.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `not_const` in constant functions LL | become not_const(); | ^^^^^^^^^^^ | +note: function `not_const` is not const + --> $DIR/constck.rs:18:1 + | +LL | fn not_const() {} + | ^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `not_const` in constant functions @@ -12,6 +17,11 @@ error[E0015]: cannot call non-const function `not_const` in constant functions LL | become yes_const(not_const()); | ^^^^^^^^^^^ | +note: function `not_const` is not const + --> $DIR/constck.rs:18:1 + | +LL | fn not_const() {} + | ^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-39559-2.stderr b/tests/ui/resolve/issue-39559-2.stderr index f6e6917d01e6..8b8b68c7c8c3 100644 --- a/tests/ui/resolve/issue-39559-2.stderr +++ b/tests/ui/resolve/issue-39559-2.stderr @@ -4,7 +4,19 @@ error[E0015]: cannot call non-const associated function `::dim` in LL | let array: [usize; Dim3::dim()] | ^^^^^^^^^^^ | +note: associated function `dim` is not const because trait `Dim` is not const + --> $DIR/issue-39559-2.rs:1:1 + | +LL | trait Dim { + | ^^^^^^^^^ this trait is not const +LL | fn dim() -> usize; + | ------------------ this associated function is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Dim` const + | +LL + #[const_trait] +LL | trait Dim { + | error[E0015]: cannot call non-const associated function `::dim` in constants --> $DIR/issue-39559-2.rs:16:15 @@ -12,7 +24,19 @@ error[E0015]: cannot call non-const associated function `::dim` in LL | = [0; Dim3::dim()]; | ^^^^^^^^^^^ | +note: associated function `dim` is not const because trait `Dim` is not const + --> $DIR/issue-39559-2.rs:1:1 + | +LL | trait Dim { + | ^^^^^^^^^ this trait is not const +LL | fn dim() -> usize; + | ------------------ this associated function is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Dim` const + | +LL + #[const_trait] +LL | trait Dim { + | error: aborting due to 2 previous errors diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr index e6ff199ae019..fa4033f6a407 100644 --- a/tests/ui/static/static-vec-repeat-not-constant.stderr +++ b/tests/ui/static/static-vec-repeat-not-constant.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `foo` in statics LL | static a: [isize; 2] = [foo(); 2]; | ^^^^^ | +note: function `foo` is not const + --> $DIR/static-vec-repeat-not-constant.rs:1:1 + | +LL | fn foo() -> isize { 23 } + | ^^^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index eb2d37d297e9..c54f4830533a 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -35,6 +35,13 @@ error[E0015]: cannot call non-const method `::to_string` in sta LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ | +note: method `to_string` is not const because trait `ToString` is not const + --> $SRC_DIR/alloc/src/string.rs:LL:COL + | + = note: this trait is not const + ::: $SRC_DIR/alloc/src/string.rs:LL:COL + | + = note: this method is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr index 599a5503b0f3..1a7ec35f3ddb 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr @@ -4,6 +4,11 @@ error[E0015]: cannot call non-const function `non_const` in constant functions LL | fn foo() { non_const() } | ^^^^^^^^^^^ | +note: function `non_const` is not const + --> $DIR/const-check-fns-in-const-impl.rs:11:1 + | +LL | fn non_const() {} + | ^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr index ad0829ff05fb..ca73ae845550 100644 --- a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr +++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr @@ -13,7 +13,19 @@ error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant func LL | ().foo(); | ^^^^^ | +note: method `foo` is not const because trait `Trait` is not const + --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:13:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ this trait is not const +LL | fn foo(self); + | ------------- this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Trait` const + | +LL + #[const_trait] +LL | trait Trait { + | error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index 5bdebbbfb032..d8a9e1898068 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -4,6 +4,8 @@ error[E0015]: cannot call non-const function `_print` in constant functions LL | println!("lul"); | ^^^^^^^^^^^^^^^ | +note: function `_print` is not const + --> $SRC_DIR/std/src/io/stdio.rs:LL:COL = 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) diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr index 96a3c4187f5c..4a912cc8274a 100644 --- a/tests/ui/traits/const-traits/issue-88155.stderr +++ b/tests/ui/traits/const-traits/issue-88155.stderr @@ -4,7 +4,19 @@ error[E0015]: cannot call non-const associated function `::assoc` in con LL | T::assoc() | ^^^^^^^^^^ | +note: associated function `assoc` is not const because trait `A` is not const + --> $DIR/issue-88155.rs:3:1 + | +LL | pub trait A { + | ^^^^^^^^^^^ this trait is not const +LL | fn assoc() -> bool; + | ------------------- this associated function is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `A` const + | +LL + #[const_trait] +LL | pub trait A { + | error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr index 0ecbad64bc85..c9dc239bef33 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr @@ -51,7 +51,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-2.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index 0e5b697d1dde..bfbf6980ab83 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -63,7 +63,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-2.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index a0ae60526ef3..97e79f28515d 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -94,7 +94,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-3.rs:17:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 9 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index a0ae60526ef3..97e79f28515d 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -94,7 +94,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-3.rs:17:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 9 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr index c8ec77c2f093..5951caebe733 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr @@ -74,7 +74,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-3.rs:17:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 7 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr index a820239cde01..563495204ad7 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr @@ -63,7 +63,19 @@ error[E0015]: cannot call non-const method `::a` in constant functions LL | x.a(); | ^^^ | +note: method `a` is not const because trait `Foo` is not const + --> $DIR/super-traits-fail-3.rs:17:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 6 previous errors diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 240dc1ae8ab9..0b70ac97fd43 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -671,6 +671,11 @@ error[E0015]: cannot call non-const function `map::` in constants LL | const _: Option<_> = map(value); | ^^^^^^^^^^ | +note: function `map` is not const + --> $DIR/typeck_type_placeholder_item.rs:222:1 + | +LL | fn map(_: fn() -> Option<&'static T>) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}>` in constants @@ -679,6 +684,13 @@ error[E0015]: cannot call non-const method ` as Iterator>:: LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^ | +note: method `filter` is not const because trait `Iterator` is not const + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this method is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants @@ -687,6 +699,13 @@ error[E0015]: cannot call non-const method `, {closu LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^ | +note: method `map` is not const because trait `Iterator` is not const + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this method is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors From eb79e68c24ba0156dea9debabbddf7abca8eda6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jul 2025 01:03:00 +0000 Subject: [PATCH 314/525] Only suggest `#[const_trait]` only on local traits --- .../rustc_const_eval/src/check_consts/ops.rs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index f2eeaebdae6a..594ef7a69cc6 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -383,18 +383,20 @@ fn build_error_for_const_call<'tcx>( `{trait_name}` is not const", ), ); - let indentation = ccx - .tcx - .sess - .source_map() - .indentation_before(trait_span) - .unwrap_or_default(); - err.span_suggestion_verbose( - trait_span.shrink_to_lo(), - format!("consider making trait `{trait_name}` const"), - format!("#[const_trait]\n{indentation}"), - Applicability::MachineApplicable, - ); + if parent.is_local() { + let indentation = ccx + .tcx + .sess + .source_map() + .indentation_before(trait_span) + .unwrap_or_default(); + err.span_suggestion_verbose( + trait_span.shrink_to_lo(), + format!("consider making trait `{trait_name}` const"), + format!("#[const_trait]\n{indentation}"), + Applicability::MachineApplicable, + ); + } } } else if ccx.tcx.constness(callee) != hir::Constness::Const { let name = ccx.tcx.item_name(callee); From 9bc814cc8d7219187f1c36957c7efbf12ef8d56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jul 2025 01:23:52 +0000 Subject: [PATCH 315/525] Point at the enclosing const context ``` error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | LL | struct Foo; LL | | LL | | impl Foo { ... | LL | | Foo::<17>::value() | | ^^^^^^^^^^^^^^^^^^ LL | | LL | | }]>; | |_- calls in constants are limited to constant functions, tuple structs and tuple variants ``` --- .../rustc_const_eval/src/check_consts/ops.rs | 18 +++++++--- tests/ui/asm/non-const.stderr | 3 +- tests/ui/borrowck/issue-64453.stderr | 5 +-- .../ui/const-generics/nested-type.full.stderr | 15 ++++++--- .../ui/const-generics/nested-type.min.stderr | 15 ++++++--- tests/ui/consts/const-call.stderr | 3 +- tests/ui/consts/const-eval/format.stderr | 3 +- .../const-extern-fn-call-extern-fn.stderr | 8 +++-- .../consts/const-fn-not-safe-for-const.stderr | 3 +- .../ui/consts/control-flow/issue-46843.stderr | 5 +-- tests/ui/consts/issue-16538.stderr | 5 +-- tests/ui/consts/issue-32829-2.stderr | 12 +++++-- tests/ui/consts/issue-43105.stderr | 5 +-- .../min_const_fn/bad_const_fn_body_ice.stderr | 3 +- tests/ui/consts/mir_check_nonconst.stderr | 5 +-- tests/ui/error-codes/E0010-teach.stderr | 5 +-- tests/ui/error-codes/E0010.stderr | 5 +-- tests/ui/error-codes/E0015.stderr | 5 +-- tests/ui/explicit-tail-calls/constck.stderr | 8 +++-- tests/ui/resolve/issue-39559-2.stderr | 6 ++-- ...lobal-variable-promotion-error-7364.stderr | 5 +-- .../ui/static/static-mut-not-constant.stderr | 5 +-- .../static-vec-repeat-not-constant.stderr | 5 +-- .../statics/check-values-constraints.stderr | 33 ++++++++++++------- .../const-check-fns-in-const-impl.stderr | 5 +-- .../const_derives/derive-const-gate.stderr | 4 +-- .../derive-const-non-const-type.stderr | 4 +-- .../const-traits/cross-crate.stock.stderr | 4 ++- .../const-traits/cross-crate.stocknc.stderr | 9 +++-- ...nline-incorrect-early-bound-in-ctfe.stderr | 3 +- .../ui/traits/const-traits/issue-79450.stderr | 3 +- .../ui/traits/const-traits/issue-88155.stderr | 3 +- .../const-traits/staged-api-user-crate.stderr | 3 +- .../const-traits/std-impl-gate.stock.stderr | 3 +- .../super-traits-fail-2.nn.stderr | 3 +- .../super-traits-fail-2.ny.stderr | 3 +- .../super-traits-fail-3.nnn.stderr | 4 ++- .../super-traits-fail-3.nny.stderr | 4 ++- .../super-traits-fail-3.nyn.stderr | 4 ++- .../super-traits-fail-3.nyy.stderr | 4 ++- .../super-traits-fail-3.ynn.stderr | 4 ++- .../super-traits-fail-3.yny.stderr | 4 ++- .../typeck_type_placeholder_item.stderr | 15 +++++---- 43 files changed, 176 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 594ef7a69cc6..55d29f9c2146 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -212,6 +212,7 @@ fn build_error_for_const_call<'tcx>( debug!(?call_kind); + let mut note = true; let mut err = match call_kind { CallKind::Normal { desugaring: Some((kind, self_ty)), .. } => { macro_rules! error { @@ -362,6 +363,12 @@ fn build_error_for_const_call<'tcx>( kind: ccx.const_kind(), non_or_conditionally, }); + let context_span = ccx.tcx.def_span(ccx.def_id()); + err.span_label(context_span, format!( + "calls in {}s are limited to constant functions, tuple structs and tuple variants", + ccx.const_kind(), + )); + note = false; let def_kind = ccx.tcx.def_kind(callee); if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn = def_kind { let parent = ccx.tcx.parent(callee); @@ -409,11 +416,12 @@ fn build_error_for_const_call<'tcx>( } }; - err.note(format!( - "calls in {}s are limited to constant functions, \ - tuple structs and tuple variants", - ccx.const_kind(), - )); + if note { + err.note(format!( + "calls in {}s are limited to constant functions, tuple structs and tuple variants", + ccx.const_kind(), + )); + } err } diff --git a/tests/ui/asm/non-const.stderr b/tests/ui/asm/non-const.stderr index d7a901ba20ee..da881a12f120 100644 --- a/tests/ui/asm/non-const.stderr +++ b/tests/ui/asm/non-const.stderr @@ -2,14 +2,13 @@ error[E0015]: cannot call non-const function `non_const_fn` in constants --> $DIR/non-const.rs:10:31 | LL | global_asm!("/* {} */", const non_const_fn(0)); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `non_const_fn` is not const --> $DIR/non-const.rs:8:1 | LL | fn non_const_fn(x: i32) -> i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 29a7363705cd..47d908276555 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -2,11 +2,12 @@ error[E0015]: cannot call non-const function `format` in statics --> $DIR/issue-64453.rs:4:31 | LL | static settings_dir: String = format!(""); - | ^^^^^^^^^^^ + | --------------------------- ^^^^^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | note: function `format` is not const --> $SRC_DIR/alloc/src/fmt.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/const-generics/nested-type.full.stderr b/tests/ui/const-generics/nested-type.full.stderr index e5a1f230380d..587de095452d 100644 --- a/tests/ui/const-generics/nested-type.full.stderr +++ b/tests/ui/const-generics/nested-type.full.stderr @@ -1,10 +1,17 @@ error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | -LL | Foo::<17>::value() - | ^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants +LL | struct Foo; +LL | | +LL | | impl Foo { +... | +LL | | Foo::<17>::value() + | | ^^^^^^^^^^^^^^^^^^ +LL | | +LL | | }]>; + | |_- calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index 8282acd4ea7b..e7d21f8a9894 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -1,10 +1,17 @@ error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | -LL | Foo::<17>::value() - | ^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants +LL | struct Foo; +LL | | +LL | | impl Foo { +... | +LL | | Foo::<17>::value() + | | ^^^^^^^^^^^^^^^^^^ +LL | | +LL | | }]>; + | |_- calls in constants are limited to constant functions, tuple structs and tuple variants error: `[u8; { struct Foo; diff --git a/tests/ui/consts/const-call.stderr b/tests/ui/consts/const-call.stderr index cc80f73d0bb6..db375f80b6c6 100644 --- a/tests/ui/consts/const-call.stderr +++ b/tests/ui/consts/const-call.stderr @@ -2,14 +2,13 @@ error[E0015]: cannot call non-const function `f` in constants --> $DIR/const-call.rs:6:17 | LL | let _ = [0; f(2)]; - | ^^^^ + | ^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `f` is not const --> $DIR/const-call.rs:1:1 | LL | fn f(x: usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index ea191eb5c098..97b4436a058e 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -18,12 +18,13 @@ LL | println!("{:?}", 0); error[E0015]: cannot call non-const function `_print` in constant functions --> $DIR/format.rs:7:5 | +LL | const fn print() { + | ---------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ | note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL - = 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[E0015]: cannot call non-const formatting macro in constant functions diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr index ac0d344d8f48..8f07e038e199 100644 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr +++ b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr @@ -1,6 +1,9 @@ error[E0015]: cannot call non-const function `regular_in_block` in constant functions --> $DIR/const-extern-fn-call-extern-fn.rs:7:9 | +LL | const extern "C" fn bar() { + | ------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | unsafe { LL | regular_in_block(); | ^^^^^^^^^^^^^^^^^^ | @@ -9,11 +12,13 @@ note: function `regular_in_block` is not const | LL | fn regular_in_block(); | ^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `regular` in constant functions --> $DIR/const-extern-fn-call-extern-fn.rs:16:9 | +LL | const extern "C" fn foo() { + | ------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | unsafe { LL | regular(); | ^^^^^^^^^ | @@ -22,7 +27,6 @@ note: function `regular` is not const | LL | extern "C" fn regular() {} | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index 8fd27df5367e..068c06601c8b 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -1,6 +1,8 @@ error[E0015]: cannot call non-const function `random` in constant functions --> $DIR/const-fn-not-safe-for-const.rs:14:5 | +LL | const fn sub1() -> u32 { + | ---------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | random() | ^^^^^^^^ | @@ -9,7 +11,6 @@ note: function `random` is not const | LL | fn random() -> u32 { | ^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/control-flow/issue-46843.stderr b/tests/ui/consts/control-flow/issue-46843.stderr index 46b2a6bf1fd3..310c860f59b4 100644 --- a/tests/ui/consts/control-flow/issue-46843.stderr +++ b/tests/ui/consts/control-flow/issue-46843.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `non_const` in constants --> $DIR/issue-46843.rs:10:26 | LL | pub const Q: i32 = match non_const() { - | ^^^^^^^^^^^ + | ---------------- ^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `non_const` is not const --> $DIR/issue-46843.rs:6:1 | LL | fn non_const() -> Thing { | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index fd97b4360a46..e78d95dcd186 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `Y::foo` in statics --> $DIR/issue-16538.rs:11:23 | LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | note: function `foo` is not const --> $DIR/issue-16538.rs:6:5 | LL | pub fn foo(value: *const X) -> *const X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr index b201454866ed..52398af41eee 100644 --- a/tests/ui/consts/issue-32829-2.stderr +++ b/tests/ui/consts/issue-32829-2.stderr @@ -1,6 +1,9 @@ error[E0015]: cannot call non-const function `invalid` in constants --> $DIR/issue-32829-2.rs:10:9 | +LL | const bad_two : u32 = { + | ------------------- calls in constants are limited to constant functions, tuple structs and tuple variants +LL | { LL | invalid(); | ^^^^^^^^^ | @@ -9,11 +12,13 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `invalid` in statics --> $DIR/issue-32829-2.rs:32:9 | +LL | static bad_five : u32 = { + | --------------------- calls in statics are limited to constant functions, tuple structs and tuple variants +LL | { LL | invalid(); | ^^^^^^^^^ | @@ -22,12 +27,14 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0015]: cannot call non-const function `invalid` in statics --> $DIR/issue-32829-2.rs:54:9 | +LL | static mut bad_eight : u32 = { + | -------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants +LL | { LL | invalid(); | ^^^^^^^^^ | @@ -36,7 +43,6 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr index 7ec0a2b73afc..442fbdd107fa 100644 --- a/tests/ui/consts/issue-43105.stderr +++ b/tests/ui/consts/issue-43105.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `xyz` in constants --> $DIR/issue-43105.rs:3:17 | LL | const NUM: u8 = xyz(); - | ^^^^^ + | ------------- ^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `xyz` is not const --> $DIR/issue-43105.rs:1:1 | LL | fn xyz() -> u8 { 42 } | ^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index 8e52a7aa35e1..c65abc530bc2 100644 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -9,10 +9,11 @@ LL | vec![1, 2, 3] error[E0015]: cannot call non-const method `slice::::into_vec::` in constant functions --> $DIR/bad_const_fn_body_ice.rs:2:5 | +LL | const fn foo(a: i32) -> Vec { + | -------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | vec![1, 2, 3] | ^^^^^^^^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr index bb0940ee789b..ad2056a73707 100644 --- a/tests/ui/consts/mir_check_nonconst.stderr +++ b/tests/ui/consts/mir_check_nonconst.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `bar` in statics --> $DIR/mir_check_nonconst.rs:8:19 | LL | static foo: Foo = bar(); - | ^^^^^ + | --------------- ^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | note: function `bar` is not const --> $DIR/mir_check_nonconst.rs:4:1 | LL | fn bar() -> Foo { | ^^^^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0010-teach.stderr b/tests/ui/error-codes/E0010-teach.stderr index 82bbe01aef79..237efbefcf6e 100644 --- a/tests/ui/error-codes/E0010-teach.stderr +++ b/tests/ui/error-codes/E0010-teach.stderr @@ -11,9 +11,10 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/E0010-teach.rs:5:23 | LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ + | ------------------- ^^^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0010.stderr b/tests/ui/error-codes/E0010.stderr index 87b722b5f656..2bb87118d242 100644 --- a/tests/ui/error-codes/E0010.stderr +++ b/tests/ui/error-codes/E0010.stderr @@ -10,9 +10,10 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/E0010.rs:3:23 | LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ + | ------------------- ^^^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0015.stderr b/tests/ui/error-codes/E0015.stderr index bc457aefaecb..4331d7c34b3c 100644 --- a/tests/ui/error-codes/E0015.stderr +++ b/tests/ui/error-codes/E0015.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `create_some` in constants --> $DIR/E0015.rs:5:25 | LL | const FOO: Option = create_some(); - | ^^^^^^^^^^^^^ + | --------------------- ^^^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `create_some` is not const --> $DIR/E0015.rs:1:1 | LL | fn create_some() -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/constck.stderr b/tests/ui/explicit-tail-calls/constck.stderr index 2fc2fb7f9338..84d7bc3a1bf1 100644 --- a/tests/ui/explicit-tail-calls/constck.stderr +++ b/tests/ui/explicit-tail-calls/constck.stderr @@ -1,6 +1,9 @@ error[E0015]: cannot call non-const function `not_const` in constant functions --> $DIR/constck.rs:6:16 | +LL | const fn f() { + | ------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | if false { LL | become not_const(); | ^^^^^^^^^^^ | @@ -9,11 +12,13 @@ note: function `not_const` is not const | LL | fn not_const() {} | ^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `not_const` in constant functions --> $DIR/constck.rs:13:26 | +LL | const fn g((): ()) { + | ------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | if false { LL | become yes_const(not_const()); | ^^^^^^^^^^^ | @@ -22,7 +27,6 @@ note: function `not_const` is not const | LL | fn not_const() {} | ^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-39559-2.stderr b/tests/ui/resolve/issue-39559-2.stderr index 8b8b68c7c8c3..8c19fb23d8e9 100644 --- a/tests/ui/resolve/issue-39559-2.stderr +++ b/tests/ui/resolve/issue-39559-2.stderr @@ -2,7 +2,7 @@ error[E0015]: cannot call non-const associated function `::dim` in --> $DIR/issue-39559-2.rs:14:24 | LL | let array: [usize; Dim3::dim()] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants | note: associated function `dim` is not const because trait `Dim` is not const --> $DIR/issue-39559-2.rs:1:1 @@ -11,7 +11,6 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const - = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | LL + #[const_trait] @@ -22,7 +21,7 @@ error[E0015]: cannot call non-const associated function `::dim` in --> $DIR/issue-39559-2.rs:16:15 | LL | = [0; Dim3::dim()]; - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants | note: associated function `dim` is not const because trait `Dim` is not const --> $DIR/issue-39559-2.rs:1:1 @@ -31,7 +30,6 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const - = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | LL + #[const_trait] diff --git a/tests/ui/static/global-variable-promotion-error-7364.stderr b/tests/ui/static/global-variable-promotion-error-7364.stderr index b9d75676bef8..bced8c152020 100644 --- a/tests/ui/static/global-variable-promotion-error-7364.stderr +++ b/tests/ui/static/global-variable-promotion-error-7364.stderr @@ -15,9 +15,10 @@ error[E0015]: cannot call non-const associated function `Box::>:: --> $DIR/global-variable-promotion-error-7364.rs:5:37 | LL | static boxed: Box> = Box::new(RefCell::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | --------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 2 previous errors diff --git a/tests/ui/static/static-mut-not-constant.stderr b/tests/ui/static/static-mut-not-constant.stderr index f28ea0b1689a..7e64d36b26d1 100644 --- a/tests/ui/static/static-mut-not-constant.stderr +++ b/tests/ui/static/static-mut-not-constant.stderr @@ -2,9 +2,10 @@ error[E0015]: cannot call non-const associated function `Box::::new` in s --> $DIR/static-mut-not-constant.rs:1:28 | LL | static mut a: Box = Box::new(3); - | ^^^^^^^^^^^ + | ------------------------ ^^^^^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr index fa4033f6a407..24f0986ccc49 100644 --- a/tests/ui/static/static-vec-repeat-not-constant.stderr +++ b/tests/ui/static/static-vec-repeat-not-constant.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `foo` in statics --> $DIR/static-vec-repeat-not-constant.rs:3:25 | LL | static a: [isize; 2] = [foo(); 2]; - | ^^^^^ + | -------------------- ^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | note: function `foo` is not const --> $DIR/static-vec-repeat-not-constant.rs:1:1 | LL | fn foo() -> isize { 23 } | ^^^^^^^^^^^^^^^^^ - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index c54f4830533a..dfbb1f6e985c 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -23,15 +23,19 @@ error[E0015]: cannot call non-const method `slice::::into_vec::< --> $DIR/check-values-constraints.rs:81:33 | LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ + | ----------------------------- ^^^^^^^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const method `::to_string` in statics --> $DIR/check-values-constraints.rs:92:38 | +LL | static mut STATIC14: SafeStruct = SafeStruct { + | ------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants +LL | field1: SafeEnum::Variant1, LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ | @@ -42,7 +46,6 @@ note: method `to_string` is not const because trait `ToString` is not const ::: $SRC_DIR/alloc/src/string.rs:LL:COL | = note: this method is not const - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0010]: allocations are not allowed in statics @@ -56,10 +59,11 @@ LL | vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:96:5 | +LL | static STATIC15: &'static [Vec] = &[ + | ---------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants LL | vec![MyOwned], | ^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -74,10 +78,12 @@ LL | vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:98:5 | +LL | static STATIC15: &'static [Vec] = &[ + | ---------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants +... LL | vec![MyOwned], | ^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -92,10 +98,11 @@ LL | &vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:103:6 | +LL | static STATIC16: (&'static Vec, &'static Vec) = ( + | --------------------------------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -110,10 +117,12 @@ LL | &vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:105:6 | +LL | static STATIC16: (&'static Vec, &'static Vec) = ( + | --------------------------------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants +... LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -129,9 +138,10 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/check-values-constraints.rs:111:31 | LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ + | --------------------------- ^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -147,9 +157,10 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/check-values-constraints.rs:117:32 | LL | static x: Vec = vec![3]; - | ^^^^^^^ + | -------------------- ^^^^^^^ + | | + | calls in statics are limited to constant functions, tuple structs and tuple variants | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr index 1a7ec35f3ddb..70704780ddce 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr @@ -2,14 +2,15 @@ error[E0015]: cannot call non-const function `non_const` in constant functions --> $DIR/const-check-fns-in-const-impl.rs:14:16 | LL | fn foo() { non_const() } - | ^^^^^^^^^^^ + | -------- ^^^^^^^^^^^ + | | + | calls in constant functions are limited to constant functions, tuple structs and tuple variants | note: function `non_const` is not const --> $DIR/const-check-fns-in-const-impl.rs:11:1 | LL | fn non_const() {} | ^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr index cbc62d602a47..ac393825ec72 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr @@ -21,9 +21,7 @@ error[E0015]: cannot call non-const method `Formatter::<'_>::write_str` in const --> $DIR/derive-const-gate.rs:1:16 | LL | #[derive_const(Debug)] - | ^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^ calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 3 previous errors diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index 93638801895d..9f620fcf81b7 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -11,9 +11,7 @@ error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_ --> $DIR/derive-const-non-const-type.rs:12:16 | LL | #[derive_const(Debug)] - | ^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^ calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr index 44a60c99ae9e..89278ff56ad0 100644 --- a/tests/ui/traits/const-traits/cross-crate.stock.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr @@ -1,10 +1,12 @@ error[E0658]: cannot call conditionally-const method `::func` in constant functions --> $DIR/cross-crate.rs:22:11 | +LL | const fn const_context() { + | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | Const.func(); | ^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index 766c20aa8211..6269e74fd1d2 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -1,18 +1,21 @@ error[E0015]: cannot call non-const method `::func` in constant functions --> $DIR/cross-crate.rs:19:14 | +LL | const fn const_context() { + | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | #[cfg(any(stocknc, gatednc))] LL | NonConst.func(); | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0658]: cannot call conditionally-const method `::func` in constant functions --> $DIR/cross-crate.rs:22:11 | +LL | const fn const_context() { + | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | Const.func(); | ^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr index ca73ae845550..092a5ac05b82 100644 --- a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr +++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr @@ -10,6 +10,8 @@ LL | fn foo(self) { error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant functions --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:26:8 | +LL | const fn foo() { + | -------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | ().foo(); | ^^^^^ | @@ -20,7 +22,6 @@ LL | trait Trait { | ^^^^^^^^^^^ this trait is not const LL | fn foo(self); | ------------- this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Trait` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index d8a9e1898068..dd78b464e782 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -1,12 +1,13 @@ error[E0015]: cannot call non-const function `_print` in constant functions --> $DIR/issue-79450.rs:9:9 | +LL | fn prov(&self) { + | -------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | println!("lul"); | ^^^^^^^^^^^^^^^ | note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL - = 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 diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr index 4a912cc8274a..2df4a0004b6a 100644 --- a/tests/ui/traits/const-traits/issue-88155.stderr +++ b/tests/ui/traits/const-traits/issue-88155.stderr @@ -1,6 +1,8 @@ error[E0015]: cannot call non-const associated function `::assoc` in constant functions --> $DIR/issue-88155.rs:8:5 | +LL | pub const fn foo() -> bool { + | -------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | T::assoc() | ^^^^^^^^^^ | @@ -11,7 +13,6 @@ LL | pub trait A { | ^^^^^^^^^^^ this trait is not const LL | fn assoc() -> bool; | ------------------- this associated function is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `A` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr index 81611da9e748..1baa8b308284 100644 --- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr +++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr @@ -1,10 +1,11 @@ error[E0658]: cannot call conditionally-const associated function `::func` in constant functions --> $DIR/staged-api-user-crate.rs:12:5 | +LL | const fn stable_const_context() { + | ------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr index 261f68bebdb2..3f40f602eefe 100644 --- a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr +++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr @@ -1,10 +1,11 @@ error[E0658]: cannot call conditionally-const associated function ` as Default>::default` in constant functions --> $DIR/std-impl-gate.rs:13:5 | +LL | const fn const_context() -> Vec { + | -------------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | Default::default() | ^^^^^^^^^^^^^^^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr index c9dc239bef33..84fc743e4a2b 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr @@ -48,6 +48,8 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-2.rs:20:7 | +LL | const fn foo(x: &T) { + | --------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -58,7 +60,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index bfbf6980ab83..9d72e149aab2 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -60,6 +60,8 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-2.rs:20:7 | +LL | const fn foo(x: &T) { + | --------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -70,7 +72,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index 97e79f28515d..8a35dd966425 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -91,6 +91,9 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | @@ -101,7 +104,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index 97e79f28515d..8a35dd966425 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -91,6 +91,9 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | @@ -101,7 +104,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr index b00ad706a5fa..155263656e36 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr @@ -41,10 +41,12 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] error[E0658]: cannot call conditionally-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr index b00ad706a5fa..155263656e36 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr @@ -41,10 +41,12 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] error[E0658]: cannot call conditionally-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr index 5951caebe733..4895b5b0cd08 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr @@ -71,6 +71,9 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | @@ -81,7 +84,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr index 563495204ad7..29bce84326ca 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr @@ -60,6 +60,9 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | +LL | const fn foo(x: &T) { + | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants +... LL | x.a(); | ^^^ | @@ -70,7 +73,6 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b70ac97fd43..0b0f9fbb9be1 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -669,20 +669,23 @@ error[E0015]: cannot call non-const function `map::` in constants --> $DIR/typeck_type_placeholder_item.rs:231:22 | LL | const _: Option<_> = map(value); - | ^^^^^^^^^^ + | ------------------ ^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: function `map` is not const --> $DIR/typeck_type_placeholder_item.rs:222:1 | LL | fn map(_: fn() -> Option<&'static T>) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}>` in constants --> $DIR/typeck_type_placeholder_item.rs:240:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ---------- ^^^^^^^^^^^^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: method `filter` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -691,13 +694,14 @@ note: method `filter` is not const because trait `Iterator` is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants --> $DIR/typeck_type_placeholder_item.rs:240:45 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^ + | ---------- ^^^^^^^^^^^^^^ + | | + | calls in constants are limited to constant functions, tuple structs and tuple variants | note: method `map` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -706,7 +710,6 @@ note: method `map` is not const because trait `Iterator` is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors From bf45da7e517b248d47a2fc08fa3dc42855227a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jul 2025 21:42:15 +0000 Subject: [PATCH 316/525] Account for `#![feature(const_trait_impl)]` state --- .../rustc_const_eval/src/check_consts/ops.rs | 10 +++++++++- .../const-super-trait-nightly-disabled.stderr | 16 +++++++++++++++- .../const-super-trait-nightly-enabled.stderr | 15 ++++++++++++++- .../const-super-trait-stable-disabled.stderr | 11 ++++++++++- .../const-super-trait-stable-enabled.stderr | 11 ++++++++++- tests/ui/resolve/issue-39559-2.stderr | 2 ++ .../const-traits/super-traits-fail-3.nnn.stderr | 1 + .../const-traits/super-traits-fail-3.nny.stderr | 1 + 8 files changed, 62 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 55d29f9c2146..c958a91f754b 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -390,7 +390,13 @@ fn build_error_for_const_call<'tcx>( `{trait_name}` is not const", ), ); - if parent.is_local() { + if parent.is_local() && ccx.tcx.sess.is_nightly_build() { + if !ccx.tcx.features().const_trait_impl() { + err.help( + "add `#![feature(const_trait_impl)]` to the crate attributes to \ + enable `#[const_trait]`", + ); + } let indentation = ccx .tcx .sess @@ -403,6 +409,8 @@ fn build_error_for_const_call<'tcx>( format!("#[const_trait]\n{indentation}"), Applicability::MachineApplicable, ); + } else if !ccx.tcx.sess.is_nightly_build() { + err.help("const traits are not yet supported on stable Rust"); } } } else if ccx.tcx.constness(callee) != hir::Constness::Const { diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr index 895558f3b0fc..47f6817b9b64 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr @@ -55,10 +55,24 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | +LL | const fn foo(x: &T) { + | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +note: method `a` is not const because trait `Foo` is not const + --> const-super-trait.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 6 previous errors diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr index 821ab6fa57cd..49e2f98c371f 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr @@ -35,10 +35,23 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | +LL | const fn foo(x: &T) { + | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +note: method `a` is not const because trait `Foo` is not const + --> const-super-trait.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ this trait is not const +LL | fn a(&self); + | ------------ this method is not const +help: consider making trait `Foo` const + | +LL + #[const_trait] +LL | trait Foo { + | error: aborting due to 4 previous errors diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr index b39be78e4384..62fd9a38b759 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr @@ -53,10 +53,19 @@ note: `Bar` can't be used with `[const]` because it isn't `const` error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | +9 | const fn foo(x: &T) { + | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants 10 | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +note: method `a` is not const because trait `Foo` is not const + --> const-super-trait.rs:3:1 + | +3 | trait Foo { + | ^^^^^^^^^ this trait is not const +4 | fn a(&self); + | ------------ this method is not const + = help: const traits are not yet supported on stable Rust error: aborting due to 6 previous errors diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr index 30ee5cf6f4b0..fc1adbe441ce 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr @@ -43,10 +43,19 @@ note: `Bar` can't be used with `[const]` because it isn't `const` error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | +9 | const fn foo(x: &T) { + | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants 10 | x.a(); | ^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +note: method `a` is not const because trait `Foo` is not const + --> const-super-trait.rs:3:1 + | +3 | trait Foo { + | ^^^^^^^^^ this trait is not const +4 | fn a(&self); + | ------------ this method is not const + = help: const traits are not yet supported on stable Rust error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/issue-39559-2.stderr b/tests/ui/resolve/issue-39559-2.stderr index 8c19fb23d8e9..fbbcaa663ae0 100644 --- a/tests/ui/resolve/issue-39559-2.stderr +++ b/tests/ui/resolve/issue-39559-2.stderr @@ -11,6 +11,7 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` help: consider making trait `Dim` const | LL + #[const_trait] @@ -30,6 +31,7 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` help: consider making trait `Dim` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index 8a35dd966425..2625f9446061 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -104,6 +104,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index 8a35dd966425..2625f9446061 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -104,6 +104,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` help: consider making trait `Foo` const | LL + #[const_trait] From a2c3913007fa77728464b9d37d827e013f127f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 23 Jul 2025 18:46:03 +0000 Subject: [PATCH 317/525] review comments --- .../rustc_const_eval/src/check_consts/ops.rs | 31 ++++++----------- .../const-super-trait-nightly-disabled.stderr | 3 +- .../const-super-trait-nightly-enabled.stderr | 3 +- .../const-super-trait-stable-disabled.stderr | 3 +- .../const-super-trait-stable-enabled.stderr | 3 +- tests/ui/asm/non-const.stderr | 3 +- tests/ui/borrowck/issue-64453.stderr | 5 ++- .../ui/const-generics/nested-type.full.stderr | 15 +++------ .../ui/const-generics/nested-type.min.stderr | 15 +++------ tests/ui/consts/const-call.stderr | 3 +- tests/ui/consts/const-eval/format.stderr | 3 +- .../const-extern-fn-call-extern-fn.stderr | 8 ++--- .../consts/const-fn-not-safe-for-const.stderr | 3 +- .../ui/consts/control-flow/issue-46843.stderr | 5 ++- tests/ui/consts/issue-16538.stderr | 5 ++- tests/ui/consts/issue-32829-2.stderr | 12 ++----- tests/ui/consts/issue-43105.stderr | 5 ++- .../min_const_fn/bad_const_fn_body_ice.stderr | 3 +- tests/ui/consts/mir_check_nonconst.stderr | 5 ++- tests/ui/error-codes/E0010-teach.stderr | 5 ++- tests/ui/error-codes/E0010.stderr | 5 ++- tests/ui/error-codes/E0015.stderr | 5 ++- tests/ui/explicit-tail-calls/constck.stderr | 8 ++--- tests/ui/resolve/issue-39559-2.stderr | 6 ++-- ...lobal-variable-promotion-error-7364.stderr | 5 ++- .../ui/static/static-mut-not-constant.stderr | 5 ++- .../static-vec-repeat-not-constant.stderr | 5 ++- .../statics/check-values-constraints.stderr | 33 +++++++------------ .../const-check-fns-in-const-impl.stderr | 5 ++- .../const_derives/derive-const-gate.stderr | 4 ++- .../derive-const-non-const-type.stderr | 4 ++- .../const-traits/cross-crate.stock.stderr | 4 +-- .../const-traits/cross-crate.stocknc.stderr | 9 ++--- ...nline-incorrect-early-bound-in-ctfe.stderr | 3 +- .../ui/traits/const-traits/issue-79450.stderr | 3 +- .../ui/traits/const-traits/issue-88155.stderr | 3 +- .../const-traits/staged-api-user-crate.stderr | 3 +- .../const-traits/std-impl-gate.stock.stderr | 3 +- .../super-traits-fail-2.nn.stderr | 3 +- .../super-traits-fail-2.ny.stderr | 3 +- .../super-traits-fail-3.nnn.stderr | 4 +-- .../super-traits-fail-3.nny.stderr | 4 +-- .../super-traits-fail-3.nyn.stderr | 4 +-- .../super-traits-fail-3.nyy.stderr | 4 +-- .../super-traits-fail-3.ynn.stderr | 4 +-- .../super-traits-fail-3.yny.stderr | 4 +-- .../typeck_type_placeholder_item.stderr | 15 ++++----- 47 files changed, 104 insertions(+), 192 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index c958a91f754b..ecb58059600d 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -4,7 +4,6 @@ use hir::{ConstContext, LangItem}; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; @@ -12,8 +11,8 @@ use rustc_middle::mir::CallSource; use rustc_middle::span_bug; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, - suggest_constraining_type_param, + self, AssocItemContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, + TraitRef, Ty, suggest_constraining_type_param, }; use rustc_session::parse::add_feature_diagnostics; use rustc_span::{BytePos, Pos, Span, Symbol, sym}; @@ -212,7 +211,6 @@ fn build_error_for_const_call<'tcx>( debug!(?call_kind); - let mut note = true; let mut err = match call_kind { CallKind::Normal { desugaring: Some((kind, self_ty)), .. } => { macro_rules! error { @@ -363,16 +361,9 @@ fn build_error_for_const_call<'tcx>( kind: ccx.const_kind(), non_or_conditionally, }); - let context_span = ccx.tcx.def_span(ccx.def_id()); - err.span_label(context_span, format!( - "calls in {}s are limited to constant functions, tuple structs and tuple variants", - ccx.const_kind(), - )); - note = false; - let def_kind = ccx.tcx.def_kind(callee); - if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn = def_kind { - let parent = ccx.tcx.parent(callee); - if let DefKind::Trait = ccx.tcx.def_kind(parent) + if let Some(item) = ccx.tcx.opt_associated_item(callee) { + if let AssocItemContainer::Trait = item.container + && let parent = item.container_id(ccx.tcx) && !ccx.tcx.is_const_trait(parent) { let assoc_span = ccx.tcx.def_span(callee); @@ -407,7 +398,7 @@ fn build_error_for_const_call<'tcx>( trait_span.shrink_to_lo(), format!("consider making trait `{trait_name}` const"), format!("#[const_trait]\n{indentation}"), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } else if !ccx.tcx.sess.is_nightly_build() { err.help("const traits are not yet supported on stable Rust"); @@ -424,12 +415,10 @@ fn build_error_for_const_call<'tcx>( } }; - if note { - err.note(format!( - "calls in {}s are limited to constant functions, tuple structs and tuple variants", - ccx.const_kind(), - )); - } + err.note(format!( + "calls in {}s are limited to constant functions, tuple structs and tuple variants", + ccx.const_kind(), + )); err } diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr index 47f6817b9b64..646688604674 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr @@ -55,8 +55,6 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | -LL | const fn foo(x: &T) { - | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -68,6 +66,7 @@ LL | trait Foo { LL | fn a(&self); | ------------ this method is not const = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr index 49e2f98c371f..d0e7edf42cdd 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr @@ -35,8 +35,6 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | -LL | const fn foo(x: &T) { - | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -47,6 +45,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr index 62fd9a38b759..e09539684953 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr @@ -53,8 +53,6 @@ note: `Bar` can't be used with `[const]` because it isn't `const` error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | -9 | const fn foo(x: &T) { - | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants 10 | x.a(); | ^^^ | @@ -66,6 +64,7 @@ note: method `a` is not const because trait `Foo` is not const 4 | fn a(&self); | ------------ this method is not const = help: const traits are not yet supported on stable Rust + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 6 previous errors diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr index fc1adbe441ce..9da10eb81d83 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr @@ -43,8 +43,6 @@ note: `Bar` can't be used with `[const]` because it isn't `const` error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 | -9 | const fn foo(x: &T) { - | ---------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants 10 | x.a(); | ^^^ | @@ -56,6 +54,7 @@ note: method `a` is not const because trait `Foo` is not const 4 | fn a(&self); | ------------ this method is not const = help: const traits are not yet supported on stable Rust + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 5 previous errors diff --git a/tests/ui/asm/non-const.stderr b/tests/ui/asm/non-const.stderr index da881a12f120..d7a901ba20ee 100644 --- a/tests/ui/asm/non-const.stderr +++ b/tests/ui/asm/non-const.stderr @@ -2,13 +2,14 @@ error[E0015]: cannot call non-const function `non_const_fn` in constants --> $DIR/non-const.rs:10:31 | LL | global_asm!("/* {} */", const non_const_fn(0)); - | ^^^^^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^^ | note: function `non_const_fn` is not const --> $DIR/non-const.rs:8:1 | LL | fn non_const_fn(x: i32) -> i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 47d908276555..29a7363705cd 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -2,12 +2,11 @@ error[E0015]: cannot call non-const function `format` in statics --> $DIR/issue-64453.rs:4:31 | LL | static settings_dir: String = format!(""); - | --------------------------- ^^^^^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | note: function `format` is not const --> $SRC_DIR/alloc/src/fmt.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/const-generics/nested-type.full.stderr b/tests/ui/const-generics/nested-type.full.stderr index 587de095452d..e5a1f230380d 100644 --- a/tests/ui/const-generics/nested-type.full.stderr +++ b/tests/ui/const-generics/nested-type.full.stderr @@ -1,17 +1,10 @@ error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | -LL | struct Foo; -LL | | -LL | | impl Foo { -... | -LL | | Foo::<17>::value() - | | ^^^^^^^^^^^^^^^^^^ -LL | | -LL | | }]>; - | |_- calls in constants are limited to constant functions, tuple structs and tuple variants +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index e7d21f8a9894..8282acd4ea7b 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -1,17 +1,10 @@ error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | -LL | struct Foo; -LL | | -LL | | impl Foo { -... | -LL | | Foo::<17>::value() - | | ^^^^^^^^^^^^^^^^^^ -LL | | -LL | | }]>; - | |_- calls in constants are limited to constant functions, tuple structs and tuple variants +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: `[u8; { struct Foo; diff --git a/tests/ui/consts/const-call.stderr b/tests/ui/consts/const-call.stderr index db375f80b6c6..cc80f73d0bb6 100644 --- a/tests/ui/consts/const-call.stderr +++ b/tests/ui/consts/const-call.stderr @@ -2,13 +2,14 @@ error[E0015]: cannot call non-const function `f` in constants --> $DIR/const-call.rs:6:17 | LL | let _ = [0; f(2)]; - | ^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^ | note: function `f` is not const --> $DIR/const-call.rs:1:1 | LL | fn f(x: usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 97b4436a058e..ea191eb5c098 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -18,13 +18,12 @@ LL | println!("{:?}", 0); error[E0015]: cannot call non-const function `_print` in constant functions --> $DIR/format.rs:7:5 | -LL | const fn print() { - | ---------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ | note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL + = 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[E0015]: cannot call non-const formatting macro in constant functions diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr index 8f07e038e199..ac0d344d8f48 100644 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr +++ b/tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr @@ -1,9 +1,6 @@ error[E0015]: cannot call non-const function `regular_in_block` in constant functions --> $DIR/const-extern-fn-call-extern-fn.rs:7:9 | -LL | const extern "C" fn bar() { - | ------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -LL | unsafe { LL | regular_in_block(); | ^^^^^^^^^^^^^^^^^^ | @@ -12,13 +9,11 @@ note: function `regular_in_block` is not const | LL | fn regular_in_block(); | ^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `regular` in constant functions --> $DIR/const-extern-fn-call-extern-fn.rs:16:9 | -LL | const extern "C" fn foo() { - | ------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -LL | unsafe { LL | regular(); | ^^^^^^^^^ | @@ -27,6 +22,7 @@ note: function `regular` is not const | LL | extern "C" fn regular() {} | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index 068c06601c8b..8fd27df5367e 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -1,8 +1,6 @@ error[E0015]: cannot call non-const function `random` in constant functions --> $DIR/const-fn-not-safe-for-const.rs:14:5 | -LL | const fn sub1() -> u32 { - | ---------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | random() | ^^^^^^^^ | @@ -11,6 +9,7 @@ note: function `random` is not const | LL | fn random() -> u32 { | ^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/control-flow/issue-46843.stderr b/tests/ui/consts/control-flow/issue-46843.stderr index 310c860f59b4..46b2a6bf1fd3 100644 --- a/tests/ui/consts/control-flow/issue-46843.stderr +++ b/tests/ui/consts/control-flow/issue-46843.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `non_const` in constants --> $DIR/issue-46843.rs:10:26 | LL | pub const Q: i32 = match non_const() { - | ---------------- ^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | note: function `non_const` is not const --> $DIR/issue-46843.rs:6:1 | LL | fn non_const() -> Thing { | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index e78d95dcd186..fd97b4360a46 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `Y::foo` in statics --> $DIR/issue-16538.rs:11:23 | LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); - | ----------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: function `foo` is not const --> $DIR/issue-16538.rs:6:5 | LL | pub fn foo(value: *const X) -> *const X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr index 52398af41eee..b201454866ed 100644 --- a/tests/ui/consts/issue-32829-2.stderr +++ b/tests/ui/consts/issue-32829-2.stderr @@ -1,9 +1,6 @@ error[E0015]: cannot call non-const function `invalid` in constants --> $DIR/issue-32829-2.rs:10:9 | -LL | const bad_two : u32 = { - | ------------------- calls in constants are limited to constant functions, tuple structs and tuple variants -LL | { LL | invalid(); | ^^^^^^^^^ | @@ -12,13 +9,11 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `invalid` in statics --> $DIR/issue-32829-2.rs:32:9 | -LL | static bad_five : u32 = { - | --------------------- calls in statics are limited to constant functions, tuple structs and tuple variants -LL | { LL | invalid(); | ^^^^^^^^^ | @@ -27,14 +22,12 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0015]: cannot call non-const function `invalid` in statics --> $DIR/issue-32829-2.rs:54:9 | -LL | static mut bad_eight : u32 = { - | -------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants -LL | { LL | invalid(); | ^^^^^^^^^ | @@ -43,6 +36,7 @@ note: function `invalid` is not const | LL | fn invalid() {} | ^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr index 442fbdd107fa..7ec0a2b73afc 100644 --- a/tests/ui/consts/issue-43105.stderr +++ b/tests/ui/consts/issue-43105.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `xyz` in constants --> $DIR/issue-43105.rs:3:17 | LL | const NUM: u8 = xyz(); - | ------------- ^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^ | note: function `xyz` is not const --> $DIR/issue-43105.rs:1:1 | LL | fn xyz() -> u8 { 42 } | ^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index c65abc530bc2..8e52a7aa35e1 100644 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -9,11 +9,10 @@ LL | vec![1, 2, 3] error[E0015]: cannot call non-const method `slice::::into_vec::` in constant functions --> $DIR/bad_const_fn_body_ice.rs:2:5 | -LL | const fn foo(a: i32) -> Vec { - | -------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | vec![1, 2, 3] | ^^^^^^^^^^^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr index ad2056a73707..bb0940ee789b 100644 --- a/tests/ui/consts/mir_check_nonconst.stderr +++ b/tests/ui/consts/mir_check_nonconst.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `bar` in statics --> $DIR/mir_check_nonconst.rs:8:19 | LL | static foo: Foo = bar(); - | --------------- ^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^ | note: function `bar` is not const --> $DIR/mir_check_nonconst.rs:4:1 | LL | fn bar() -> Foo { | ^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0010-teach.stderr b/tests/ui/error-codes/E0010-teach.stderr index 237efbefcf6e..82bbe01aef79 100644 --- a/tests/ui/error-codes/E0010-teach.stderr +++ b/tests/ui/error-codes/E0010-teach.stderr @@ -11,10 +11,9 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/E0010-teach.rs:5:23 | LL | const CON: Vec = vec![1, 2, 3]; - | ------------------- ^^^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^ | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0010.stderr b/tests/ui/error-codes/E0010.stderr index 2bb87118d242..87b722b5f656 100644 --- a/tests/ui/error-codes/E0010.stderr +++ b/tests/ui/error-codes/E0010.stderr @@ -10,10 +10,9 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/E0010.rs:3:23 | LL | const CON: Vec = vec![1, 2, 3]; - | ------------------- ^^^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^ | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0015.stderr b/tests/ui/error-codes/E0015.stderr index 4331d7c34b3c..bc457aefaecb 100644 --- a/tests/ui/error-codes/E0015.stderr +++ b/tests/ui/error-codes/E0015.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `create_some` in constants --> $DIR/E0015.rs:5:25 | LL | const FOO: Option = create_some(); - | --------------------- ^^^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^ | note: function `create_some` is not const --> $DIR/E0015.rs:1:1 | LL | fn create_some() -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/constck.stderr b/tests/ui/explicit-tail-calls/constck.stderr index 84d7bc3a1bf1..2fc2fb7f9338 100644 --- a/tests/ui/explicit-tail-calls/constck.stderr +++ b/tests/ui/explicit-tail-calls/constck.stderr @@ -1,9 +1,6 @@ error[E0015]: cannot call non-const function `not_const` in constant functions --> $DIR/constck.rs:6:16 | -LL | const fn f() { - | ------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants -LL | if false { LL | become not_const(); | ^^^^^^^^^^^ | @@ -12,13 +9,11 @@ note: function `not_const` is not const | LL | fn not_const() {} | ^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const function `not_const` in constant functions --> $DIR/constck.rs:13:26 | -LL | const fn g((): ()) { - | ------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants -LL | if false { LL | become yes_const(not_const()); | ^^^^^^^^^^^ | @@ -27,6 +22,7 @@ note: function `not_const` is not const | LL | fn not_const() {} | ^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-39559-2.stderr b/tests/ui/resolve/issue-39559-2.stderr index fbbcaa663ae0..4bfa1d1b1322 100644 --- a/tests/ui/resolve/issue-39559-2.stderr +++ b/tests/ui/resolve/issue-39559-2.stderr @@ -2,7 +2,7 @@ error[E0015]: cannot call non-const associated function `::dim` in --> $DIR/issue-39559-2.rs:14:24 | LL | let array: [usize; Dim3::dim()] - | ^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | note: associated function `dim` is not const because trait `Dim` is not const --> $DIR/issue-39559-2.rs:1:1 @@ -12,6 +12,7 @@ LL | trait Dim { LL | fn dim() -> usize; | ------------------ this associated function is not const = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | LL + #[const_trait] @@ -22,7 +23,7 @@ error[E0015]: cannot call non-const associated function `::dim` in --> $DIR/issue-39559-2.rs:16:15 | LL | = [0; Dim3::dim()]; - | ^^^^^^^^^^^ calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | note: associated function `dim` is not const because trait `Dim` is not const --> $DIR/issue-39559-2.rs:1:1 @@ -32,6 +33,7 @@ LL | trait Dim { LL | fn dim() -> usize; | ------------------ this associated function is not const = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | LL + #[const_trait] diff --git a/tests/ui/static/global-variable-promotion-error-7364.stderr b/tests/ui/static/global-variable-promotion-error-7364.stderr index bced8c152020..b9d75676bef8 100644 --- a/tests/ui/static/global-variable-promotion-error-7364.stderr +++ b/tests/ui/static/global-variable-promotion-error-7364.stderr @@ -15,10 +15,9 @@ error[E0015]: cannot call non-const associated function `Box::>:: --> $DIR/global-variable-promotion-error-7364.rs:5:37 | LL | static boxed: Box> = Box::new(RefCell::new(0)); - | --------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 2 previous errors diff --git a/tests/ui/static/static-mut-not-constant.stderr b/tests/ui/static/static-mut-not-constant.stderr index 7e64d36b26d1..f28ea0b1689a 100644 --- a/tests/ui/static/static-mut-not-constant.stderr +++ b/tests/ui/static/static-mut-not-constant.stderr @@ -2,10 +2,9 @@ error[E0015]: cannot call non-const associated function `Box::::new` in s --> $DIR/static-mut-not-constant.rs:1:28 | LL | static mut a: Box = Box::new(3); - | ------------------------ ^^^^^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr index 24f0986ccc49..fa4033f6a407 100644 --- a/tests/ui/static/static-vec-repeat-not-constant.stderr +++ b/tests/ui/static/static-vec-repeat-not-constant.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `foo` in statics --> $DIR/static-vec-repeat-not-constant.rs:3:25 | LL | static a: [isize; 2] = [foo(); 2]; - | -------------------- ^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^ | note: function `foo` is not const --> $DIR/static-vec-repeat-not-constant.rs:1:1 | LL | fn foo() -> isize { 23 } | ^^^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index dfbb1f6e985c..c54f4830533a 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -23,19 +23,15 @@ error[E0015]: cannot call non-const method `slice::::into_vec::< --> $DIR/check-values-constraints.rs:81:33 | LL | static STATIC11: Vec = vec![MyOwned]; - | ----------------------------- ^^^^^^^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const method `::to_string` in statics --> $DIR/check-values-constraints.rs:92:38 | -LL | static mut STATIC14: SafeStruct = SafeStruct { - | ------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants -LL | field1: SafeEnum::Variant1, LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ | @@ -46,6 +42,7 @@ note: method `to_string` is not const because trait `ToString` is not const ::: $SRC_DIR/alloc/src/string.rs:LL:COL | = note: this method is not const + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0010]: allocations are not allowed in statics @@ -59,11 +56,10 @@ LL | vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:96:5 | -LL | static STATIC15: &'static [Vec] = &[ - | ---------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants LL | vec![MyOwned], | ^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -78,12 +74,10 @@ LL | vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:98:5 | -LL | static STATIC15: &'static [Vec] = &[ - | ---------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants -... LL | vec![MyOwned], | ^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -98,11 +92,10 @@ LL | &vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:103:6 | -LL | static STATIC16: (&'static Vec, &'static Vec) = ( - | --------------------------------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -117,12 +110,10 @@ LL | &vec![MyOwned], error[E0015]: cannot call non-const method `slice::::into_vec::` in statics --> $DIR/check-values-constraints.rs:105:6 | -LL | static STATIC16: (&'static Vec, &'static Vec) = ( - | --------------------------------------------------------------- calls in statics are limited to constant functions, tuple structs and tuple variants -... LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -138,10 +129,9 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/check-values-constraints.rs:111:31 | LL | static STATIC19: Vec = vec![3]; - | --------------------------- ^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -157,10 +147,9 @@ error[E0015]: cannot call non-const method `slice::::into_vec:: $DIR/check-values-constraints.rs:117:32 | LL | static x: Vec = vec![3]; - | -------------------- ^^^^^^^ - | | - | calls in statics are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^ | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr index 70704780ddce..1a7ec35f3ddb 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr @@ -2,15 +2,14 @@ error[E0015]: cannot call non-const function `non_const` in constant functions --> $DIR/const-check-fns-in-const-impl.rs:14:16 | LL | fn foo() { non_const() } - | -------- ^^^^^^^^^^^ - | | - | calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^ | note: function `non_const` is not const --> $DIR/const-check-fns-in-const-impl.rs:11:1 | LL | fn non_const() {} | ^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr index ac393825ec72..cbc62d602a47 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr @@ -21,7 +21,9 @@ error[E0015]: cannot call non-const method `Formatter::<'_>::write_str` in const --> $DIR/derive-const-gate.rs:1:16 | LL | #[derive_const(Debug)] - | ^^^^^ calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 3 previous errors diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index 9f620fcf81b7..93638801895d 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -11,7 +11,9 @@ error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_ --> $DIR/derive-const-non-const-type.rs:12:16 | LL | #[derive_const(Debug)] - | ^^^^^ calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr index 89278ff56ad0..44a60c99ae9e 100644 --- a/tests/ui/traits/const-traits/cross-crate.stock.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr @@ -1,12 +1,10 @@ error[E0658]: cannot call conditionally-const method `::func` in constant functions --> $DIR/cross-crate.rs:22:11 | -LL | const fn const_context() { - | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | Const.func(); | ^^^^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index 6269e74fd1d2..766c20aa8211 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -1,21 +1,18 @@ error[E0015]: cannot call non-const method `::func` in constant functions --> $DIR/cross-crate.rs:19:14 | -LL | const fn const_context() { - | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants -LL | #[cfg(any(stocknc, gatednc))] LL | NonConst.func(); | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0658]: cannot call conditionally-const method `::func` in constant functions --> $DIR/cross-crate.rs:22:11 | -LL | const fn const_context() { - | ------------------------ calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | Const.func(); | ^^^^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr index 092a5ac05b82..ca73ae845550 100644 --- a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr +++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr @@ -10,8 +10,6 @@ LL | fn foo(self) { error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant functions --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:26:8 | -LL | const fn foo() { - | -------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | ().foo(); | ^^^^^ | @@ -22,6 +20,7 @@ LL | trait Trait { | ^^^^^^^^^^^ this trait is not const LL | fn foo(self); | ------------- this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Trait` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index dd78b464e782..d8a9e1898068 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -1,13 +1,12 @@ error[E0015]: cannot call non-const function `_print` in constant functions --> $DIR/issue-79450.rs:9:9 | -LL | fn prov(&self) { - | -------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | println!("lul"); | ^^^^^^^^^^^^^^^ | note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL + = 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 diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr index 2df4a0004b6a..4a912cc8274a 100644 --- a/tests/ui/traits/const-traits/issue-88155.stderr +++ b/tests/ui/traits/const-traits/issue-88155.stderr @@ -1,8 +1,6 @@ error[E0015]: cannot call non-const associated function `::assoc` in constant functions --> $DIR/issue-88155.rs:8:5 | -LL | pub const fn foo() -> bool { - | -------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | T::assoc() | ^^^^^^^^^^ | @@ -13,6 +11,7 @@ LL | pub trait A { | ^^^^^^^^^^^ this trait is not const LL | fn assoc() -> bool; | ------------------- this associated function is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `A` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr index 1baa8b308284..81611da9e748 100644 --- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr +++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr @@ -1,11 +1,10 @@ error[E0658]: cannot call conditionally-const associated function `::func` in constant functions --> $DIR/staged-api-user-crate.rs:12:5 | -LL | const fn stable_const_context() { - | ------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr index 3f40f602eefe..261f68bebdb2 100644 --- a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr +++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr @@ -1,11 +1,10 @@ error[E0658]: cannot call conditionally-const associated function ` as Default>::default` in constant functions --> $DIR/std-impl-gate.rs:13:5 | -LL | const fn const_context() -> Vec { - | -------------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | Default::default() | ^^^^^^^^^^^^^^^^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr index 84fc743e4a2b..c9dc239bef33 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr @@ -48,8 +48,6 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-2.rs:20:7 | -LL | const fn foo(x: &T) { - | --------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -60,6 +58,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index 9d72e149aab2..bfbf6980ab83 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -60,8 +60,6 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-2.rs:20:7 | -LL | const fn foo(x: &T) { - | --------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants LL | x.a(); | ^^^ | @@ -72,6 +70,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index 2625f9446061..ea487cbd563f 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -91,9 +91,6 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | @@ -105,6 +102,7 @@ LL | trait Foo { LL | fn a(&self); | ------------ this method is not const = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index 2625f9446061..ea487cbd563f 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -91,9 +91,6 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | @@ -105,6 +102,7 @@ LL | trait Foo { LL | fn a(&self); | ------------ this method is not const = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr index 155263656e36..b00ad706a5fa 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr @@ -41,12 +41,10 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] error[E0658]: cannot call conditionally-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr index 155263656e36..b00ad706a5fa 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr @@ -41,12 +41,10 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] error[E0658]: cannot call conditionally-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: see issue #143874 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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr index 4895b5b0cd08..5951caebe733 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr @@ -71,9 +71,6 @@ LL | #[const_trait] trait Bar: [const] Foo {} error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | @@ -84,6 +81,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr index 29bce84326ca..563495204ad7 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr @@ -60,9 +60,6 @@ LL | #[const_trait] trait Foo { error[E0015]: cannot call non-const method `::a` in constant functions --> $DIR/super-traits-fail-3.rs:36:7 | -LL | const fn foo(x: &T) { - | ----------------------------------- calls in constant functions are limited to constant functions, tuple structs and tuple variants -... LL | x.a(); | ^^^ | @@ -73,6 +70,7 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | LL + #[const_trait] diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b0f9fbb9be1..0b70ac97fd43 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -669,23 +669,20 @@ error[E0015]: cannot call non-const function `map::` in constants --> $DIR/typeck_type_placeholder_item.rs:231:22 | LL | const _: Option<_> = map(value); - | ------------------ ^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^ | note: function `map` is not const --> $DIR/typeck_type_placeholder_item.rs:222:1 | LL | fn map(_: fn() -> Option<&'static T>) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}>` in constants --> $DIR/typeck_type_placeholder_item.rs:240:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^^^^^^^^^ | note: method `filter` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -694,14 +691,13 @@ note: method `filter` is not const because trait `Iterator` is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants --> $DIR/typeck_type_placeholder_item.rs:240:45 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ---------- ^^^^^^^^^^^^^^ - | | - | calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^ | note: method `map` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -710,6 +706,7 @@ note: method `map` is not const because trait `Iterator` is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors From 74b7592ce936a8e4cf57d3e73cded0a9f7a93f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Oct 2025 21:23:59 +0000 Subject: [PATCH 318/525] fix rebase --- compiler/rustc_const_eval/src/check_consts/ops.rs | 6 +++--- .../const-super-trait-stable-disabled.stderr | 4 ++-- .../const-super-trait-stable-enabled.stderr | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index ecb58059600d..d81b31b704b3 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -11,8 +11,8 @@ use rustc_middle::mir::CallSource; use rustc_middle::span_bug; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, AssocItemContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, - TraitRef, Ty, suggest_constraining_type_param, + self, AssocContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, + Ty, suggest_constraining_type_param, }; use rustc_session::parse::add_feature_diagnostics; use rustc_span::{BytePos, Pos, Span, Symbol, sym}; @@ -362,7 +362,7 @@ fn build_error_for_const_call<'tcx>( non_or_conditionally, }); if let Some(item) = ccx.tcx.opt_associated_item(callee) { - if let AssocItemContainer::Trait = item.container + if let AssocContainer::Trait = item.container && let parent = item.container_id(ccx.tcx) && !ccx.tcx.is_const_trait(parent) { diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr index e09539684953..e8b5c0969920 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr @@ -59,9 +59,9 @@ error[E0015]: cannot call non-const method `::a` in constant functions note: method `a` is not const because trait `Foo` is not const --> const-super-trait.rs:3:1 | -3 | trait Foo { + 3 | trait Foo { | ^^^^^^^^^ this trait is not const -4 | fn a(&self); + 4 | fn a(&self); | ------------ this method is not const = help: const traits are not yet supported on stable Rust = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr index 9da10eb81d83..263532f3a940 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr @@ -49,9 +49,9 @@ error[E0015]: cannot call non-const method `::a` in constant functions note: method `a` is not const because trait `Foo` is not const --> const-super-trait.rs:3:1 | -3 | trait Foo { + 3 | trait Foo { | ^^^^^^^^^ this trait is not const -4 | fn a(&self); + 4 | fn a(&self); | ------------ this method is not const = help: const traits are not yet supported on stable Rust = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants From 116bd9258594ba59975ee7c6787305a6e8be2138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 22:21:24 +0000 Subject: [PATCH 319/525] Always point at trait assoc item when generics don't match Previously we only showed the trait's assoc item if the trait was local, because we were looking for a small span only for the generics, which we don't have for foreign traits. We now use `def_span` for the item, so we at least provide some context, even if its span is too wide. ``` error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration --> tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs:7:18 | 7 | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ^^^^ lifetimes do not match type in trait | ::: /home/gh-estebank/rust/library/core/src/iter/traits/collect.rs:292:5 | 292 | type IntoIter: Iterator; | ------------------------------------------ lifetimes in impl do not match this type in trait ``` --- compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 4 ++-- compiler/rustc_hir_analysis/src/errors.rs | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 936b02cac5bb..74bf68362fc5 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1097,14 +1097,14 @@ fn check_region_bounds_on_impl_item<'tcx>( .expect("expected impl item to have generics or else we can't compare them") .span; - let mut generics_span = None; + let mut generics_span = tcx.def_span(trait_m.def_id); let mut bounds_span = vec![]; let mut where_span = None; if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id) && let Some(trait_generics) = trait_node.generics() { - generics_span = Some(trait_generics.span); + generics_span = trait_generics.span; // FIXME: we could potentially look at the impl's bounds to not point at bounds that // *are* present in the impl. for p in trait_generics.predicates { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index d1eb328c0e76..dbad98fd7952 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -191,7 +191,7 @@ pub(crate) struct LifetimesOrBoundsMismatchOnTrait { #[label] pub span: Span, #[label(hir_analysis_generics_label)] - pub generics_span: Option, + pub generics_span: Span, #[label(hir_analysis_where_label)] pub where_span: Option, #[label(hir_analysis_bounds_label)] diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr index ebe051509aad..f07b5cdd65ca 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -11,6 +11,9 @@ error[E0195]: lifetime parameters or bounds on associated type `IntoIter` do not | LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ^^^^ lifetimes do not match associated type in trait + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + | + = note: lifetimes in impl do not match this associated type in trait error: aborting due to 2 previous errors From 0d7ef4f7575b096a7baa9e28a479f8ee0bea3b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 23:03:26 +0000 Subject: [PATCH 320/525] Look at the current `impl` before suggesting adding a lifetime Given an associated item that needs a named lifetime, look at the enclosing `impl` item for one. If there is none, look at the self type and the implemented trait to see if either of those has an anonimous lifetime. If so, suggest adding a named lifetime. ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | LL | type Item = &T; | ^ this lifetime must come from the implemented type | help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> IntoIterator for &'a S { LL ~ type Item = &'a T; | ``` --- compiler/rustc_resolve/src/late.rs | 63 +++++++++++++++++-- .../assoc-type.rs | 13 ++++ .../assoc-type.stderr | 35 ++++++++++- .../missing-lifetime-in-assoc-type-2.stderr | 8 ++- .../missing-lifetime-in-assoc-type-3.stderr | 8 ++- .../missing-lifetime-in-assoc-type-4.stderr | 8 ++- .../ui/lifetimes/no_lending_iterators.stderr | 2 +- 7 files changed, 122 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 91d0cae062a7..bc5bae0b46d5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -10,6 +10,7 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::mem::{replace, swap, take}; +use std::ops::ControlFlow; use rustc_ast::visit::{ AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list, @@ -1953,11 +1954,63 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); } } else { - err.span_label( - span, - "you could add a lifetime on the impl block, if the trait or the self type can \ - have one", - ); + struct AnonRefFinder; + impl<'ast> Visitor<'ast> for AnonRefFinder { + type Result = ControlFlow; + + fn visit_ty(&mut self, ty: &'ast ast::Ty) -> Self::Result { + if let ast::TyKind::Ref(None, mut_ty) = &ty.kind { + return ControlFlow::Break(mut_ty.ty.span.shrink_to_lo()); + } + visit::walk_ty(self, ty) + } + + fn visit_lifetime( + &mut self, + lt: &'ast ast::Lifetime, + _cx: visit::LifetimeCtxt, + ) -> Self::Result { + if lt.ident.name == kw::UnderscoreLifetime { + return ControlFlow::Break(lt.ident.span); + } + visit::walk_lifetime(self, lt) + } + } + + if let Some(ty) = &self.diag_metadata.current_self_type + && let ControlFlow::Break(sp) = AnonRefFinder.visit_ty(ty) + { + err.multipart_suggestion_verbose( + "add a lifetime to the impl block and use it in the self type and associated \ + type", + vec![ + (span, "<'a>".to_string()), + (sp, "'a ".to_string()), + (lifetime.shrink_to_hi(), "'a ".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } else if let Some(item) = &self.diag_metadata.current_item + && let ItemKind::Impl(impl_) = &item.kind + && let Some(of_trait) = &impl_.of_trait + && let ControlFlow::Break(sp) = AnonRefFinder.visit_trait_ref(of_trait) + { + err.multipart_suggestion_verbose( + "add a lifetime to the impl block and use it in the trait and associated type", + vec![ + (span, "<'a>".to_string()), + (sp, "'a".to_string()), + (lifetime.shrink_to_hi(), "'a ".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + "you could add a lifetime on the impl block, if the trait or the self type \ + could have one", + ); + } } } diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.rs b/tests/ui/impl-header-lifetime-elision/assoc-type.rs index 14b2ea647f19..e999bd02db26 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.rs +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.rs @@ -17,6 +17,19 @@ impl MyTrait for &u32 { //~^ ERROR `'_` cannot be used here } +impl<'a> MyTrait for &f64 { + type Output = &f64; + //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +} + +trait OtherTrait<'a> { + type Output; +} +impl OtherTrait<'_> for f64 { + type Output = &f64; + //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +} + // This is what you have to do: impl<'a> MyTrait for &'a f32 { type Output = &'a f32; diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr index 72c066426bd9..933ed3efec5d 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -1,10 +1,14 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/assoc-type.rs:11:19 | -LL | impl MyTrait for &i32 { - | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Output = &i32; | ^ this lifetime must come from the implemented type + | +help: add a lifetime to the impl block and use it in the self type and associated type + | +LL ~ impl<'a> MyTrait for &'a i32 { +LL ~ type Output = &'a i32; + | error[E0637]: `'_` cannot be used here --> $DIR/assoc-type.rs:16:20 @@ -12,6 +16,31 @@ error[E0637]: `'_` cannot be used here LL | type Output = &'_ i32; | ^^ `'_` is a reserved lifetime name -error: aborting due to 2 previous errors +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/assoc-type.rs:21:19 + | +LL | impl<'a> MyTrait for &f64 { + | ---- there is a named lifetime specified on the impl block you could use +LL | type Output = &f64; + | ^ this lifetime must come from the implemented type + | +help: consider using the lifetime from the impl block + | +LL | type Output = &'a f64; + | ++ + +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/assoc-type.rs:29:19 + | +LL | type Output = &f64; + | ^ this lifetime must come from the implemented type + | +help: add a lifetime to the impl block and use it in the trait and associated type + | +LL ~ impl<'a> OtherTrait<'a> for f64 { +LL ~ type Output = &'a f64; + | + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0637`. diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr index 7a0246eaac8f..cd6fa2894ad2 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr @@ -1,10 +1,14 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | -LL | impl IntoIterator for &S { - | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type + | +help: add a lifetime to the impl block and use it in the self type and associated type + | +LL ~ impl<'a> IntoIterator for &'a S { +LL ~ type Item = &'a T; + | error[E0261]: use of undeclared lifetime name `'a` --> $DIR/missing-lifetime-in-assoc-type-2.rs:7:57 diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr index 408d5bb40664..a71042fa9872 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr @@ -1,10 +1,14 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-3.rs:5:17 | -LL | impl IntoIterator for &S { - | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type + | +help: add a lifetime to the impl block and use it in the self type and associated type + | +LL ~ impl<'a> IntoIterator for &'a S { +LL ~ type Item = &'a T; + | error[E0106]: missing lifetime specifier --> $DIR/missing-lifetime-in-assoc-type-3.rs:7:56 diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr index f07b5cdd65ca..8481b60f845a 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -1,10 +1,14 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17 | -LL | impl IntoIterator for &S { - | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type + | +help: add a lifetime to the impl block and use it in the self type and associated type + | +LL ~ impl<'a> IntoIterator for &'a S { +LL ~ type Item = &'a T; + | error[E0195]: lifetime parameters or bounds on associated type `IntoIter` do not match the trait declaration --> $DIR/missing-lifetime-in-assoc-type-4.rs:7:18 diff --git a/tests/ui/lifetimes/no_lending_iterators.stderr b/tests/ui/lifetimes/no_lending_iterators.stderr index cadba149c234..0f18f858cb8f 100644 --- a/tests/ui/lifetimes/no_lending_iterators.stderr +++ b/tests/ui/lifetimes/no_lending_iterators.stderr @@ -14,7 +14,7 @@ error: in the trait associated type is declared without lifetime parameters, so --> $DIR/no_lending_iterators.rs:18:17 | LL | impl Bar for usize { - | - you could add a lifetime on the impl block, if the trait or the self type can have one + | - you could add a lifetime on the impl block, if the trait or the self type could have one LL | type Item = &usize; | ^ this lifetime must come from the implemented type From 04804c713ea269ea9599ff6b690740cb0106f2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 17 Jan 2025 01:05:15 +0000 Subject: [PATCH 321/525] Tweak wording in associated type with anon lifetime error Move the previous long message to a note and use a shorter primary message: ``` error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use ... LL | type Item = &T; | ^ this lifetime must come from the implemented type | note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider using the lifetime from the impl block | LL | type Item = &'a T; | ++ ``` --- compiler/rustc_resolve/messages.ftl | 4 +- compiler/rustc_resolve/src/errors.rs | 2 + compiler/rustc_resolve/src/late.rs | 38 ++++++++++++++++--- .../assoc-type.rs | 6 +-- .../assoc-type.stderr | 9 +++-- .../missing-lifetime-in-assoc-type-1.rs | 3 +- .../missing-lifetime-in-assoc-type-1.stderr | 4 +- .../missing-lifetime-in-assoc-type-2.rs | 2 +- .../missing-lifetime-in-assoc-type-2.stderr | 4 +- .../missing-lifetime-in-assoc-type-3.rs | 2 +- .../missing-lifetime-in-assoc-type-3.stderr | 4 +- .../missing-lifetime-in-assoc-type-4.rs | 2 +- .../missing-lifetime-in-assoc-type-4.stderr | 4 +- .../missing-lifetime-in-assoc-type-5.rs | 3 +- .../missing-lifetime-in-assoc-type-5.stderr | 4 +- .../missing-lifetime-in-assoc-type-6.rs | 26 +++++++++++++ .../missing-lifetime-in-assoc-type-6.stderr | 30 +++++++++++++++ tests/ui/lifetimes/no_lending_iterators.rs | 2 +- .../ui/lifetimes/no_lending_iterators.stderr | 4 +- 19 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 5bf90d2637df..f5a3363c50d3 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -11,9 +11,9 @@ resolve_added_macro_use = resolve_ancestor_only = visibilities can only be restricted to ancestor modules -resolve_anonymous_lifetime_non_gat_report_error = - in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +resolve_anonymous_lifetime_non_gat_report_error = missing lifetime in associated type .label = this lifetime must come from the implemented type + .note = in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index f0ea97ba8a0c..8b06230c7667 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -930,6 +930,8 @@ pub(crate) struct AnonymousLifetimeNonGatReportError { #[primary_span] #[label] pub(crate) lifetime: Span, + #[note] + pub(crate) decl: MultiSpan, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bc5bae0b46d5..3b03e21fcd56 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -20,21 +20,21 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions, - pluralize, + Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan, StashKey, + Suggestions, pluralize, }; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1; -use rustc_middle::ty::{DelegationFnSig, Visibility}; +use rustc_middle::ty::{AssocTag, DelegationFnSig, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, SyntaxContext, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; @@ -725,6 +725,9 @@ struct DiagMetadata<'ast> { /// The current impl items (used to suggest). current_impl_items: Option<&'ast [Box]>, + /// The current impl items (used to suggest). + current_impl_item: Option<&'ast AssocItem>, + /// When processing impl trait currently_processing_impl_trait: Option<(TraitRef, Ty)>, @@ -1878,9 +1881,31 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ty: ty.span, }); } else { + let decl = if !trait_id.is_local() + && let Some(assoc) = self.diag_metadata.current_impl_item + && let AssocItemKind::Type(_) = assoc.kind + && let assocs = self.r.tcx.associated_items(trait_id) + && let Some(ident) = assoc.kind.ident() + && let Some(assoc) = assocs.find_by_ident_and_kind( + self.r.tcx, + ident, + AssocTag::Type, + trait_id, + ) { + let mut decl: MultiSpan = + self.r.tcx.def_span(assoc.def_id).into(); + decl.push_span_label( + self.r.tcx.def_span(trait_id), + String::new(), + ); + decl + } else { + DUMMY_SP.into() + }; let mut err = self.r.dcx().create_err( errors::AnonymousLifetimeNonGatReportError { lifetime: lifetime.ident.span, + decl, }, ); self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span); @@ -1993,7 +2018,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } else if let Some(item) = &self.diag_metadata.current_item && let ItemKind::Impl(impl_) = &item.kind && let Some(of_trait) = &impl_.of_trait - && let ControlFlow::Break(sp) = AnonRefFinder.visit_trait_ref(of_trait) + && let ControlFlow::Break(sp) = AnonRefFinder.visit_trait_ref(&of_trait.trait_ref) { err.multipart_suggestion_verbose( "add a lifetime to the impl block and use it in the trait and associated type", @@ -3354,6 +3379,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ) { use crate::ResolutionError::*; self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis))); + let prev = self.diag_metadata.current_impl_item.take(); + self.diag_metadata.current_impl_item = Some(&item); match &item.kind { AssocItemKind::Const(box ast::ConstItem { ident, @@ -3502,6 +3529,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { panic!("unexpanded macro in resolve!") } } + self.diag_metadata.current_impl_item = prev; } fn check_trait_item( diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.rs b/tests/ui/impl-header-lifetime-elision/assoc-type.rs index e999bd02db26..f03a110d7dc1 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.rs +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.rs @@ -9,7 +9,7 @@ trait MyTrait { impl MyTrait for &i32 { type Output = &i32; - //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR missing lifetime in associated type } impl MyTrait for &u32 { @@ -19,7 +19,7 @@ impl MyTrait for &u32 { impl<'a> MyTrait for &f64 { type Output = &f64; - //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR missing lifetime in associated type } trait OtherTrait<'a> { @@ -27,7 +27,7 @@ trait OtherTrait<'a> { } impl OtherTrait<'_> for f64 { type Output = &f64; - //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR missing lifetime in associated type } // This is what you have to do: diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr index 933ed3efec5d..201ea2d894eb 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -1,9 +1,10 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/assoc-type.rs:11:19 | LL | type Output = &i32; | ^ this lifetime must come from the implemented type | + = note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> MyTrait for &'a i32 { @@ -16,7 +17,7 @@ error[E0637]: `'_` cannot be used here LL | type Output = &'_ i32; | ^^ `'_` is a reserved lifetime name -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/assoc-type.rs:21:19 | LL | impl<'a> MyTrait for &f64 { @@ -24,17 +25,19 @@ LL | impl<'a> MyTrait for &f64 { LL | type Output = &f64; | ^ this lifetime must come from the implemented type | + = note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type help: consider using the lifetime from the impl block | LL | type Output = &'a f64; | ++ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/assoc-type.rs:29:19 | LL | type Output = &f64; | ^ this lifetime must come from the implemented type | + = note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type help: add a lifetime to the impl block and use it in the trait and associated type | LL ~ impl<'a> OtherTrait<'a> for f64 { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 5401bc4ecb87..3d02d1bb1bd8 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -7,9 +7,10 @@ impl<'a> IntoIterator for &S { //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime type Item = &T; - //~^ ERROR in the trait associated type + //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block //~| NOTE this lifetime must come from the implemented type + //~| NOTE in the trait the associated type is declared without lifetime parameters type IntoIter = std::collections::btree_map::Values<'a, i32, T>; fn into_iter(self) -> Self::IntoIter { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index feac49eb0ff5..3374c76bb76b 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -1,4 +1,4 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 | LL | impl<'a> IntoIterator for &S { @@ -7,6 +7,8 @@ LL | impl<'a> IntoIterator for &S { LL | type Item = &T; | ^ this lifetime must come from the implemented type | +note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider using the lifetime from the impl block | LL | type Item = &'a T; diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs index dd720f075ac4..d24aaaf8b10e 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs @@ -3,7 +3,7 @@ struct T; impl IntoIterator for &S { type Item = &T; - //~^ ERROR in the trait associated type + //~^ ERROR missing lifetime in associated type type IntoIter = std::collections::btree_map::Values<'a, i32, T>; //~^ ERROR use of undeclared lifetime name `'a` diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr index cd6fa2894ad2..9d9d2bc97d90 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr @@ -1,9 +1,11 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | LL | type Item = &T; | ^ this lifetime must come from the implemented type | +note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> IntoIterator for &'a S { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs index 60d1f0f8fe57..cf745ab97eb3 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs @@ -3,7 +3,7 @@ struct T; impl IntoIterator for &S { type Item = &T; - //~^ ERROR in the trait associated type + //~^ ERROR missing lifetime in associated type type IntoIter = std::collections::btree_map::Values; //~^ ERROR missing lifetime specifier diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr index a71042fa9872..b5811dc8ff27 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr @@ -1,9 +1,11 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-3.rs:5:17 | LL | type Item = &T; | ^ this lifetime must come from the implemented type | +note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> IntoIterator for &'a S { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs index 0c99e8874c35..138f6d7bdf2f 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs @@ -3,7 +3,7 @@ struct T; impl IntoIterator for &S { type Item = &T; - //~^ ERROR in the trait associated type + //~^ ERROR missing lifetime in associated type type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; //~^ ERROR lifetime parameters or bounds on associated type `IntoIter` do not match the trait declaration diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr index 8481b60f845a..ccc0d7ebae9f 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -1,9 +1,11 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17 | LL | type Item = &T; | ^ this lifetime must come from the implemented type | +note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> IntoIterator for &'a S { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs index 17cca7cc9e37..853cc6dc8e4e 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs @@ -7,9 +7,10 @@ impl<'a> IntoIterator for &'_ S { //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime type Item = &T; - //~^ ERROR in the trait associated type + //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block //~| NOTE this lifetime must come from the implemented type + //~| NOTE in the trait the associated type is declared without lifetime parameters type IntoIter = std::collections::btree_map::Values<'a, i32, T>; fn into_iter(self) -> Self::IntoIter { diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index cb15bcb7d504..d58fd8995ef9 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -1,4 +1,4 @@ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-5.rs:9:17 | LL | impl<'a> IntoIterator for &'_ S { @@ -7,6 +7,8 @@ LL | impl<'a> IntoIterator for &'_ S { LL | type Item = &T; | ^ this lifetime must come from the implemented type | +note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider using the lifetime from the impl block | LL | type Item = &'a T; diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs new file mode 100644 index 000000000000..036596c2aec6 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs @@ -0,0 +1,26 @@ +//~ NOTE in the trait the associated type is declared without lifetime parameters +struct S; +struct T; + +trait Trait { + type Item; + type IntoIter; + fn into_iter(self) -> Self::IntoIter; +} + +impl<'a> Trait for &'_ S { + //~^ ERROR E0207 + //~| NOTE there is a named lifetime specified on the impl block you could use + //~| NOTE unconstrained lifetime parameter + //~| HELP consider using the named lifetime here instead of an implict lifetime + type Item = &T; + //~^ ERROR missing lifetime in associated type + //~| HELP consider using the lifetime from the impl block + //~| NOTE this lifetime must come from the implemented type + type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr new file mode 100644 index 000000000000..2e81d4367461 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr @@ -0,0 +1,30 @@ +error: missing lifetime in associated type + --> $DIR/missing-lifetime-in-assoc-type-6.rs:16:17 + | +LL | impl<'a> Trait for &'_ S { + | ---- there is a named lifetime specified on the impl block you could use +... +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + | + = note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +help: consider using the lifetime from the impl block + | +LL | type Item = &'a T; + | ++ + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/missing-lifetime-in-assoc-type-6.rs:11:6 + | +LL | impl<'a> Trait for &'_ S { + | ^^ unconstrained lifetime parameter + | +help: consider using the named lifetime here instead of an implict lifetime + | +LL - impl<'a> Trait for &'_ S { +LL + impl<'a> Trait for &'a S { + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/no_lending_iterators.rs b/tests/ui/lifetimes/no_lending_iterators.rs index 88b8cda0898b..aa2e57ee3036 100644 --- a/tests/ui/lifetimes/no_lending_iterators.rs +++ b/tests/ui/lifetimes/no_lending_iterators.rs @@ -16,7 +16,7 @@ trait Bar { impl Bar for usize { type Item = &usize; - //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR missing lifetime in associated type fn poke(&mut self, item: Self::Item) { self += *item; diff --git a/tests/ui/lifetimes/no_lending_iterators.stderr b/tests/ui/lifetimes/no_lending_iterators.stderr index 0f18f858cb8f..ef90c286fc75 100644 --- a/tests/ui/lifetimes/no_lending_iterators.stderr +++ b/tests/ui/lifetimes/no_lending_iterators.stderr @@ -10,13 +10,15 @@ note: you can't create an `Iterator` that borrows each `Item` from itself, but y LL | impl Iterator for Data { | ^^^^ -error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type +error: missing lifetime in associated type --> $DIR/no_lending_iterators.rs:18:17 | LL | impl Bar for usize { | - you could add a lifetime on the impl block, if the trait or the self type could have one LL | type Item = &usize; | ^ this lifetime must come from the implemented type + | + = note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type error[E0195]: lifetime parameters or bounds on associated type `Item` do not match the trait declaration --> $DIR/no_lending_iterators.rs:27:14 From 0a27256e00d6861f196bb2d5a95e19d196b5fee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Aug 2025 17:58:52 +0000 Subject: [PATCH 322/525] review comments --- compiler/rustc_resolve/src/late.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3b03e21fcd56..691e2c386c10 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -374,11 +374,14 @@ enum LifetimeBinderKind { FnPtrType, PolyTrait, WhereBound, + // Item covers foreign items, ADTs, type aliases, trait associated items and + // trait alias associated items. Item, ConstItem, Function, Closure, ImplBlock, + // Covers only `impl` associated types. ImplAssocType, } @@ -1950,14 +1953,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let Some((rib, span)) = self.lifetime_ribs[..i] .iter() .rev() - .skip(1) - .filter_map(|rib| match rib.kind { + .find_map(|rib| match rib.kind { LifetimeRibKind::Generics { span, kind: LifetimeBinderKind::ImplBlock, .. } => { Some((rib, span)) } _ => None, }) - .next() else { return; }; From 4e09cd1a797103781ad90d9d02ec50594b61aada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 02:14:58 +0000 Subject: [PATCH 323/525] fix tidy --- compiler/rustc_resolve/src/late.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 691e2c386c10..b86e9492c8c2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1950,10 +1950,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) { - let Some((rib, span)) = self.lifetime_ribs[..i] - .iter() - .rev() - .find_map(|rib| match rib.kind { + let Some((rib, span)) = + self.lifetime_ribs[..i].iter().rev().find_map(|rib| match rib.kind { LifetimeRibKind::Generics { span, kind: LifetimeBinderKind::ImplBlock, .. } => { Some((rib, span)) } From 817cf4b0a52bd552506c011b5b8d77432853e347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 02:23:12 +0000 Subject: [PATCH 324/525] fix tests --- tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr | 1 + tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr index ccc0d7ebae9f..a0b7ad08e8b6 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -17,6 +17,7 @@ error[E0195]: lifetime parameters or bounds on associated type `IntoIter` do not | LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ^^^^ lifetimes do not match associated type in trait + | --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | = note: lifetimes in impl do not match this associated type in trait diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs index 036596c2aec6..b4fac575edb3 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs @@ -12,7 +12,7 @@ impl<'a> Trait for &'_ S { //~^ ERROR E0207 //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter - //~| HELP consider using the named lifetime here instead of an implict lifetime + //~| HELP consider using the named lifetime here instead of an implicit lifetime type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr index 2e81d4367461..6767243bf21b 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr @@ -19,7 +19,7 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a> Trait for &'_ S { | ^^ unconstrained lifetime parameter | -help: consider using the named lifetime here instead of an implict lifetime +help: consider using the named lifetime here instead of an implicit lifetime | LL - impl<'a> Trait for &'_ S { LL + impl<'a> Trait for &'a S { From 449576a590ecd0dceab9e6e73eb57f996bad3b52 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 3 Nov 2025 04:15:21 +0000 Subject: [PATCH 325/525] Prepare for merging from rust-lang/rust This updates the rust-version file to c5dabe8cf798123087d094f06417f5a767ca73e8. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index c9529fde2363..0e89b4ab6ac7 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -fb24b04b096a980bffd80154f6aba22fd07cb3d9 +c5dabe8cf798123087d094f06417f5a767ca73e8 From c850c272cf91bd898eb06488792741876525cc2d Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 3 Nov 2025 04:17:30 +0000 Subject: [PATCH 326/525] Prepare for merging from rust-lang/rust This updates the rust-version file to c5dabe8cf798123087d094f06417f5a767ca73e8. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index f100e4116686..0e89b4ab6ac7 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -b1b464d6f61ec8c4e609c1328106378c066a9729 +c5dabe8cf798123087d094f06417f5a767ca73e8 From b9133371848d979f4ddc3b50b27b10be644a41f4 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 3 Nov 2025 04:55:29 +0000 Subject: [PATCH 327/525] Prepare for merging from rust-lang/rust This updates the rust-version file to c5dabe8cf798123087d094f06417f5a767ca73e8. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index bf33c10dd035..0e89b4ab6ac7 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -292be5c7c05138d753bbd4b30db7a3f1a5c914f7 +c5dabe8cf798123087d094f06417f5a767ca73e8 From d335ea91b5bc6cf184229c49e313e70f3ab180bd Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 9 Oct 2025 17:05:34 +0530 Subject: [PATCH 328/525] Refactor implementation of float minmax intrinsics --- .../src/interpret/intrinsics.rs | 135 +++++++++--------- .../src/interpret/intrinsics/simd.rs | 54 ++----- 2 files changed, 81 insertions(+), 108 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index f0712644465a..90f14a69fac3 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -34,6 +34,26 @@ enum MulAddType { Nondeterministic, } +#[derive(Copy, Clone)] +pub(crate) enum MinMax { + /// The IEEE `Minimum` operation - see `f32::minimum` etc + /// In particular, `-0.0` is considered smaller than `+0.0` and + /// if either input is NaN, the result is NaN. + Minimum, + /// The IEEE `MinNum` operation - see `f32::min` etc + /// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic, + /// and is one argument is NaN, the other one is returned. + MinNum, + /// The IEEE `Maximum` operation - see `f32::maximum` etc + /// In particular, `-0.0` is considered smaller than `+0.0` and + /// if either input is NaN, the result is NaN. + Maximum, + /// The IEEE `MaxNum` operation - see `f32::max` etc + /// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic, + /// and is one argument is NaN, the other one is returned. + MaxNum, +} + /// Directly returns an `Allocation` containing an absolute path representation of the given type. pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, u64) { let path = crate::util::type_name(tcx, ty); @@ -513,25 +533,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } - sym::minnumf16 => self.float_min_intrinsic::(args, dest)?, - sym::minnumf32 => self.float_min_intrinsic::(args, dest)?, - sym::minnumf64 => self.float_min_intrinsic::(args, dest)?, - sym::minnumf128 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf16 => self.float_minmax_intrinsic::(args, MinMax::MinNum, dest)?, + sym::minnumf32 => self.float_minmax_intrinsic::(args, MinMax::MinNum, dest)?, + sym::minnumf64 => self.float_minmax_intrinsic::(args, MinMax::MinNum, dest)?, + sym::minnumf128 => self.float_minmax_intrinsic::(args, MinMax::MinNum, dest)?, - sym::minimumf16 => self.float_minimum_intrinsic::(args, dest)?, - sym::minimumf32 => self.float_minimum_intrinsic::(args, dest)?, - sym::minimumf64 => self.float_minimum_intrinsic::(args, dest)?, - sym::minimumf128 => self.float_minimum_intrinsic::(args, dest)?, + sym::minimumf16 => self.float_minmax_intrinsic::(args, MinMax::Minimum, dest)?, + sym::minimumf32 => { + self.float_minmax_intrinsic::(args, MinMax::Minimum, dest)? + } + sym::minimumf64 => { + self.float_minmax_intrinsic::(args, MinMax::Minimum, dest)? + } + sym::minimumf128 => self.float_minmax_intrinsic::(args, MinMax::Minimum, dest)?, - sym::maxnumf16 => self.float_max_intrinsic::(args, dest)?, - sym::maxnumf32 => self.float_max_intrinsic::(args, dest)?, - sym::maxnumf64 => self.float_max_intrinsic::(args, dest)?, - sym::maxnumf128 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf16 => self.float_minmax_intrinsic::(args, MinMax::MaxNum, dest)?, + sym::maxnumf32 => self.float_minmax_intrinsic::(args, MinMax::MaxNum, dest)?, + sym::maxnumf64 => self.float_minmax_intrinsic::(args, MinMax::MaxNum, dest)?, + sym::maxnumf128 => self.float_minmax_intrinsic::(args, MinMax::MaxNum, dest)?, - sym::maximumf16 => self.float_maximum_intrinsic::(args, dest)?, - sym::maximumf32 => self.float_maximum_intrinsic::(args, dest)?, - sym::maximumf64 => self.float_maximum_intrinsic::(args, dest)?, - sym::maximumf128 => self.float_maximum_intrinsic::(args, dest)?, + sym::maximumf16 => self.float_minmax_intrinsic::(args, MinMax::Maximum, dest)?, + sym::maximumf32 => { + self.float_minmax_intrinsic::(args, MinMax::Maximum, dest)? + } + sym::maximumf64 => { + self.float_minmax_intrinsic::(args, MinMax::Maximum, dest)? + } + sym::maximumf128 => self.float_minmax_intrinsic::(args, MinMax::Maximum, dest)?, sym::copysignf16 => self.float_copysign_intrinsic::(args, dest)?, sym::copysignf32 => self.float_copysign_intrinsic::(args, dest)?, @@ -936,76 +964,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } - fn float_min_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> + fn float_minmax( + &self, + a: Scalar, + b: Scalar, + op: MinMax, + ) -> InterpResult<'tcx, Scalar> where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let res = if a == b { + let a: F = a.to_float()?; + let b: F = b.to_float()?; + let res = if matches!(op, MinMax::MinNum | MinMax::MaxNum) && a == b { // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`. // Let the machine decide which one to return. M::equal_float_min_max(self, a, b) } else { - self.adjust_nan(a.min(b), &[a, b]) + let result = match op { + MinMax::Minimum => a.minimum(b), + MinMax::MinNum => a.min(b), + MinMax::Maximum => a.maximum(b), + MinMax::MaxNum => a.max(b), + }; + self.adjust_nan(result, &[a, b]) }; - self.write_scalar(res, dest)?; - interp_ok(()) + + interp_ok(res.into()) } - fn float_max_intrinsic( + fn float_minmax_intrinsic( &mut self, args: &[OpTy<'tcx, M::Provenance>], + op: MinMax, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx, ()> where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let res = if a == b { - // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`. - // Let the machine decide which one to return. - M::equal_float_min_max(self, a, b) - } else { - self.adjust_nan(a.max(b), &[a, b]) - }; - self.write_scalar(res, dest)?; - interp_ok(()) - } - - fn float_minimum_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, - { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let res = a.minimum(b); - let res = self.adjust_nan(res, &[a, b]); - self.write_scalar(res, dest)?; - interp_ok(()) - } - - fn float_maximum_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, - { - let a: F = self.read_scalar(&args[0])?.to_float()?; - let b: F = self.read_scalar(&args[1])?.to_float()?; - let res = a.maximum(b); - let res = self.adjust_nan(res, &[a, b]); + let res = + self.float_minmax::(self.read_scalar(&args[0])?, self.read_scalar(&args[1])?, op)?; self.write_scalar(res, dest)?; interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 84489028e190..13b6623accd2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -9,17 +9,11 @@ use rustc_span::{Symbol, sym}; use tracing::trace; use super::{ - ImmTy, InterpCx, InterpResult, Machine, MulAddType, OpTy, PlaceTy, Provenance, Scalar, Size, - interp_ok, throw_ub_format, + ImmTy, InterpCx, InterpResult, Machine, MinMax, MulAddType, OpTy, PlaceTy, Provenance, Scalar, + Size, interp_ok, throw_ub_format, }; use crate::interpret::Writeable; -#[derive(Copy, Clone)] -pub(crate) enum MinMax { - Min, - Max, -} - impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Returns `true` if emulation happened. /// Here we implement the intrinsics that are common to all CTFE instances; individual machines can add their own @@ -217,8 +211,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::simd_le => Op::MirOp(BinOp::Le), sym::simd_gt => Op::MirOp(BinOp::Gt), sym::simd_ge => Op::MirOp(BinOp::Ge), - sym::simd_fmax => Op::FMinMax(MinMax::Max), - sym::simd_fmin => Op::FMinMax(MinMax::Min), + sym::simd_fmax => Op::FMinMax(MinMax::MaxNum), + sym::simd_fmin => Op::FMinMax(MinMax::MinNum), sym::simd_saturating_add => Op::SaturatingOp(BinOp::Add), sym::simd_saturating_sub => Op::SaturatingOp(BinOp::Sub), sym::simd_arith_offset => Op::WrappingOffset, @@ -310,8 +304,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::simd_reduce_xor => Op::MirOp(BinOp::BitXor), sym::simd_reduce_any => Op::MirOpBool(BinOp::BitOr), sym::simd_reduce_all => Op::MirOpBool(BinOp::BitAnd), - sym::simd_reduce_max => Op::MinMax(MinMax::Max), - sym::simd_reduce_min => Op::MinMax(MinMax::Min), + sym::simd_reduce_max => Op::MinMax(MinMax::MaxNum), + sym::simd_reduce_min => Op::MinMax(MinMax::MinNum), _ => unreachable!(), }; @@ -333,10 +327,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if matches!(res.layout.ty.kind(), ty::Float(_)) { ImmTy::from_scalar(self.fminmax_op(mmop, &res, &op)?, res.layout) } else { - // Just boring integers, so NaNs to worry about + // Just boring integers, no NaNs to worry about. let mirop = match mmop { - MinMax::Min => BinOp::Le, - MinMax::Max => BinOp::Ge, + MinMax::MinNum | MinMax::Minimum => BinOp::Le, + MinMax::MaxNum | MinMax::Maximum => BinOp::Ge, }; if self.binary_op(mirop, &res, &op)?.to_scalar().to_bool()? { res @@ -749,12 +743,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(true) } - fn fminmax_op( + fn fminmax_op( &self, op: MinMax, - left: &ImmTy<'tcx, Prov>, - right: &ImmTy<'tcx, Prov>, - ) -> InterpResult<'tcx, Scalar> { + left: &ImmTy<'tcx, M::Provenance>, + right: &ImmTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, Scalar> { assert_eq!(left.layout.ty, right.layout.ty); let ty::Float(float_ty) = left.layout.ty.kind() else { bug!("fmax operand is not a float") @@ -763,26 +757,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let right = right.to_scalar(); interp_ok(match float_ty { FloatTy::F16 => unimplemented!("f16_f128"), - FloatTy::F32 => { - let left = left.to_f32()?; - let right = right.to_f32()?; - let res = match op { - MinMax::Min => left.min(right), - MinMax::Max => left.max(right), - }; - let res = self.adjust_nan(res, &[left, right]); - Scalar::from_f32(res) - } - FloatTy::F64 => { - let left = left.to_f64()?; - let right = right.to_f64()?; - let res = match op { - MinMax::Min => left.min(right), - MinMax::Max => left.max(right), - }; - let res = self.adjust_nan(res, &[left, right]); - Scalar::from_f64(res) - } + FloatTy::F32 => self.float_minmax::(left, right, op)?, + FloatTy::F64 => self.float_minmax::(left, right, op)?, FloatTy::F128 => unimplemented!("f16_f128"), }) } From ebf2e10238b946936ff9ff0476932e583fa59c9f Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 10 Oct 2025 22:00:13 +0530 Subject: [PATCH 329/525] Refactor float rounding intrinsics a bit --- .../src/interpret/intrinsics.rs | 18 +++++++++++++++--- .../src/interpret/intrinsics/simd.rs | 15 +++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 90f14a69fac3..58d7f8ef8c63 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -1036,6 +1036,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } + fn float_round( + &mut self, + x: Scalar, + mode: rustc_apfloat::Round, + ) -> InterpResult<'tcx, Scalar> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = x.to_float()?; + let res = x.round_to_integral(mode).value; + let res = self.adjust_nan(res, &[x]); + interp_ok(res.into()) + } + fn float_round_intrinsic( &mut self, args: &[OpTy<'tcx, M::Provenance>], @@ -1045,9 +1059,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let x: F = self.read_scalar(&args[0])?.to_float()?; - let res = x.round_to_integral(mode).value; - let res = self.adjust_nan(res, &[x]); + let res = self.float_round::(self.read_scalar(&args[0])?, mode)?; self.write_scalar(res, dest)?; interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 13b6623accd2..f580dc6bebc3 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -134,20 +134,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { intrinsic_name ) }; + let op = op.to_scalar(); match float_ty { FloatTy::F16 => unimplemented!("f16_f128"), - FloatTy::F32 => { - let f = op.to_scalar().to_f32()?; - let res = f.round_to_integral(rounding).value; - let res = self.adjust_nan(res, &[f]); - Scalar::from_f32(res) - } - FloatTy::F64 => { - let f = op.to_scalar().to_f64()?; - let res = f.round_to_integral(rounding).value; - let res = self.adjust_nan(res, &[f]); - Scalar::from_f64(res) - } + FloatTy::F32 => self.float_round::(op, rounding)?, + FloatTy::F64 => self.float_round::(op, rounding)?, FloatTy::F128 => unimplemented!("f16_f128"), } } From 4d70bf4c5a4ba773002c031355690c2d717eea4b Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 10 Oct 2025 22:02:19 +0530 Subject: [PATCH 330/525] Add some missing f16-f128 support in intrinsics --- .../src/interpret/intrinsics/simd.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index f580dc6bebc3..f97bdf627ed9 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -1,6 +1,6 @@ use either::Either; use rustc_abi::Endian; -use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; use rustc_middle::mir::interpret::{InterpErrorKind, UndefinedBehaviorInfo}; use rustc_middle::ty::FloatTy; @@ -120,10 +120,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let op = op.to_scalar(); // "Bitwise" operation, no NaN adjustments match float_ty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(op.to_f16()?.abs()), FloatTy::F32 => Scalar::from_f32(op.to_f32()?.abs()), FloatTy::F64 => Scalar::from_f64(op.to_f64()?.abs()), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(op.to_f128()?.abs()), } } Op::Round(rounding) => { @@ -136,10 +136,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let op = op.to_scalar(); match float_ty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.float_round::(op, rounding)?, FloatTy::F32 => self.float_round::(op, rounding)?, FloatTy::F64 => self.float_round::(op, rounding)?, - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.float_round::(op, rounding)?, } } Op::Numeric(name) => { @@ -716,10 +716,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let val = match float_ty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.float_muladd::(a, b, c, typ)?, FloatTy::F32 => self.float_muladd::(a, b, c, typ)?, FloatTy::F64 => self.float_muladd::(a, b, c, typ)?, - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.float_muladd::(a, b, c, typ)?, }; self.write_scalar(val, &dest)?; } @@ -747,10 +747,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let left = left.to_scalar(); let right = right.to_scalar(); interp_ok(match float_ty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.float_minmax::(left, right, op)?, FloatTy::F32 => self.float_minmax::(left, right, op)?, FloatTy::F64 => self.float_minmax::(left, right, op)?, - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.float_minmax::(left, right, op)?, }) } } From 0681bae055ce776bf20c62289c9cc179a011d329 Mon Sep 17 00:00:00 2001 From: sayantn Date: Sat, 11 Oct 2025 03:24:23 +0530 Subject: [PATCH 331/525] Add Miri tests for f16/f128 SIMD operations --- .../tests/pass/intrinsics/portable-simd.rs | 262 +++++++++++++++++- 1 file changed, 260 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index e2cd08733af1..b7d2584c58fb 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -6,18 +6,143 @@ rustc_attrs, intrinsics, core_intrinsics, - repr_simd + repr_simd, + f16, + f128 )] -#![allow(incomplete_features, internal_features)] +#![allow(incomplete_features, internal_features, non_camel_case_types)] +use std::fmt::{self, Debug, Formatter}; use std::intrinsics::simd as intrinsics; use std::ptr; use std::simd::StdFloat; use std::simd::prelude::*; +#[repr(simd, packed)] +#[derive(Copy)] +struct PackedSimd([T; N]); + +impl Clone for PackedSimd { + fn clone(&self) -> Self { + *self + } +} + +impl PartialEq for PackedSimd { + fn eq(&self, other: &Self) -> bool { + self.into_array() == other.into_array() + } +} + +impl Debug for PackedSimd { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + Debug::fmt(&self.into_array(), f) + } +} + +type f16x2 = PackedSimd; +type f16x4 = PackedSimd; + +type f128x2 = PackedSimd; +type f128x4 = PackedSimd; + +impl PackedSimd { + fn splat(x: T) -> Self { + Self([x; N]) + } + fn from_array(a: [T; N]) -> Self { + Self(a) + } + fn into_array(self) -> [T; N] { + // as we have `repr(packed)`, there shouldn't be any padding bytes + unsafe { std::mem::transmute_copy(&self) } + } +} + #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; +pub fn simd_ops_f16() { + use intrinsics::*; + + // small hack to make type inference better + macro_rules! assert_eq { + ($a:expr, $b:expr $(,$t:tt)*) => {{ + let a = $a; + let b = $b; + if false { let _inference = b == a; } + ::std::assert_eq!(a, b, $(,$t)*) + }} + } + + let a = f16x4::splat(10.0); + let b = f16x4::from_array([1.0, 2.0, 3.0, -4.0]); + + unsafe { + assert_eq!(simd_neg(b), f16x4::from_array([-1.0, -2.0, -3.0, 4.0])); + assert_eq!(simd_add(a, b), f16x4::from_array([11.0, 12.0, 13.0, 6.0])); + assert_eq!(simd_sub(a, b), f16x4::from_array([9.0, 8.0, 7.0, 14.0])); + assert_eq!(simd_mul(a, b), f16x4::from_array([10.0, 20.0, 30.0, -40.0])); + assert_eq!(simd_div(b, a), f16x4::from_array([0.1, 0.2, 0.3, -0.4])); + assert_eq!(simd_div(a, f16x4::splat(2.0)), f16x4::splat(5.0)); + assert_eq!(simd_rem(a, b), f16x4::from_array([0.0, 0.0, 1.0, 2.0])); + assert_eq!(simd_fabs(b), f16x4::from_array([1.0, 2.0, 3.0, 4.0])); + assert_eq!( + simd_fmax(a, simd_mul(b, f16x4::splat(4.0))), + f16x4::from_array([10.0, 10.0, 12.0, 10.0]) + ); + assert_eq!( + simd_fmin(a, simd_mul(b, f16x4::splat(4.0))), + f16x4::from_array([4.0, 8.0, 10.0, -16.0]) + ); + + assert_eq!(simd_fma(a, b, a), simd_add(simd_mul(a, b), a)); + assert_eq!(simd_fma(b, b, a), simd_add(simd_mul(b, b), a)); + assert_eq!(simd_fma(a, b, b), simd_add(simd_mul(a, b), b)); + assert_eq!( + simd_fma(f16x4::splat(-3.2), b, f16x4::splat(f16::NEG_INFINITY)), + f16x4::splat(f16::NEG_INFINITY) + ); + + assert_eq!(simd_relaxed_fma(a, b, a), simd_add(simd_mul(a, b), a)); + assert_eq!(simd_relaxed_fma(b, b, a), simd_add(simd_mul(b, b), a)); + assert_eq!(simd_relaxed_fma(a, b, b), simd_add(simd_mul(a, b), b)); + assert_eq!( + simd_relaxed_fma(f16x4::splat(-3.2), b, f16x4::splat(f16::NEG_INFINITY)), + f16x4::splat(f16::NEG_INFINITY) + ); + + assert_eq!(simd_eq(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([0, !0, 0, 0])); + assert_eq!(simd_ne(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([!0, 0, !0, !0])); + assert_eq!(simd_le(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([0, !0, !0, 0])); + assert_eq!(simd_lt(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([0, 0, !0, 0])); + assert_eq!(simd_ge(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([!0, !0, 0, !0])); + assert_eq!(simd_gt(a, simd_mul(f16x4::splat(5.0), b)), i32x4::from_array([!0, 0, 0, !0])); + + assert_eq!(simd_reduce_add_ordered(a, 0.0), 40.0f16); + assert_eq!(simd_reduce_add_ordered(b, 0.0), 2.0f16); + assert_eq!(simd_reduce_mul_ordered(a, 1.0), 10000.0f16); + assert_eq!(simd_reduce_mul_ordered(b, 1.0), -24.0f16); + assert_eq!(simd_reduce_max(a), 10.0f16); + assert_eq!(simd_reduce_max(b), 3.0f16); + assert_eq!(simd_reduce_min(a), 10.0f16); + assert_eq!(simd_reduce_min(b), -4.0f16); + + assert_eq!( + simd_fmax(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + f16x2::from_array([0.0, 0.0]) + ); + assert_eq!(simd_reduce_max(f16x2::from_array([0.0, f16::NAN])), 0.0f16); + assert_eq!(simd_reduce_max(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); + assert_eq!( + simd_fmin(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + f16x2::from_array([0.0, 0.0]) + ); + assert_eq!(simd_reduce_min(f16x2::from_array([0.0, f16::NAN])), 0.0f16); + assert_eq!(simd_reduce_min(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); + } +} + fn simd_ops_f32() { let a = f32x4::splat(10.0); let b = f32x4::from_array([1.0, 2.0, 3.0, -4.0]); @@ -148,6 +273,87 @@ fn simd_ops_f64() { assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_min(), 0.0); } +pub fn simd_ops_f128() { + use intrinsics::*; + + // small hack to make type inference better + macro_rules! assert_eq { + ($a:expr, $b:expr $(,$t:tt)*) => {{ + let a = $a; + let b = $b; + if false { let _inference = b == a; } + ::std::assert_eq!(a, b, $(,$t)*) + }} + } + + let a = f128x4::splat(10.0); + let b = f128x4::from_array([1.0, 2.0, 3.0, -4.0]); + + unsafe { + assert_eq!(simd_neg(b), f128x4::from_array([-1.0, -2.0, -3.0, 4.0])); + assert_eq!(simd_add(a, b), f128x4::from_array([11.0, 12.0, 13.0, 6.0])); + assert_eq!(simd_sub(a, b), f128x4::from_array([9.0, 8.0, 7.0, 14.0])); + assert_eq!(simd_mul(a, b), f128x4::from_array([10.0, 20.0, 30.0, -40.0])); + assert_eq!(simd_div(b, a), f128x4::from_array([0.1, 0.2, 0.3, -0.4])); + assert_eq!(simd_div(a, f128x4::splat(2.0)), f128x4::splat(5.0)); + assert_eq!(simd_rem(a, b), f128x4::from_array([0.0, 0.0, 1.0, 2.0])); + assert_eq!(simd_fabs(b), f128x4::from_array([1.0, 2.0, 3.0, 4.0])); + assert_eq!( + simd_fmax(a, simd_mul(b, f128x4::splat(4.0))), + f128x4::from_array([10.0, 10.0, 12.0, 10.0]) + ); + assert_eq!( + simd_fmin(a, simd_mul(b, f128x4::splat(4.0))), + f128x4::from_array([4.0, 8.0, 10.0, -16.0]) + ); + + assert_eq!(simd_fma(a, b, a), simd_add(simd_mul(a, b), a)); + assert_eq!(simd_fma(b, b, a), simd_add(simd_mul(b, b), a)); + assert_eq!(simd_fma(a, b, b), simd_add(simd_mul(a, b), b)); + assert_eq!( + simd_fma(f128x4::splat(-3.2), b, f128x4::splat(f128::NEG_INFINITY)), + f128x4::splat(f128::NEG_INFINITY) + ); + + assert_eq!(simd_relaxed_fma(a, b, a), simd_add(simd_mul(a, b), a)); + assert_eq!(simd_relaxed_fma(b, b, a), simd_add(simd_mul(b, b), a)); + assert_eq!(simd_relaxed_fma(a, b, b), simd_add(simd_mul(a, b), b)); + assert_eq!( + simd_relaxed_fma(f128x4::splat(-3.2), b, f128x4::splat(f128::NEG_INFINITY)), + f128x4::splat(f128::NEG_INFINITY) + ); + + assert_eq!(simd_eq(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([0, !0, 0, 0])); + assert_eq!(simd_ne(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([!0, 0, !0, !0])); + assert_eq!(simd_le(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([0, !0, !0, 0])); + assert_eq!(simd_lt(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([0, 0, !0, 0])); + assert_eq!(simd_ge(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([!0, !0, 0, !0])); + assert_eq!(simd_gt(a, simd_mul(f128x4::splat(5.0), b)), i32x4::from_array([!0, 0, 0, !0])); + + assert_eq!(simd_reduce_add_ordered(a, 0.0), 40.0f128); + assert_eq!(simd_reduce_add_ordered(b, 0.0), 2.0f128); + assert_eq!(simd_reduce_mul_ordered(a, 1.0), 10000.0f128); + assert_eq!(simd_reduce_mul_ordered(b, 1.0), -24.0f128); + assert_eq!(simd_reduce_max(a), 10.0f128); + assert_eq!(simd_reduce_max(b), 3.0f128); + assert_eq!(simd_reduce_min(a), 10.0f128); + assert_eq!(simd_reduce_min(b), -4.0f128); + + assert_eq!( + simd_fmax(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + f128x2::from_array([0.0, 0.0]) + ); + assert_eq!(simd_reduce_max(f128x2::from_array([0.0, f128::NAN])), 0.0f128); + assert_eq!(simd_reduce_max(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); + assert_eq!( + simd_fmin(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + f128x2::from_array([0.0, 0.0]) + ); + assert_eq!(simd_reduce_min(f128x2::from_array([0.0, f128::NAN])), 0.0f128); + assert_eq!(simd_reduce_min(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); + } +} + fn simd_ops_i32() { let a = i32x4::splat(10); let b = i32x4::from_array([1, 2, 3, -4]); @@ -563,6 +769,31 @@ fn simd_gather_scatter() { } fn simd_round() { + unsafe { + use intrinsics::*; + + assert_eq!( + simd_ceil(f16x4::from_array([0.9, 1.001, 2.0, -4.5])), + f16x4::from_array([1.0, 2.0, 2.0, -4.0]) + ); + assert_eq!( + simd_floor(f16x4::from_array([0.9, 1.001, 2.0, -4.5])), + f16x4::from_array([0.0, 1.0, 2.0, -5.0]) + ); + assert_eq!( + simd_round(f16x4::from_array([0.9, 1.001, 2.0, -4.5])), + f16x4::from_array([1.0, 1.0, 2.0, -5.0]) + ); + assert_eq!( + simd_round_ties_even(f16x4::from_array([0.9, 1.001, 2.0, -4.5])), + f16x4::from_array([1.0, 1.0, 2.0, -4.0]) + ); + assert_eq!( + simd_trunc(f16x4::from_array([0.9, 1.001, 2.0, -4.5])), + f16x4::from_array([0.0, 1.0, 2.0, -4.0]) + ); + } + assert_eq!( f32x4::from_array([0.9, 1.001, 2.0, -4.5]).ceil(), f32x4::from_array([1.0, 2.0, 2.0, -4.0]) @@ -604,6 +835,31 @@ fn simd_round() { f64x4::from_array([0.9, 1.001, 2.0, -4.5]).trunc(), f64x4::from_array([0.0, 1.0, 2.0, -4.0]) ); + + unsafe { + use intrinsics::*; + + assert_eq!( + simd_ceil(f128x4::from_array([0.9, 1.001, 2.0, -4.5])), + f128x4::from_array([1.0, 2.0, 2.0, -4.0]) + ); + assert_eq!( + simd_floor(f128x4::from_array([0.9, 1.001, 2.0, -4.5])), + f128x4::from_array([0.0, 1.0, 2.0, -5.0]) + ); + assert_eq!( + simd_round(f128x4::from_array([0.9, 1.001, 2.0, -4.5])), + f128x4::from_array([1.0, 1.0, 2.0, -5.0]) + ); + assert_eq!( + simd_round_ties_even(f128x4::from_array([0.9, 1.001, 2.0, -4.5])), + f128x4::from_array([1.0, 1.0, 2.0, -4.0]) + ); + assert_eq!( + simd_trunc(f128x4::from_array([0.9, 1.001, 2.0, -4.5])), + f128x4::from_array([0.0, 1.0, 2.0, -4.0]) + ); + } } fn simd_intrinsics() { @@ -724,8 +980,10 @@ fn simd_ops_non_pow2() { fn main() { simd_mask(); + simd_ops_f16(); simd_ops_f32(); simd_ops_f64(); + simd_ops_f128(); simd_ops_i32(); simd_ops_non_pow2(); simd_cast(); From 1af9b63c7b0d3c12a77eb5f0971823067a148d57 Mon Sep 17 00:00:00 2001 From: Zhongyao Chen Date: Mon, 3 Nov 2025 16:17:04 +0800 Subject: [PATCH 332/525] Implement the MCP 932: Promote riscv64a23-unknown-linux-gnu to Tier 2 without host tools Changes: - Update target tier from 3 to 2 in target specification - Update platform documentation - Add CI/CD support for automatic building and distribution via rustup --- .../targets/riscv64a23_unknown_linux_gnu.rs | 4 ++-- .../host-x86_64/dist-riscv64-linux/Dockerfile | 8 ++++++-- .../riscv64a23-unknown-linux-gnu.md | 20 ++++++++++--------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs index 60f2e7da042c..339f0ec53e58 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs @@ -7,8 +7,8 @@ pub(crate) fn target() -> Target { llvm_target: "riscv64-unknown-linux-gnu".into(), metadata: TargetMetadata { description: Some("RISC-V Linux (kernel 6.8.0, glibc 2.39)".into()), - tier: Some(3), - host_tools: Some(true), + tier: Some(2), + host_tools: Some(false), std: Some(true), }, pointer_width: 64, diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile index 4d9334dde8c5..4a66564a90ac 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile @@ -22,9 +22,13 @@ ENV PATH=$PATH:/x-tools/riscv64-unknown-linux-gnu/bin ENV CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ - CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ + CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \ + CC_riscv64a23_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ + AR_riscv64a23_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ + CXX_riscv64a23_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ ENV HOSTS=riscv64gc-unknown-linux-gnu +ENV TARGETS=riscv64gc-unknown-linux-gnu,riscv64a23-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --target $HOSTS --host $HOSTS +ENV SCRIPT python3 ../x.py dist --target $TARGETS --host $HOSTS diff --git a/src/doc/rustc/src/platform-support/riscv64a23-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64a23-unknown-linux-gnu.md index 2cbaaa866541..e24e93f7a18f 100644 --- a/src/doc/rustc/src/platform-support/riscv64a23-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64a23-unknown-linux-gnu.md @@ -1,6 +1,6 @@ # `riscv64a23-unknown-linux-gnu` -**Tier: 3** +**Tier: 2 (without Host Tools)** RISC-V target using the ratified [RVA23 Profile](https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc). This target will enable all mandary features of rva23u64 by default. @@ -18,24 +18,26 @@ Other platforms may work, but are not tested. Please contanct if you encounter a ## Building the target -Tier-3 target is not distributed through `rustup`. - -You need to build your own Rust, the target can be build with: +Tier-2 targets are distributed through `rustup`. Install the target with: ```bash -./x build --target riscv64a23-unknown-linux-gnu +rustup target add riscv64a23-unknown-linux-gnu ``` ## Building Rust programs -Add the toolchain: +Cross compile crates with: ```bash -rustup toolchain link rva23-toolchain {path-to-rust}/build/host/stage2 +cargo build --target=riscv64a23-unknown-linux-gnu ``` -Then cross compile crates with: +For cross-compilation, you may need to install the appropriate linker: ```bash -RUSTFLAGS="-C linker=riscv64-linux-gnu-gcc" cargo +rva23-toolchain build --target=riscv64a23-unknown-linux-gnu +# Ubuntu/Debian +sudo apt-get install gcc-riscv64-linux-gnu + +# Then set the linker +RUSTFLAGS="-C linker=riscv64-linux-gnu-gcc" cargo build --target=riscv64a23-unknown-linux-gnu ``` From c6a8c46b6c7678dcd965dcf523482a436218ff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 22 Oct 2025 16:54:07 +0200 Subject: [PATCH 333/525] add test for duplicate warning on used deprecated unit structs Co-authored-by: Waffle Lapkin --- tests/ui/deprecation/unit_and_tuple_struct.rs | 50 +++++++++ .../deprecation/unit_and_tuple_struct.stderr | 104 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 tests/ui/deprecation/unit_and_tuple_struct.rs create mode 100644 tests/ui/deprecation/unit_and_tuple_struct.stderr diff --git a/tests/ui/deprecation/unit_and_tuple_struct.rs b/tests/ui/deprecation/unit_and_tuple_struct.rs new file mode 100644 index 000000000000..c1f757d9547d --- /dev/null +++ b/tests/ui/deprecation/unit_and_tuple_struct.rs @@ -0,0 +1,50 @@ +#![deny(deprecated)] +#![allow(unused_imports)] + +#[deprecated] +pub mod a { + pub struct Foo; + pub struct Bar(); + pub struct Baz {} + + pub enum Enum { + VFoo, + VBar(), + VBaz {}, + } +} + + +use a::Foo; +//~^ ERROR use of deprecated struct `a::Foo` +//~| ERROR use of deprecated unit struct `a::Foo` +use a::Bar; +//~^ ERROR use of deprecated struct `a::Bar` +//~| ERROR use of deprecated tuple struct `a::Bar` +use a::Baz; +//~^ ERROR use of deprecated struct `a::Baz` + +use a::Enum::VFoo; +//~^ ERROR use of deprecated variant `a::Enum::VFoo` +//~| ERROR use of deprecated unit variant `a::Enum::VFoo` +use a::Enum::VBar; +//~^ ERROR use of deprecated variant `a::Enum::VBar` +//~| ERROR use of deprecated tuple variant `a::Enum::VBar` +use a::Enum::VBaz; +//~^ ERROR use of deprecated variant `a::Enum::VBaz` + +fn main() { + a::Foo; + //~^ ERROR use of deprecated unit struct `a::Foo` + a::Bar(); + //~^ ERROR use of deprecated tuple struct `a::Bar` + a::Baz {}; + //~^ ERROR use of deprecated struct `a::Baz` + + a::Enum::VFoo; + //~^ ERROR use of deprecated unit variant `a::Enum::VFoo` + a::Enum::VBar(); + //~^ ERROR use of deprecated tuple variant `a::Enum::VBar` + a::Enum::VBaz{}; + //~^ ERROR use of deprecated variant `a::Enum::VBaz` +} diff --git a/tests/ui/deprecation/unit_and_tuple_struct.stderr b/tests/ui/deprecation/unit_and_tuple_struct.stderr new file mode 100644 index 000000000000..5d1c4dcb23c3 --- /dev/null +++ b/tests/ui/deprecation/unit_and_tuple_struct.stderr @@ -0,0 +1,104 @@ +error: use of deprecated struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:18:8 + | +LL | use a::Foo; + | ^^^ + | +note: the lint level is defined here + --> $DIR/unit_and_tuple_struct.rs:1:9 + | +LL | #![deny(deprecated)] + | ^^^^^^^^^^ + +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:18:8 + | +LL | use a::Foo; + | ^^^ + +error: use of deprecated struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:21:8 + | +LL | use a::Bar; + | ^^^ + +error: use of deprecated tuple struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:21:8 + | +LL | use a::Bar; + | ^^^ + +error: use of deprecated struct `a::Baz` + --> $DIR/unit_and_tuple_struct.rs:24:8 + | +LL | use a::Baz; + | ^^^ + +error: use of deprecated variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:27:14 + | +LL | use a::Enum::VFoo; + | ^^^^ + +error: use of deprecated unit variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:27:14 + | +LL | use a::Enum::VFoo; + | ^^^^ + +error: use of deprecated variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:30:14 + | +LL | use a::Enum::VBar; + | ^^^^ + +error: use of deprecated tuple variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:30:14 + | +LL | use a::Enum::VBar; + | ^^^^ + +error: use of deprecated variant `a::Enum::VBaz` + --> $DIR/unit_and_tuple_struct.rs:33:14 + | +LL | use a::Enum::VBaz; + | ^^^^ + +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:37:6 + | +LL | a::Foo; + | ^^^ + +error: use of deprecated tuple struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:39:6 + | +LL | a::Bar(); + | ^^^ + +error: use of deprecated struct `a::Baz` + --> $DIR/unit_and_tuple_struct.rs:41:6 + | +LL | a::Baz {}; + | ^^^ + +error: use of deprecated unit variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:44:12 + | +LL | a::Enum::VFoo; + | ^^^^ + +error: use of deprecated tuple variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:46:12 + | +LL | a::Enum::VBar(); + | ^^^^ + +error: use of deprecated variant `a::Enum::VBaz` + --> $DIR/unit_and_tuple_struct.rs:48:12 + | +LL | a::Enum::VBaz{}; + | ^^^^ + +error: aborting due to 16 previous errors + From 1b00911b5b247c7da7089b140a0806269dca6905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 28 Oct 2025 16:24:14 +0100 Subject: [PATCH 334/525] deduplicate warnings (attempt 2) --- compiler/rustc_passes/src/stability.rs | 33 +++++++++++- tests/ui/deprecation/unit_and_tuple_struct.rs | 13 ++--- .../deprecation/unit_and_tuple_struct.stderr | 52 +++++-------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 2ee1bd0dfd1e..af78954ba154 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -12,8 +12,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor, VisitorExt}; use rustc_hir::{ - self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, Item, ItemKind, - Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, + self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, HirId, Item, ItemKind, + Path, Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, UsePath, VERSION_PLACEHOLDER, Variant, find_attr, }; use rustc_middle::hir::nested_filter; @@ -739,6 +739,35 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { intravisit::walk_poly_trait_ref(self, t); } + fn visit_use(&mut self, path: &'tcx UsePath<'tcx>, hir_id: HirId) { + let res = path.res; + + // A use item can import something from two namespaces at the same time. + // For deprecation/stability we don't want to warn twice. + // This specifically happens with constructors for unit/tuple structs. + if let Some(ty_ns_res) = res.type_ns + && let Some(value_ns_res) = res.value_ns + && let Some(type_ns_did) = ty_ns_res.opt_def_id() + && let Some(value_ns_did) = value_ns_res.opt_def_id() + && let DefKind::Ctor(.., _) = self.tcx.def_kind(value_ns_did) + && self.tcx.parent(value_ns_did) == type_ns_did + { + // Only visit the value namespace path when we've detected a duplicate, + // not the type namespace path. + let UsePath { segments, res: _, span } = *path; + self.visit_path(&Path { segments, res: value_ns_res, span }, hir_id); + + // Though, visit the macro namespace if it exists, + // regardless of the checks above relating to constructors. + if let Some(res) = res.macro_ns { + self.visit_path(&Path { segments, res, span }, hir_id); + } + } else { + // if there's no duplicate, just walk as normal + intravisit::walk_use(self, path, hir_id) + } + } + fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) { if let Some(def_id) = path.res.opt_def_id() { let method_span = path.segments.last().map(|s| s.ident.span); diff --git a/tests/ui/deprecation/unit_and_tuple_struct.rs b/tests/ui/deprecation/unit_and_tuple_struct.rs index c1f757d9547d..5f1484e7431d 100644 --- a/tests/ui/deprecation/unit_and_tuple_struct.rs +++ b/tests/ui/deprecation/unit_and_tuple_struct.rs @@ -1,5 +1,4 @@ #![deny(deprecated)] -#![allow(unused_imports)] #[deprecated] pub mod a { @@ -16,20 +15,16 @@ pub mod a { use a::Foo; -//~^ ERROR use of deprecated struct `a::Foo` -//~| ERROR use of deprecated unit struct `a::Foo` +//~^ ERROR use of deprecated unit struct `a::Foo` use a::Bar; -//~^ ERROR use of deprecated struct `a::Bar` -//~| ERROR use of deprecated tuple struct `a::Bar` +//~^ ERROR use of deprecated tuple struct `a::Bar` use a::Baz; //~^ ERROR use of deprecated struct `a::Baz` use a::Enum::VFoo; -//~^ ERROR use of deprecated variant `a::Enum::VFoo` -//~| ERROR use of deprecated unit variant `a::Enum::VFoo` +//~^ ERROR use of deprecated unit variant `a::Enum::VFoo` use a::Enum::VBar; -//~^ ERROR use of deprecated variant `a::Enum::VBar` -//~| ERROR use of deprecated tuple variant `a::Enum::VBar` +//~^ ERROR use of deprecated tuple variant `a::Enum::VBar` use a::Enum::VBaz; //~^ ERROR use of deprecated variant `a::Enum::VBaz` diff --git a/tests/ui/deprecation/unit_and_tuple_struct.stderr b/tests/ui/deprecation/unit_and_tuple_struct.stderr index 5d1c4dcb23c3..4408eaefb81e 100644 --- a/tests/ui/deprecation/unit_and_tuple_struct.stderr +++ b/tests/ui/deprecation/unit_and_tuple_struct.stderr @@ -1,5 +1,5 @@ -error: use of deprecated struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:18:8 +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:17:8 | LL | use a::Foo; | ^^^ @@ -10,95 +10,71 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated unit struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:18:8 - | -LL | use a::Foo; - | ^^^ - -error: use of deprecated struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:21:8 - | -LL | use a::Bar; - | ^^^ - error: use of deprecated tuple struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:21:8 + --> $DIR/unit_and_tuple_struct.rs:19:8 | LL | use a::Bar; | ^^^ error: use of deprecated struct `a::Baz` - --> $DIR/unit_and_tuple_struct.rs:24:8 + --> $DIR/unit_and_tuple_struct.rs:21:8 | LL | use a::Baz; | ^^^ -error: use of deprecated variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:27:14 - | -LL | use a::Enum::VFoo; - | ^^^^ - error: use of deprecated unit variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:27:14 + --> $DIR/unit_and_tuple_struct.rs:24:14 | LL | use a::Enum::VFoo; | ^^^^ -error: use of deprecated variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:30:14 - | -LL | use a::Enum::VBar; - | ^^^^ - error: use of deprecated tuple variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:30:14 + --> $DIR/unit_and_tuple_struct.rs:26:14 | LL | use a::Enum::VBar; | ^^^^ error: use of deprecated variant `a::Enum::VBaz` - --> $DIR/unit_and_tuple_struct.rs:33:14 + --> $DIR/unit_and_tuple_struct.rs:28:14 | LL | use a::Enum::VBaz; | ^^^^ error: use of deprecated unit struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:37:6 + --> $DIR/unit_and_tuple_struct.rs:32:6 | LL | a::Foo; | ^^^ error: use of deprecated tuple struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:39:6 + --> $DIR/unit_and_tuple_struct.rs:34:6 | LL | a::Bar(); | ^^^ error: use of deprecated struct `a::Baz` - --> $DIR/unit_and_tuple_struct.rs:41:6 + --> $DIR/unit_and_tuple_struct.rs:36:6 | LL | a::Baz {}; | ^^^ error: use of deprecated unit variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:44:12 + --> $DIR/unit_and_tuple_struct.rs:39:12 | LL | a::Enum::VFoo; | ^^^^ error: use of deprecated tuple variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:46:12 + --> $DIR/unit_and_tuple_struct.rs:41:12 | LL | a::Enum::VBar(); | ^^^^ error: use of deprecated variant `a::Enum::VBaz` - --> $DIR/unit_and_tuple_struct.rs:48:12 + --> $DIR/unit_and_tuple_struct.rs:43:12 | LL | a::Enum::VBaz{}; | ^^^^ -error: aborting due to 16 previous errors +error: aborting due to 12 previous errors From accd1fe76c8250a4aadfa9e372f6ba9b8e2e374c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 24 Oct 2025 15:40:43 +0200 Subject: [PATCH 335/525] rustdoc: Use configured target modifiers when collecting doctests To support loading dependencies with target modifiers and avoid ABI mismatch errors. --- src/librustdoc/doctest.rs | 1 + .../rustdoc-target-modifiers/rmake.rs | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 51f79047f991..e6b7a6bfcfb6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -166,6 +166,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions remap_path_prefix: options.remap_path_prefix.clone(), unstable_opts: options.unstable_opts.clone(), error_format: options.error_format.clone(), + target_modifiers: options.target_modifiers.clone(), ..config::Options::default() }; diff --git a/tests/run-make/rustdoc-target-modifiers/rmake.rs b/tests/run-make/rustdoc-target-modifiers/rmake.rs index ee522501fd28..ffe87f3f7650 100644 --- a/tests/run-make/rustdoc-target-modifiers/rmake.rs +++ b/tests/run-make/rustdoc-target-modifiers/rmake.rs @@ -25,4 +25,43 @@ fn main() { .target("aarch64-unknown-none-softfloat") .arg("-Zfixed-x18") .run(); + + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("-Zfixed-x18") + .arg("--test") + .run(); + + rustdoc() + .input("c.rs") + .edition("2024") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("-Zfixed-x18") + .arg("--test") + .run(); + + // rustdoc --test detects ABI mismatch + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("--test") + .run_fail() + .assert_stderr_contains("mixing `-Zfixed-x18` will cause an ABI mismatch"); + + // rustdoc --test -Cunsafe-allow-abi-mismatch=... ignores the mismatch + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("--test") + .arg("-Cunsafe-allow-abi-mismatch=fixed-x18") + .run(); } From 5b96677adb0f879f7a991913baa0c1f9609af556 Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Mon, 3 Nov 2025 12:35:30 +0100 Subject: [PATCH 336/525] add specialization for extend_front and prepend with copied slice iterator --- .../alloc/src/collections/vec_deque/mod.rs | 29 ++++++++ .../src/collections/vec_deque/spec_extend.rs | 71 +++++++++++-------- library/alloc/src/lib.rs | 1 + library/alloctests/lib.rs | 2 + library/alloctests/tests/vec_deque.rs | 41 +++++++++-- library/core/src/iter/adapters/copied.rs | 6 ++ 6 files changed, 117 insertions(+), 33 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index fc0220022dbb..a85c874d54de 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -520,6 +520,35 @@ impl VecDeque { } } + /// Copies all values from `src` to `dst` in reversed order, wrapping around if needed. + /// Assumes capacity is sufficient. + /// Equivalent to calling [`VecDeque::copy_slice`] with a [reversed](https://doc.rust-lang.org/std/primitive.slice.html#method.reverse) slice. + #[inline] + unsafe fn copy_slice_reversed(&mut self, dst: usize, src: &[T]) { + /// # Safety + /// + /// See [`ptr::copy_nonoverlapping`]. + unsafe fn copy_nonoverlapping_reversed(src: *const T, dst: *mut T, count: usize) { + for i in 0..count { + unsafe { ptr::copy_nonoverlapping(src.add(count - 1 - i), dst.add(i), 1) }; + } + } + + debug_assert!(src.len() <= self.capacity()); + let head_room = self.capacity() - dst; + if src.len() <= head_room { + unsafe { + copy_nonoverlapping_reversed(src.as_ptr(), self.ptr().add(dst), src.len()); + } + } else { + let (left, right) = src.split_at(src.len() - head_room); + unsafe { + copy_nonoverlapping_reversed(right.as_ptr(), self.ptr().add(dst), right.len()); + copy_nonoverlapping_reversed(left.as_ptr(), self.ptr(), left.len()); + } + } + } + /// Writes all values from `iter` to `dst`. /// /// # Safety diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index 3e830d2afe67..f73ba795cbea 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -1,6 +1,4 @@ -#[cfg(not(test))] -use core::iter::Rev; -use core::iter::TrustedLen; +use core::iter::{Copied, Rev, TrustedLen}; use core::slice; use super::VecDeque; @@ -158,9 +156,9 @@ where impl SpecExtendFront> for VecDeque { #[track_caller] fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { - let slice = iterator.as_mut_slice(); - slice.reverse(); - unsafe { prepend(self, slice) }; + let slice = iterator.as_slice(); + // SAFETY: elements in the slice are forgotten after this call + unsafe { prepend_reversed(self, slice) }; iterator.forget_remaining_elements(); } } @@ -170,36 +168,40 @@ impl SpecExtendFront>> for VecDeque>) { let mut iterator = iterator.into_inner(); - unsafe { prepend(self, iterator.as_slice()) }; + let slice = iterator.as_slice(); + // SAFETY: elements in the slice are forgotten after this call + unsafe { prepend(self, slice) }; iterator.forget_remaining_elements(); } } -// impl SpecExtendFront>> for VecDeque -// where -// T: Copy, -// { -// #[track_caller] -// fn spec_extend_front(&mut self, _iter: Copied>) { -// // unsafe { prepend(self, slice) }; -// // reverse in place? -// } -// } +impl<'a, T, A: Allocator> SpecExtendFront>> for VecDeque +where + Copied>: Iterator, +{ + #[track_caller] + fn spec_extend_front(&mut self, iter: Copied>) { + let slice = iter.into_inner().as_slice(); + // SAFETY: T is Copy because Copied> is Iterator + unsafe { prepend_reversed(self, slice) }; + } +} -// impl SpecExtendFront>>> for VecDeque -// where -// T: Copy, -// { -// #[track_caller] -// fn spec_extend_front(&mut self, iter: Rev>>) { -// unsafe { prepend(self, iter.into_inner().it.as_slice()) }; -// } -// } +impl<'a, T, A: Allocator> SpecExtendFront>>> for VecDeque +where + Rev>>: Iterator, +{ + #[track_caller] + fn spec_extend_front(&mut self, iter: Rev>>) { + let slice = iter.into_inner().into_inner().as_slice(); + // SAFETY: T is Copy because Rev>> is Iterator + unsafe { prepend(self, slice) }; + } +} /// # Safety /// -/// `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. -#[cfg(not(test))] +/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { deque.reserve(slice.len()); @@ -209,3 +211,16 @@ unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { deque.len += slice.len(); } } + +/// # Safety +/// +/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +unsafe fn prepend_reversed(deque: &mut VecDeque, slice: &[T]) { + deque.reserve(slice.len()); + + unsafe { + deque.head = deque.wrap_sub(deque.head, slice.len()); + deque.copy_slice_reversed(deque.head, slice); + deque.len += slice.len(); + } +} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 81feb1cfc3f2..73197d021f1a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,6 +106,7 @@ #![feature(const_default)] #![feature(const_eval_select)] #![feature(const_heap)] +#![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 0201c8752210..efdcb893bfee 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -20,6 +20,7 @@ #![feature(assert_matches)] #![feature(char_internals)] #![feature(char_max_len)] +#![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(exact_size_is_empty)] #![feature(extend_one)] @@ -32,6 +33,7 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(ptr_alignment_type)] #![feature(ptr_internals)] +#![feature(rev_into_inner)] #![feature(sized_type_properties)] #![feature(slice_iter_mut_as_mut_slice)] #![feature(slice_ptr_get)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 6442ee536fb5..cf31613577f7 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -2113,14 +2113,45 @@ fn test_extend_front() { } #[test] -fn test_extend_front_specialization() { +fn test_extend_front_specialization_vec_into_iter() { + // trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap let mut v = VecDeque::with_capacity(4); v.prepend(vec![1, 2, 3]); assert_eq!(v, [1, 2, 3]); - v.pop_front(); - v.prepend((-4..2).collect::>()); - assert_eq!(v, (-4..=3).collect::>()); - v.clear(); + v.pop_back(); + // this should wrap around the physical buffer + v.prepend(vec![-1, 0]); + // check it really wrapped + assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice())); + + let mut v = VecDeque::with_capacity(4); v.extend_front(vec![1, 2, 3]); assert_eq!(v, [3, 2, 1]); + v.pop_back(); + // this should wrap around the physical buffer + v.extend_front(vec![4, 5]); + // check it really wrapped + assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); +} + +#[test] +fn test_extend_front_specialization_copy_slice() { + // trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap + let mut v = VecDeque::with_capacity(4); + v.prepend([1, 2, 3].as_slice().iter().copied()); + assert_eq!(v, [1, 2, 3]); + v.pop_back(); + // this should wrap around the physical buffer + v.prepend([-1, 0].as_slice().iter().copied()); + // check it really wrapped + assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice())); + + let mut v = VecDeque::with_capacity(4); + v.extend_front([1, 2, 3].as_slice().iter().copied()); + assert_eq!(v, [3, 2, 1]); + v.pop_back(); + // this should wrap around the physical buffer + v.extend_front([4, 5].as_slice().iter().copied()); + // check it really wrapped + assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 23e4e25ab538..9627ace29795 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -24,6 +24,12 @@ impl Copied { pub(in crate::iter) fn new(it: I) -> Copied { Copied { it } } + + #[doc(hidden)] + #[unstable(feature = "copied_into_inner", issue = "none")] + pub fn into_inner(self) -> I { + self.it + } } fn copy_fold(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc { From 4aeb2970640cc81926f06b40ef9c7841064a4c28 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 3 Nov 2025 19:39:50 +0800 Subject: [PATCH 337/525] Revert "unicode_data refactors RUST-147622" This PR reverts RUST-147622 for several reasons: 1. The RUST-147622 PR would format the generated core library code using an arbitrary `rustfmt` picked up from `PATH`, which will cause hard-to-debug failures when the `rustfmt` used to format the generated unicode data code versus the `rustfmt` used to format the in-tree library code. 2. Previously, the `unicode-table-generator` tests were not run under CI as part of `coretests`, and since for `x86_64-gnu-aux` job we run library `coretests` with `miri`, the generated tests unfortunately caused an unacceptably large Merge CI time regression from ~2 hours to ~3.5 hours, making it the slowest Merge CI job (and thus the new bottleneck). 3. This PR also has an unintended effect of causing a diagnostic regression (RUST-148387), though that's mostly an edge case not properly handled by `rustc` diagnostics. Given that these are three distinct causes with non-trivial fixes, I'm proposing to revert this PR to return us to baseline. This is not prejudice against relanding the changes with these issues addressed, but to alleviate time pressure to address these non-trivial issues. --- library/core/src/unicode/mod.rs | 3 +- library/core/src/unicode/unicode_data.rs | 2543 +++++++------- library/coretests/tests/lib.rs | 1 - library/coretests/tests/unicode.rs | 96 - library/coretests/tests/unicode/test_data.rs | 2928 ----------------- src/bootstrap/src/core/build_steps/run.rs | 1 - .../src/cascading_map.rs | 39 +- .../src/case_mapping.rs | 126 +- .../src/fmt_helpers.rs | 82 - src/tools/unicode-table-generator/src/main.rs | 221 +- .../src/range_search.rs | 46 +- .../src/raw_emitter.rs | 94 +- .../unicode-table-generator/src/skiplist.rs | 104 +- 13 files changed, 1588 insertions(+), 4696 deletions(-) delete mode 100644 library/coretests/tests/unicode/test_data.rs delete mode 100644 src/tools/unicode-table-generator/src/fmt_helpers.rs rename library/core/src/unicode/rt.rs => src/tools/unicode-table-generator/src/range_search.rs (76%) diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 1ee97d64d01b..c71fa754e68f 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -18,9 +18,8 @@ pub(crate) use unicode_data::white_space::lookup as White_Space; pub(crate) mod printable; -mod rt; #[allow(unreachable_pub)] -pub mod unicode_data; +mod unicode_data; /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of /// `char` and `str` methods are based on. diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 81d0484310cf..3c38b44224f8 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -11,64 +11,167 @@ // to_upper : 13656 bytes // Total : 31911 bytes -use super::rt::*; +#[inline(always)] +const fn bitset_search< + const N: usize, + const CHUNK_SIZE: usize, + const N1: usize, + const CANONICAL: usize, + const CANONICALIZED: usize, +>( + needle: u32, + chunk_idx_map: &[u8; N], + bitset_chunk_idx: &[[u8; CHUNK_SIZE]; N1], + bitset_canonical: &[u64; CANONICAL], + bitset_canonicalized: &[(u8, u8); CANONICALIZED], +) -> bool { + let bucket_idx = (needle / 64) as usize; + let chunk_map_idx = bucket_idx / CHUNK_SIZE; + let chunk_piece = bucket_idx % CHUNK_SIZE; + // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const. + let chunk_idx = if chunk_map_idx < chunk_idx_map.len() { + chunk_idx_map[chunk_map_idx] + } else { + return false; + }; + let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize; + // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const. + let word = if idx < bitset_canonical.len() { + bitset_canonical[idx] + } else { + let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()]; + let mut word = bitset_canonical[real_idx as usize]; + let should_invert = mapping & (1 << 6) != 0; + if should_invert { + word = !word; + } + // Lower 6 bits + let quantity = mapping & ((1 << 6) - 1); + if mapping & (1 << 7) != 0 { + // shift + word >>= quantity as u64; + } else { + word = word.rotate_left(quantity as u32); + } + word + }; + (word & (1 << (needle % 64) as u64)) != 0 +} + +#[repr(transparent)] +struct ShortOffsetRunHeader(u32); + +impl ShortOffsetRunHeader { + const fn new(start_index: usize, prefix_sum: u32) -> Self { + assert!(start_index < (1 << 11)); + assert!(prefix_sum < (1 << 21)); + + Self((start_index as u32) << 21 | prefix_sum) + } + + #[inline] + const fn start_index(&self) -> usize { + (self.0 >> 21) as usize + } + + #[inline] + const fn prefix_sum(&self) -> u32 { + self.0 & ((1 << 21) - 1) + } +} + +/// # Safety +/// +/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`. +/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`. +#[inline(always)] +unsafe fn skip_search( + needle: char, + short_offset_runs: &[ShortOffsetRunHeader; SOR], + offsets: &[u8; OFFSETS], +) -> bool { + let needle = needle as u32; + + let last_idx = + match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) { + Ok(idx) => idx + 1, + Err(idx) => idx, + }; + // SAFETY: `last_idx` *cannot* be past the end of the array, as the last + // element is greater than `std::char::MAX` (the largest possible needle) + // as guaranteed by the caller. + // + // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the + // correct location cannot be past it, so `Err(idx) => idx != length` either. + // + // This means that we can avoid bounds checking for the accesses below, too. + // + // We need to use `intrinsics::assume` since the `panic_nounwind` contained + // in `hint::assert_unchecked` may not be optimized out. + unsafe { crate::intrinsics::assume(last_idx < SOR) }; + + let mut offset_idx = short_offset_runs[last_idx].start_index(); + let length = if let Some(next) = short_offset_runs.get(last_idx + 1) { + (*next).start_index() - offset_idx + } else { + offsets.len() - offset_idx + }; + + let prev = + last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0); + + let total = needle - prev; + let mut prefix_sum = 0; + for _ in 0..(length - 1) { + // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`, + // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore + // `offset_idx < OFFSETS` is always true in this loop. + // + // We need to use `intrinsics::assume` since the `panic_nounwind` contained + // in `hint::assert_unchecked` may not be optimized out. + unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) }; + let offset = offsets[offset_idx]; + prefix_sum += offset as u32; + if prefix_sum > total { + break; + } + offset_idx += 1; + } + offset_idx % 2 == 1 +} pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0); +#[rustfmt::skip] pub mod alphabetic { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 51] = [ - ShortOffsetRunHeader::new(0, 706), - ShortOffsetRunHeader::new(12, 4681), - ShortOffsetRunHeader::new(414, 5741), - ShortOffsetRunHeader::new(452, 7958), - ShortOffsetRunHeader::new(552, 9398), - ShortOffsetRunHeader::new(623, 11264), - ShortOffsetRunHeader::new(625, 12293), - ShortOffsetRunHeader::new(663, 13312), - ShortOffsetRunHeader::new(687, 19904), - ShortOffsetRunHeader::new(688, 42125), - ShortOffsetRunHeader::new(690, 42509), - ShortOffsetRunHeader::new(694, 55204), - ShortOffsetRunHeader::new(778, 63744), - ShortOffsetRunHeader::new(783, 64110), - ShortOffsetRunHeader::new(784, 64830), - ShortOffsetRunHeader::new(806, 66176), - ShortOffsetRunHeader::new(847, 67383), - ShortOffsetRunHeader::new(894, 73440), - ShortOffsetRunHeader::new(1217, 74650), - ShortOffsetRunHeader::new(1228, 77712), - ShortOffsetRunHeader::new(1233, 78896), - ShortOffsetRunHeader::new(1236, 82939), - ShortOffsetRunHeader::new(1240, 83527), - ShortOffsetRunHeader::new(1242, 90368), - ShortOffsetRunHeader::new(1243, 92160), - ShortOffsetRunHeader::new(1245, 92729), - ShortOffsetRunHeader::new(1246, 93504), - ShortOffsetRunHeader::new(1261, 101590), - ShortOffsetRunHeader::new(1282, 110576), - ShortOffsetRunHeader::new(1287, 110883), - ShortOffsetRunHeader::new(1294, 111356), - ShortOffsetRunHeader::new(1304, 113664), - ShortOffsetRunHeader::new(1305, 119808), - ShortOffsetRunHeader::new(1315, 120486), - ShortOffsetRunHeader::new(1352, 122624), - ShortOffsetRunHeader::new(1375, 123536), - ShortOffsetRunHeader::new(1399, 124112), - ShortOffsetRunHeader::new(1403, 126464), - ShortOffsetRunHeader::new(1431, 127280), - ShortOffsetRunHeader::new(1497, 131072), - ShortOffsetRunHeader::new(1503, 173792), - ShortOffsetRunHeader::new(1504, 178206), - ShortOffsetRunHeader::new(1506, 183982), - ShortOffsetRunHeader::new(1508, 191457), - ShortOffsetRunHeader::new(1510, 192094), - ShortOffsetRunHeader::new(1512, 194560), - ShortOffsetRunHeader::new(1513, 195102), - ShortOffsetRunHeader::new(1514, 196608), - ShortOffsetRunHeader::new(1515, 201547), - ShortOffsetRunHeader::new(1516, 210042), + ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(12, 4681), + ShortOffsetRunHeader::new(414, 5741), ShortOffsetRunHeader::new(452, 7958), + ShortOffsetRunHeader::new(552, 9398), ShortOffsetRunHeader::new(623, 11264), + ShortOffsetRunHeader::new(625, 12293), ShortOffsetRunHeader::new(663, 13312), + ShortOffsetRunHeader::new(687, 19904), ShortOffsetRunHeader::new(688, 42125), + ShortOffsetRunHeader::new(690, 42509), ShortOffsetRunHeader::new(694, 55204), + ShortOffsetRunHeader::new(778, 63744), ShortOffsetRunHeader::new(783, 64110), + ShortOffsetRunHeader::new(784, 64830), ShortOffsetRunHeader::new(806, 66176), + ShortOffsetRunHeader::new(847, 67383), ShortOffsetRunHeader::new(894, 73440), + ShortOffsetRunHeader::new(1217, 74650), ShortOffsetRunHeader::new(1228, 77712), + ShortOffsetRunHeader::new(1233, 78896), ShortOffsetRunHeader::new(1236, 82939), + ShortOffsetRunHeader::new(1240, 83527), ShortOffsetRunHeader::new(1242, 90368), + ShortOffsetRunHeader::new(1243, 92160), ShortOffsetRunHeader::new(1245, 92729), + ShortOffsetRunHeader::new(1246, 93504), ShortOffsetRunHeader::new(1261, 101590), + ShortOffsetRunHeader::new(1282, 110576), ShortOffsetRunHeader::new(1287, 110883), + ShortOffsetRunHeader::new(1294, 111356), ShortOffsetRunHeader::new(1304, 113664), + ShortOffsetRunHeader::new(1305, 119808), ShortOffsetRunHeader::new(1315, 120486), + ShortOffsetRunHeader::new(1352, 122624), ShortOffsetRunHeader::new(1375, 123536), + ShortOffsetRunHeader::new(1399, 124112), ShortOffsetRunHeader::new(1403, 126464), + ShortOffsetRunHeader::new(1431, 127280), ShortOffsetRunHeader::new(1497, 131072), + ShortOffsetRunHeader::new(1503, 173792), ShortOffsetRunHeader::new(1504, 178206), + ShortOffsetRunHeader::new(1506, 183982), ShortOffsetRunHeader::new(1508, 191457), + ShortOffsetRunHeader::new(1510, 192094), ShortOffsetRunHeader::new(1512, 194560), + ShortOffsetRunHeader::new(1513, 195102), ShortOffsetRunHeader::new(1514, 196608), + ShortOffsetRunHeader::new(1515, 201547), ShortOffsetRunHeader::new(1516, 210042), ShortOffsetRunHeader::new(1518, 1324154), ]; static OFFSETS: [u8; 1519] = [ @@ -77,60 +180,58 @@ pub mod alphabetic { 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10, 3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 7, 7, 1, 8, 42, 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8, - 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, - 2, 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, - 1, 5, 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, - 8, 2, 2, 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, - 3, 3, 12, 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, - 1, 3, 1, 2, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 5, 3, 1, - 4, 13, 3, 12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, - 24, 1, 9, 1, 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, - 24, 1, 1, 1, 19, 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, - 67, 55, 1, 1, 2, 5, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, - 2, 41, 1, 4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, - 6, 3, 0, 2, 17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, - 19, 14, 1, 4, 1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, - 54, 28, 4, 63, 2, 20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, - 11, 14, 55, 22, 3, 10, 36, 2, 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, - 0, 2, 6, 2, 38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, - 2, 6, 4, 13, 5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, - 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, - 1, 2, 56, 7, 1, 16, 23, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, - 25, 9, 7, 5, 2, 5, 4, 86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, - 46, 2, 0, 3, 16, 10, 2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 82, 20, 21, 1, 33, 24, 52, - 12, 68, 1, 1, 44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, - 1, 55, 9, 14, 18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, - 1, 43, 1, 14, 6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, - 1, 1, 1, 2, 1, 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, - 89, 3, 6, 2, 6, 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, - 29, 3, 49, 47, 32, 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, - 8, 52, 12, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, - 6, 1, 42, 1, 9, 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, - 10, 26, 6, 26, 38, 56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, - 27, 54, 10, 22, 10, 19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, - 42, 1, 2, 3, 2, 16, 6, 50, 3, 3, 29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, - 10, 57, 9, 1, 13, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, - 1, 34, 2, 1, 6, 4, 62, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, - 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, - 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, 66, 1, 3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, - 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, - 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, - 72, 5, 1, 18, 73, 103, 8, 88, 33, 31, 9, 1, 45, 1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, - 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 23, 44, 0, - 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111, 17, 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, - 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16, 4, 31, 21, 5, 19, 0, 45, 211, 64, 32, 25, - 2, 25, 44, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 7, 9, 0, 41, 32, 97, 115, 0, 4, 1, 7, 1, 2, - 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, - 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, - 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, - 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, 10, 7, 16, 1, 0, 30, 18, - 44, 0, 28, 228, 30, 2, 1, 207, 31, 1, 22, 8, 2, 224, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, - 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, - 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, - 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, 32, 0, 2, 0, 2, 0, 15, 0, 0, 0, - 0, 0, 5, 0, 0, + 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2, + 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5, + 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, + 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12, + 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3, 1, + 2, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 5, 3, 1, 4, 13, 3, + 12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1, + 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19, + 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, 55, 1, 1, 2, 5, + 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33, + 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26, + 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1, 67, 89, + 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2, 20, 50, 1, + 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36, 2, + 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8, 1, + 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, 1, + 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5, + 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23, 9, 7, 1, + 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4, 86, 6, 3, + 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10, 2, 20, 47, + 5, 8, 3, 113, 39, 9, 2, 103, 2, 82, 20, 21, 1, 33, 24, 52, 12, 68, 1, 1, 44, 6, 3, 1, 1, 3, + 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14, 18, 23, 3, 69, 1, + 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14, 6, 123, 21, 0, 12, + 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1, 2, 1, 2, 1, 108, 33, 0, + 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6, 2, 6, 2, 6, 2, 3, 35, + 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49, 47, 32, 13, 30, 5, 43, + 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12, 11, 1, 15, 1, 7, 1, 2, + 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 9, 69, 6, 2, 1, 1, + 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 6, 26, 38, 56, 6, 2, 64, + 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10, 19, 13, 18, + 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, 3, 2, 16, 6, 50, 3, 3, + 29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23, 51, 17, 4, + 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1, 1, 1, 4, + 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, + 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, 66, 1, 3, + 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71, + 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8, + 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 103, 8, 88, 33, 31, 9, 1, 45, + 1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, + 1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 23, 44, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111, + 17, 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16, + 4, 31, 21, 5, 19, 0, 45, 211, 64, 32, 25, 2, 25, 44, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 7, + 9, 0, 41, 32, 97, 115, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, + 13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, + 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, + 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, + 1, 112, 45, 10, 7, 16, 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 207, 31, 1, 22, 8, 2, 224, 7, + 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, + 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, + 32, 0, 2, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0, ]; - #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -153,84 +254,66 @@ pub mod alphabetic { } } +#[rustfmt::skip] pub mod case_ignorable { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 36] = [ - ShortOffsetRunHeader::new(0, 688), - ShortOffsetRunHeader::new(11, 4957), - ShortOffsetRunHeader::new(263, 5906), - ShortOffsetRunHeader::new(265, 8125), - ShortOffsetRunHeader::new(377, 11388), - ShortOffsetRunHeader::new(411, 12293), - ShortOffsetRunHeader::new(423, 40981), - ShortOffsetRunHeader::new(435, 42232), - ShortOffsetRunHeader::new(437, 42508), - ShortOffsetRunHeader::new(439, 64286), - ShortOffsetRunHeader::new(535, 65024), - ShortOffsetRunHeader::new(539, 66045), - ShortOffsetRunHeader::new(569, 67456), - ShortOffsetRunHeader::new(575, 68097), - ShortOffsetRunHeader::new(581, 68900), - ShortOffsetRunHeader::new(593, 69291), - ShortOffsetRunHeader::new(601, 71727), - ShortOffsetRunHeader::new(727, 71995), - ShortOffsetRunHeader::new(731, 73459), - ShortOffsetRunHeader::new(797, 78896), - ShortOffsetRunHeader::new(809, 90398), - ShortOffsetRunHeader::new(813, 92912), - ShortOffsetRunHeader::new(817, 93504), - ShortOffsetRunHeader::new(823, 94031), - ShortOffsetRunHeader::new(827, 110576), - ShortOffsetRunHeader::new(837, 113821), - ShortOffsetRunHeader::new(843, 118528), - ShortOffsetRunHeader::new(847, 119143), - ShortOffsetRunHeader::new(851, 121344), - ShortOffsetRunHeader::new(861, 122880), - ShortOffsetRunHeader::new(873, 123566), - ShortOffsetRunHeader::new(889, 124139), - ShortOffsetRunHeader::new(893, 125136), - ShortOffsetRunHeader::new(907, 127995), - ShortOffsetRunHeader::new(911, 917505), - ShortOffsetRunHeader::new(913, 2032112), + ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957), + ShortOffsetRunHeader::new(263, 5906), ShortOffsetRunHeader::new(265, 8125), + ShortOffsetRunHeader::new(377, 11388), ShortOffsetRunHeader::new(411, 12293), + ShortOffsetRunHeader::new(423, 40981), ShortOffsetRunHeader::new(435, 42232), + ShortOffsetRunHeader::new(437, 42508), ShortOffsetRunHeader::new(439, 64286), + ShortOffsetRunHeader::new(535, 65024), ShortOffsetRunHeader::new(539, 66045), + ShortOffsetRunHeader::new(569, 67456), ShortOffsetRunHeader::new(575, 68097), + ShortOffsetRunHeader::new(581, 68900), ShortOffsetRunHeader::new(593, 69291), + ShortOffsetRunHeader::new(601, 71727), ShortOffsetRunHeader::new(727, 71995), + ShortOffsetRunHeader::new(731, 73459), ShortOffsetRunHeader::new(797, 78896), + ShortOffsetRunHeader::new(809, 90398), ShortOffsetRunHeader::new(813, 92912), + ShortOffsetRunHeader::new(817, 93504), ShortOffsetRunHeader::new(823, 94031), + ShortOffsetRunHeader::new(827, 110576), ShortOffsetRunHeader::new(837, 113821), + ShortOffsetRunHeader::new(843, 118528), ShortOffsetRunHeader::new(847, 119143), + ShortOffsetRunHeader::new(851, 121344), ShortOffsetRunHeader::new(861, 122880), + ShortOffsetRunHeader::new(873, 123566), ShortOffsetRunHeader::new(889, 124139), + ShortOffsetRunHeader::new(893, 125136), ShortOffsetRunHeader::new(907, 127995), + ShortOffsetRunHeader::new(911, 917505), ShortOffsetRunHeader::new(913, 2032112), ]; static OFFSETS: [u8; 919] = [ 168, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, 1, 1, 251, 7, 207, 1, 5, 1, 49, - 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8, 1, - 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5, - 9, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, - 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, - 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, - 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, - 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 7, - 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, - 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, - 2, 1, 7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, - 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 46, 2, 12, 20, 4, 48, - 1, 1, 5, 1, 1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, - 64, 6, 82, 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, - 3, 13, 3, 13, 2, 12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, - 0, 2, 113, 3, 125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, - 6, 0, 1, 98, 4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 102, 4, 3, 2, 8, 1, 3, 1, - 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, - 21, 2, 66, 6, 2, 2, 2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, - 14, 2, 5, 2, 1, 1, 100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, - 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, - 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, - 1, 0, 2, 24, 1, 52, 6, 70, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, - 1, 4, 1, 10, 1, 50, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, - 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, - 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, - 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, - 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, - 1, 201, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, - 1, 1, 1, 65, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1, 1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, - 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1, 2, 13, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, - 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, - 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14, 0, 1, 61, 4, 0, 5, 254, 2, 243, 1, 2, 1, 7, - 2, 5, 1, 9, 1, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0, + 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8, 1, 10, + 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5, 9, 41, + 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, + 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, + 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, + 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, + 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27, 1, + 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, + 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, + 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, + 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 46, 2, 12, 20, 4, 48, 1, 1, 5, 1, 1, 5, 1, + 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13, + 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12, + 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3, 125, 1, + 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, + 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 102, 4, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, + 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, + 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, + 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, + 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, + 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 24, 1, 52, 6, 70, 11, + 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3, 36, 5, 1, + 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, + 2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, + 1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, + 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, + 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, + 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 65, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1, + 1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1, + 2, 13, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, + 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14, + 0, 1, 61, 4, 0, 5, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 9, 1, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, + 128, 240, 0, ]; - #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -253,48 +336,37 @@ pub mod case_ignorable { } } +#[rustfmt::skip] pub mod cased { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 22] = [ - ShortOffsetRunHeader::new(0, 4256), - ShortOffsetRunHeader::new(51, 5024), - ShortOffsetRunHeader::new(61, 7296), - ShortOffsetRunHeader::new(65, 7958), - ShortOffsetRunHeader::new(74, 9398), - ShortOffsetRunHeader::new(149, 11264), - ShortOffsetRunHeader::new(151, 42560), - ShortOffsetRunHeader::new(163, 43824), - ShortOffsetRunHeader::new(177, 64256), - ShortOffsetRunHeader::new(183, 65313), - ShortOffsetRunHeader::new(187, 66560), - ShortOffsetRunHeader::new(191, 67456), - ShortOffsetRunHeader::new(213, 68736), - ShortOffsetRunHeader::new(221, 71840), - ShortOffsetRunHeader::new(229, 93760), - ShortOffsetRunHeader::new(231, 119808), - ShortOffsetRunHeader::new(237, 120486), - ShortOffsetRunHeader::new(274, 122624), - ShortOffsetRunHeader::new(297, 122928), - ShortOffsetRunHeader::new(303, 125184), - ShortOffsetRunHeader::new(305, 127280), - ShortOffsetRunHeader::new(307, 1241482), + ShortOffsetRunHeader::new(0, 4256), ShortOffsetRunHeader::new(51, 5024), + ShortOffsetRunHeader::new(61, 7296), ShortOffsetRunHeader::new(65, 7958), + ShortOffsetRunHeader::new(74, 9398), ShortOffsetRunHeader::new(149, 11264), + ShortOffsetRunHeader::new(151, 42560), ShortOffsetRunHeader::new(163, 43824), + ShortOffsetRunHeader::new(177, 64256), ShortOffsetRunHeader::new(183, 65313), + ShortOffsetRunHeader::new(187, 66560), ShortOffsetRunHeader::new(191, 67456), + ShortOffsetRunHeader::new(213, 68736), ShortOffsetRunHeader::new(221, 71840), + ShortOffsetRunHeader::new(229, 93760), ShortOffsetRunHeader::new(231, 119808), + ShortOffsetRunHeader::new(237, 120486), ShortOffsetRunHeader::new(274, 122624), + ShortOffsetRunHeader::new(297, 122928), ShortOffsetRunHeader::new(303, 125184), + ShortOffsetRunHeader::new(305, 127280), ShortOffsetRunHeader::new(307, 1241482), ]; static OFFSETS: [u8; 313] = [ 170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 2, 35, 7, 2, 30, 5, 96, 1, 42, 4, - 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9, 41, 0, 38, 1, - 1, 5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 11, 5, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2, 38, 2, 6, - 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, - 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 6, 4, - 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 0, 46, - 18, 30, 132, 102, 3, 4, 1, 77, 20, 6, 1, 3, 0, 43, 1, 14, 6, 80, 0, 7, 12, 5, 0, 26, 6, 26, - 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 0, 1, 2, 3, 1, - 42, 1, 9, 0, 51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 32, 25, 2, 25, 0, 85, 1, 71, 1, 2, - 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, - 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, - 1, 20, 6, 6, 0, 62, 0, 68, 0, 26, 6, 26, 6, 26, 0, + 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9, 41, 0, 38, 1, 1, + 5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 11, 5, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2, 38, 2, 6, 2, 8, + 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, + 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 6, 4, 1, 2, 4, + 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 0, 46, 18, 30, 132, + 102, 3, 4, 1, 77, 20, 6, 1, 3, 0, 43, 1, 14, 6, 80, 0, 7, 12, 5, 0, 26, 6, 26, 0, 80, 96, + 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0, + 51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 32, 25, 2, 25, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, + 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, + 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 6, 6, 0, + 62, 0, 68, 0, 26, 6, 26, 6, 26, 0, ]; - #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -317,75 +389,59 @@ pub mod cased { } } +#[rustfmt::skip] pub mod grapheme_extend { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 33] = [ - ShortOffsetRunHeader::new(0, 768), - ShortOffsetRunHeader::new(1, 1155), - ShortOffsetRunHeader::new(3, 1425), - ShortOffsetRunHeader::new(5, 4957), - ShortOffsetRunHeader::new(249, 5906), - ShortOffsetRunHeader::new(251, 8204), - ShortOffsetRunHeader::new(347, 11503), - ShortOffsetRunHeader::new(351, 12330), - ShortOffsetRunHeader::new(357, 42607), - ShortOffsetRunHeader::new(361, 43010), - ShortOffsetRunHeader::new(369, 64286), - ShortOffsetRunHeader::new(435, 65024), - ShortOffsetRunHeader::new(437, 65438), - ShortOffsetRunHeader::new(441, 66045), - ShortOffsetRunHeader::new(443, 68097), - ShortOffsetRunHeader::new(449, 68900), - ShortOffsetRunHeader::new(461, 69291), - ShortOffsetRunHeader::new(465, 71727), - ShortOffsetRunHeader::new(601, 73459), - ShortOffsetRunHeader::new(669, 78912), - ShortOffsetRunHeader::new(679, 90398), - ShortOffsetRunHeader::new(683, 92912), - ShortOffsetRunHeader::new(687, 94031), - ShortOffsetRunHeader::new(691, 113821), - ShortOffsetRunHeader::new(699, 118528), - ShortOffsetRunHeader::new(701, 119141), - ShortOffsetRunHeader::new(705, 121344), - ShortOffsetRunHeader::new(717, 122880), - ShortOffsetRunHeader::new(729, 123566), - ShortOffsetRunHeader::new(743, 124140), - ShortOffsetRunHeader::new(747, 125136), - ShortOffsetRunHeader::new(759, 917536), + ShortOffsetRunHeader::new(0, 768), ShortOffsetRunHeader::new(1, 1155), + ShortOffsetRunHeader::new(3, 1425), ShortOffsetRunHeader::new(5, 4957), + ShortOffsetRunHeader::new(249, 5906), ShortOffsetRunHeader::new(251, 8204), + ShortOffsetRunHeader::new(347, 11503), ShortOffsetRunHeader::new(351, 12330), + ShortOffsetRunHeader::new(357, 42607), ShortOffsetRunHeader::new(361, 43010), + ShortOffsetRunHeader::new(369, 64286), ShortOffsetRunHeader::new(435, 65024), + ShortOffsetRunHeader::new(437, 65438), ShortOffsetRunHeader::new(441, 66045), + ShortOffsetRunHeader::new(443, 68097), ShortOffsetRunHeader::new(449, 68900), + ShortOffsetRunHeader::new(461, 69291), ShortOffsetRunHeader::new(465, 71727), + ShortOffsetRunHeader::new(601, 73459), ShortOffsetRunHeader::new(669, 78912), + ShortOffsetRunHeader::new(679, 90398), ShortOffsetRunHeader::new(683, 92912), + ShortOffsetRunHeader::new(687, 94031), ShortOffsetRunHeader::new(691, 113821), + ShortOffsetRunHeader::new(699, 118528), ShortOffsetRunHeader::new(701, 119141), + ShortOffsetRunHeader::new(705, 121344), ShortOffsetRunHeader::new(717, 122880), + ShortOffsetRunHeader::new(729, 123566), ShortOffsetRunHeader::new(743, 124140), + ShortOffsetRunHeader::new(747, 125136), ShortOffsetRunHeader::new(759, 917536), ShortOffsetRunHeader::new(763, 2032112), ]; static OFFSETS: [u8; 767] = [ 0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1, - 4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 59, 9, 42, 24, 1, - 32, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, - 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, - 22, 6, 1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, - 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, - 2, 28, 2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, - 1, 2, 7, 12, 8, 98, 1, 2, 9, 11, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, - 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, - 4, 28, 3, 29, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, - 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 46, 2, 12, - 20, 4, 48, 10, 4, 3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, - 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, - 2, 0, 4, 1, 10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, - 25, 11, 1, 1, 44, 3, 48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, - 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, - 0, 1, 226, 1, 149, 5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 77, 6, 70, - 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, - 1, 12, 2, 52, 9, 1, 1, 8, 4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, - 1, 1, 1, 12, 1, 9, 1, 14, 7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, - 2, 3, 1, 1, 23, 1, 81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, - 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, - 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, - 3, 1, 1, 201, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, - 2, 3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 3, 23, 1, 0, 1, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 0, - 1, 63, 4, 81, 1, 11, 2, 0, 2, 0, 46, 2, 23, 0, 5, 3, 6, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, - 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 100, 1, 160, 7, 0, 1, 61, - 4, 0, 4, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 0, 7, 109, 7, 0, 96, 128, 240, 0, + 4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 59, 9, 42, 24, 1, 32, + 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2, + 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, + 1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1, + 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, 2, 28, + 2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7, + 12, 8, 98, 1, 2, 9, 11, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, + 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 4, 28, 3, + 29, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9, + 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 46, 2, 12, 20, 4, 48, + 10, 4, 3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, 3, 1, 13, 1, + 7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1, + 10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 1, 1, + 44, 3, 48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, + 2, 2, 5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, + 149, 5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 77, 6, 70, 11, 49, 4, 123, + 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, + 1, 1, 8, 4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 12, 1, 9, + 1, 14, 7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, + 81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, + 106, 1, 1, 1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, 4, 1, 144, 4, 2, 2, + 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6, + 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11, + 2, 52, 5, 5, 3, 23, 1, 0, 1, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 11, 2, 0, + 2, 0, 46, 2, 23, 0, 5, 3, 6, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, + 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 100, 1, 160, 7, 0, 1, 61, 4, 0, 4, 254, 2, 243, 1, 2, 1, + 7, 2, 5, 1, 0, 7, 109, 7, 0, 96, 128, 240, 0, ]; - #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -408,13 +464,14 @@ pub mod grapheme_extend { } } +#[rustfmt::skip] pub mod lowercase { static BITSET_CHUNKS_MAP: [u8; 123] = [ 12, 17, 0, 0, 9, 0, 0, 13, 14, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 0, 3, 18, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, + 3, 18, 0, 7, ]; static BITSET_INDEX_CHUNKS: [[u8; 16]; 20] = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -498,107 +555,66 @@ pub mod lowercase { 0b1110101111000000000000000000000000001111111111111111111111111100, ]; static BITSET_MAPPING: [(u8, u8); 22] = [ - (0, 64), - (1, 184), - (1, 182), - (1, 179), - (1, 172), - (1, 168), - (1, 161), - (1, 146), - (1, 144), - (1, 140), - (1, 136), - (1, 132), - (2, 146), - (2, 144), - (2, 83), - (3, 93), - (3, 147), - (3, 133), - (4, 12), - (4, 6), - (5, 187), - (6, 78), + (0, 64), (1, 184), (1, 182), (1, 179), (1, 172), (1, 168), (1, 161), (1, 146), (1, 144), + (1, 140), (1, 136), (1, 132), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133), + (4, 12), (4, 6), (5, 187), (6, 78), ]; pub const fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); - (c as u32) >= 0xaa - && super::bitset_search( - c as u32, - &BITSET_CHUNKS_MAP, - &BITSET_INDEX_CHUNKS, - &BITSET_CANONICAL, - &BITSET_MAPPING, - ) + (c as u32) >= 0xaa && + super::bitset_search( + c as u32, + &BITSET_CHUNKS_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET_CANONICAL, + &BITSET_MAPPING, + ) } } +#[rustfmt::skip] pub mod n { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 43] = [ - ShortOffsetRunHeader::new(0, 1632), - ShortOffsetRunHeader::new(7, 2406), - ShortOffsetRunHeader::new(13, 4160), - ShortOffsetRunHeader::new(47, 4969), - ShortOffsetRunHeader::new(51, 5870), - ShortOffsetRunHeader::new(53, 6470), - ShortOffsetRunHeader::new(61, 8304), - ShortOffsetRunHeader::new(77, 9312), - ShortOffsetRunHeader::new(87, 10102), - ShortOffsetRunHeader::new(91, 11517), - ShortOffsetRunHeader::new(93, 12295), - ShortOffsetRunHeader::new(95, 12690), - ShortOffsetRunHeader::new(101, 42528), - ShortOffsetRunHeader::new(113, 43056), - ShortOffsetRunHeader::new(117, 44016), - ShortOffsetRunHeader::new(129, 65296), - ShortOffsetRunHeader::new(131, 65799), - ShortOffsetRunHeader::new(133, 66273), - ShortOffsetRunHeader::new(139, 67672), - ShortOffsetRunHeader::new(151, 68858), - ShortOffsetRunHeader::new(181, 69216), - ShortOffsetRunHeader::new(187, 70736), - ShortOffsetRunHeader::new(207, 71248), - ShortOffsetRunHeader::new(211, 71904), - ShortOffsetRunHeader::new(219, 72688), - ShortOffsetRunHeader::new(223, 73552), - ShortOffsetRunHeader::new(233, 74752), - ShortOffsetRunHeader::new(237, 90416), - ShortOffsetRunHeader::new(239, 92768), - ShortOffsetRunHeader::new(241, 93552), - ShortOffsetRunHeader::new(249, 93824), - ShortOffsetRunHeader::new(251, 94196), - ShortOffsetRunHeader::new(253, 118000), - ShortOffsetRunHeader::new(255, 119488), - ShortOffsetRunHeader::new(257, 120782), - ShortOffsetRunHeader::new(263, 123200), - ShortOffsetRunHeader::new(265, 123632), - ShortOffsetRunHeader::new(267, 124144), - ShortOffsetRunHeader::new(269, 125127), - ShortOffsetRunHeader::new(273, 126065), - ShortOffsetRunHeader::new(277, 127232), - ShortOffsetRunHeader::new(287, 130032), + ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(7, 2406), + ShortOffsetRunHeader::new(13, 4160), ShortOffsetRunHeader::new(47, 4969), + ShortOffsetRunHeader::new(51, 5870), ShortOffsetRunHeader::new(53, 6470), + ShortOffsetRunHeader::new(61, 8304), ShortOffsetRunHeader::new(77, 9312), + ShortOffsetRunHeader::new(87, 10102), ShortOffsetRunHeader::new(91, 11517), + ShortOffsetRunHeader::new(93, 12295), ShortOffsetRunHeader::new(95, 12690), + ShortOffsetRunHeader::new(101, 42528), ShortOffsetRunHeader::new(113, 43056), + ShortOffsetRunHeader::new(117, 44016), ShortOffsetRunHeader::new(129, 65296), + ShortOffsetRunHeader::new(131, 65799), ShortOffsetRunHeader::new(133, 66273), + ShortOffsetRunHeader::new(139, 67672), ShortOffsetRunHeader::new(151, 68858), + ShortOffsetRunHeader::new(181, 69216), ShortOffsetRunHeader::new(187, 70736), + ShortOffsetRunHeader::new(207, 71248), ShortOffsetRunHeader::new(211, 71904), + ShortOffsetRunHeader::new(219, 72688), ShortOffsetRunHeader::new(223, 73552), + ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 90416), + ShortOffsetRunHeader::new(239, 92768), ShortOffsetRunHeader::new(241, 93552), + ShortOffsetRunHeader::new(249, 93824), ShortOffsetRunHeader::new(251, 94196), + ShortOffsetRunHeader::new(253, 118000), ShortOffsetRunHeader::new(255, 119488), + ShortOffsetRunHeader::new(257, 120782), ShortOffsetRunHeader::new(263, 123200), + ShortOffsetRunHeader::new(265, 123632), ShortOffsetRunHeader::new(267, 124144), + ShortOffsetRunHeader::new(269, 125127), ShortOffsetRunHeader::new(273, 126065), + ShortOffsetRunHeader::new(277, 127232), ShortOffsetRunHeader::new(287, 130032), ShortOffsetRunHeader::new(289, 1244154), ]; static OFFSETS: [u8; 291] = [ 178, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, 10, 118, 10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, 70, 20, - 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, - 10, 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, - 0, 1, 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, - 10, 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, - 1, 8, 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, - 52, 2, 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, - 7, 134, 30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, - 20, 76, 12, 0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 54, 10, 0, 10, 102, 21, 0, 111, - 0, 10, 0, 10, 86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 3, 0, 10, 0, 20, 12, 20, 108, 25, 0, - 50, 0, 10, 0, 10, 0, 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, - 0, 10, 0, + 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, 10, + 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, 0, 1, + 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, 10, + 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, 1, 8, + 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2, + 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134, + 30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, 76, 12, + 0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 54, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10, + 86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 3, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0, + 10, 0, 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0, ]; - #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -621,13 +637,14 @@ pub mod n { } } +#[rustfmt::skip] pub mod uppercase { static BITSET_CHUNKS_MAP: [u8; 125] = [ 3, 14, 6, 6, 0, 6, 6, 2, 5, 12, 6, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, - 6, 6, 6, 10, 6, 4, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, 6, + 6, 6, 10, 6, 4, ]; static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [ [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 0], @@ -695,1001 +712,877 @@ pub mod uppercase { 0b1111111100000000111111110000000000111111000000001111111100000000, ]; static BITSET_MAPPING: [(u8, u8); 25] = [ - (0, 182), - (0, 74), - (0, 166), - (0, 162), - (0, 159), - (0, 150), - (0, 148), - (0, 142), - (0, 134), - (0, 131), - (0, 64), - (1, 66), - (1, 70), - (1, 83), - (1, 12), - (1, 8), - (2, 146), - (2, 140), - (2, 134), - (2, 130), - (3, 164), - (3, 146), - (3, 20), - (4, 178), - (4, 171), + (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 134), + (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 146), (2, 140), (2, 134), + (2, 130), (3, 164), (3, 146), (3, 20), (4, 178), (4, 171), ]; pub const fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); - (c as u32) >= 0xc0 - && super::bitset_search( - c as u32, - &BITSET_CHUNKS_MAP, - &BITSET_INDEX_CHUNKS, - &BITSET_CANONICAL, - &BITSET_MAPPING, - ) + (c as u32) >= 0xc0 && + super::bitset_search( + c as u32, + &BITSET_CHUNKS_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET_CANONICAL, + &BITSET_MAPPING, + ) } } +#[rustfmt::skip] pub mod white_space { static WHITESPACE_MAP: [u8; 256] = [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - #[inline] pub const fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); match c as u32 >> 8 { - 0x00 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0, - 0x16 => c as u32 == 0x1680, - 0x20 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0, - 0x30 => c as u32 == 0x3000, + 0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0, + 22 => c as u32 == 0x1680, + 32 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0, + 48 => c as u32 == 0x3000, _ => false, } } } +#[rustfmt::skip] pub mod conversions { - #[rustfmt::skip] - static LOWERCASE_TABLE: &[(char, u32); 1462] = &[ - ('\u{c0}', 0xe0), ('\u{c1}', 0xe1), ('\u{c2}', 0xe2), ('\u{c3}', 0xe3), ('\u{c4}', 0xe4), - ('\u{c5}', 0xe5), ('\u{c6}', 0xe6), ('\u{c7}', 0xe7), ('\u{c8}', 0xe8), ('\u{c9}', 0xe9), - ('\u{ca}', 0xea), ('\u{cb}', 0xeb), ('\u{cc}', 0xec), ('\u{cd}', 0xed), ('\u{ce}', 0xee), - ('\u{cf}', 0xef), ('\u{d0}', 0xf0), ('\u{d1}', 0xf1), ('\u{d2}', 0xf2), ('\u{d3}', 0xf3), - ('\u{d4}', 0xf4), ('\u{d5}', 0xf5), ('\u{d6}', 0xf6), ('\u{d8}', 0xf8), ('\u{d9}', 0xf9), - ('\u{da}', 0xfa), ('\u{db}', 0xfb), ('\u{dc}', 0xfc), ('\u{dd}', 0xfd), ('\u{de}', 0xfe), - ('\u{100}', 0x101), ('\u{102}', 0x103), ('\u{104}', 0x105), ('\u{106}', 0x107), - ('\u{108}', 0x109), ('\u{10a}', 0x10b), ('\u{10c}', 0x10d), ('\u{10e}', 0x10f), - ('\u{110}', 0x111), ('\u{112}', 0x113), ('\u{114}', 0x115), ('\u{116}', 0x117), - ('\u{118}', 0x119), ('\u{11a}', 0x11b), ('\u{11c}', 0x11d), ('\u{11e}', 0x11f), - ('\u{120}', 0x121), ('\u{122}', 0x123), ('\u{124}', 0x125), ('\u{126}', 0x127), - ('\u{128}', 0x129), ('\u{12a}', 0x12b), ('\u{12c}', 0x12d), ('\u{12e}', 0x12f), - ('\u{130}', 0x400000), ('\u{132}', 0x133), ('\u{134}', 0x135), ('\u{136}', 0x137), - ('\u{139}', 0x13a), ('\u{13b}', 0x13c), ('\u{13d}', 0x13e), ('\u{13f}', 0x140), - ('\u{141}', 0x142), ('\u{143}', 0x144), ('\u{145}', 0x146), ('\u{147}', 0x148), - ('\u{14a}', 0x14b), ('\u{14c}', 0x14d), ('\u{14e}', 0x14f), ('\u{150}', 0x151), - ('\u{152}', 0x153), ('\u{154}', 0x155), ('\u{156}', 0x157), ('\u{158}', 0x159), - ('\u{15a}', 0x15b), ('\u{15c}', 0x15d), ('\u{15e}', 0x15f), ('\u{160}', 0x161), - ('\u{162}', 0x163), ('\u{164}', 0x165), ('\u{166}', 0x167), ('\u{168}', 0x169), - ('\u{16a}', 0x16b), ('\u{16c}', 0x16d), ('\u{16e}', 0x16f), ('\u{170}', 0x171), - ('\u{172}', 0x173), ('\u{174}', 0x175), ('\u{176}', 0x177), ('\u{178}', 0xff), - ('\u{179}', 0x17a), ('\u{17b}', 0x17c), ('\u{17d}', 0x17e), ('\u{181}', 0x253), - ('\u{182}', 0x183), ('\u{184}', 0x185), ('\u{186}', 0x254), ('\u{187}', 0x188), - ('\u{189}', 0x256), ('\u{18a}', 0x257), ('\u{18b}', 0x18c), ('\u{18e}', 0x1dd), - ('\u{18f}', 0x259), ('\u{190}', 0x25b), ('\u{191}', 0x192), ('\u{193}', 0x260), - ('\u{194}', 0x263), ('\u{196}', 0x269), ('\u{197}', 0x268), ('\u{198}', 0x199), - ('\u{19c}', 0x26f), ('\u{19d}', 0x272), ('\u{19f}', 0x275), ('\u{1a0}', 0x1a1), - ('\u{1a2}', 0x1a3), ('\u{1a4}', 0x1a5), ('\u{1a6}', 0x280), ('\u{1a7}', 0x1a8), - ('\u{1a9}', 0x283), ('\u{1ac}', 0x1ad), ('\u{1ae}', 0x288), ('\u{1af}', 0x1b0), - ('\u{1b1}', 0x28a), ('\u{1b2}', 0x28b), ('\u{1b3}', 0x1b4), ('\u{1b5}', 0x1b6), - ('\u{1b7}', 0x292), ('\u{1b8}', 0x1b9), ('\u{1bc}', 0x1bd), ('\u{1c4}', 0x1c6), - ('\u{1c5}', 0x1c6), ('\u{1c7}', 0x1c9), ('\u{1c8}', 0x1c9), ('\u{1ca}', 0x1cc), - ('\u{1cb}', 0x1cc), ('\u{1cd}', 0x1ce), ('\u{1cf}', 0x1d0), ('\u{1d1}', 0x1d2), - ('\u{1d3}', 0x1d4), ('\u{1d5}', 0x1d6), ('\u{1d7}', 0x1d8), ('\u{1d9}', 0x1da), - ('\u{1db}', 0x1dc), ('\u{1de}', 0x1df), ('\u{1e0}', 0x1e1), ('\u{1e2}', 0x1e3), - ('\u{1e4}', 0x1e5), ('\u{1e6}', 0x1e7), ('\u{1e8}', 0x1e9), ('\u{1ea}', 0x1eb), - ('\u{1ec}', 0x1ed), ('\u{1ee}', 0x1ef), ('\u{1f1}', 0x1f3), ('\u{1f2}', 0x1f3), - ('\u{1f4}', 0x1f5), ('\u{1f6}', 0x195), ('\u{1f7}', 0x1bf), ('\u{1f8}', 0x1f9), - ('\u{1fa}', 0x1fb), ('\u{1fc}', 0x1fd), ('\u{1fe}', 0x1ff), ('\u{200}', 0x201), - ('\u{202}', 0x203), ('\u{204}', 0x205), ('\u{206}', 0x207), ('\u{208}', 0x209), - ('\u{20a}', 0x20b), ('\u{20c}', 0x20d), ('\u{20e}', 0x20f), ('\u{210}', 0x211), - ('\u{212}', 0x213), ('\u{214}', 0x215), ('\u{216}', 0x217), ('\u{218}', 0x219), - ('\u{21a}', 0x21b), ('\u{21c}', 0x21d), ('\u{21e}', 0x21f), ('\u{220}', 0x19e), - ('\u{222}', 0x223), ('\u{224}', 0x225), ('\u{226}', 0x227), ('\u{228}', 0x229), - ('\u{22a}', 0x22b), ('\u{22c}', 0x22d), ('\u{22e}', 0x22f), ('\u{230}', 0x231), - ('\u{232}', 0x233), ('\u{23a}', 0x2c65), ('\u{23b}', 0x23c), ('\u{23d}', 0x19a), - ('\u{23e}', 0x2c66), ('\u{241}', 0x242), ('\u{243}', 0x180), ('\u{244}', 0x289), - ('\u{245}', 0x28c), ('\u{246}', 0x247), ('\u{248}', 0x249), ('\u{24a}', 0x24b), - ('\u{24c}', 0x24d), ('\u{24e}', 0x24f), ('\u{370}', 0x371), ('\u{372}', 0x373), - ('\u{376}', 0x377), ('\u{37f}', 0x3f3), ('\u{386}', 0x3ac), ('\u{388}', 0x3ad), - ('\u{389}', 0x3ae), ('\u{38a}', 0x3af), ('\u{38c}', 0x3cc), ('\u{38e}', 0x3cd), - ('\u{38f}', 0x3ce), ('\u{391}', 0x3b1), ('\u{392}', 0x3b2), ('\u{393}', 0x3b3), - ('\u{394}', 0x3b4), ('\u{395}', 0x3b5), ('\u{396}', 0x3b6), ('\u{397}', 0x3b7), - ('\u{398}', 0x3b8), ('\u{399}', 0x3b9), ('\u{39a}', 0x3ba), ('\u{39b}', 0x3bb), - ('\u{39c}', 0x3bc), ('\u{39d}', 0x3bd), ('\u{39e}', 0x3be), ('\u{39f}', 0x3bf), - ('\u{3a0}', 0x3c0), ('\u{3a1}', 0x3c1), ('\u{3a3}', 0x3c3), ('\u{3a4}', 0x3c4), - ('\u{3a5}', 0x3c5), ('\u{3a6}', 0x3c6), ('\u{3a7}', 0x3c7), ('\u{3a8}', 0x3c8), - ('\u{3a9}', 0x3c9), ('\u{3aa}', 0x3ca), ('\u{3ab}', 0x3cb), ('\u{3cf}', 0x3d7), - ('\u{3d8}', 0x3d9), ('\u{3da}', 0x3db), ('\u{3dc}', 0x3dd), ('\u{3de}', 0x3df), - ('\u{3e0}', 0x3e1), ('\u{3e2}', 0x3e3), ('\u{3e4}', 0x3e5), ('\u{3e6}', 0x3e7), - ('\u{3e8}', 0x3e9), ('\u{3ea}', 0x3eb), ('\u{3ec}', 0x3ed), ('\u{3ee}', 0x3ef), - ('\u{3f4}', 0x3b8), ('\u{3f7}', 0x3f8), ('\u{3f9}', 0x3f2), ('\u{3fa}', 0x3fb), - ('\u{3fd}', 0x37b), ('\u{3fe}', 0x37c), ('\u{3ff}', 0x37d), ('\u{400}', 0x450), - ('\u{401}', 0x451), ('\u{402}', 0x452), ('\u{403}', 0x453), ('\u{404}', 0x454), - ('\u{405}', 0x455), ('\u{406}', 0x456), ('\u{407}', 0x457), ('\u{408}', 0x458), - ('\u{409}', 0x459), ('\u{40a}', 0x45a), ('\u{40b}', 0x45b), ('\u{40c}', 0x45c), - ('\u{40d}', 0x45d), ('\u{40e}', 0x45e), ('\u{40f}', 0x45f), ('\u{410}', 0x430), - ('\u{411}', 0x431), ('\u{412}', 0x432), ('\u{413}', 0x433), ('\u{414}', 0x434), - ('\u{415}', 0x435), ('\u{416}', 0x436), ('\u{417}', 0x437), ('\u{418}', 0x438), - ('\u{419}', 0x439), ('\u{41a}', 0x43a), ('\u{41b}', 0x43b), ('\u{41c}', 0x43c), - ('\u{41d}', 0x43d), ('\u{41e}', 0x43e), ('\u{41f}', 0x43f), ('\u{420}', 0x440), - ('\u{421}', 0x441), ('\u{422}', 0x442), ('\u{423}', 0x443), ('\u{424}', 0x444), - ('\u{425}', 0x445), ('\u{426}', 0x446), ('\u{427}', 0x447), ('\u{428}', 0x448), - ('\u{429}', 0x449), ('\u{42a}', 0x44a), ('\u{42b}', 0x44b), ('\u{42c}', 0x44c), - ('\u{42d}', 0x44d), ('\u{42e}', 0x44e), ('\u{42f}', 0x44f), ('\u{460}', 0x461), - ('\u{462}', 0x463), ('\u{464}', 0x465), ('\u{466}', 0x467), ('\u{468}', 0x469), - ('\u{46a}', 0x46b), ('\u{46c}', 0x46d), ('\u{46e}', 0x46f), ('\u{470}', 0x471), - ('\u{472}', 0x473), ('\u{474}', 0x475), ('\u{476}', 0x477), ('\u{478}', 0x479), - ('\u{47a}', 0x47b), ('\u{47c}', 0x47d), ('\u{47e}', 0x47f), ('\u{480}', 0x481), - ('\u{48a}', 0x48b), ('\u{48c}', 0x48d), ('\u{48e}', 0x48f), ('\u{490}', 0x491), - ('\u{492}', 0x493), ('\u{494}', 0x495), ('\u{496}', 0x497), ('\u{498}', 0x499), - ('\u{49a}', 0x49b), ('\u{49c}', 0x49d), ('\u{49e}', 0x49f), ('\u{4a0}', 0x4a1), - ('\u{4a2}', 0x4a3), ('\u{4a4}', 0x4a5), ('\u{4a6}', 0x4a7), ('\u{4a8}', 0x4a9), - ('\u{4aa}', 0x4ab), ('\u{4ac}', 0x4ad), ('\u{4ae}', 0x4af), ('\u{4b0}', 0x4b1), - ('\u{4b2}', 0x4b3), ('\u{4b4}', 0x4b5), ('\u{4b6}', 0x4b7), ('\u{4b8}', 0x4b9), - ('\u{4ba}', 0x4bb), ('\u{4bc}', 0x4bd), ('\u{4be}', 0x4bf), ('\u{4c0}', 0x4cf), - ('\u{4c1}', 0x4c2), ('\u{4c3}', 0x4c4), ('\u{4c5}', 0x4c6), ('\u{4c7}', 0x4c8), - ('\u{4c9}', 0x4ca), ('\u{4cb}', 0x4cc), ('\u{4cd}', 0x4ce), ('\u{4d0}', 0x4d1), - ('\u{4d2}', 0x4d3), ('\u{4d4}', 0x4d5), ('\u{4d6}', 0x4d7), ('\u{4d8}', 0x4d9), - ('\u{4da}', 0x4db), ('\u{4dc}', 0x4dd), ('\u{4de}', 0x4df), ('\u{4e0}', 0x4e1), - ('\u{4e2}', 0x4e3), ('\u{4e4}', 0x4e5), ('\u{4e6}', 0x4e7), ('\u{4e8}', 0x4e9), - ('\u{4ea}', 0x4eb), ('\u{4ec}', 0x4ed), ('\u{4ee}', 0x4ef), ('\u{4f0}', 0x4f1), - ('\u{4f2}', 0x4f3), ('\u{4f4}', 0x4f5), ('\u{4f6}', 0x4f7), ('\u{4f8}', 0x4f9), - ('\u{4fa}', 0x4fb), ('\u{4fc}', 0x4fd), ('\u{4fe}', 0x4ff), ('\u{500}', 0x501), - ('\u{502}', 0x503), ('\u{504}', 0x505), ('\u{506}', 0x507), ('\u{508}', 0x509), - ('\u{50a}', 0x50b), ('\u{50c}', 0x50d), ('\u{50e}', 0x50f), ('\u{510}', 0x511), - ('\u{512}', 0x513), ('\u{514}', 0x515), ('\u{516}', 0x517), ('\u{518}', 0x519), - ('\u{51a}', 0x51b), ('\u{51c}', 0x51d), ('\u{51e}', 0x51f), ('\u{520}', 0x521), - ('\u{522}', 0x523), ('\u{524}', 0x525), ('\u{526}', 0x527), ('\u{528}', 0x529), - ('\u{52a}', 0x52b), ('\u{52c}', 0x52d), ('\u{52e}', 0x52f), ('\u{531}', 0x561), - ('\u{532}', 0x562), ('\u{533}', 0x563), ('\u{534}', 0x564), ('\u{535}', 0x565), - ('\u{536}', 0x566), ('\u{537}', 0x567), ('\u{538}', 0x568), ('\u{539}', 0x569), - ('\u{53a}', 0x56a), ('\u{53b}', 0x56b), ('\u{53c}', 0x56c), ('\u{53d}', 0x56d), - ('\u{53e}', 0x56e), ('\u{53f}', 0x56f), ('\u{540}', 0x570), ('\u{541}', 0x571), - ('\u{542}', 0x572), ('\u{543}', 0x573), ('\u{544}', 0x574), ('\u{545}', 0x575), - ('\u{546}', 0x576), ('\u{547}', 0x577), ('\u{548}', 0x578), ('\u{549}', 0x579), - ('\u{54a}', 0x57a), ('\u{54b}', 0x57b), ('\u{54c}', 0x57c), ('\u{54d}', 0x57d), - ('\u{54e}', 0x57e), ('\u{54f}', 0x57f), ('\u{550}', 0x580), ('\u{551}', 0x581), - ('\u{552}', 0x582), ('\u{553}', 0x583), ('\u{554}', 0x584), ('\u{555}', 0x585), - ('\u{556}', 0x586), ('\u{10a0}', 0x2d00), ('\u{10a1}', 0x2d01), ('\u{10a2}', 0x2d02), - ('\u{10a3}', 0x2d03), ('\u{10a4}', 0x2d04), ('\u{10a5}', 0x2d05), ('\u{10a6}', 0x2d06), - ('\u{10a7}', 0x2d07), ('\u{10a8}', 0x2d08), ('\u{10a9}', 0x2d09), ('\u{10aa}', 0x2d0a), - ('\u{10ab}', 0x2d0b), ('\u{10ac}', 0x2d0c), ('\u{10ad}', 0x2d0d), ('\u{10ae}', 0x2d0e), - ('\u{10af}', 0x2d0f), ('\u{10b0}', 0x2d10), ('\u{10b1}', 0x2d11), ('\u{10b2}', 0x2d12), - ('\u{10b3}', 0x2d13), ('\u{10b4}', 0x2d14), ('\u{10b5}', 0x2d15), ('\u{10b6}', 0x2d16), - ('\u{10b7}', 0x2d17), ('\u{10b8}', 0x2d18), ('\u{10b9}', 0x2d19), ('\u{10ba}', 0x2d1a), - ('\u{10bb}', 0x2d1b), ('\u{10bc}', 0x2d1c), ('\u{10bd}', 0x2d1d), ('\u{10be}', 0x2d1e), - ('\u{10bf}', 0x2d1f), ('\u{10c0}', 0x2d20), ('\u{10c1}', 0x2d21), ('\u{10c2}', 0x2d22), - ('\u{10c3}', 0x2d23), ('\u{10c4}', 0x2d24), ('\u{10c5}', 0x2d25), ('\u{10c7}', 0x2d27), - ('\u{10cd}', 0x2d2d), ('\u{13a0}', 0xab70), ('\u{13a1}', 0xab71), ('\u{13a2}', 0xab72), - ('\u{13a3}', 0xab73), ('\u{13a4}', 0xab74), ('\u{13a5}', 0xab75), ('\u{13a6}', 0xab76), - ('\u{13a7}', 0xab77), ('\u{13a8}', 0xab78), ('\u{13a9}', 0xab79), ('\u{13aa}', 0xab7a), - ('\u{13ab}', 0xab7b), ('\u{13ac}', 0xab7c), ('\u{13ad}', 0xab7d), ('\u{13ae}', 0xab7e), - ('\u{13af}', 0xab7f), ('\u{13b0}', 0xab80), ('\u{13b1}', 0xab81), ('\u{13b2}', 0xab82), - ('\u{13b3}', 0xab83), ('\u{13b4}', 0xab84), ('\u{13b5}', 0xab85), ('\u{13b6}', 0xab86), - ('\u{13b7}', 0xab87), ('\u{13b8}', 0xab88), ('\u{13b9}', 0xab89), ('\u{13ba}', 0xab8a), - ('\u{13bb}', 0xab8b), ('\u{13bc}', 0xab8c), ('\u{13bd}', 0xab8d), ('\u{13be}', 0xab8e), - ('\u{13bf}', 0xab8f), ('\u{13c0}', 0xab90), ('\u{13c1}', 0xab91), ('\u{13c2}', 0xab92), - ('\u{13c3}', 0xab93), ('\u{13c4}', 0xab94), ('\u{13c5}', 0xab95), ('\u{13c6}', 0xab96), - ('\u{13c7}', 0xab97), ('\u{13c8}', 0xab98), ('\u{13c9}', 0xab99), ('\u{13ca}', 0xab9a), - ('\u{13cb}', 0xab9b), ('\u{13cc}', 0xab9c), ('\u{13cd}', 0xab9d), ('\u{13ce}', 0xab9e), - ('\u{13cf}', 0xab9f), ('\u{13d0}', 0xaba0), ('\u{13d1}', 0xaba1), ('\u{13d2}', 0xaba2), - ('\u{13d3}', 0xaba3), ('\u{13d4}', 0xaba4), ('\u{13d5}', 0xaba5), ('\u{13d6}', 0xaba6), - ('\u{13d7}', 0xaba7), ('\u{13d8}', 0xaba8), ('\u{13d9}', 0xaba9), ('\u{13da}', 0xabaa), - ('\u{13db}', 0xabab), ('\u{13dc}', 0xabac), ('\u{13dd}', 0xabad), ('\u{13de}', 0xabae), - ('\u{13df}', 0xabaf), ('\u{13e0}', 0xabb0), ('\u{13e1}', 0xabb1), ('\u{13e2}', 0xabb2), - ('\u{13e3}', 0xabb3), ('\u{13e4}', 0xabb4), ('\u{13e5}', 0xabb5), ('\u{13e6}', 0xabb6), - ('\u{13e7}', 0xabb7), ('\u{13e8}', 0xabb8), ('\u{13e9}', 0xabb9), ('\u{13ea}', 0xabba), - ('\u{13eb}', 0xabbb), ('\u{13ec}', 0xabbc), ('\u{13ed}', 0xabbd), ('\u{13ee}', 0xabbe), - ('\u{13ef}', 0xabbf), ('\u{13f0}', 0x13f8), ('\u{13f1}', 0x13f9), ('\u{13f2}', 0x13fa), - ('\u{13f3}', 0x13fb), ('\u{13f4}', 0x13fc), ('\u{13f5}', 0x13fd), ('\u{1c89}', 0x1c8a), - ('\u{1c90}', 0x10d0), ('\u{1c91}', 0x10d1), ('\u{1c92}', 0x10d2), ('\u{1c93}', 0x10d3), - ('\u{1c94}', 0x10d4), ('\u{1c95}', 0x10d5), ('\u{1c96}', 0x10d6), ('\u{1c97}', 0x10d7), - ('\u{1c98}', 0x10d8), ('\u{1c99}', 0x10d9), ('\u{1c9a}', 0x10da), ('\u{1c9b}', 0x10db), - ('\u{1c9c}', 0x10dc), ('\u{1c9d}', 0x10dd), ('\u{1c9e}', 0x10de), ('\u{1c9f}', 0x10df), - ('\u{1ca0}', 0x10e0), ('\u{1ca1}', 0x10e1), ('\u{1ca2}', 0x10e2), ('\u{1ca3}', 0x10e3), - ('\u{1ca4}', 0x10e4), ('\u{1ca5}', 0x10e5), ('\u{1ca6}', 0x10e6), ('\u{1ca7}', 0x10e7), - ('\u{1ca8}', 0x10e8), ('\u{1ca9}', 0x10e9), ('\u{1caa}', 0x10ea), ('\u{1cab}', 0x10eb), - ('\u{1cac}', 0x10ec), ('\u{1cad}', 0x10ed), ('\u{1cae}', 0x10ee), ('\u{1caf}', 0x10ef), - ('\u{1cb0}', 0x10f0), ('\u{1cb1}', 0x10f1), ('\u{1cb2}', 0x10f2), ('\u{1cb3}', 0x10f3), - ('\u{1cb4}', 0x10f4), ('\u{1cb5}', 0x10f5), ('\u{1cb6}', 0x10f6), ('\u{1cb7}', 0x10f7), - ('\u{1cb8}', 0x10f8), ('\u{1cb9}', 0x10f9), ('\u{1cba}', 0x10fa), ('\u{1cbd}', 0x10fd), - ('\u{1cbe}', 0x10fe), ('\u{1cbf}', 0x10ff), ('\u{1e00}', 0x1e01), ('\u{1e02}', 0x1e03), - ('\u{1e04}', 0x1e05), ('\u{1e06}', 0x1e07), ('\u{1e08}', 0x1e09), ('\u{1e0a}', 0x1e0b), - ('\u{1e0c}', 0x1e0d), ('\u{1e0e}', 0x1e0f), ('\u{1e10}', 0x1e11), ('\u{1e12}', 0x1e13), - ('\u{1e14}', 0x1e15), ('\u{1e16}', 0x1e17), ('\u{1e18}', 0x1e19), ('\u{1e1a}', 0x1e1b), - ('\u{1e1c}', 0x1e1d), ('\u{1e1e}', 0x1e1f), ('\u{1e20}', 0x1e21), ('\u{1e22}', 0x1e23), - ('\u{1e24}', 0x1e25), ('\u{1e26}', 0x1e27), ('\u{1e28}', 0x1e29), ('\u{1e2a}', 0x1e2b), - ('\u{1e2c}', 0x1e2d), ('\u{1e2e}', 0x1e2f), ('\u{1e30}', 0x1e31), ('\u{1e32}', 0x1e33), - ('\u{1e34}', 0x1e35), ('\u{1e36}', 0x1e37), ('\u{1e38}', 0x1e39), ('\u{1e3a}', 0x1e3b), - ('\u{1e3c}', 0x1e3d), ('\u{1e3e}', 0x1e3f), ('\u{1e40}', 0x1e41), ('\u{1e42}', 0x1e43), - ('\u{1e44}', 0x1e45), ('\u{1e46}', 0x1e47), ('\u{1e48}', 0x1e49), ('\u{1e4a}', 0x1e4b), - ('\u{1e4c}', 0x1e4d), ('\u{1e4e}', 0x1e4f), ('\u{1e50}', 0x1e51), ('\u{1e52}', 0x1e53), - ('\u{1e54}', 0x1e55), ('\u{1e56}', 0x1e57), ('\u{1e58}', 0x1e59), ('\u{1e5a}', 0x1e5b), - ('\u{1e5c}', 0x1e5d), ('\u{1e5e}', 0x1e5f), ('\u{1e60}', 0x1e61), ('\u{1e62}', 0x1e63), - ('\u{1e64}', 0x1e65), ('\u{1e66}', 0x1e67), ('\u{1e68}', 0x1e69), ('\u{1e6a}', 0x1e6b), - ('\u{1e6c}', 0x1e6d), ('\u{1e6e}', 0x1e6f), ('\u{1e70}', 0x1e71), ('\u{1e72}', 0x1e73), - ('\u{1e74}', 0x1e75), ('\u{1e76}', 0x1e77), ('\u{1e78}', 0x1e79), ('\u{1e7a}', 0x1e7b), - ('\u{1e7c}', 0x1e7d), ('\u{1e7e}', 0x1e7f), ('\u{1e80}', 0x1e81), ('\u{1e82}', 0x1e83), - ('\u{1e84}', 0x1e85), ('\u{1e86}', 0x1e87), ('\u{1e88}', 0x1e89), ('\u{1e8a}', 0x1e8b), - ('\u{1e8c}', 0x1e8d), ('\u{1e8e}', 0x1e8f), ('\u{1e90}', 0x1e91), ('\u{1e92}', 0x1e93), - ('\u{1e94}', 0x1e95), ('\u{1e9e}', 0xdf), ('\u{1ea0}', 0x1ea1), ('\u{1ea2}', 0x1ea3), - ('\u{1ea4}', 0x1ea5), ('\u{1ea6}', 0x1ea7), ('\u{1ea8}', 0x1ea9), ('\u{1eaa}', 0x1eab), - ('\u{1eac}', 0x1ead), ('\u{1eae}', 0x1eaf), ('\u{1eb0}', 0x1eb1), ('\u{1eb2}', 0x1eb3), - ('\u{1eb4}', 0x1eb5), ('\u{1eb6}', 0x1eb7), ('\u{1eb8}', 0x1eb9), ('\u{1eba}', 0x1ebb), - ('\u{1ebc}', 0x1ebd), ('\u{1ebe}', 0x1ebf), ('\u{1ec0}', 0x1ec1), ('\u{1ec2}', 0x1ec3), - ('\u{1ec4}', 0x1ec5), ('\u{1ec6}', 0x1ec7), ('\u{1ec8}', 0x1ec9), ('\u{1eca}', 0x1ecb), - ('\u{1ecc}', 0x1ecd), ('\u{1ece}', 0x1ecf), ('\u{1ed0}', 0x1ed1), ('\u{1ed2}', 0x1ed3), - ('\u{1ed4}', 0x1ed5), ('\u{1ed6}', 0x1ed7), ('\u{1ed8}', 0x1ed9), ('\u{1eda}', 0x1edb), - ('\u{1edc}', 0x1edd), ('\u{1ede}', 0x1edf), ('\u{1ee0}', 0x1ee1), ('\u{1ee2}', 0x1ee3), - ('\u{1ee4}', 0x1ee5), ('\u{1ee6}', 0x1ee7), ('\u{1ee8}', 0x1ee9), ('\u{1eea}', 0x1eeb), - ('\u{1eec}', 0x1eed), ('\u{1eee}', 0x1eef), ('\u{1ef0}', 0x1ef1), ('\u{1ef2}', 0x1ef3), - ('\u{1ef4}', 0x1ef5), ('\u{1ef6}', 0x1ef7), ('\u{1ef8}', 0x1ef9), ('\u{1efa}', 0x1efb), - ('\u{1efc}', 0x1efd), ('\u{1efe}', 0x1eff), ('\u{1f08}', 0x1f00), ('\u{1f09}', 0x1f01), - ('\u{1f0a}', 0x1f02), ('\u{1f0b}', 0x1f03), ('\u{1f0c}', 0x1f04), ('\u{1f0d}', 0x1f05), - ('\u{1f0e}', 0x1f06), ('\u{1f0f}', 0x1f07), ('\u{1f18}', 0x1f10), ('\u{1f19}', 0x1f11), - ('\u{1f1a}', 0x1f12), ('\u{1f1b}', 0x1f13), ('\u{1f1c}', 0x1f14), ('\u{1f1d}', 0x1f15), - ('\u{1f28}', 0x1f20), ('\u{1f29}', 0x1f21), ('\u{1f2a}', 0x1f22), ('\u{1f2b}', 0x1f23), - ('\u{1f2c}', 0x1f24), ('\u{1f2d}', 0x1f25), ('\u{1f2e}', 0x1f26), ('\u{1f2f}', 0x1f27), - ('\u{1f38}', 0x1f30), ('\u{1f39}', 0x1f31), ('\u{1f3a}', 0x1f32), ('\u{1f3b}', 0x1f33), - ('\u{1f3c}', 0x1f34), ('\u{1f3d}', 0x1f35), ('\u{1f3e}', 0x1f36), ('\u{1f3f}', 0x1f37), - ('\u{1f48}', 0x1f40), ('\u{1f49}', 0x1f41), ('\u{1f4a}', 0x1f42), ('\u{1f4b}', 0x1f43), - ('\u{1f4c}', 0x1f44), ('\u{1f4d}', 0x1f45), ('\u{1f59}', 0x1f51), ('\u{1f5b}', 0x1f53), - ('\u{1f5d}', 0x1f55), ('\u{1f5f}', 0x1f57), ('\u{1f68}', 0x1f60), ('\u{1f69}', 0x1f61), - ('\u{1f6a}', 0x1f62), ('\u{1f6b}', 0x1f63), ('\u{1f6c}', 0x1f64), ('\u{1f6d}', 0x1f65), - ('\u{1f6e}', 0x1f66), ('\u{1f6f}', 0x1f67), ('\u{1f88}', 0x1f80), ('\u{1f89}', 0x1f81), - ('\u{1f8a}', 0x1f82), ('\u{1f8b}', 0x1f83), ('\u{1f8c}', 0x1f84), ('\u{1f8d}', 0x1f85), - ('\u{1f8e}', 0x1f86), ('\u{1f8f}', 0x1f87), ('\u{1f98}', 0x1f90), ('\u{1f99}', 0x1f91), - ('\u{1f9a}', 0x1f92), ('\u{1f9b}', 0x1f93), ('\u{1f9c}', 0x1f94), ('\u{1f9d}', 0x1f95), - ('\u{1f9e}', 0x1f96), ('\u{1f9f}', 0x1f97), ('\u{1fa8}', 0x1fa0), ('\u{1fa9}', 0x1fa1), - ('\u{1faa}', 0x1fa2), ('\u{1fab}', 0x1fa3), ('\u{1fac}', 0x1fa4), ('\u{1fad}', 0x1fa5), - ('\u{1fae}', 0x1fa6), ('\u{1faf}', 0x1fa7), ('\u{1fb8}', 0x1fb0), ('\u{1fb9}', 0x1fb1), - ('\u{1fba}', 0x1f70), ('\u{1fbb}', 0x1f71), ('\u{1fbc}', 0x1fb3), ('\u{1fc8}', 0x1f72), - ('\u{1fc9}', 0x1f73), ('\u{1fca}', 0x1f74), ('\u{1fcb}', 0x1f75), ('\u{1fcc}', 0x1fc3), - ('\u{1fd8}', 0x1fd0), ('\u{1fd9}', 0x1fd1), ('\u{1fda}', 0x1f76), ('\u{1fdb}', 0x1f77), - ('\u{1fe8}', 0x1fe0), ('\u{1fe9}', 0x1fe1), ('\u{1fea}', 0x1f7a), ('\u{1feb}', 0x1f7b), - ('\u{1fec}', 0x1fe5), ('\u{1ff8}', 0x1f78), ('\u{1ff9}', 0x1f79), ('\u{1ffa}', 0x1f7c), - ('\u{1ffb}', 0x1f7d), ('\u{1ffc}', 0x1ff3), ('\u{2126}', 0x3c9), ('\u{212a}', 0x6b), - ('\u{212b}', 0xe5), ('\u{2132}', 0x214e), ('\u{2160}', 0x2170), ('\u{2161}', 0x2171), - ('\u{2162}', 0x2172), ('\u{2163}', 0x2173), ('\u{2164}', 0x2174), ('\u{2165}', 0x2175), - ('\u{2166}', 0x2176), ('\u{2167}', 0x2177), ('\u{2168}', 0x2178), ('\u{2169}', 0x2179), - ('\u{216a}', 0x217a), ('\u{216b}', 0x217b), ('\u{216c}', 0x217c), ('\u{216d}', 0x217d), - ('\u{216e}', 0x217e), ('\u{216f}', 0x217f), ('\u{2183}', 0x2184), ('\u{24b6}', 0x24d0), - ('\u{24b7}', 0x24d1), ('\u{24b8}', 0x24d2), ('\u{24b9}', 0x24d3), ('\u{24ba}', 0x24d4), - ('\u{24bb}', 0x24d5), ('\u{24bc}', 0x24d6), ('\u{24bd}', 0x24d7), ('\u{24be}', 0x24d8), - ('\u{24bf}', 0x24d9), ('\u{24c0}', 0x24da), ('\u{24c1}', 0x24db), ('\u{24c2}', 0x24dc), - ('\u{24c3}', 0x24dd), ('\u{24c4}', 0x24de), ('\u{24c5}', 0x24df), ('\u{24c6}', 0x24e0), - ('\u{24c7}', 0x24e1), ('\u{24c8}', 0x24e2), ('\u{24c9}', 0x24e3), ('\u{24ca}', 0x24e4), - ('\u{24cb}', 0x24e5), ('\u{24cc}', 0x24e6), ('\u{24cd}', 0x24e7), ('\u{24ce}', 0x24e8), - ('\u{24cf}', 0x24e9), ('\u{2c00}', 0x2c30), ('\u{2c01}', 0x2c31), ('\u{2c02}', 0x2c32), - ('\u{2c03}', 0x2c33), ('\u{2c04}', 0x2c34), ('\u{2c05}', 0x2c35), ('\u{2c06}', 0x2c36), - ('\u{2c07}', 0x2c37), ('\u{2c08}', 0x2c38), ('\u{2c09}', 0x2c39), ('\u{2c0a}', 0x2c3a), - ('\u{2c0b}', 0x2c3b), ('\u{2c0c}', 0x2c3c), ('\u{2c0d}', 0x2c3d), ('\u{2c0e}', 0x2c3e), - ('\u{2c0f}', 0x2c3f), ('\u{2c10}', 0x2c40), ('\u{2c11}', 0x2c41), ('\u{2c12}', 0x2c42), - ('\u{2c13}', 0x2c43), ('\u{2c14}', 0x2c44), ('\u{2c15}', 0x2c45), ('\u{2c16}', 0x2c46), - ('\u{2c17}', 0x2c47), ('\u{2c18}', 0x2c48), ('\u{2c19}', 0x2c49), ('\u{2c1a}', 0x2c4a), - ('\u{2c1b}', 0x2c4b), ('\u{2c1c}', 0x2c4c), ('\u{2c1d}', 0x2c4d), ('\u{2c1e}', 0x2c4e), - ('\u{2c1f}', 0x2c4f), ('\u{2c20}', 0x2c50), ('\u{2c21}', 0x2c51), ('\u{2c22}', 0x2c52), - ('\u{2c23}', 0x2c53), ('\u{2c24}', 0x2c54), ('\u{2c25}', 0x2c55), ('\u{2c26}', 0x2c56), - ('\u{2c27}', 0x2c57), ('\u{2c28}', 0x2c58), ('\u{2c29}', 0x2c59), ('\u{2c2a}', 0x2c5a), - ('\u{2c2b}', 0x2c5b), ('\u{2c2c}', 0x2c5c), ('\u{2c2d}', 0x2c5d), ('\u{2c2e}', 0x2c5e), - ('\u{2c2f}', 0x2c5f), ('\u{2c60}', 0x2c61), ('\u{2c62}', 0x26b), ('\u{2c63}', 0x1d7d), - ('\u{2c64}', 0x27d), ('\u{2c67}', 0x2c68), ('\u{2c69}', 0x2c6a), ('\u{2c6b}', 0x2c6c), - ('\u{2c6d}', 0x251), ('\u{2c6e}', 0x271), ('\u{2c6f}', 0x250), ('\u{2c70}', 0x252), - ('\u{2c72}', 0x2c73), ('\u{2c75}', 0x2c76), ('\u{2c7e}', 0x23f), ('\u{2c7f}', 0x240), - ('\u{2c80}', 0x2c81), ('\u{2c82}', 0x2c83), ('\u{2c84}', 0x2c85), ('\u{2c86}', 0x2c87), - ('\u{2c88}', 0x2c89), ('\u{2c8a}', 0x2c8b), ('\u{2c8c}', 0x2c8d), ('\u{2c8e}', 0x2c8f), - ('\u{2c90}', 0x2c91), ('\u{2c92}', 0x2c93), ('\u{2c94}', 0x2c95), ('\u{2c96}', 0x2c97), - ('\u{2c98}', 0x2c99), ('\u{2c9a}', 0x2c9b), ('\u{2c9c}', 0x2c9d), ('\u{2c9e}', 0x2c9f), - ('\u{2ca0}', 0x2ca1), ('\u{2ca2}', 0x2ca3), ('\u{2ca4}', 0x2ca5), ('\u{2ca6}', 0x2ca7), - ('\u{2ca8}', 0x2ca9), ('\u{2caa}', 0x2cab), ('\u{2cac}', 0x2cad), ('\u{2cae}', 0x2caf), - ('\u{2cb0}', 0x2cb1), ('\u{2cb2}', 0x2cb3), ('\u{2cb4}', 0x2cb5), ('\u{2cb6}', 0x2cb7), - ('\u{2cb8}', 0x2cb9), ('\u{2cba}', 0x2cbb), ('\u{2cbc}', 0x2cbd), ('\u{2cbe}', 0x2cbf), - ('\u{2cc0}', 0x2cc1), ('\u{2cc2}', 0x2cc3), ('\u{2cc4}', 0x2cc5), ('\u{2cc6}', 0x2cc7), - ('\u{2cc8}', 0x2cc9), ('\u{2cca}', 0x2ccb), ('\u{2ccc}', 0x2ccd), ('\u{2cce}', 0x2ccf), - ('\u{2cd0}', 0x2cd1), ('\u{2cd2}', 0x2cd3), ('\u{2cd4}', 0x2cd5), ('\u{2cd6}', 0x2cd7), - ('\u{2cd8}', 0x2cd9), ('\u{2cda}', 0x2cdb), ('\u{2cdc}', 0x2cdd), ('\u{2cde}', 0x2cdf), - ('\u{2ce0}', 0x2ce1), ('\u{2ce2}', 0x2ce3), ('\u{2ceb}', 0x2cec), ('\u{2ced}', 0x2cee), - ('\u{2cf2}', 0x2cf3), ('\u{a640}', 0xa641), ('\u{a642}', 0xa643), ('\u{a644}', 0xa645), - ('\u{a646}', 0xa647), ('\u{a648}', 0xa649), ('\u{a64a}', 0xa64b), ('\u{a64c}', 0xa64d), - ('\u{a64e}', 0xa64f), ('\u{a650}', 0xa651), ('\u{a652}', 0xa653), ('\u{a654}', 0xa655), - ('\u{a656}', 0xa657), ('\u{a658}', 0xa659), ('\u{a65a}', 0xa65b), ('\u{a65c}', 0xa65d), - ('\u{a65e}', 0xa65f), ('\u{a660}', 0xa661), ('\u{a662}', 0xa663), ('\u{a664}', 0xa665), - ('\u{a666}', 0xa667), ('\u{a668}', 0xa669), ('\u{a66a}', 0xa66b), ('\u{a66c}', 0xa66d), - ('\u{a680}', 0xa681), ('\u{a682}', 0xa683), ('\u{a684}', 0xa685), ('\u{a686}', 0xa687), - ('\u{a688}', 0xa689), ('\u{a68a}', 0xa68b), ('\u{a68c}', 0xa68d), ('\u{a68e}', 0xa68f), - ('\u{a690}', 0xa691), ('\u{a692}', 0xa693), ('\u{a694}', 0xa695), ('\u{a696}', 0xa697), - ('\u{a698}', 0xa699), ('\u{a69a}', 0xa69b), ('\u{a722}', 0xa723), ('\u{a724}', 0xa725), - ('\u{a726}', 0xa727), ('\u{a728}', 0xa729), ('\u{a72a}', 0xa72b), ('\u{a72c}', 0xa72d), - ('\u{a72e}', 0xa72f), ('\u{a732}', 0xa733), ('\u{a734}', 0xa735), ('\u{a736}', 0xa737), - ('\u{a738}', 0xa739), ('\u{a73a}', 0xa73b), ('\u{a73c}', 0xa73d), ('\u{a73e}', 0xa73f), - ('\u{a740}', 0xa741), ('\u{a742}', 0xa743), ('\u{a744}', 0xa745), ('\u{a746}', 0xa747), - ('\u{a748}', 0xa749), ('\u{a74a}', 0xa74b), ('\u{a74c}', 0xa74d), ('\u{a74e}', 0xa74f), - ('\u{a750}', 0xa751), ('\u{a752}', 0xa753), ('\u{a754}', 0xa755), ('\u{a756}', 0xa757), - ('\u{a758}', 0xa759), ('\u{a75a}', 0xa75b), ('\u{a75c}', 0xa75d), ('\u{a75e}', 0xa75f), - ('\u{a760}', 0xa761), ('\u{a762}', 0xa763), ('\u{a764}', 0xa765), ('\u{a766}', 0xa767), - ('\u{a768}', 0xa769), ('\u{a76a}', 0xa76b), ('\u{a76c}', 0xa76d), ('\u{a76e}', 0xa76f), - ('\u{a779}', 0xa77a), ('\u{a77b}', 0xa77c), ('\u{a77d}', 0x1d79), ('\u{a77e}', 0xa77f), - ('\u{a780}', 0xa781), ('\u{a782}', 0xa783), ('\u{a784}', 0xa785), ('\u{a786}', 0xa787), - ('\u{a78b}', 0xa78c), ('\u{a78d}', 0x265), ('\u{a790}', 0xa791), ('\u{a792}', 0xa793), - ('\u{a796}', 0xa797), ('\u{a798}', 0xa799), ('\u{a79a}', 0xa79b), ('\u{a79c}', 0xa79d), - ('\u{a79e}', 0xa79f), ('\u{a7a0}', 0xa7a1), ('\u{a7a2}', 0xa7a3), ('\u{a7a4}', 0xa7a5), - ('\u{a7a6}', 0xa7a7), ('\u{a7a8}', 0xa7a9), ('\u{a7aa}', 0x266), ('\u{a7ab}', 0x25c), - ('\u{a7ac}', 0x261), ('\u{a7ad}', 0x26c), ('\u{a7ae}', 0x26a), ('\u{a7b0}', 0x29e), - ('\u{a7b1}', 0x287), ('\u{a7b2}', 0x29d), ('\u{a7b3}', 0xab53), ('\u{a7b4}', 0xa7b5), - ('\u{a7b6}', 0xa7b7), ('\u{a7b8}', 0xa7b9), ('\u{a7ba}', 0xa7bb), ('\u{a7bc}', 0xa7bd), - ('\u{a7be}', 0xa7bf), ('\u{a7c0}', 0xa7c1), ('\u{a7c2}', 0xa7c3), ('\u{a7c4}', 0xa794), - ('\u{a7c5}', 0x282), ('\u{a7c6}', 0x1d8e), ('\u{a7c7}', 0xa7c8), ('\u{a7c9}', 0xa7ca), - ('\u{a7cb}', 0x264), ('\u{a7cc}', 0xa7cd), ('\u{a7ce}', 0xa7cf), ('\u{a7d0}', 0xa7d1), - ('\u{a7d2}', 0xa7d3), ('\u{a7d4}', 0xa7d5), ('\u{a7d6}', 0xa7d7), ('\u{a7d8}', 0xa7d9), - ('\u{a7da}', 0xa7db), ('\u{a7dc}', 0x19b), ('\u{a7f5}', 0xa7f6), ('\u{ff21}', 0xff41), - ('\u{ff22}', 0xff42), ('\u{ff23}', 0xff43), ('\u{ff24}', 0xff44), ('\u{ff25}', 0xff45), - ('\u{ff26}', 0xff46), ('\u{ff27}', 0xff47), ('\u{ff28}', 0xff48), ('\u{ff29}', 0xff49), - ('\u{ff2a}', 0xff4a), ('\u{ff2b}', 0xff4b), ('\u{ff2c}', 0xff4c), ('\u{ff2d}', 0xff4d), - ('\u{ff2e}', 0xff4e), ('\u{ff2f}', 0xff4f), ('\u{ff30}', 0xff50), ('\u{ff31}', 0xff51), - ('\u{ff32}', 0xff52), ('\u{ff33}', 0xff53), ('\u{ff34}', 0xff54), ('\u{ff35}', 0xff55), - ('\u{ff36}', 0xff56), ('\u{ff37}', 0xff57), ('\u{ff38}', 0xff58), ('\u{ff39}', 0xff59), - ('\u{ff3a}', 0xff5a), ('\u{10400}', 0x10428), ('\u{10401}', 0x10429), - ('\u{10402}', 0x1042a), ('\u{10403}', 0x1042b), ('\u{10404}', 0x1042c), - ('\u{10405}', 0x1042d), ('\u{10406}', 0x1042e), ('\u{10407}', 0x1042f), - ('\u{10408}', 0x10430), ('\u{10409}', 0x10431), ('\u{1040a}', 0x10432), - ('\u{1040b}', 0x10433), ('\u{1040c}', 0x10434), ('\u{1040d}', 0x10435), - ('\u{1040e}', 0x10436), ('\u{1040f}', 0x10437), ('\u{10410}', 0x10438), - ('\u{10411}', 0x10439), ('\u{10412}', 0x1043a), ('\u{10413}', 0x1043b), - ('\u{10414}', 0x1043c), ('\u{10415}', 0x1043d), ('\u{10416}', 0x1043e), - ('\u{10417}', 0x1043f), ('\u{10418}', 0x10440), ('\u{10419}', 0x10441), - ('\u{1041a}', 0x10442), ('\u{1041b}', 0x10443), ('\u{1041c}', 0x10444), - ('\u{1041d}', 0x10445), ('\u{1041e}', 0x10446), ('\u{1041f}', 0x10447), - ('\u{10420}', 0x10448), ('\u{10421}', 0x10449), ('\u{10422}', 0x1044a), - ('\u{10423}', 0x1044b), ('\u{10424}', 0x1044c), ('\u{10425}', 0x1044d), - ('\u{10426}', 0x1044e), ('\u{10427}', 0x1044f), ('\u{104b0}', 0x104d8), - ('\u{104b1}', 0x104d9), ('\u{104b2}', 0x104da), ('\u{104b3}', 0x104db), - ('\u{104b4}', 0x104dc), ('\u{104b5}', 0x104dd), ('\u{104b6}', 0x104de), - ('\u{104b7}', 0x104df), ('\u{104b8}', 0x104e0), ('\u{104b9}', 0x104e1), - ('\u{104ba}', 0x104e2), ('\u{104bb}', 0x104e3), ('\u{104bc}', 0x104e4), - ('\u{104bd}', 0x104e5), ('\u{104be}', 0x104e6), ('\u{104bf}', 0x104e7), - ('\u{104c0}', 0x104e8), ('\u{104c1}', 0x104e9), ('\u{104c2}', 0x104ea), - ('\u{104c3}', 0x104eb), ('\u{104c4}', 0x104ec), ('\u{104c5}', 0x104ed), - ('\u{104c6}', 0x104ee), ('\u{104c7}', 0x104ef), ('\u{104c8}', 0x104f0), - ('\u{104c9}', 0x104f1), ('\u{104ca}', 0x104f2), ('\u{104cb}', 0x104f3), - ('\u{104cc}', 0x104f4), ('\u{104cd}', 0x104f5), ('\u{104ce}', 0x104f6), - ('\u{104cf}', 0x104f7), ('\u{104d0}', 0x104f8), ('\u{104d1}', 0x104f9), - ('\u{104d2}', 0x104fa), ('\u{104d3}', 0x104fb), ('\u{10570}', 0x10597), - ('\u{10571}', 0x10598), ('\u{10572}', 0x10599), ('\u{10573}', 0x1059a), - ('\u{10574}', 0x1059b), ('\u{10575}', 0x1059c), ('\u{10576}', 0x1059d), - ('\u{10577}', 0x1059e), ('\u{10578}', 0x1059f), ('\u{10579}', 0x105a0), - ('\u{1057a}', 0x105a1), ('\u{1057c}', 0x105a3), ('\u{1057d}', 0x105a4), - ('\u{1057e}', 0x105a5), ('\u{1057f}', 0x105a6), ('\u{10580}', 0x105a7), - ('\u{10581}', 0x105a8), ('\u{10582}', 0x105a9), ('\u{10583}', 0x105aa), - ('\u{10584}', 0x105ab), ('\u{10585}', 0x105ac), ('\u{10586}', 0x105ad), - ('\u{10587}', 0x105ae), ('\u{10588}', 0x105af), ('\u{10589}', 0x105b0), - ('\u{1058a}', 0x105b1), ('\u{1058c}', 0x105b3), ('\u{1058d}', 0x105b4), - ('\u{1058e}', 0x105b5), ('\u{1058f}', 0x105b6), ('\u{10590}', 0x105b7), - ('\u{10591}', 0x105b8), ('\u{10592}', 0x105b9), ('\u{10594}', 0x105bb), - ('\u{10595}', 0x105bc), ('\u{10c80}', 0x10cc0), ('\u{10c81}', 0x10cc1), - ('\u{10c82}', 0x10cc2), ('\u{10c83}', 0x10cc3), ('\u{10c84}', 0x10cc4), - ('\u{10c85}', 0x10cc5), ('\u{10c86}', 0x10cc6), ('\u{10c87}', 0x10cc7), - ('\u{10c88}', 0x10cc8), ('\u{10c89}', 0x10cc9), ('\u{10c8a}', 0x10cca), - ('\u{10c8b}', 0x10ccb), ('\u{10c8c}', 0x10ccc), ('\u{10c8d}', 0x10ccd), - ('\u{10c8e}', 0x10cce), ('\u{10c8f}', 0x10ccf), ('\u{10c90}', 0x10cd0), - ('\u{10c91}', 0x10cd1), ('\u{10c92}', 0x10cd2), ('\u{10c93}', 0x10cd3), - ('\u{10c94}', 0x10cd4), ('\u{10c95}', 0x10cd5), ('\u{10c96}', 0x10cd6), - ('\u{10c97}', 0x10cd7), ('\u{10c98}', 0x10cd8), ('\u{10c99}', 0x10cd9), - ('\u{10c9a}', 0x10cda), ('\u{10c9b}', 0x10cdb), ('\u{10c9c}', 0x10cdc), - ('\u{10c9d}', 0x10cdd), ('\u{10c9e}', 0x10cde), ('\u{10c9f}', 0x10cdf), - ('\u{10ca0}', 0x10ce0), ('\u{10ca1}', 0x10ce1), ('\u{10ca2}', 0x10ce2), - ('\u{10ca3}', 0x10ce3), ('\u{10ca4}', 0x10ce4), ('\u{10ca5}', 0x10ce5), - ('\u{10ca6}', 0x10ce6), ('\u{10ca7}', 0x10ce7), ('\u{10ca8}', 0x10ce8), - ('\u{10ca9}', 0x10ce9), ('\u{10caa}', 0x10cea), ('\u{10cab}', 0x10ceb), - ('\u{10cac}', 0x10cec), ('\u{10cad}', 0x10ced), ('\u{10cae}', 0x10cee), - ('\u{10caf}', 0x10cef), ('\u{10cb0}', 0x10cf0), ('\u{10cb1}', 0x10cf1), - ('\u{10cb2}', 0x10cf2), ('\u{10d50}', 0x10d70), ('\u{10d51}', 0x10d71), - ('\u{10d52}', 0x10d72), ('\u{10d53}', 0x10d73), ('\u{10d54}', 0x10d74), - ('\u{10d55}', 0x10d75), ('\u{10d56}', 0x10d76), ('\u{10d57}', 0x10d77), - ('\u{10d58}', 0x10d78), ('\u{10d59}', 0x10d79), ('\u{10d5a}', 0x10d7a), - ('\u{10d5b}', 0x10d7b), ('\u{10d5c}', 0x10d7c), ('\u{10d5d}', 0x10d7d), - ('\u{10d5e}', 0x10d7e), ('\u{10d5f}', 0x10d7f), ('\u{10d60}', 0x10d80), - ('\u{10d61}', 0x10d81), ('\u{10d62}', 0x10d82), ('\u{10d63}', 0x10d83), - ('\u{10d64}', 0x10d84), ('\u{10d65}', 0x10d85), ('\u{118a0}', 0x118c0), - ('\u{118a1}', 0x118c1), ('\u{118a2}', 0x118c2), ('\u{118a3}', 0x118c3), - ('\u{118a4}', 0x118c4), ('\u{118a5}', 0x118c5), ('\u{118a6}', 0x118c6), - ('\u{118a7}', 0x118c7), ('\u{118a8}', 0x118c8), ('\u{118a9}', 0x118c9), - ('\u{118aa}', 0x118ca), ('\u{118ab}', 0x118cb), ('\u{118ac}', 0x118cc), - ('\u{118ad}', 0x118cd), ('\u{118ae}', 0x118ce), ('\u{118af}', 0x118cf), - ('\u{118b0}', 0x118d0), ('\u{118b1}', 0x118d1), ('\u{118b2}', 0x118d2), - ('\u{118b3}', 0x118d3), ('\u{118b4}', 0x118d4), ('\u{118b5}', 0x118d5), - ('\u{118b6}', 0x118d6), ('\u{118b7}', 0x118d7), ('\u{118b8}', 0x118d8), - ('\u{118b9}', 0x118d9), ('\u{118ba}', 0x118da), ('\u{118bb}', 0x118db), - ('\u{118bc}', 0x118dc), ('\u{118bd}', 0x118dd), ('\u{118be}', 0x118de), - ('\u{118bf}', 0x118df), ('\u{16e40}', 0x16e60), ('\u{16e41}', 0x16e61), - ('\u{16e42}', 0x16e62), ('\u{16e43}', 0x16e63), ('\u{16e44}', 0x16e64), - ('\u{16e45}', 0x16e65), ('\u{16e46}', 0x16e66), ('\u{16e47}', 0x16e67), - ('\u{16e48}', 0x16e68), ('\u{16e49}', 0x16e69), ('\u{16e4a}', 0x16e6a), - ('\u{16e4b}', 0x16e6b), ('\u{16e4c}', 0x16e6c), ('\u{16e4d}', 0x16e6d), - ('\u{16e4e}', 0x16e6e), ('\u{16e4f}', 0x16e6f), ('\u{16e50}', 0x16e70), - ('\u{16e51}', 0x16e71), ('\u{16e52}', 0x16e72), ('\u{16e53}', 0x16e73), - ('\u{16e54}', 0x16e74), ('\u{16e55}', 0x16e75), ('\u{16e56}', 0x16e76), - ('\u{16e57}', 0x16e77), ('\u{16e58}', 0x16e78), ('\u{16e59}', 0x16e79), - ('\u{16e5a}', 0x16e7a), ('\u{16e5b}', 0x16e7b), ('\u{16e5c}', 0x16e7c), - ('\u{16e5d}', 0x16e7d), ('\u{16e5e}', 0x16e7e), ('\u{16e5f}', 0x16e7f), - ('\u{16ea0}', 0x16ebb), ('\u{16ea1}', 0x16ebc), ('\u{16ea2}', 0x16ebd), - ('\u{16ea3}', 0x16ebe), ('\u{16ea4}', 0x16ebf), ('\u{16ea5}', 0x16ec0), - ('\u{16ea6}', 0x16ec1), ('\u{16ea7}', 0x16ec2), ('\u{16ea8}', 0x16ec3), - ('\u{16ea9}', 0x16ec4), ('\u{16eaa}', 0x16ec5), ('\u{16eab}', 0x16ec6), - ('\u{16eac}', 0x16ec7), ('\u{16ead}', 0x16ec8), ('\u{16eae}', 0x16ec9), - ('\u{16eaf}', 0x16eca), ('\u{16eb0}', 0x16ecb), ('\u{16eb1}', 0x16ecc), - ('\u{16eb2}', 0x16ecd), ('\u{16eb3}', 0x16ece), ('\u{16eb4}', 0x16ecf), - ('\u{16eb5}', 0x16ed0), ('\u{16eb6}', 0x16ed1), ('\u{16eb7}', 0x16ed2), - ('\u{16eb8}', 0x16ed3), ('\u{1e900}', 0x1e922), ('\u{1e901}', 0x1e923), - ('\u{1e902}', 0x1e924), ('\u{1e903}', 0x1e925), ('\u{1e904}', 0x1e926), - ('\u{1e905}', 0x1e927), ('\u{1e906}', 0x1e928), ('\u{1e907}', 0x1e929), - ('\u{1e908}', 0x1e92a), ('\u{1e909}', 0x1e92b), ('\u{1e90a}', 0x1e92c), - ('\u{1e90b}', 0x1e92d), ('\u{1e90c}', 0x1e92e), ('\u{1e90d}', 0x1e92f), - ('\u{1e90e}', 0x1e930), ('\u{1e90f}', 0x1e931), ('\u{1e910}', 0x1e932), - ('\u{1e911}', 0x1e933), ('\u{1e912}', 0x1e934), ('\u{1e913}', 0x1e935), - ('\u{1e914}', 0x1e936), ('\u{1e915}', 0x1e937), ('\u{1e916}', 0x1e938), - ('\u{1e917}', 0x1e939), ('\u{1e918}', 0x1e93a), ('\u{1e919}', 0x1e93b), - ('\u{1e91a}', 0x1e93c), ('\u{1e91b}', 0x1e93d), ('\u{1e91c}', 0x1e93e), - ('\u{1e91d}', 0x1e93f), ('\u{1e91e}', 0x1e940), ('\u{1e91f}', 0x1e941), - ('\u{1e920}', 0x1e942), ('\u{1e921}', 0x1e943), - ]; + const INDEX_MASK: u32 = 0x400000; - #[rustfmt::skip] - static LOWERCASE_TABLE_MULTI: &[[char; 3]; 1] = &[ - ['\u{69}', '\u{307}', '\u{0}'], - ]; - - #[inline] pub fn to_lower(c: char) -> [char; 3] { - const { - let mut i = 0; - while i < LOWERCASE_TABLE.len() { - let (_, val) = LOWERCASE_TABLE[i]; - if val & (1 << 22) == 0 { - assert!(char::from_u32(val).is_some()); - } else { - let index = val & ((1 << 22) - 1); - assert!((index as usize) < LOWERCASE_TABLE_MULTI.len()); - } - i += 1; - } - } - - // SAFETY: Just checked that the tables are valid - unsafe { - super::case_conversion( - c, - |c| c.to_ascii_lowercase(), - LOWERCASE_TABLE, - LOWERCASE_TABLE_MULTI, - ) + if c.is_ascii() { + [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] + } else { + LOWERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = LOWERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) } } - #[rustfmt::skip] - static UPPERCASE_TABLE: &[(char, u32); 1554] = &[ - ('\u{b5}', 0x39c), ('\u{df}', 0x400000), ('\u{e0}', 0xc0), ('\u{e1}', 0xc1), - ('\u{e2}', 0xc2), ('\u{e3}', 0xc3), ('\u{e4}', 0xc4), ('\u{e5}', 0xc5), ('\u{e6}', 0xc6), - ('\u{e7}', 0xc7), ('\u{e8}', 0xc8), ('\u{e9}', 0xc9), ('\u{ea}', 0xca), ('\u{eb}', 0xcb), - ('\u{ec}', 0xcc), ('\u{ed}', 0xcd), ('\u{ee}', 0xce), ('\u{ef}', 0xcf), ('\u{f0}', 0xd0), - ('\u{f1}', 0xd1), ('\u{f2}', 0xd2), ('\u{f3}', 0xd3), ('\u{f4}', 0xd4), ('\u{f5}', 0xd5), - ('\u{f6}', 0xd6), ('\u{f8}', 0xd8), ('\u{f9}', 0xd9), ('\u{fa}', 0xda), ('\u{fb}', 0xdb), - ('\u{fc}', 0xdc), ('\u{fd}', 0xdd), ('\u{fe}', 0xde), ('\u{ff}', 0x178), ('\u{101}', 0x100), - ('\u{103}', 0x102), ('\u{105}', 0x104), ('\u{107}', 0x106), ('\u{109}', 0x108), - ('\u{10b}', 0x10a), ('\u{10d}', 0x10c), ('\u{10f}', 0x10e), ('\u{111}', 0x110), - ('\u{113}', 0x112), ('\u{115}', 0x114), ('\u{117}', 0x116), ('\u{119}', 0x118), - ('\u{11b}', 0x11a), ('\u{11d}', 0x11c), ('\u{11f}', 0x11e), ('\u{121}', 0x120), - ('\u{123}', 0x122), ('\u{125}', 0x124), ('\u{127}', 0x126), ('\u{129}', 0x128), - ('\u{12b}', 0x12a), ('\u{12d}', 0x12c), ('\u{12f}', 0x12e), ('\u{131}', 0x49), - ('\u{133}', 0x132), ('\u{135}', 0x134), ('\u{137}', 0x136), ('\u{13a}', 0x139), - ('\u{13c}', 0x13b), ('\u{13e}', 0x13d), ('\u{140}', 0x13f), ('\u{142}', 0x141), - ('\u{144}', 0x143), ('\u{146}', 0x145), ('\u{148}', 0x147), ('\u{149}', 0x400001), - ('\u{14b}', 0x14a), ('\u{14d}', 0x14c), ('\u{14f}', 0x14e), ('\u{151}', 0x150), - ('\u{153}', 0x152), ('\u{155}', 0x154), ('\u{157}', 0x156), ('\u{159}', 0x158), - ('\u{15b}', 0x15a), ('\u{15d}', 0x15c), ('\u{15f}', 0x15e), ('\u{161}', 0x160), - ('\u{163}', 0x162), ('\u{165}', 0x164), ('\u{167}', 0x166), ('\u{169}', 0x168), - ('\u{16b}', 0x16a), ('\u{16d}', 0x16c), ('\u{16f}', 0x16e), ('\u{171}', 0x170), - ('\u{173}', 0x172), ('\u{175}', 0x174), ('\u{177}', 0x176), ('\u{17a}', 0x179), - ('\u{17c}', 0x17b), ('\u{17e}', 0x17d), ('\u{17f}', 0x53), ('\u{180}', 0x243), - ('\u{183}', 0x182), ('\u{185}', 0x184), ('\u{188}', 0x187), ('\u{18c}', 0x18b), - ('\u{192}', 0x191), ('\u{195}', 0x1f6), ('\u{199}', 0x198), ('\u{19a}', 0x23d), - ('\u{19b}', 0xa7dc), ('\u{19e}', 0x220), ('\u{1a1}', 0x1a0), ('\u{1a3}', 0x1a2), - ('\u{1a5}', 0x1a4), ('\u{1a8}', 0x1a7), ('\u{1ad}', 0x1ac), ('\u{1b0}', 0x1af), - ('\u{1b4}', 0x1b3), ('\u{1b6}', 0x1b5), ('\u{1b9}', 0x1b8), ('\u{1bd}', 0x1bc), - ('\u{1bf}', 0x1f7), ('\u{1c5}', 0x1c4), ('\u{1c6}', 0x1c4), ('\u{1c8}', 0x1c7), - ('\u{1c9}', 0x1c7), ('\u{1cb}', 0x1ca), ('\u{1cc}', 0x1ca), ('\u{1ce}', 0x1cd), - ('\u{1d0}', 0x1cf), ('\u{1d2}', 0x1d1), ('\u{1d4}', 0x1d3), ('\u{1d6}', 0x1d5), - ('\u{1d8}', 0x1d7), ('\u{1da}', 0x1d9), ('\u{1dc}', 0x1db), ('\u{1dd}', 0x18e), - ('\u{1df}', 0x1de), ('\u{1e1}', 0x1e0), ('\u{1e3}', 0x1e2), ('\u{1e5}', 0x1e4), - ('\u{1e7}', 0x1e6), ('\u{1e9}', 0x1e8), ('\u{1eb}', 0x1ea), ('\u{1ed}', 0x1ec), - ('\u{1ef}', 0x1ee), ('\u{1f0}', 0x400002), ('\u{1f2}', 0x1f1), ('\u{1f3}', 0x1f1), - ('\u{1f5}', 0x1f4), ('\u{1f9}', 0x1f8), ('\u{1fb}', 0x1fa), ('\u{1fd}', 0x1fc), - ('\u{1ff}', 0x1fe), ('\u{201}', 0x200), ('\u{203}', 0x202), ('\u{205}', 0x204), - ('\u{207}', 0x206), ('\u{209}', 0x208), ('\u{20b}', 0x20a), ('\u{20d}', 0x20c), - ('\u{20f}', 0x20e), ('\u{211}', 0x210), ('\u{213}', 0x212), ('\u{215}', 0x214), - ('\u{217}', 0x216), ('\u{219}', 0x218), ('\u{21b}', 0x21a), ('\u{21d}', 0x21c), - ('\u{21f}', 0x21e), ('\u{223}', 0x222), ('\u{225}', 0x224), ('\u{227}', 0x226), - ('\u{229}', 0x228), ('\u{22b}', 0x22a), ('\u{22d}', 0x22c), ('\u{22f}', 0x22e), - ('\u{231}', 0x230), ('\u{233}', 0x232), ('\u{23c}', 0x23b), ('\u{23f}', 0x2c7e), - ('\u{240}', 0x2c7f), ('\u{242}', 0x241), ('\u{247}', 0x246), ('\u{249}', 0x248), - ('\u{24b}', 0x24a), ('\u{24d}', 0x24c), ('\u{24f}', 0x24e), ('\u{250}', 0x2c6f), - ('\u{251}', 0x2c6d), ('\u{252}', 0x2c70), ('\u{253}', 0x181), ('\u{254}', 0x186), - ('\u{256}', 0x189), ('\u{257}', 0x18a), ('\u{259}', 0x18f), ('\u{25b}', 0x190), - ('\u{25c}', 0xa7ab), ('\u{260}', 0x193), ('\u{261}', 0xa7ac), ('\u{263}', 0x194), - ('\u{264}', 0xa7cb), ('\u{265}', 0xa78d), ('\u{266}', 0xa7aa), ('\u{268}', 0x197), - ('\u{269}', 0x196), ('\u{26a}', 0xa7ae), ('\u{26b}', 0x2c62), ('\u{26c}', 0xa7ad), - ('\u{26f}', 0x19c), ('\u{271}', 0x2c6e), ('\u{272}', 0x19d), ('\u{275}', 0x19f), - ('\u{27d}', 0x2c64), ('\u{280}', 0x1a6), ('\u{282}', 0xa7c5), ('\u{283}', 0x1a9), - ('\u{287}', 0xa7b1), ('\u{288}', 0x1ae), ('\u{289}', 0x244), ('\u{28a}', 0x1b1), - ('\u{28b}', 0x1b2), ('\u{28c}', 0x245), ('\u{292}', 0x1b7), ('\u{29d}', 0xa7b2), - ('\u{29e}', 0xa7b0), ('\u{345}', 0x399), ('\u{371}', 0x370), ('\u{373}', 0x372), - ('\u{377}', 0x376), ('\u{37b}', 0x3fd), ('\u{37c}', 0x3fe), ('\u{37d}', 0x3ff), - ('\u{390}', 0x400003), ('\u{3ac}', 0x386), ('\u{3ad}', 0x388), ('\u{3ae}', 0x389), - ('\u{3af}', 0x38a), ('\u{3b0}', 0x400004), ('\u{3b1}', 0x391), ('\u{3b2}', 0x392), - ('\u{3b3}', 0x393), ('\u{3b4}', 0x394), ('\u{3b5}', 0x395), ('\u{3b6}', 0x396), - ('\u{3b7}', 0x397), ('\u{3b8}', 0x398), ('\u{3b9}', 0x399), ('\u{3ba}', 0x39a), - ('\u{3bb}', 0x39b), ('\u{3bc}', 0x39c), ('\u{3bd}', 0x39d), ('\u{3be}', 0x39e), - ('\u{3bf}', 0x39f), ('\u{3c0}', 0x3a0), ('\u{3c1}', 0x3a1), ('\u{3c2}', 0x3a3), - ('\u{3c3}', 0x3a3), ('\u{3c4}', 0x3a4), ('\u{3c5}', 0x3a5), ('\u{3c6}', 0x3a6), - ('\u{3c7}', 0x3a7), ('\u{3c8}', 0x3a8), ('\u{3c9}', 0x3a9), ('\u{3ca}', 0x3aa), - ('\u{3cb}', 0x3ab), ('\u{3cc}', 0x38c), ('\u{3cd}', 0x38e), ('\u{3ce}', 0x38f), - ('\u{3d0}', 0x392), ('\u{3d1}', 0x398), ('\u{3d5}', 0x3a6), ('\u{3d6}', 0x3a0), - ('\u{3d7}', 0x3cf), ('\u{3d9}', 0x3d8), ('\u{3db}', 0x3da), ('\u{3dd}', 0x3dc), - ('\u{3df}', 0x3de), ('\u{3e1}', 0x3e0), ('\u{3e3}', 0x3e2), ('\u{3e5}', 0x3e4), - ('\u{3e7}', 0x3e6), ('\u{3e9}', 0x3e8), ('\u{3eb}', 0x3ea), ('\u{3ed}', 0x3ec), - ('\u{3ef}', 0x3ee), ('\u{3f0}', 0x39a), ('\u{3f1}', 0x3a1), ('\u{3f2}', 0x3f9), - ('\u{3f3}', 0x37f), ('\u{3f5}', 0x395), ('\u{3f8}', 0x3f7), ('\u{3fb}', 0x3fa), - ('\u{430}', 0x410), ('\u{431}', 0x411), ('\u{432}', 0x412), ('\u{433}', 0x413), - ('\u{434}', 0x414), ('\u{435}', 0x415), ('\u{436}', 0x416), ('\u{437}', 0x417), - ('\u{438}', 0x418), ('\u{439}', 0x419), ('\u{43a}', 0x41a), ('\u{43b}', 0x41b), - ('\u{43c}', 0x41c), ('\u{43d}', 0x41d), ('\u{43e}', 0x41e), ('\u{43f}', 0x41f), - ('\u{440}', 0x420), ('\u{441}', 0x421), ('\u{442}', 0x422), ('\u{443}', 0x423), - ('\u{444}', 0x424), ('\u{445}', 0x425), ('\u{446}', 0x426), ('\u{447}', 0x427), - ('\u{448}', 0x428), ('\u{449}', 0x429), ('\u{44a}', 0x42a), ('\u{44b}', 0x42b), - ('\u{44c}', 0x42c), ('\u{44d}', 0x42d), ('\u{44e}', 0x42e), ('\u{44f}', 0x42f), - ('\u{450}', 0x400), ('\u{451}', 0x401), ('\u{452}', 0x402), ('\u{453}', 0x403), - ('\u{454}', 0x404), ('\u{455}', 0x405), ('\u{456}', 0x406), ('\u{457}', 0x407), - ('\u{458}', 0x408), ('\u{459}', 0x409), ('\u{45a}', 0x40a), ('\u{45b}', 0x40b), - ('\u{45c}', 0x40c), ('\u{45d}', 0x40d), ('\u{45e}', 0x40e), ('\u{45f}', 0x40f), - ('\u{461}', 0x460), ('\u{463}', 0x462), ('\u{465}', 0x464), ('\u{467}', 0x466), - ('\u{469}', 0x468), ('\u{46b}', 0x46a), ('\u{46d}', 0x46c), ('\u{46f}', 0x46e), - ('\u{471}', 0x470), ('\u{473}', 0x472), ('\u{475}', 0x474), ('\u{477}', 0x476), - ('\u{479}', 0x478), ('\u{47b}', 0x47a), ('\u{47d}', 0x47c), ('\u{47f}', 0x47e), - ('\u{481}', 0x480), ('\u{48b}', 0x48a), ('\u{48d}', 0x48c), ('\u{48f}', 0x48e), - ('\u{491}', 0x490), ('\u{493}', 0x492), ('\u{495}', 0x494), ('\u{497}', 0x496), - ('\u{499}', 0x498), ('\u{49b}', 0x49a), ('\u{49d}', 0x49c), ('\u{49f}', 0x49e), - ('\u{4a1}', 0x4a0), ('\u{4a3}', 0x4a2), ('\u{4a5}', 0x4a4), ('\u{4a7}', 0x4a6), - ('\u{4a9}', 0x4a8), ('\u{4ab}', 0x4aa), ('\u{4ad}', 0x4ac), ('\u{4af}', 0x4ae), - ('\u{4b1}', 0x4b0), ('\u{4b3}', 0x4b2), ('\u{4b5}', 0x4b4), ('\u{4b7}', 0x4b6), - ('\u{4b9}', 0x4b8), ('\u{4bb}', 0x4ba), ('\u{4bd}', 0x4bc), ('\u{4bf}', 0x4be), - ('\u{4c2}', 0x4c1), ('\u{4c4}', 0x4c3), ('\u{4c6}', 0x4c5), ('\u{4c8}', 0x4c7), - ('\u{4ca}', 0x4c9), ('\u{4cc}', 0x4cb), ('\u{4ce}', 0x4cd), ('\u{4cf}', 0x4c0), - ('\u{4d1}', 0x4d0), ('\u{4d3}', 0x4d2), ('\u{4d5}', 0x4d4), ('\u{4d7}', 0x4d6), - ('\u{4d9}', 0x4d8), ('\u{4db}', 0x4da), ('\u{4dd}', 0x4dc), ('\u{4df}', 0x4de), - ('\u{4e1}', 0x4e0), ('\u{4e3}', 0x4e2), ('\u{4e5}', 0x4e4), ('\u{4e7}', 0x4e6), - ('\u{4e9}', 0x4e8), ('\u{4eb}', 0x4ea), ('\u{4ed}', 0x4ec), ('\u{4ef}', 0x4ee), - ('\u{4f1}', 0x4f0), ('\u{4f3}', 0x4f2), ('\u{4f5}', 0x4f4), ('\u{4f7}', 0x4f6), - ('\u{4f9}', 0x4f8), ('\u{4fb}', 0x4fa), ('\u{4fd}', 0x4fc), ('\u{4ff}', 0x4fe), - ('\u{501}', 0x500), ('\u{503}', 0x502), ('\u{505}', 0x504), ('\u{507}', 0x506), - ('\u{509}', 0x508), ('\u{50b}', 0x50a), ('\u{50d}', 0x50c), ('\u{50f}', 0x50e), - ('\u{511}', 0x510), ('\u{513}', 0x512), ('\u{515}', 0x514), ('\u{517}', 0x516), - ('\u{519}', 0x518), ('\u{51b}', 0x51a), ('\u{51d}', 0x51c), ('\u{51f}', 0x51e), - ('\u{521}', 0x520), ('\u{523}', 0x522), ('\u{525}', 0x524), ('\u{527}', 0x526), - ('\u{529}', 0x528), ('\u{52b}', 0x52a), ('\u{52d}', 0x52c), ('\u{52f}', 0x52e), - ('\u{561}', 0x531), ('\u{562}', 0x532), ('\u{563}', 0x533), ('\u{564}', 0x534), - ('\u{565}', 0x535), ('\u{566}', 0x536), ('\u{567}', 0x537), ('\u{568}', 0x538), - ('\u{569}', 0x539), ('\u{56a}', 0x53a), ('\u{56b}', 0x53b), ('\u{56c}', 0x53c), - ('\u{56d}', 0x53d), ('\u{56e}', 0x53e), ('\u{56f}', 0x53f), ('\u{570}', 0x540), - ('\u{571}', 0x541), ('\u{572}', 0x542), ('\u{573}', 0x543), ('\u{574}', 0x544), - ('\u{575}', 0x545), ('\u{576}', 0x546), ('\u{577}', 0x547), ('\u{578}', 0x548), - ('\u{579}', 0x549), ('\u{57a}', 0x54a), ('\u{57b}', 0x54b), ('\u{57c}', 0x54c), - ('\u{57d}', 0x54d), ('\u{57e}', 0x54e), ('\u{57f}', 0x54f), ('\u{580}', 0x550), - ('\u{581}', 0x551), ('\u{582}', 0x552), ('\u{583}', 0x553), ('\u{584}', 0x554), - ('\u{585}', 0x555), ('\u{586}', 0x556), ('\u{587}', 0x400005), ('\u{10d0}', 0x1c90), - ('\u{10d1}', 0x1c91), ('\u{10d2}', 0x1c92), ('\u{10d3}', 0x1c93), ('\u{10d4}', 0x1c94), - ('\u{10d5}', 0x1c95), ('\u{10d6}', 0x1c96), ('\u{10d7}', 0x1c97), ('\u{10d8}', 0x1c98), - ('\u{10d9}', 0x1c99), ('\u{10da}', 0x1c9a), ('\u{10db}', 0x1c9b), ('\u{10dc}', 0x1c9c), - ('\u{10dd}', 0x1c9d), ('\u{10de}', 0x1c9e), ('\u{10df}', 0x1c9f), ('\u{10e0}', 0x1ca0), - ('\u{10e1}', 0x1ca1), ('\u{10e2}', 0x1ca2), ('\u{10e3}', 0x1ca3), ('\u{10e4}', 0x1ca4), - ('\u{10e5}', 0x1ca5), ('\u{10e6}', 0x1ca6), ('\u{10e7}', 0x1ca7), ('\u{10e8}', 0x1ca8), - ('\u{10e9}', 0x1ca9), ('\u{10ea}', 0x1caa), ('\u{10eb}', 0x1cab), ('\u{10ec}', 0x1cac), - ('\u{10ed}', 0x1cad), ('\u{10ee}', 0x1cae), ('\u{10ef}', 0x1caf), ('\u{10f0}', 0x1cb0), - ('\u{10f1}', 0x1cb1), ('\u{10f2}', 0x1cb2), ('\u{10f3}', 0x1cb3), ('\u{10f4}', 0x1cb4), - ('\u{10f5}', 0x1cb5), ('\u{10f6}', 0x1cb6), ('\u{10f7}', 0x1cb7), ('\u{10f8}', 0x1cb8), - ('\u{10f9}', 0x1cb9), ('\u{10fa}', 0x1cba), ('\u{10fd}', 0x1cbd), ('\u{10fe}', 0x1cbe), - ('\u{10ff}', 0x1cbf), ('\u{13f8}', 0x13f0), ('\u{13f9}', 0x13f1), ('\u{13fa}', 0x13f2), - ('\u{13fb}', 0x13f3), ('\u{13fc}', 0x13f4), ('\u{13fd}', 0x13f5), ('\u{1c80}', 0x412), - ('\u{1c81}', 0x414), ('\u{1c82}', 0x41e), ('\u{1c83}', 0x421), ('\u{1c84}', 0x422), - ('\u{1c85}', 0x422), ('\u{1c86}', 0x42a), ('\u{1c87}', 0x462), ('\u{1c88}', 0xa64a), - ('\u{1c8a}', 0x1c89), ('\u{1d79}', 0xa77d), ('\u{1d7d}', 0x2c63), ('\u{1d8e}', 0xa7c6), - ('\u{1e01}', 0x1e00), ('\u{1e03}', 0x1e02), ('\u{1e05}', 0x1e04), ('\u{1e07}', 0x1e06), - ('\u{1e09}', 0x1e08), ('\u{1e0b}', 0x1e0a), ('\u{1e0d}', 0x1e0c), ('\u{1e0f}', 0x1e0e), - ('\u{1e11}', 0x1e10), ('\u{1e13}', 0x1e12), ('\u{1e15}', 0x1e14), ('\u{1e17}', 0x1e16), - ('\u{1e19}', 0x1e18), ('\u{1e1b}', 0x1e1a), ('\u{1e1d}', 0x1e1c), ('\u{1e1f}', 0x1e1e), - ('\u{1e21}', 0x1e20), ('\u{1e23}', 0x1e22), ('\u{1e25}', 0x1e24), ('\u{1e27}', 0x1e26), - ('\u{1e29}', 0x1e28), ('\u{1e2b}', 0x1e2a), ('\u{1e2d}', 0x1e2c), ('\u{1e2f}', 0x1e2e), - ('\u{1e31}', 0x1e30), ('\u{1e33}', 0x1e32), ('\u{1e35}', 0x1e34), ('\u{1e37}', 0x1e36), - ('\u{1e39}', 0x1e38), ('\u{1e3b}', 0x1e3a), ('\u{1e3d}', 0x1e3c), ('\u{1e3f}', 0x1e3e), - ('\u{1e41}', 0x1e40), ('\u{1e43}', 0x1e42), ('\u{1e45}', 0x1e44), ('\u{1e47}', 0x1e46), - ('\u{1e49}', 0x1e48), ('\u{1e4b}', 0x1e4a), ('\u{1e4d}', 0x1e4c), ('\u{1e4f}', 0x1e4e), - ('\u{1e51}', 0x1e50), ('\u{1e53}', 0x1e52), ('\u{1e55}', 0x1e54), ('\u{1e57}', 0x1e56), - ('\u{1e59}', 0x1e58), ('\u{1e5b}', 0x1e5a), ('\u{1e5d}', 0x1e5c), ('\u{1e5f}', 0x1e5e), - ('\u{1e61}', 0x1e60), ('\u{1e63}', 0x1e62), ('\u{1e65}', 0x1e64), ('\u{1e67}', 0x1e66), - ('\u{1e69}', 0x1e68), ('\u{1e6b}', 0x1e6a), ('\u{1e6d}', 0x1e6c), ('\u{1e6f}', 0x1e6e), - ('\u{1e71}', 0x1e70), ('\u{1e73}', 0x1e72), ('\u{1e75}', 0x1e74), ('\u{1e77}', 0x1e76), - ('\u{1e79}', 0x1e78), ('\u{1e7b}', 0x1e7a), ('\u{1e7d}', 0x1e7c), ('\u{1e7f}', 0x1e7e), - ('\u{1e81}', 0x1e80), ('\u{1e83}', 0x1e82), ('\u{1e85}', 0x1e84), ('\u{1e87}', 0x1e86), - ('\u{1e89}', 0x1e88), ('\u{1e8b}', 0x1e8a), ('\u{1e8d}', 0x1e8c), ('\u{1e8f}', 0x1e8e), - ('\u{1e91}', 0x1e90), ('\u{1e93}', 0x1e92), ('\u{1e95}', 0x1e94), ('\u{1e96}', 0x400006), - ('\u{1e97}', 0x400007), ('\u{1e98}', 0x400008), ('\u{1e99}', 0x400009), - ('\u{1e9a}', 0x40000a), ('\u{1e9b}', 0x1e60), ('\u{1ea1}', 0x1ea0), ('\u{1ea3}', 0x1ea2), - ('\u{1ea5}', 0x1ea4), ('\u{1ea7}', 0x1ea6), ('\u{1ea9}', 0x1ea8), ('\u{1eab}', 0x1eaa), - ('\u{1ead}', 0x1eac), ('\u{1eaf}', 0x1eae), ('\u{1eb1}', 0x1eb0), ('\u{1eb3}', 0x1eb2), - ('\u{1eb5}', 0x1eb4), ('\u{1eb7}', 0x1eb6), ('\u{1eb9}', 0x1eb8), ('\u{1ebb}', 0x1eba), - ('\u{1ebd}', 0x1ebc), ('\u{1ebf}', 0x1ebe), ('\u{1ec1}', 0x1ec0), ('\u{1ec3}', 0x1ec2), - ('\u{1ec5}', 0x1ec4), ('\u{1ec7}', 0x1ec6), ('\u{1ec9}', 0x1ec8), ('\u{1ecb}', 0x1eca), - ('\u{1ecd}', 0x1ecc), ('\u{1ecf}', 0x1ece), ('\u{1ed1}', 0x1ed0), ('\u{1ed3}', 0x1ed2), - ('\u{1ed5}', 0x1ed4), ('\u{1ed7}', 0x1ed6), ('\u{1ed9}', 0x1ed8), ('\u{1edb}', 0x1eda), - ('\u{1edd}', 0x1edc), ('\u{1edf}', 0x1ede), ('\u{1ee1}', 0x1ee0), ('\u{1ee3}', 0x1ee2), - ('\u{1ee5}', 0x1ee4), ('\u{1ee7}', 0x1ee6), ('\u{1ee9}', 0x1ee8), ('\u{1eeb}', 0x1eea), - ('\u{1eed}', 0x1eec), ('\u{1eef}', 0x1eee), ('\u{1ef1}', 0x1ef0), ('\u{1ef3}', 0x1ef2), - ('\u{1ef5}', 0x1ef4), ('\u{1ef7}', 0x1ef6), ('\u{1ef9}', 0x1ef8), ('\u{1efb}', 0x1efa), - ('\u{1efd}', 0x1efc), ('\u{1eff}', 0x1efe), ('\u{1f00}', 0x1f08), ('\u{1f01}', 0x1f09), - ('\u{1f02}', 0x1f0a), ('\u{1f03}', 0x1f0b), ('\u{1f04}', 0x1f0c), ('\u{1f05}', 0x1f0d), - ('\u{1f06}', 0x1f0e), ('\u{1f07}', 0x1f0f), ('\u{1f10}', 0x1f18), ('\u{1f11}', 0x1f19), - ('\u{1f12}', 0x1f1a), ('\u{1f13}', 0x1f1b), ('\u{1f14}', 0x1f1c), ('\u{1f15}', 0x1f1d), - ('\u{1f20}', 0x1f28), ('\u{1f21}', 0x1f29), ('\u{1f22}', 0x1f2a), ('\u{1f23}', 0x1f2b), - ('\u{1f24}', 0x1f2c), ('\u{1f25}', 0x1f2d), ('\u{1f26}', 0x1f2e), ('\u{1f27}', 0x1f2f), - ('\u{1f30}', 0x1f38), ('\u{1f31}', 0x1f39), ('\u{1f32}', 0x1f3a), ('\u{1f33}', 0x1f3b), - ('\u{1f34}', 0x1f3c), ('\u{1f35}', 0x1f3d), ('\u{1f36}', 0x1f3e), ('\u{1f37}', 0x1f3f), - ('\u{1f40}', 0x1f48), ('\u{1f41}', 0x1f49), ('\u{1f42}', 0x1f4a), ('\u{1f43}', 0x1f4b), - ('\u{1f44}', 0x1f4c), ('\u{1f45}', 0x1f4d), ('\u{1f50}', 0x40000b), ('\u{1f51}', 0x1f59), - ('\u{1f52}', 0x40000c), ('\u{1f53}', 0x1f5b), ('\u{1f54}', 0x40000d), ('\u{1f55}', 0x1f5d), - ('\u{1f56}', 0x40000e), ('\u{1f57}', 0x1f5f), ('\u{1f60}', 0x1f68), ('\u{1f61}', 0x1f69), - ('\u{1f62}', 0x1f6a), ('\u{1f63}', 0x1f6b), ('\u{1f64}', 0x1f6c), ('\u{1f65}', 0x1f6d), - ('\u{1f66}', 0x1f6e), ('\u{1f67}', 0x1f6f), ('\u{1f70}', 0x1fba), ('\u{1f71}', 0x1fbb), - ('\u{1f72}', 0x1fc8), ('\u{1f73}', 0x1fc9), ('\u{1f74}', 0x1fca), ('\u{1f75}', 0x1fcb), - ('\u{1f76}', 0x1fda), ('\u{1f77}', 0x1fdb), ('\u{1f78}', 0x1ff8), ('\u{1f79}', 0x1ff9), - ('\u{1f7a}', 0x1fea), ('\u{1f7b}', 0x1feb), ('\u{1f7c}', 0x1ffa), ('\u{1f7d}', 0x1ffb), - ('\u{1f80}', 0x40000f), ('\u{1f81}', 0x400010), ('\u{1f82}', 0x400011), - ('\u{1f83}', 0x400012), ('\u{1f84}', 0x400013), ('\u{1f85}', 0x400014), - ('\u{1f86}', 0x400015), ('\u{1f87}', 0x400016), ('\u{1f88}', 0x400017), - ('\u{1f89}', 0x400018), ('\u{1f8a}', 0x400019), ('\u{1f8b}', 0x40001a), - ('\u{1f8c}', 0x40001b), ('\u{1f8d}', 0x40001c), ('\u{1f8e}', 0x40001d), - ('\u{1f8f}', 0x40001e), ('\u{1f90}', 0x40001f), ('\u{1f91}', 0x400020), - ('\u{1f92}', 0x400021), ('\u{1f93}', 0x400022), ('\u{1f94}', 0x400023), - ('\u{1f95}', 0x400024), ('\u{1f96}', 0x400025), ('\u{1f97}', 0x400026), - ('\u{1f98}', 0x400027), ('\u{1f99}', 0x400028), ('\u{1f9a}', 0x400029), - ('\u{1f9b}', 0x40002a), ('\u{1f9c}', 0x40002b), ('\u{1f9d}', 0x40002c), - ('\u{1f9e}', 0x40002d), ('\u{1f9f}', 0x40002e), ('\u{1fa0}', 0x40002f), - ('\u{1fa1}', 0x400030), ('\u{1fa2}', 0x400031), ('\u{1fa3}', 0x400032), - ('\u{1fa4}', 0x400033), ('\u{1fa5}', 0x400034), ('\u{1fa6}', 0x400035), - ('\u{1fa7}', 0x400036), ('\u{1fa8}', 0x400037), ('\u{1fa9}', 0x400038), - ('\u{1faa}', 0x400039), ('\u{1fab}', 0x40003a), ('\u{1fac}', 0x40003b), - ('\u{1fad}', 0x40003c), ('\u{1fae}', 0x40003d), ('\u{1faf}', 0x40003e), - ('\u{1fb0}', 0x1fb8), ('\u{1fb1}', 0x1fb9), ('\u{1fb2}', 0x40003f), ('\u{1fb3}', 0x400040), - ('\u{1fb4}', 0x400041), ('\u{1fb6}', 0x400042), ('\u{1fb7}', 0x400043), - ('\u{1fbc}', 0x400044), ('\u{1fbe}', 0x399), ('\u{1fc2}', 0x400045), ('\u{1fc3}', 0x400046), - ('\u{1fc4}', 0x400047), ('\u{1fc6}', 0x400048), ('\u{1fc7}', 0x400049), - ('\u{1fcc}', 0x40004a), ('\u{1fd0}', 0x1fd8), ('\u{1fd1}', 0x1fd9), ('\u{1fd2}', 0x40004b), - ('\u{1fd3}', 0x40004c), ('\u{1fd6}', 0x40004d), ('\u{1fd7}', 0x40004e), - ('\u{1fe0}', 0x1fe8), ('\u{1fe1}', 0x1fe9), ('\u{1fe2}', 0x40004f), ('\u{1fe3}', 0x400050), - ('\u{1fe4}', 0x400051), ('\u{1fe5}', 0x1fec), ('\u{1fe6}', 0x400052), - ('\u{1fe7}', 0x400053), ('\u{1ff2}', 0x400054), ('\u{1ff3}', 0x400055), - ('\u{1ff4}', 0x400056), ('\u{1ff6}', 0x400057), ('\u{1ff7}', 0x400058), - ('\u{1ffc}', 0x400059), ('\u{214e}', 0x2132), ('\u{2170}', 0x2160), ('\u{2171}', 0x2161), - ('\u{2172}', 0x2162), ('\u{2173}', 0x2163), ('\u{2174}', 0x2164), ('\u{2175}', 0x2165), - ('\u{2176}', 0x2166), ('\u{2177}', 0x2167), ('\u{2178}', 0x2168), ('\u{2179}', 0x2169), - ('\u{217a}', 0x216a), ('\u{217b}', 0x216b), ('\u{217c}', 0x216c), ('\u{217d}', 0x216d), - ('\u{217e}', 0x216e), ('\u{217f}', 0x216f), ('\u{2184}', 0x2183), ('\u{24d0}', 0x24b6), - ('\u{24d1}', 0x24b7), ('\u{24d2}', 0x24b8), ('\u{24d3}', 0x24b9), ('\u{24d4}', 0x24ba), - ('\u{24d5}', 0x24bb), ('\u{24d6}', 0x24bc), ('\u{24d7}', 0x24bd), ('\u{24d8}', 0x24be), - ('\u{24d9}', 0x24bf), ('\u{24da}', 0x24c0), ('\u{24db}', 0x24c1), ('\u{24dc}', 0x24c2), - ('\u{24dd}', 0x24c3), ('\u{24de}', 0x24c4), ('\u{24df}', 0x24c5), ('\u{24e0}', 0x24c6), - ('\u{24e1}', 0x24c7), ('\u{24e2}', 0x24c8), ('\u{24e3}', 0x24c9), ('\u{24e4}', 0x24ca), - ('\u{24e5}', 0x24cb), ('\u{24e6}', 0x24cc), ('\u{24e7}', 0x24cd), ('\u{24e8}', 0x24ce), - ('\u{24e9}', 0x24cf), ('\u{2c30}', 0x2c00), ('\u{2c31}', 0x2c01), ('\u{2c32}', 0x2c02), - ('\u{2c33}', 0x2c03), ('\u{2c34}', 0x2c04), ('\u{2c35}', 0x2c05), ('\u{2c36}', 0x2c06), - ('\u{2c37}', 0x2c07), ('\u{2c38}', 0x2c08), ('\u{2c39}', 0x2c09), ('\u{2c3a}', 0x2c0a), - ('\u{2c3b}', 0x2c0b), ('\u{2c3c}', 0x2c0c), ('\u{2c3d}', 0x2c0d), ('\u{2c3e}', 0x2c0e), - ('\u{2c3f}', 0x2c0f), ('\u{2c40}', 0x2c10), ('\u{2c41}', 0x2c11), ('\u{2c42}', 0x2c12), - ('\u{2c43}', 0x2c13), ('\u{2c44}', 0x2c14), ('\u{2c45}', 0x2c15), ('\u{2c46}', 0x2c16), - ('\u{2c47}', 0x2c17), ('\u{2c48}', 0x2c18), ('\u{2c49}', 0x2c19), ('\u{2c4a}', 0x2c1a), - ('\u{2c4b}', 0x2c1b), ('\u{2c4c}', 0x2c1c), ('\u{2c4d}', 0x2c1d), ('\u{2c4e}', 0x2c1e), - ('\u{2c4f}', 0x2c1f), ('\u{2c50}', 0x2c20), ('\u{2c51}', 0x2c21), ('\u{2c52}', 0x2c22), - ('\u{2c53}', 0x2c23), ('\u{2c54}', 0x2c24), ('\u{2c55}', 0x2c25), ('\u{2c56}', 0x2c26), - ('\u{2c57}', 0x2c27), ('\u{2c58}', 0x2c28), ('\u{2c59}', 0x2c29), ('\u{2c5a}', 0x2c2a), - ('\u{2c5b}', 0x2c2b), ('\u{2c5c}', 0x2c2c), ('\u{2c5d}', 0x2c2d), ('\u{2c5e}', 0x2c2e), - ('\u{2c5f}', 0x2c2f), ('\u{2c61}', 0x2c60), ('\u{2c65}', 0x23a), ('\u{2c66}', 0x23e), - ('\u{2c68}', 0x2c67), ('\u{2c6a}', 0x2c69), ('\u{2c6c}', 0x2c6b), ('\u{2c73}', 0x2c72), - ('\u{2c76}', 0x2c75), ('\u{2c81}', 0x2c80), ('\u{2c83}', 0x2c82), ('\u{2c85}', 0x2c84), - ('\u{2c87}', 0x2c86), ('\u{2c89}', 0x2c88), ('\u{2c8b}', 0x2c8a), ('\u{2c8d}', 0x2c8c), - ('\u{2c8f}', 0x2c8e), ('\u{2c91}', 0x2c90), ('\u{2c93}', 0x2c92), ('\u{2c95}', 0x2c94), - ('\u{2c97}', 0x2c96), ('\u{2c99}', 0x2c98), ('\u{2c9b}', 0x2c9a), ('\u{2c9d}', 0x2c9c), - ('\u{2c9f}', 0x2c9e), ('\u{2ca1}', 0x2ca0), ('\u{2ca3}', 0x2ca2), ('\u{2ca5}', 0x2ca4), - ('\u{2ca7}', 0x2ca6), ('\u{2ca9}', 0x2ca8), ('\u{2cab}', 0x2caa), ('\u{2cad}', 0x2cac), - ('\u{2caf}', 0x2cae), ('\u{2cb1}', 0x2cb0), ('\u{2cb3}', 0x2cb2), ('\u{2cb5}', 0x2cb4), - ('\u{2cb7}', 0x2cb6), ('\u{2cb9}', 0x2cb8), ('\u{2cbb}', 0x2cba), ('\u{2cbd}', 0x2cbc), - ('\u{2cbf}', 0x2cbe), ('\u{2cc1}', 0x2cc0), ('\u{2cc3}', 0x2cc2), ('\u{2cc5}', 0x2cc4), - ('\u{2cc7}', 0x2cc6), ('\u{2cc9}', 0x2cc8), ('\u{2ccb}', 0x2cca), ('\u{2ccd}', 0x2ccc), - ('\u{2ccf}', 0x2cce), ('\u{2cd1}', 0x2cd0), ('\u{2cd3}', 0x2cd2), ('\u{2cd5}', 0x2cd4), - ('\u{2cd7}', 0x2cd6), ('\u{2cd9}', 0x2cd8), ('\u{2cdb}', 0x2cda), ('\u{2cdd}', 0x2cdc), - ('\u{2cdf}', 0x2cde), ('\u{2ce1}', 0x2ce0), ('\u{2ce3}', 0x2ce2), ('\u{2cec}', 0x2ceb), - ('\u{2cee}', 0x2ced), ('\u{2cf3}', 0x2cf2), ('\u{2d00}', 0x10a0), ('\u{2d01}', 0x10a1), - ('\u{2d02}', 0x10a2), ('\u{2d03}', 0x10a3), ('\u{2d04}', 0x10a4), ('\u{2d05}', 0x10a5), - ('\u{2d06}', 0x10a6), ('\u{2d07}', 0x10a7), ('\u{2d08}', 0x10a8), ('\u{2d09}', 0x10a9), - ('\u{2d0a}', 0x10aa), ('\u{2d0b}', 0x10ab), ('\u{2d0c}', 0x10ac), ('\u{2d0d}', 0x10ad), - ('\u{2d0e}', 0x10ae), ('\u{2d0f}', 0x10af), ('\u{2d10}', 0x10b0), ('\u{2d11}', 0x10b1), - ('\u{2d12}', 0x10b2), ('\u{2d13}', 0x10b3), ('\u{2d14}', 0x10b4), ('\u{2d15}', 0x10b5), - ('\u{2d16}', 0x10b6), ('\u{2d17}', 0x10b7), ('\u{2d18}', 0x10b8), ('\u{2d19}', 0x10b9), - ('\u{2d1a}', 0x10ba), ('\u{2d1b}', 0x10bb), ('\u{2d1c}', 0x10bc), ('\u{2d1d}', 0x10bd), - ('\u{2d1e}', 0x10be), ('\u{2d1f}', 0x10bf), ('\u{2d20}', 0x10c0), ('\u{2d21}', 0x10c1), - ('\u{2d22}', 0x10c2), ('\u{2d23}', 0x10c3), ('\u{2d24}', 0x10c4), ('\u{2d25}', 0x10c5), - ('\u{2d27}', 0x10c7), ('\u{2d2d}', 0x10cd), ('\u{a641}', 0xa640), ('\u{a643}', 0xa642), - ('\u{a645}', 0xa644), ('\u{a647}', 0xa646), ('\u{a649}', 0xa648), ('\u{a64b}', 0xa64a), - ('\u{a64d}', 0xa64c), ('\u{a64f}', 0xa64e), ('\u{a651}', 0xa650), ('\u{a653}', 0xa652), - ('\u{a655}', 0xa654), ('\u{a657}', 0xa656), ('\u{a659}', 0xa658), ('\u{a65b}', 0xa65a), - ('\u{a65d}', 0xa65c), ('\u{a65f}', 0xa65e), ('\u{a661}', 0xa660), ('\u{a663}', 0xa662), - ('\u{a665}', 0xa664), ('\u{a667}', 0xa666), ('\u{a669}', 0xa668), ('\u{a66b}', 0xa66a), - ('\u{a66d}', 0xa66c), ('\u{a681}', 0xa680), ('\u{a683}', 0xa682), ('\u{a685}', 0xa684), - ('\u{a687}', 0xa686), ('\u{a689}', 0xa688), ('\u{a68b}', 0xa68a), ('\u{a68d}', 0xa68c), - ('\u{a68f}', 0xa68e), ('\u{a691}', 0xa690), ('\u{a693}', 0xa692), ('\u{a695}', 0xa694), - ('\u{a697}', 0xa696), ('\u{a699}', 0xa698), ('\u{a69b}', 0xa69a), ('\u{a723}', 0xa722), - ('\u{a725}', 0xa724), ('\u{a727}', 0xa726), ('\u{a729}', 0xa728), ('\u{a72b}', 0xa72a), - ('\u{a72d}', 0xa72c), ('\u{a72f}', 0xa72e), ('\u{a733}', 0xa732), ('\u{a735}', 0xa734), - ('\u{a737}', 0xa736), ('\u{a739}', 0xa738), ('\u{a73b}', 0xa73a), ('\u{a73d}', 0xa73c), - ('\u{a73f}', 0xa73e), ('\u{a741}', 0xa740), ('\u{a743}', 0xa742), ('\u{a745}', 0xa744), - ('\u{a747}', 0xa746), ('\u{a749}', 0xa748), ('\u{a74b}', 0xa74a), ('\u{a74d}', 0xa74c), - ('\u{a74f}', 0xa74e), ('\u{a751}', 0xa750), ('\u{a753}', 0xa752), ('\u{a755}', 0xa754), - ('\u{a757}', 0xa756), ('\u{a759}', 0xa758), ('\u{a75b}', 0xa75a), ('\u{a75d}', 0xa75c), - ('\u{a75f}', 0xa75e), ('\u{a761}', 0xa760), ('\u{a763}', 0xa762), ('\u{a765}', 0xa764), - ('\u{a767}', 0xa766), ('\u{a769}', 0xa768), ('\u{a76b}', 0xa76a), ('\u{a76d}', 0xa76c), - ('\u{a76f}', 0xa76e), ('\u{a77a}', 0xa779), ('\u{a77c}', 0xa77b), ('\u{a77f}', 0xa77e), - ('\u{a781}', 0xa780), ('\u{a783}', 0xa782), ('\u{a785}', 0xa784), ('\u{a787}', 0xa786), - ('\u{a78c}', 0xa78b), ('\u{a791}', 0xa790), ('\u{a793}', 0xa792), ('\u{a794}', 0xa7c4), - ('\u{a797}', 0xa796), ('\u{a799}', 0xa798), ('\u{a79b}', 0xa79a), ('\u{a79d}', 0xa79c), - ('\u{a79f}', 0xa79e), ('\u{a7a1}', 0xa7a0), ('\u{a7a3}', 0xa7a2), ('\u{a7a5}', 0xa7a4), - ('\u{a7a7}', 0xa7a6), ('\u{a7a9}', 0xa7a8), ('\u{a7b5}', 0xa7b4), ('\u{a7b7}', 0xa7b6), - ('\u{a7b9}', 0xa7b8), ('\u{a7bb}', 0xa7ba), ('\u{a7bd}', 0xa7bc), ('\u{a7bf}', 0xa7be), - ('\u{a7c1}', 0xa7c0), ('\u{a7c3}', 0xa7c2), ('\u{a7c8}', 0xa7c7), ('\u{a7ca}', 0xa7c9), - ('\u{a7cd}', 0xa7cc), ('\u{a7cf}', 0xa7ce), ('\u{a7d1}', 0xa7d0), ('\u{a7d3}', 0xa7d2), - ('\u{a7d5}', 0xa7d4), ('\u{a7d7}', 0xa7d6), ('\u{a7d9}', 0xa7d8), ('\u{a7db}', 0xa7da), - ('\u{a7f6}', 0xa7f5), ('\u{ab53}', 0xa7b3), ('\u{ab70}', 0x13a0), ('\u{ab71}', 0x13a1), - ('\u{ab72}', 0x13a2), ('\u{ab73}', 0x13a3), ('\u{ab74}', 0x13a4), ('\u{ab75}', 0x13a5), - ('\u{ab76}', 0x13a6), ('\u{ab77}', 0x13a7), ('\u{ab78}', 0x13a8), ('\u{ab79}', 0x13a9), - ('\u{ab7a}', 0x13aa), ('\u{ab7b}', 0x13ab), ('\u{ab7c}', 0x13ac), ('\u{ab7d}', 0x13ad), - ('\u{ab7e}', 0x13ae), ('\u{ab7f}', 0x13af), ('\u{ab80}', 0x13b0), ('\u{ab81}', 0x13b1), - ('\u{ab82}', 0x13b2), ('\u{ab83}', 0x13b3), ('\u{ab84}', 0x13b4), ('\u{ab85}', 0x13b5), - ('\u{ab86}', 0x13b6), ('\u{ab87}', 0x13b7), ('\u{ab88}', 0x13b8), ('\u{ab89}', 0x13b9), - ('\u{ab8a}', 0x13ba), ('\u{ab8b}', 0x13bb), ('\u{ab8c}', 0x13bc), ('\u{ab8d}', 0x13bd), - ('\u{ab8e}', 0x13be), ('\u{ab8f}', 0x13bf), ('\u{ab90}', 0x13c0), ('\u{ab91}', 0x13c1), - ('\u{ab92}', 0x13c2), ('\u{ab93}', 0x13c3), ('\u{ab94}', 0x13c4), ('\u{ab95}', 0x13c5), - ('\u{ab96}', 0x13c6), ('\u{ab97}', 0x13c7), ('\u{ab98}', 0x13c8), ('\u{ab99}', 0x13c9), - ('\u{ab9a}', 0x13ca), ('\u{ab9b}', 0x13cb), ('\u{ab9c}', 0x13cc), ('\u{ab9d}', 0x13cd), - ('\u{ab9e}', 0x13ce), ('\u{ab9f}', 0x13cf), ('\u{aba0}', 0x13d0), ('\u{aba1}', 0x13d1), - ('\u{aba2}', 0x13d2), ('\u{aba3}', 0x13d3), ('\u{aba4}', 0x13d4), ('\u{aba5}', 0x13d5), - ('\u{aba6}', 0x13d6), ('\u{aba7}', 0x13d7), ('\u{aba8}', 0x13d8), ('\u{aba9}', 0x13d9), - ('\u{abaa}', 0x13da), ('\u{abab}', 0x13db), ('\u{abac}', 0x13dc), ('\u{abad}', 0x13dd), - ('\u{abae}', 0x13de), ('\u{abaf}', 0x13df), ('\u{abb0}', 0x13e0), ('\u{abb1}', 0x13e1), - ('\u{abb2}', 0x13e2), ('\u{abb3}', 0x13e3), ('\u{abb4}', 0x13e4), ('\u{abb5}', 0x13e5), - ('\u{abb6}', 0x13e6), ('\u{abb7}', 0x13e7), ('\u{abb8}', 0x13e8), ('\u{abb9}', 0x13e9), - ('\u{abba}', 0x13ea), ('\u{abbb}', 0x13eb), ('\u{abbc}', 0x13ec), ('\u{abbd}', 0x13ed), - ('\u{abbe}', 0x13ee), ('\u{abbf}', 0x13ef), ('\u{fb00}', 0x40005a), ('\u{fb01}', 0x40005b), - ('\u{fb02}', 0x40005c), ('\u{fb03}', 0x40005d), ('\u{fb04}', 0x40005e), - ('\u{fb05}', 0x40005f), ('\u{fb06}', 0x400060), ('\u{fb13}', 0x400061), - ('\u{fb14}', 0x400062), ('\u{fb15}', 0x400063), ('\u{fb16}', 0x400064), - ('\u{fb17}', 0x400065), ('\u{ff41}', 0xff21), ('\u{ff42}', 0xff22), ('\u{ff43}', 0xff23), - ('\u{ff44}', 0xff24), ('\u{ff45}', 0xff25), ('\u{ff46}', 0xff26), ('\u{ff47}', 0xff27), - ('\u{ff48}', 0xff28), ('\u{ff49}', 0xff29), ('\u{ff4a}', 0xff2a), ('\u{ff4b}', 0xff2b), - ('\u{ff4c}', 0xff2c), ('\u{ff4d}', 0xff2d), ('\u{ff4e}', 0xff2e), ('\u{ff4f}', 0xff2f), - ('\u{ff50}', 0xff30), ('\u{ff51}', 0xff31), ('\u{ff52}', 0xff32), ('\u{ff53}', 0xff33), - ('\u{ff54}', 0xff34), ('\u{ff55}', 0xff35), ('\u{ff56}', 0xff36), ('\u{ff57}', 0xff37), - ('\u{ff58}', 0xff38), ('\u{ff59}', 0xff39), ('\u{ff5a}', 0xff3a), ('\u{10428}', 0x10400), - ('\u{10429}', 0x10401), ('\u{1042a}', 0x10402), ('\u{1042b}', 0x10403), - ('\u{1042c}', 0x10404), ('\u{1042d}', 0x10405), ('\u{1042e}', 0x10406), - ('\u{1042f}', 0x10407), ('\u{10430}', 0x10408), ('\u{10431}', 0x10409), - ('\u{10432}', 0x1040a), ('\u{10433}', 0x1040b), ('\u{10434}', 0x1040c), - ('\u{10435}', 0x1040d), ('\u{10436}', 0x1040e), ('\u{10437}', 0x1040f), - ('\u{10438}', 0x10410), ('\u{10439}', 0x10411), ('\u{1043a}', 0x10412), - ('\u{1043b}', 0x10413), ('\u{1043c}', 0x10414), ('\u{1043d}', 0x10415), - ('\u{1043e}', 0x10416), ('\u{1043f}', 0x10417), ('\u{10440}', 0x10418), - ('\u{10441}', 0x10419), ('\u{10442}', 0x1041a), ('\u{10443}', 0x1041b), - ('\u{10444}', 0x1041c), ('\u{10445}', 0x1041d), ('\u{10446}', 0x1041e), - ('\u{10447}', 0x1041f), ('\u{10448}', 0x10420), ('\u{10449}', 0x10421), - ('\u{1044a}', 0x10422), ('\u{1044b}', 0x10423), ('\u{1044c}', 0x10424), - ('\u{1044d}', 0x10425), ('\u{1044e}', 0x10426), ('\u{1044f}', 0x10427), - ('\u{104d8}', 0x104b0), ('\u{104d9}', 0x104b1), ('\u{104da}', 0x104b2), - ('\u{104db}', 0x104b3), ('\u{104dc}', 0x104b4), ('\u{104dd}', 0x104b5), - ('\u{104de}', 0x104b6), ('\u{104df}', 0x104b7), ('\u{104e0}', 0x104b8), - ('\u{104e1}', 0x104b9), ('\u{104e2}', 0x104ba), ('\u{104e3}', 0x104bb), - ('\u{104e4}', 0x104bc), ('\u{104e5}', 0x104bd), ('\u{104e6}', 0x104be), - ('\u{104e7}', 0x104bf), ('\u{104e8}', 0x104c0), ('\u{104e9}', 0x104c1), - ('\u{104ea}', 0x104c2), ('\u{104eb}', 0x104c3), ('\u{104ec}', 0x104c4), - ('\u{104ed}', 0x104c5), ('\u{104ee}', 0x104c6), ('\u{104ef}', 0x104c7), - ('\u{104f0}', 0x104c8), ('\u{104f1}', 0x104c9), ('\u{104f2}', 0x104ca), - ('\u{104f3}', 0x104cb), ('\u{104f4}', 0x104cc), ('\u{104f5}', 0x104cd), - ('\u{104f6}', 0x104ce), ('\u{104f7}', 0x104cf), ('\u{104f8}', 0x104d0), - ('\u{104f9}', 0x104d1), ('\u{104fa}', 0x104d2), ('\u{104fb}', 0x104d3), - ('\u{10597}', 0x10570), ('\u{10598}', 0x10571), ('\u{10599}', 0x10572), - ('\u{1059a}', 0x10573), ('\u{1059b}', 0x10574), ('\u{1059c}', 0x10575), - ('\u{1059d}', 0x10576), ('\u{1059e}', 0x10577), ('\u{1059f}', 0x10578), - ('\u{105a0}', 0x10579), ('\u{105a1}', 0x1057a), ('\u{105a3}', 0x1057c), - ('\u{105a4}', 0x1057d), ('\u{105a5}', 0x1057e), ('\u{105a6}', 0x1057f), - ('\u{105a7}', 0x10580), ('\u{105a8}', 0x10581), ('\u{105a9}', 0x10582), - ('\u{105aa}', 0x10583), ('\u{105ab}', 0x10584), ('\u{105ac}', 0x10585), - ('\u{105ad}', 0x10586), ('\u{105ae}', 0x10587), ('\u{105af}', 0x10588), - ('\u{105b0}', 0x10589), ('\u{105b1}', 0x1058a), ('\u{105b3}', 0x1058c), - ('\u{105b4}', 0x1058d), ('\u{105b5}', 0x1058e), ('\u{105b6}', 0x1058f), - ('\u{105b7}', 0x10590), ('\u{105b8}', 0x10591), ('\u{105b9}', 0x10592), - ('\u{105bb}', 0x10594), ('\u{105bc}', 0x10595), ('\u{10cc0}', 0x10c80), - ('\u{10cc1}', 0x10c81), ('\u{10cc2}', 0x10c82), ('\u{10cc3}', 0x10c83), - ('\u{10cc4}', 0x10c84), ('\u{10cc5}', 0x10c85), ('\u{10cc6}', 0x10c86), - ('\u{10cc7}', 0x10c87), ('\u{10cc8}', 0x10c88), ('\u{10cc9}', 0x10c89), - ('\u{10cca}', 0x10c8a), ('\u{10ccb}', 0x10c8b), ('\u{10ccc}', 0x10c8c), - ('\u{10ccd}', 0x10c8d), ('\u{10cce}', 0x10c8e), ('\u{10ccf}', 0x10c8f), - ('\u{10cd0}', 0x10c90), ('\u{10cd1}', 0x10c91), ('\u{10cd2}', 0x10c92), - ('\u{10cd3}', 0x10c93), ('\u{10cd4}', 0x10c94), ('\u{10cd5}', 0x10c95), - ('\u{10cd6}', 0x10c96), ('\u{10cd7}', 0x10c97), ('\u{10cd8}', 0x10c98), - ('\u{10cd9}', 0x10c99), ('\u{10cda}', 0x10c9a), ('\u{10cdb}', 0x10c9b), - ('\u{10cdc}', 0x10c9c), ('\u{10cdd}', 0x10c9d), ('\u{10cde}', 0x10c9e), - ('\u{10cdf}', 0x10c9f), ('\u{10ce0}', 0x10ca0), ('\u{10ce1}', 0x10ca1), - ('\u{10ce2}', 0x10ca2), ('\u{10ce3}', 0x10ca3), ('\u{10ce4}', 0x10ca4), - ('\u{10ce5}', 0x10ca5), ('\u{10ce6}', 0x10ca6), ('\u{10ce7}', 0x10ca7), - ('\u{10ce8}', 0x10ca8), ('\u{10ce9}', 0x10ca9), ('\u{10cea}', 0x10caa), - ('\u{10ceb}', 0x10cab), ('\u{10cec}', 0x10cac), ('\u{10ced}', 0x10cad), - ('\u{10cee}', 0x10cae), ('\u{10cef}', 0x10caf), ('\u{10cf0}', 0x10cb0), - ('\u{10cf1}', 0x10cb1), ('\u{10cf2}', 0x10cb2), ('\u{10d70}', 0x10d50), - ('\u{10d71}', 0x10d51), ('\u{10d72}', 0x10d52), ('\u{10d73}', 0x10d53), - ('\u{10d74}', 0x10d54), ('\u{10d75}', 0x10d55), ('\u{10d76}', 0x10d56), - ('\u{10d77}', 0x10d57), ('\u{10d78}', 0x10d58), ('\u{10d79}', 0x10d59), - ('\u{10d7a}', 0x10d5a), ('\u{10d7b}', 0x10d5b), ('\u{10d7c}', 0x10d5c), - ('\u{10d7d}', 0x10d5d), ('\u{10d7e}', 0x10d5e), ('\u{10d7f}', 0x10d5f), - ('\u{10d80}', 0x10d60), ('\u{10d81}', 0x10d61), ('\u{10d82}', 0x10d62), - ('\u{10d83}', 0x10d63), ('\u{10d84}', 0x10d64), ('\u{10d85}', 0x10d65), - ('\u{118c0}', 0x118a0), ('\u{118c1}', 0x118a1), ('\u{118c2}', 0x118a2), - ('\u{118c3}', 0x118a3), ('\u{118c4}', 0x118a4), ('\u{118c5}', 0x118a5), - ('\u{118c6}', 0x118a6), ('\u{118c7}', 0x118a7), ('\u{118c8}', 0x118a8), - ('\u{118c9}', 0x118a9), ('\u{118ca}', 0x118aa), ('\u{118cb}', 0x118ab), - ('\u{118cc}', 0x118ac), ('\u{118cd}', 0x118ad), ('\u{118ce}', 0x118ae), - ('\u{118cf}', 0x118af), ('\u{118d0}', 0x118b0), ('\u{118d1}', 0x118b1), - ('\u{118d2}', 0x118b2), ('\u{118d3}', 0x118b3), ('\u{118d4}', 0x118b4), - ('\u{118d5}', 0x118b5), ('\u{118d6}', 0x118b6), ('\u{118d7}', 0x118b7), - ('\u{118d8}', 0x118b8), ('\u{118d9}', 0x118b9), ('\u{118da}', 0x118ba), - ('\u{118db}', 0x118bb), ('\u{118dc}', 0x118bc), ('\u{118dd}', 0x118bd), - ('\u{118de}', 0x118be), ('\u{118df}', 0x118bf), ('\u{16e60}', 0x16e40), - ('\u{16e61}', 0x16e41), ('\u{16e62}', 0x16e42), ('\u{16e63}', 0x16e43), - ('\u{16e64}', 0x16e44), ('\u{16e65}', 0x16e45), ('\u{16e66}', 0x16e46), - ('\u{16e67}', 0x16e47), ('\u{16e68}', 0x16e48), ('\u{16e69}', 0x16e49), - ('\u{16e6a}', 0x16e4a), ('\u{16e6b}', 0x16e4b), ('\u{16e6c}', 0x16e4c), - ('\u{16e6d}', 0x16e4d), ('\u{16e6e}', 0x16e4e), ('\u{16e6f}', 0x16e4f), - ('\u{16e70}', 0x16e50), ('\u{16e71}', 0x16e51), ('\u{16e72}', 0x16e52), - ('\u{16e73}', 0x16e53), ('\u{16e74}', 0x16e54), ('\u{16e75}', 0x16e55), - ('\u{16e76}', 0x16e56), ('\u{16e77}', 0x16e57), ('\u{16e78}', 0x16e58), - ('\u{16e79}', 0x16e59), ('\u{16e7a}', 0x16e5a), ('\u{16e7b}', 0x16e5b), - ('\u{16e7c}', 0x16e5c), ('\u{16e7d}', 0x16e5d), ('\u{16e7e}', 0x16e5e), - ('\u{16e7f}', 0x16e5f), ('\u{16ebb}', 0x16ea0), ('\u{16ebc}', 0x16ea1), - ('\u{16ebd}', 0x16ea2), ('\u{16ebe}', 0x16ea3), ('\u{16ebf}', 0x16ea4), - ('\u{16ec0}', 0x16ea5), ('\u{16ec1}', 0x16ea6), ('\u{16ec2}', 0x16ea7), - ('\u{16ec3}', 0x16ea8), ('\u{16ec4}', 0x16ea9), ('\u{16ec5}', 0x16eaa), - ('\u{16ec6}', 0x16eab), ('\u{16ec7}', 0x16eac), ('\u{16ec8}', 0x16ead), - ('\u{16ec9}', 0x16eae), ('\u{16eca}', 0x16eaf), ('\u{16ecb}', 0x16eb0), - ('\u{16ecc}', 0x16eb1), ('\u{16ecd}', 0x16eb2), ('\u{16ece}', 0x16eb3), - ('\u{16ecf}', 0x16eb4), ('\u{16ed0}', 0x16eb5), ('\u{16ed1}', 0x16eb6), - ('\u{16ed2}', 0x16eb7), ('\u{16ed3}', 0x16eb8), ('\u{1e922}', 0x1e900), - ('\u{1e923}', 0x1e901), ('\u{1e924}', 0x1e902), ('\u{1e925}', 0x1e903), - ('\u{1e926}', 0x1e904), ('\u{1e927}', 0x1e905), ('\u{1e928}', 0x1e906), - ('\u{1e929}', 0x1e907), ('\u{1e92a}', 0x1e908), ('\u{1e92b}', 0x1e909), - ('\u{1e92c}', 0x1e90a), ('\u{1e92d}', 0x1e90b), ('\u{1e92e}', 0x1e90c), - ('\u{1e92f}', 0x1e90d), ('\u{1e930}', 0x1e90e), ('\u{1e931}', 0x1e90f), - ('\u{1e932}', 0x1e910), ('\u{1e933}', 0x1e911), ('\u{1e934}', 0x1e912), - ('\u{1e935}', 0x1e913), ('\u{1e936}', 0x1e914), ('\u{1e937}', 0x1e915), - ('\u{1e938}', 0x1e916), ('\u{1e939}', 0x1e917), ('\u{1e93a}', 0x1e918), - ('\u{1e93b}', 0x1e919), ('\u{1e93c}', 0x1e91a), ('\u{1e93d}', 0x1e91b), - ('\u{1e93e}', 0x1e91c), ('\u{1e93f}', 0x1e91d), ('\u{1e940}', 0x1e91e), - ('\u{1e941}', 0x1e91f), ('\u{1e942}', 0x1e920), ('\u{1e943}', 0x1e921), + pub fn to_upper(c: char) -> [char; 3] { + if c.is_ascii() { + [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] + } else { + UPPERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = UPPERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) + } + } + + static LOWERCASE_TABLE: &[(char, u32); 1462] = &[ + ('\u{c0}', 224), ('\u{c1}', 225), ('\u{c2}', 226), ('\u{c3}', 227), ('\u{c4}', 228), + ('\u{c5}', 229), ('\u{c6}', 230), ('\u{c7}', 231), ('\u{c8}', 232), ('\u{c9}', 233), + ('\u{ca}', 234), ('\u{cb}', 235), ('\u{cc}', 236), ('\u{cd}', 237), ('\u{ce}', 238), + ('\u{cf}', 239), ('\u{d0}', 240), ('\u{d1}', 241), ('\u{d2}', 242), ('\u{d3}', 243), + ('\u{d4}', 244), ('\u{d5}', 245), ('\u{d6}', 246), ('\u{d8}', 248), ('\u{d9}', 249), + ('\u{da}', 250), ('\u{db}', 251), ('\u{dc}', 252), ('\u{dd}', 253), ('\u{de}', 254), + ('\u{100}', 257), ('\u{102}', 259), ('\u{104}', 261), ('\u{106}', 263), ('\u{108}', 265), + ('\u{10a}', 267), ('\u{10c}', 269), ('\u{10e}', 271), ('\u{110}', 273), ('\u{112}', 275), + ('\u{114}', 277), ('\u{116}', 279), ('\u{118}', 281), ('\u{11a}', 283), ('\u{11c}', 285), + ('\u{11e}', 287), ('\u{120}', 289), ('\u{122}', 291), ('\u{124}', 293), ('\u{126}', 295), + ('\u{128}', 297), ('\u{12a}', 299), ('\u{12c}', 301), ('\u{12e}', 303), + ('\u{130}', 4194304), ('\u{132}', 307), ('\u{134}', 309), ('\u{136}', 311), + ('\u{139}', 314), ('\u{13b}', 316), ('\u{13d}', 318), ('\u{13f}', 320), ('\u{141}', 322), + ('\u{143}', 324), ('\u{145}', 326), ('\u{147}', 328), ('\u{14a}', 331), ('\u{14c}', 333), + ('\u{14e}', 335), ('\u{150}', 337), ('\u{152}', 339), ('\u{154}', 341), ('\u{156}', 343), + ('\u{158}', 345), ('\u{15a}', 347), ('\u{15c}', 349), ('\u{15e}', 351), ('\u{160}', 353), + ('\u{162}', 355), ('\u{164}', 357), ('\u{166}', 359), ('\u{168}', 361), ('\u{16a}', 363), + ('\u{16c}', 365), ('\u{16e}', 367), ('\u{170}', 369), ('\u{172}', 371), ('\u{174}', 373), + ('\u{176}', 375), ('\u{178}', 255), ('\u{179}', 378), ('\u{17b}', 380), ('\u{17d}', 382), + ('\u{181}', 595), ('\u{182}', 387), ('\u{184}', 389), ('\u{186}', 596), ('\u{187}', 392), + ('\u{189}', 598), ('\u{18a}', 599), ('\u{18b}', 396), ('\u{18e}', 477), ('\u{18f}', 601), + ('\u{190}', 603), ('\u{191}', 402), ('\u{193}', 608), ('\u{194}', 611), ('\u{196}', 617), + ('\u{197}', 616), ('\u{198}', 409), ('\u{19c}', 623), ('\u{19d}', 626), ('\u{19f}', 629), + ('\u{1a0}', 417), ('\u{1a2}', 419), ('\u{1a4}', 421), ('\u{1a6}', 640), ('\u{1a7}', 424), + ('\u{1a9}', 643), ('\u{1ac}', 429), ('\u{1ae}', 648), ('\u{1af}', 432), ('\u{1b1}', 650), + ('\u{1b2}', 651), ('\u{1b3}', 436), ('\u{1b5}', 438), ('\u{1b7}', 658), ('\u{1b8}', 441), + ('\u{1bc}', 445), ('\u{1c4}', 454), ('\u{1c5}', 454), ('\u{1c7}', 457), ('\u{1c8}', 457), + ('\u{1ca}', 460), ('\u{1cb}', 460), ('\u{1cd}', 462), ('\u{1cf}', 464), ('\u{1d1}', 466), + ('\u{1d3}', 468), ('\u{1d5}', 470), ('\u{1d7}', 472), ('\u{1d9}', 474), ('\u{1db}', 476), + ('\u{1de}', 479), ('\u{1e0}', 481), ('\u{1e2}', 483), ('\u{1e4}', 485), ('\u{1e6}', 487), + ('\u{1e8}', 489), ('\u{1ea}', 491), ('\u{1ec}', 493), ('\u{1ee}', 495), ('\u{1f1}', 499), + ('\u{1f2}', 499), ('\u{1f4}', 501), ('\u{1f6}', 405), ('\u{1f7}', 447), ('\u{1f8}', 505), + ('\u{1fa}', 507), ('\u{1fc}', 509), ('\u{1fe}', 511), ('\u{200}', 513), ('\u{202}', 515), + ('\u{204}', 517), ('\u{206}', 519), ('\u{208}', 521), ('\u{20a}', 523), ('\u{20c}', 525), + ('\u{20e}', 527), ('\u{210}', 529), ('\u{212}', 531), ('\u{214}', 533), ('\u{216}', 535), + ('\u{218}', 537), ('\u{21a}', 539), ('\u{21c}', 541), ('\u{21e}', 543), ('\u{220}', 414), + ('\u{222}', 547), ('\u{224}', 549), ('\u{226}', 551), ('\u{228}', 553), ('\u{22a}', 555), + ('\u{22c}', 557), ('\u{22e}', 559), ('\u{230}', 561), ('\u{232}', 563), ('\u{23a}', 11365), + ('\u{23b}', 572), ('\u{23d}', 410), ('\u{23e}', 11366), ('\u{241}', 578), ('\u{243}', 384), + ('\u{244}', 649), ('\u{245}', 652), ('\u{246}', 583), ('\u{248}', 585), ('\u{24a}', 587), + ('\u{24c}', 589), ('\u{24e}', 591), ('\u{370}', 881), ('\u{372}', 883), ('\u{376}', 887), + ('\u{37f}', 1011), ('\u{386}', 940), ('\u{388}', 941), ('\u{389}', 942), ('\u{38a}', 943), + ('\u{38c}', 972), ('\u{38e}', 973), ('\u{38f}', 974), ('\u{391}', 945), ('\u{392}', 946), + ('\u{393}', 947), ('\u{394}', 948), ('\u{395}', 949), ('\u{396}', 950), ('\u{397}', 951), + ('\u{398}', 952), ('\u{399}', 953), ('\u{39a}', 954), ('\u{39b}', 955), ('\u{39c}', 956), + ('\u{39d}', 957), ('\u{39e}', 958), ('\u{39f}', 959), ('\u{3a0}', 960), ('\u{3a1}', 961), + ('\u{3a3}', 963), ('\u{3a4}', 964), ('\u{3a5}', 965), ('\u{3a6}', 966), ('\u{3a7}', 967), + ('\u{3a8}', 968), ('\u{3a9}', 969), ('\u{3aa}', 970), ('\u{3ab}', 971), ('\u{3cf}', 983), + ('\u{3d8}', 985), ('\u{3da}', 987), ('\u{3dc}', 989), ('\u{3de}', 991), ('\u{3e0}', 993), + ('\u{3e2}', 995), ('\u{3e4}', 997), ('\u{3e6}', 999), ('\u{3e8}', 1001), ('\u{3ea}', 1003), + ('\u{3ec}', 1005), ('\u{3ee}', 1007), ('\u{3f4}', 952), ('\u{3f7}', 1016), + ('\u{3f9}', 1010), ('\u{3fa}', 1019), ('\u{3fd}', 891), ('\u{3fe}', 892), ('\u{3ff}', 893), + ('\u{400}', 1104), ('\u{401}', 1105), ('\u{402}', 1106), ('\u{403}', 1107), + ('\u{404}', 1108), ('\u{405}', 1109), ('\u{406}', 1110), ('\u{407}', 1111), + ('\u{408}', 1112), ('\u{409}', 1113), ('\u{40a}', 1114), ('\u{40b}', 1115), + ('\u{40c}', 1116), ('\u{40d}', 1117), ('\u{40e}', 1118), ('\u{40f}', 1119), + ('\u{410}', 1072), ('\u{411}', 1073), ('\u{412}', 1074), ('\u{413}', 1075), + ('\u{414}', 1076), ('\u{415}', 1077), ('\u{416}', 1078), ('\u{417}', 1079), + ('\u{418}', 1080), ('\u{419}', 1081), ('\u{41a}', 1082), ('\u{41b}', 1083), + ('\u{41c}', 1084), ('\u{41d}', 1085), ('\u{41e}', 1086), ('\u{41f}', 1087), + ('\u{420}', 1088), ('\u{421}', 1089), ('\u{422}', 1090), ('\u{423}', 1091), + ('\u{424}', 1092), ('\u{425}', 1093), ('\u{426}', 1094), ('\u{427}', 1095), + ('\u{428}', 1096), ('\u{429}', 1097), ('\u{42a}', 1098), ('\u{42b}', 1099), + ('\u{42c}', 1100), ('\u{42d}', 1101), ('\u{42e}', 1102), ('\u{42f}', 1103), + ('\u{460}', 1121), ('\u{462}', 1123), ('\u{464}', 1125), ('\u{466}', 1127), + ('\u{468}', 1129), ('\u{46a}', 1131), ('\u{46c}', 1133), ('\u{46e}', 1135), + ('\u{470}', 1137), ('\u{472}', 1139), ('\u{474}', 1141), ('\u{476}', 1143), + ('\u{478}', 1145), ('\u{47a}', 1147), ('\u{47c}', 1149), ('\u{47e}', 1151), + ('\u{480}', 1153), ('\u{48a}', 1163), ('\u{48c}', 1165), ('\u{48e}', 1167), + ('\u{490}', 1169), ('\u{492}', 1171), ('\u{494}', 1173), ('\u{496}', 1175), + ('\u{498}', 1177), ('\u{49a}', 1179), ('\u{49c}', 1181), ('\u{49e}', 1183), + ('\u{4a0}', 1185), ('\u{4a2}', 1187), ('\u{4a4}', 1189), ('\u{4a6}', 1191), + ('\u{4a8}', 1193), ('\u{4aa}', 1195), ('\u{4ac}', 1197), ('\u{4ae}', 1199), + ('\u{4b0}', 1201), ('\u{4b2}', 1203), ('\u{4b4}', 1205), ('\u{4b6}', 1207), + ('\u{4b8}', 1209), ('\u{4ba}', 1211), ('\u{4bc}', 1213), ('\u{4be}', 1215), + ('\u{4c0}', 1231), ('\u{4c1}', 1218), ('\u{4c3}', 1220), ('\u{4c5}', 1222), + ('\u{4c7}', 1224), ('\u{4c9}', 1226), ('\u{4cb}', 1228), ('\u{4cd}', 1230), + ('\u{4d0}', 1233), ('\u{4d2}', 1235), ('\u{4d4}', 1237), ('\u{4d6}', 1239), + ('\u{4d8}', 1241), ('\u{4da}', 1243), ('\u{4dc}', 1245), ('\u{4de}', 1247), + ('\u{4e0}', 1249), ('\u{4e2}', 1251), ('\u{4e4}', 1253), ('\u{4e6}', 1255), + ('\u{4e8}', 1257), ('\u{4ea}', 1259), ('\u{4ec}', 1261), ('\u{4ee}', 1263), + ('\u{4f0}', 1265), ('\u{4f2}', 1267), ('\u{4f4}', 1269), ('\u{4f6}', 1271), + ('\u{4f8}', 1273), ('\u{4fa}', 1275), ('\u{4fc}', 1277), ('\u{4fe}', 1279), + ('\u{500}', 1281), ('\u{502}', 1283), ('\u{504}', 1285), ('\u{506}', 1287), + ('\u{508}', 1289), ('\u{50a}', 1291), ('\u{50c}', 1293), ('\u{50e}', 1295), + ('\u{510}', 1297), ('\u{512}', 1299), ('\u{514}', 1301), ('\u{516}', 1303), + ('\u{518}', 1305), ('\u{51a}', 1307), ('\u{51c}', 1309), ('\u{51e}', 1311), + ('\u{520}', 1313), ('\u{522}', 1315), ('\u{524}', 1317), ('\u{526}', 1319), + ('\u{528}', 1321), ('\u{52a}', 1323), ('\u{52c}', 1325), ('\u{52e}', 1327), + ('\u{531}', 1377), ('\u{532}', 1378), ('\u{533}', 1379), ('\u{534}', 1380), + ('\u{535}', 1381), ('\u{536}', 1382), ('\u{537}', 1383), ('\u{538}', 1384), + ('\u{539}', 1385), ('\u{53a}', 1386), ('\u{53b}', 1387), ('\u{53c}', 1388), + ('\u{53d}', 1389), ('\u{53e}', 1390), ('\u{53f}', 1391), ('\u{540}', 1392), + ('\u{541}', 1393), ('\u{542}', 1394), ('\u{543}', 1395), ('\u{544}', 1396), + ('\u{545}', 1397), ('\u{546}', 1398), ('\u{547}', 1399), ('\u{548}', 1400), + ('\u{549}', 1401), ('\u{54a}', 1402), ('\u{54b}', 1403), ('\u{54c}', 1404), + ('\u{54d}', 1405), ('\u{54e}', 1406), ('\u{54f}', 1407), ('\u{550}', 1408), + ('\u{551}', 1409), ('\u{552}', 1410), ('\u{553}', 1411), ('\u{554}', 1412), + ('\u{555}', 1413), ('\u{556}', 1414), ('\u{10a0}', 11520), ('\u{10a1}', 11521), + ('\u{10a2}', 11522), ('\u{10a3}', 11523), ('\u{10a4}', 11524), ('\u{10a5}', 11525), + ('\u{10a6}', 11526), ('\u{10a7}', 11527), ('\u{10a8}', 11528), ('\u{10a9}', 11529), + ('\u{10aa}', 11530), ('\u{10ab}', 11531), ('\u{10ac}', 11532), ('\u{10ad}', 11533), + ('\u{10ae}', 11534), ('\u{10af}', 11535), ('\u{10b0}', 11536), ('\u{10b1}', 11537), + ('\u{10b2}', 11538), ('\u{10b3}', 11539), ('\u{10b4}', 11540), ('\u{10b5}', 11541), + ('\u{10b6}', 11542), ('\u{10b7}', 11543), ('\u{10b8}', 11544), ('\u{10b9}', 11545), + ('\u{10ba}', 11546), ('\u{10bb}', 11547), ('\u{10bc}', 11548), ('\u{10bd}', 11549), + ('\u{10be}', 11550), ('\u{10bf}', 11551), ('\u{10c0}', 11552), ('\u{10c1}', 11553), + ('\u{10c2}', 11554), ('\u{10c3}', 11555), ('\u{10c4}', 11556), ('\u{10c5}', 11557), + ('\u{10c7}', 11559), ('\u{10cd}', 11565), ('\u{13a0}', 43888), ('\u{13a1}', 43889), + ('\u{13a2}', 43890), ('\u{13a3}', 43891), ('\u{13a4}', 43892), ('\u{13a5}', 43893), + ('\u{13a6}', 43894), ('\u{13a7}', 43895), ('\u{13a8}', 43896), ('\u{13a9}', 43897), + ('\u{13aa}', 43898), ('\u{13ab}', 43899), ('\u{13ac}', 43900), ('\u{13ad}', 43901), + ('\u{13ae}', 43902), ('\u{13af}', 43903), ('\u{13b0}', 43904), ('\u{13b1}', 43905), + ('\u{13b2}', 43906), ('\u{13b3}', 43907), ('\u{13b4}', 43908), ('\u{13b5}', 43909), + ('\u{13b6}', 43910), ('\u{13b7}', 43911), ('\u{13b8}', 43912), ('\u{13b9}', 43913), + ('\u{13ba}', 43914), ('\u{13bb}', 43915), ('\u{13bc}', 43916), ('\u{13bd}', 43917), + ('\u{13be}', 43918), ('\u{13bf}', 43919), ('\u{13c0}', 43920), ('\u{13c1}', 43921), + ('\u{13c2}', 43922), ('\u{13c3}', 43923), ('\u{13c4}', 43924), ('\u{13c5}', 43925), + ('\u{13c6}', 43926), ('\u{13c7}', 43927), ('\u{13c8}', 43928), ('\u{13c9}', 43929), + ('\u{13ca}', 43930), ('\u{13cb}', 43931), ('\u{13cc}', 43932), ('\u{13cd}', 43933), + ('\u{13ce}', 43934), ('\u{13cf}', 43935), ('\u{13d0}', 43936), ('\u{13d1}', 43937), + ('\u{13d2}', 43938), ('\u{13d3}', 43939), ('\u{13d4}', 43940), ('\u{13d5}', 43941), + ('\u{13d6}', 43942), ('\u{13d7}', 43943), ('\u{13d8}', 43944), ('\u{13d9}', 43945), + ('\u{13da}', 43946), ('\u{13db}', 43947), ('\u{13dc}', 43948), ('\u{13dd}', 43949), + ('\u{13de}', 43950), ('\u{13df}', 43951), ('\u{13e0}', 43952), ('\u{13e1}', 43953), + ('\u{13e2}', 43954), ('\u{13e3}', 43955), ('\u{13e4}', 43956), ('\u{13e5}', 43957), + ('\u{13e6}', 43958), ('\u{13e7}', 43959), ('\u{13e8}', 43960), ('\u{13e9}', 43961), + ('\u{13ea}', 43962), ('\u{13eb}', 43963), ('\u{13ec}', 43964), ('\u{13ed}', 43965), + ('\u{13ee}', 43966), ('\u{13ef}', 43967), ('\u{13f0}', 5112), ('\u{13f1}', 5113), + ('\u{13f2}', 5114), ('\u{13f3}', 5115), ('\u{13f4}', 5116), ('\u{13f5}', 5117), + ('\u{1c89}', 7306), ('\u{1c90}', 4304), ('\u{1c91}', 4305), ('\u{1c92}', 4306), + ('\u{1c93}', 4307), ('\u{1c94}', 4308), ('\u{1c95}', 4309), ('\u{1c96}', 4310), + ('\u{1c97}', 4311), ('\u{1c98}', 4312), ('\u{1c99}', 4313), ('\u{1c9a}', 4314), + ('\u{1c9b}', 4315), ('\u{1c9c}', 4316), ('\u{1c9d}', 4317), ('\u{1c9e}', 4318), + ('\u{1c9f}', 4319), ('\u{1ca0}', 4320), ('\u{1ca1}', 4321), ('\u{1ca2}', 4322), + ('\u{1ca3}', 4323), ('\u{1ca4}', 4324), ('\u{1ca5}', 4325), ('\u{1ca6}', 4326), + ('\u{1ca7}', 4327), ('\u{1ca8}', 4328), ('\u{1ca9}', 4329), ('\u{1caa}', 4330), + ('\u{1cab}', 4331), ('\u{1cac}', 4332), ('\u{1cad}', 4333), ('\u{1cae}', 4334), + ('\u{1caf}', 4335), ('\u{1cb0}', 4336), ('\u{1cb1}', 4337), ('\u{1cb2}', 4338), + ('\u{1cb3}', 4339), ('\u{1cb4}', 4340), ('\u{1cb5}', 4341), ('\u{1cb6}', 4342), + ('\u{1cb7}', 4343), ('\u{1cb8}', 4344), ('\u{1cb9}', 4345), ('\u{1cba}', 4346), + ('\u{1cbd}', 4349), ('\u{1cbe}', 4350), ('\u{1cbf}', 4351), ('\u{1e00}', 7681), + ('\u{1e02}', 7683), ('\u{1e04}', 7685), ('\u{1e06}', 7687), ('\u{1e08}', 7689), + ('\u{1e0a}', 7691), ('\u{1e0c}', 7693), ('\u{1e0e}', 7695), ('\u{1e10}', 7697), + ('\u{1e12}', 7699), ('\u{1e14}', 7701), ('\u{1e16}', 7703), ('\u{1e18}', 7705), + ('\u{1e1a}', 7707), ('\u{1e1c}', 7709), ('\u{1e1e}', 7711), ('\u{1e20}', 7713), + ('\u{1e22}', 7715), ('\u{1e24}', 7717), ('\u{1e26}', 7719), ('\u{1e28}', 7721), + ('\u{1e2a}', 7723), ('\u{1e2c}', 7725), ('\u{1e2e}', 7727), ('\u{1e30}', 7729), + ('\u{1e32}', 7731), ('\u{1e34}', 7733), ('\u{1e36}', 7735), ('\u{1e38}', 7737), + ('\u{1e3a}', 7739), ('\u{1e3c}', 7741), ('\u{1e3e}', 7743), ('\u{1e40}', 7745), + ('\u{1e42}', 7747), ('\u{1e44}', 7749), ('\u{1e46}', 7751), ('\u{1e48}', 7753), + ('\u{1e4a}', 7755), ('\u{1e4c}', 7757), ('\u{1e4e}', 7759), ('\u{1e50}', 7761), + ('\u{1e52}', 7763), ('\u{1e54}', 7765), ('\u{1e56}', 7767), ('\u{1e58}', 7769), + ('\u{1e5a}', 7771), ('\u{1e5c}', 7773), ('\u{1e5e}', 7775), ('\u{1e60}', 7777), + ('\u{1e62}', 7779), ('\u{1e64}', 7781), ('\u{1e66}', 7783), ('\u{1e68}', 7785), + ('\u{1e6a}', 7787), ('\u{1e6c}', 7789), ('\u{1e6e}', 7791), ('\u{1e70}', 7793), + ('\u{1e72}', 7795), ('\u{1e74}', 7797), ('\u{1e76}', 7799), ('\u{1e78}', 7801), + ('\u{1e7a}', 7803), ('\u{1e7c}', 7805), ('\u{1e7e}', 7807), ('\u{1e80}', 7809), + ('\u{1e82}', 7811), ('\u{1e84}', 7813), ('\u{1e86}', 7815), ('\u{1e88}', 7817), + ('\u{1e8a}', 7819), ('\u{1e8c}', 7821), ('\u{1e8e}', 7823), ('\u{1e90}', 7825), + ('\u{1e92}', 7827), ('\u{1e94}', 7829), ('\u{1e9e}', 223), ('\u{1ea0}', 7841), + ('\u{1ea2}', 7843), ('\u{1ea4}', 7845), ('\u{1ea6}', 7847), ('\u{1ea8}', 7849), + ('\u{1eaa}', 7851), ('\u{1eac}', 7853), ('\u{1eae}', 7855), ('\u{1eb0}', 7857), + ('\u{1eb2}', 7859), ('\u{1eb4}', 7861), ('\u{1eb6}', 7863), ('\u{1eb8}', 7865), + ('\u{1eba}', 7867), ('\u{1ebc}', 7869), ('\u{1ebe}', 7871), ('\u{1ec0}', 7873), + ('\u{1ec2}', 7875), ('\u{1ec4}', 7877), ('\u{1ec6}', 7879), ('\u{1ec8}', 7881), + ('\u{1eca}', 7883), ('\u{1ecc}', 7885), ('\u{1ece}', 7887), ('\u{1ed0}', 7889), + ('\u{1ed2}', 7891), ('\u{1ed4}', 7893), ('\u{1ed6}', 7895), ('\u{1ed8}', 7897), + ('\u{1eda}', 7899), ('\u{1edc}', 7901), ('\u{1ede}', 7903), ('\u{1ee0}', 7905), + ('\u{1ee2}', 7907), ('\u{1ee4}', 7909), ('\u{1ee6}', 7911), ('\u{1ee8}', 7913), + ('\u{1eea}', 7915), ('\u{1eec}', 7917), ('\u{1eee}', 7919), ('\u{1ef0}', 7921), + ('\u{1ef2}', 7923), ('\u{1ef4}', 7925), ('\u{1ef6}', 7927), ('\u{1ef8}', 7929), + ('\u{1efa}', 7931), ('\u{1efc}', 7933), ('\u{1efe}', 7935), ('\u{1f08}', 7936), + ('\u{1f09}', 7937), ('\u{1f0a}', 7938), ('\u{1f0b}', 7939), ('\u{1f0c}', 7940), + ('\u{1f0d}', 7941), ('\u{1f0e}', 7942), ('\u{1f0f}', 7943), ('\u{1f18}', 7952), + ('\u{1f19}', 7953), ('\u{1f1a}', 7954), ('\u{1f1b}', 7955), ('\u{1f1c}', 7956), + ('\u{1f1d}', 7957), ('\u{1f28}', 7968), ('\u{1f29}', 7969), ('\u{1f2a}', 7970), + ('\u{1f2b}', 7971), ('\u{1f2c}', 7972), ('\u{1f2d}', 7973), ('\u{1f2e}', 7974), + ('\u{1f2f}', 7975), ('\u{1f38}', 7984), ('\u{1f39}', 7985), ('\u{1f3a}', 7986), + ('\u{1f3b}', 7987), ('\u{1f3c}', 7988), ('\u{1f3d}', 7989), ('\u{1f3e}', 7990), + ('\u{1f3f}', 7991), ('\u{1f48}', 8000), ('\u{1f49}', 8001), ('\u{1f4a}', 8002), + ('\u{1f4b}', 8003), ('\u{1f4c}', 8004), ('\u{1f4d}', 8005), ('\u{1f59}', 8017), + ('\u{1f5b}', 8019), ('\u{1f5d}', 8021), ('\u{1f5f}', 8023), ('\u{1f68}', 8032), + ('\u{1f69}', 8033), ('\u{1f6a}', 8034), ('\u{1f6b}', 8035), ('\u{1f6c}', 8036), + ('\u{1f6d}', 8037), ('\u{1f6e}', 8038), ('\u{1f6f}', 8039), ('\u{1f88}', 8064), + ('\u{1f89}', 8065), ('\u{1f8a}', 8066), ('\u{1f8b}', 8067), ('\u{1f8c}', 8068), + ('\u{1f8d}', 8069), ('\u{1f8e}', 8070), ('\u{1f8f}', 8071), ('\u{1f98}', 8080), + ('\u{1f99}', 8081), ('\u{1f9a}', 8082), ('\u{1f9b}', 8083), ('\u{1f9c}', 8084), + ('\u{1f9d}', 8085), ('\u{1f9e}', 8086), ('\u{1f9f}', 8087), ('\u{1fa8}', 8096), + ('\u{1fa9}', 8097), ('\u{1faa}', 8098), ('\u{1fab}', 8099), ('\u{1fac}', 8100), + ('\u{1fad}', 8101), ('\u{1fae}', 8102), ('\u{1faf}', 8103), ('\u{1fb8}', 8112), + ('\u{1fb9}', 8113), ('\u{1fba}', 8048), ('\u{1fbb}', 8049), ('\u{1fbc}', 8115), + ('\u{1fc8}', 8050), ('\u{1fc9}', 8051), ('\u{1fca}', 8052), ('\u{1fcb}', 8053), + ('\u{1fcc}', 8131), ('\u{1fd8}', 8144), ('\u{1fd9}', 8145), ('\u{1fda}', 8054), + ('\u{1fdb}', 8055), ('\u{1fe8}', 8160), ('\u{1fe9}', 8161), ('\u{1fea}', 8058), + ('\u{1feb}', 8059), ('\u{1fec}', 8165), ('\u{1ff8}', 8056), ('\u{1ff9}', 8057), + ('\u{1ffa}', 8060), ('\u{1ffb}', 8061), ('\u{1ffc}', 8179), ('\u{2126}', 969), + ('\u{212a}', 107), ('\u{212b}', 229), ('\u{2132}', 8526), ('\u{2160}', 8560), + ('\u{2161}', 8561), ('\u{2162}', 8562), ('\u{2163}', 8563), ('\u{2164}', 8564), + ('\u{2165}', 8565), ('\u{2166}', 8566), ('\u{2167}', 8567), ('\u{2168}', 8568), + ('\u{2169}', 8569), ('\u{216a}', 8570), ('\u{216b}', 8571), ('\u{216c}', 8572), + ('\u{216d}', 8573), ('\u{216e}', 8574), ('\u{216f}', 8575), ('\u{2183}', 8580), + ('\u{24b6}', 9424), ('\u{24b7}', 9425), ('\u{24b8}', 9426), ('\u{24b9}', 9427), + ('\u{24ba}', 9428), ('\u{24bb}', 9429), ('\u{24bc}', 9430), ('\u{24bd}', 9431), + ('\u{24be}', 9432), ('\u{24bf}', 9433), ('\u{24c0}', 9434), ('\u{24c1}', 9435), + ('\u{24c2}', 9436), ('\u{24c3}', 9437), ('\u{24c4}', 9438), ('\u{24c5}', 9439), + ('\u{24c6}', 9440), ('\u{24c7}', 9441), ('\u{24c8}', 9442), ('\u{24c9}', 9443), + ('\u{24ca}', 9444), ('\u{24cb}', 9445), ('\u{24cc}', 9446), ('\u{24cd}', 9447), + ('\u{24ce}', 9448), ('\u{24cf}', 9449), ('\u{2c00}', 11312), ('\u{2c01}', 11313), + ('\u{2c02}', 11314), ('\u{2c03}', 11315), ('\u{2c04}', 11316), ('\u{2c05}', 11317), + ('\u{2c06}', 11318), ('\u{2c07}', 11319), ('\u{2c08}', 11320), ('\u{2c09}', 11321), + ('\u{2c0a}', 11322), ('\u{2c0b}', 11323), ('\u{2c0c}', 11324), ('\u{2c0d}', 11325), + ('\u{2c0e}', 11326), ('\u{2c0f}', 11327), ('\u{2c10}', 11328), ('\u{2c11}', 11329), + ('\u{2c12}', 11330), ('\u{2c13}', 11331), ('\u{2c14}', 11332), ('\u{2c15}', 11333), + ('\u{2c16}', 11334), ('\u{2c17}', 11335), ('\u{2c18}', 11336), ('\u{2c19}', 11337), + ('\u{2c1a}', 11338), ('\u{2c1b}', 11339), ('\u{2c1c}', 11340), ('\u{2c1d}', 11341), + ('\u{2c1e}', 11342), ('\u{2c1f}', 11343), ('\u{2c20}', 11344), ('\u{2c21}', 11345), + ('\u{2c22}', 11346), ('\u{2c23}', 11347), ('\u{2c24}', 11348), ('\u{2c25}', 11349), + ('\u{2c26}', 11350), ('\u{2c27}', 11351), ('\u{2c28}', 11352), ('\u{2c29}', 11353), + ('\u{2c2a}', 11354), ('\u{2c2b}', 11355), ('\u{2c2c}', 11356), ('\u{2c2d}', 11357), + ('\u{2c2e}', 11358), ('\u{2c2f}', 11359), ('\u{2c60}', 11361), ('\u{2c62}', 619), + ('\u{2c63}', 7549), ('\u{2c64}', 637), ('\u{2c67}', 11368), ('\u{2c69}', 11370), + ('\u{2c6b}', 11372), ('\u{2c6d}', 593), ('\u{2c6e}', 625), ('\u{2c6f}', 592), + ('\u{2c70}', 594), ('\u{2c72}', 11379), ('\u{2c75}', 11382), ('\u{2c7e}', 575), + ('\u{2c7f}', 576), ('\u{2c80}', 11393), ('\u{2c82}', 11395), ('\u{2c84}', 11397), + ('\u{2c86}', 11399), ('\u{2c88}', 11401), ('\u{2c8a}', 11403), ('\u{2c8c}', 11405), + ('\u{2c8e}', 11407), ('\u{2c90}', 11409), ('\u{2c92}', 11411), ('\u{2c94}', 11413), + ('\u{2c96}', 11415), ('\u{2c98}', 11417), ('\u{2c9a}', 11419), ('\u{2c9c}', 11421), + ('\u{2c9e}', 11423), ('\u{2ca0}', 11425), ('\u{2ca2}', 11427), ('\u{2ca4}', 11429), + ('\u{2ca6}', 11431), ('\u{2ca8}', 11433), ('\u{2caa}', 11435), ('\u{2cac}', 11437), + ('\u{2cae}', 11439), ('\u{2cb0}', 11441), ('\u{2cb2}', 11443), ('\u{2cb4}', 11445), + ('\u{2cb6}', 11447), ('\u{2cb8}', 11449), ('\u{2cba}', 11451), ('\u{2cbc}', 11453), + ('\u{2cbe}', 11455), ('\u{2cc0}', 11457), ('\u{2cc2}', 11459), ('\u{2cc4}', 11461), + ('\u{2cc6}', 11463), ('\u{2cc8}', 11465), ('\u{2cca}', 11467), ('\u{2ccc}', 11469), + ('\u{2cce}', 11471), ('\u{2cd0}', 11473), ('\u{2cd2}', 11475), ('\u{2cd4}', 11477), + ('\u{2cd6}', 11479), ('\u{2cd8}', 11481), ('\u{2cda}', 11483), ('\u{2cdc}', 11485), + ('\u{2cde}', 11487), ('\u{2ce0}', 11489), ('\u{2ce2}', 11491), ('\u{2ceb}', 11500), + ('\u{2ced}', 11502), ('\u{2cf2}', 11507), ('\u{a640}', 42561), ('\u{a642}', 42563), + ('\u{a644}', 42565), ('\u{a646}', 42567), ('\u{a648}', 42569), ('\u{a64a}', 42571), + ('\u{a64c}', 42573), ('\u{a64e}', 42575), ('\u{a650}', 42577), ('\u{a652}', 42579), + ('\u{a654}', 42581), ('\u{a656}', 42583), ('\u{a658}', 42585), ('\u{a65a}', 42587), + ('\u{a65c}', 42589), ('\u{a65e}', 42591), ('\u{a660}', 42593), ('\u{a662}', 42595), + ('\u{a664}', 42597), ('\u{a666}', 42599), ('\u{a668}', 42601), ('\u{a66a}', 42603), + ('\u{a66c}', 42605), ('\u{a680}', 42625), ('\u{a682}', 42627), ('\u{a684}', 42629), + ('\u{a686}', 42631), ('\u{a688}', 42633), ('\u{a68a}', 42635), ('\u{a68c}', 42637), + ('\u{a68e}', 42639), ('\u{a690}', 42641), ('\u{a692}', 42643), ('\u{a694}', 42645), + ('\u{a696}', 42647), ('\u{a698}', 42649), ('\u{a69a}', 42651), ('\u{a722}', 42787), + ('\u{a724}', 42789), ('\u{a726}', 42791), ('\u{a728}', 42793), ('\u{a72a}', 42795), + ('\u{a72c}', 42797), ('\u{a72e}', 42799), ('\u{a732}', 42803), ('\u{a734}', 42805), + ('\u{a736}', 42807), ('\u{a738}', 42809), ('\u{a73a}', 42811), ('\u{a73c}', 42813), + ('\u{a73e}', 42815), ('\u{a740}', 42817), ('\u{a742}', 42819), ('\u{a744}', 42821), + ('\u{a746}', 42823), ('\u{a748}', 42825), ('\u{a74a}', 42827), ('\u{a74c}', 42829), + ('\u{a74e}', 42831), ('\u{a750}', 42833), ('\u{a752}', 42835), ('\u{a754}', 42837), + ('\u{a756}', 42839), ('\u{a758}', 42841), ('\u{a75a}', 42843), ('\u{a75c}', 42845), + ('\u{a75e}', 42847), ('\u{a760}', 42849), ('\u{a762}', 42851), ('\u{a764}', 42853), + ('\u{a766}', 42855), ('\u{a768}', 42857), ('\u{a76a}', 42859), ('\u{a76c}', 42861), + ('\u{a76e}', 42863), ('\u{a779}', 42874), ('\u{a77b}', 42876), ('\u{a77d}', 7545), + ('\u{a77e}', 42879), ('\u{a780}', 42881), ('\u{a782}', 42883), ('\u{a784}', 42885), + ('\u{a786}', 42887), ('\u{a78b}', 42892), ('\u{a78d}', 613), ('\u{a790}', 42897), + ('\u{a792}', 42899), ('\u{a796}', 42903), ('\u{a798}', 42905), ('\u{a79a}', 42907), + ('\u{a79c}', 42909), ('\u{a79e}', 42911), ('\u{a7a0}', 42913), ('\u{a7a2}', 42915), + ('\u{a7a4}', 42917), ('\u{a7a6}', 42919), ('\u{a7a8}', 42921), ('\u{a7aa}', 614), + ('\u{a7ab}', 604), ('\u{a7ac}', 609), ('\u{a7ad}', 620), ('\u{a7ae}', 618), + ('\u{a7b0}', 670), ('\u{a7b1}', 647), ('\u{a7b2}', 669), ('\u{a7b3}', 43859), + ('\u{a7b4}', 42933), ('\u{a7b6}', 42935), ('\u{a7b8}', 42937), ('\u{a7ba}', 42939), + ('\u{a7bc}', 42941), ('\u{a7be}', 42943), ('\u{a7c0}', 42945), ('\u{a7c2}', 42947), + ('\u{a7c4}', 42900), ('\u{a7c5}', 642), ('\u{a7c6}', 7566), ('\u{a7c7}', 42952), + ('\u{a7c9}', 42954), ('\u{a7cb}', 612), ('\u{a7cc}', 42957), ('\u{a7ce}', 42959), + ('\u{a7d0}', 42961), ('\u{a7d2}', 42963), ('\u{a7d4}', 42965), ('\u{a7d6}', 42967), + ('\u{a7d8}', 42969), ('\u{a7da}', 42971), ('\u{a7dc}', 411), ('\u{a7f5}', 42998), + ('\u{ff21}', 65345), ('\u{ff22}', 65346), ('\u{ff23}', 65347), ('\u{ff24}', 65348), + ('\u{ff25}', 65349), ('\u{ff26}', 65350), ('\u{ff27}', 65351), ('\u{ff28}', 65352), + ('\u{ff29}', 65353), ('\u{ff2a}', 65354), ('\u{ff2b}', 65355), ('\u{ff2c}', 65356), + ('\u{ff2d}', 65357), ('\u{ff2e}', 65358), ('\u{ff2f}', 65359), ('\u{ff30}', 65360), + ('\u{ff31}', 65361), ('\u{ff32}', 65362), ('\u{ff33}', 65363), ('\u{ff34}', 65364), + ('\u{ff35}', 65365), ('\u{ff36}', 65366), ('\u{ff37}', 65367), ('\u{ff38}', 65368), + ('\u{ff39}', 65369), ('\u{ff3a}', 65370), ('\u{10400}', 66600), ('\u{10401}', 66601), + ('\u{10402}', 66602), ('\u{10403}', 66603), ('\u{10404}', 66604), ('\u{10405}', 66605), + ('\u{10406}', 66606), ('\u{10407}', 66607), ('\u{10408}', 66608), ('\u{10409}', 66609), + ('\u{1040a}', 66610), ('\u{1040b}', 66611), ('\u{1040c}', 66612), ('\u{1040d}', 66613), + ('\u{1040e}', 66614), ('\u{1040f}', 66615), ('\u{10410}', 66616), ('\u{10411}', 66617), + ('\u{10412}', 66618), ('\u{10413}', 66619), ('\u{10414}', 66620), ('\u{10415}', 66621), + ('\u{10416}', 66622), ('\u{10417}', 66623), ('\u{10418}', 66624), ('\u{10419}', 66625), + ('\u{1041a}', 66626), ('\u{1041b}', 66627), ('\u{1041c}', 66628), ('\u{1041d}', 66629), + ('\u{1041e}', 66630), ('\u{1041f}', 66631), ('\u{10420}', 66632), ('\u{10421}', 66633), + ('\u{10422}', 66634), ('\u{10423}', 66635), ('\u{10424}', 66636), ('\u{10425}', 66637), + ('\u{10426}', 66638), ('\u{10427}', 66639), ('\u{104b0}', 66776), ('\u{104b1}', 66777), + ('\u{104b2}', 66778), ('\u{104b3}', 66779), ('\u{104b4}', 66780), ('\u{104b5}', 66781), + ('\u{104b6}', 66782), ('\u{104b7}', 66783), ('\u{104b8}', 66784), ('\u{104b9}', 66785), + ('\u{104ba}', 66786), ('\u{104bb}', 66787), ('\u{104bc}', 66788), ('\u{104bd}', 66789), + ('\u{104be}', 66790), ('\u{104bf}', 66791), ('\u{104c0}', 66792), ('\u{104c1}', 66793), + ('\u{104c2}', 66794), ('\u{104c3}', 66795), ('\u{104c4}', 66796), ('\u{104c5}', 66797), + ('\u{104c6}', 66798), ('\u{104c7}', 66799), ('\u{104c8}', 66800), ('\u{104c9}', 66801), + ('\u{104ca}', 66802), ('\u{104cb}', 66803), ('\u{104cc}', 66804), ('\u{104cd}', 66805), + ('\u{104ce}', 66806), ('\u{104cf}', 66807), ('\u{104d0}', 66808), ('\u{104d1}', 66809), + ('\u{104d2}', 66810), ('\u{104d3}', 66811), ('\u{10570}', 66967), ('\u{10571}', 66968), + ('\u{10572}', 66969), ('\u{10573}', 66970), ('\u{10574}', 66971), ('\u{10575}', 66972), + ('\u{10576}', 66973), ('\u{10577}', 66974), ('\u{10578}', 66975), ('\u{10579}', 66976), + ('\u{1057a}', 66977), ('\u{1057c}', 66979), ('\u{1057d}', 66980), ('\u{1057e}', 66981), + ('\u{1057f}', 66982), ('\u{10580}', 66983), ('\u{10581}', 66984), ('\u{10582}', 66985), + ('\u{10583}', 66986), ('\u{10584}', 66987), ('\u{10585}', 66988), ('\u{10586}', 66989), + ('\u{10587}', 66990), ('\u{10588}', 66991), ('\u{10589}', 66992), ('\u{1058a}', 66993), + ('\u{1058c}', 66995), ('\u{1058d}', 66996), ('\u{1058e}', 66997), ('\u{1058f}', 66998), + ('\u{10590}', 66999), ('\u{10591}', 67000), ('\u{10592}', 67001), ('\u{10594}', 67003), + ('\u{10595}', 67004), ('\u{10c80}', 68800), ('\u{10c81}', 68801), ('\u{10c82}', 68802), + ('\u{10c83}', 68803), ('\u{10c84}', 68804), ('\u{10c85}', 68805), ('\u{10c86}', 68806), + ('\u{10c87}', 68807), ('\u{10c88}', 68808), ('\u{10c89}', 68809), ('\u{10c8a}', 68810), + ('\u{10c8b}', 68811), ('\u{10c8c}', 68812), ('\u{10c8d}', 68813), ('\u{10c8e}', 68814), + ('\u{10c8f}', 68815), ('\u{10c90}', 68816), ('\u{10c91}', 68817), ('\u{10c92}', 68818), + ('\u{10c93}', 68819), ('\u{10c94}', 68820), ('\u{10c95}', 68821), ('\u{10c96}', 68822), + ('\u{10c97}', 68823), ('\u{10c98}', 68824), ('\u{10c99}', 68825), ('\u{10c9a}', 68826), + ('\u{10c9b}', 68827), ('\u{10c9c}', 68828), ('\u{10c9d}', 68829), ('\u{10c9e}', 68830), + ('\u{10c9f}', 68831), ('\u{10ca0}', 68832), ('\u{10ca1}', 68833), ('\u{10ca2}', 68834), + ('\u{10ca3}', 68835), ('\u{10ca4}', 68836), ('\u{10ca5}', 68837), ('\u{10ca6}', 68838), + ('\u{10ca7}', 68839), ('\u{10ca8}', 68840), ('\u{10ca9}', 68841), ('\u{10caa}', 68842), + ('\u{10cab}', 68843), ('\u{10cac}', 68844), ('\u{10cad}', 68845), ('\u{10cae}', 68846), + ('\u{10caf}', 68847), ('\u{10cb0}', 68848), ('\u{10cb1}', 68849), ('\u{10cb2}', 68850), + ('\u{10d50}', 68976), ('\u{10d51}', 68977), ('\u{10d52}', 68978), ('\u{10d53}', 68979), + ('\u{10d54}', 68980), ('\u{10d55}', 68981), ('\u{10d56}', 68982), ('\u{10d57}', 68983), + ('\u{10d58}', 68984), ('\u{10d59}', 68985), ('\u{10d5a}', 68986), ('\u{10d5b}', 68987), + ('\u{10d5c}', 68988), ('\u{10d5d}', 68989), ('\u{10d5e}', 68990), ('\u{10d5f}', 68991), + ('\u{10d60}', 68992), ('\u{10d61}', 68993), ('\u{10d62}', 68994), ('\u{10d63}', 68995), + ('\u{10d64}', 68996), ('\u{10d65}', 68997), ('\u{118a0}', 71872), ('\u{118a1}', 71873), + ('\u{118a2}', 71874), ('\u{118a3}', 71875), ('\u{118a4}', 71876), ('\u{118a5}', 71877), + ('\u{118a6}', 71878), ('\u{118a7}', 71879), ('\u{118a8}', 71880), ('\u{118a9}', 71881), + ('\u{118aa}', 71882), ('\u{118ab}', 71883), ('\u{118ac}', 71884), ('\u{118ad}', 71885), + ('\u{118ae}', 71886), ('\u{118af}', 71887), ('\u{118b0}', 71888), ('\u{118b1}', 71889), + ('\u{118b2}', 71890), ('\u{118b3}', 71891), ('\u{118b4}', 71892), ('\u{118b5}', 71893), + ('\u{118b6}', 71894), ('\u{118b7}', 71895), ('\u{118b8}', 71896), ('\u{118b9}', 71897), + ('\u{118ba}', 71898), ('\u{118bb}', 71899), ('\u{118bc}', 71900), ('\u{118bd}', 71901), + ('\u{118be}', 71902), ('\u{118bf}', 71903), ('\u{16e40}', 93792), ('\u{16e41}', 93793), + ('\u{16e42}', 93794), ('\u{16e43}', 93795), ('\u{16e44}', 93796), ('\u{16e45}', 93797), + ('\u{16e46}', 93798), ('\u{16e47}', 93799), ('\u{16e48}', 93800), ('\u{16e49}', 93801), + ('\u{16e4a}', 93802), ('\u{16e4b}', 93803), ('\u{16e4c}', 93804), ('\u{16e4d}', 93805), + ('\u{16e4e}', 93806), ('\u{16e4f}', 93807), ('\u{16e50}', 93808), ('\u{16e51}', 93809), + ('\u{16e52}', 93810), ('\u{16e53}', 93811), ('\u{16e54}', 93812), ('\u{16e55}', 93813), + ('\u{16e56}', 93814), ('\u{16e57}', 93815), ('\u{16e58}', 93816), ('\u{16e59}', 93817), + ('\u{16e5a}', 93818), ('\u{16e5b}', 93819), ('\u{16e5c}', 93820), ('\u{16e5d}', 93821), + ('\u{16e5e}', 93822), ('\u{16e5f}', 93823), ('\u{16ea0}', 93883), ('\u{16ea1}', 93884), + ('\u{16ea2}', 93885), ('\u{16ea3}', 93886), ('\u{16ea4}', 93887), ('\u{16ea5}', 93888), + ('\u{16ea6}', 93889), ('\u{16ea7}', 93890), ('\u{16ea8}', 93891), ('\u{16ea9}', 93892), + ('\u{16eaa}', 93893), ('\u{16eab}', 93894), ('\u{16eac}', 93895), ('\u{16ead}', 93896), + ('\u{16eae}', 93897), ('\u{16eaf}', 93898), ('\u{16eb0}', 93899), ('\u{16eb1}', 93900), + ('\u{16eb2}', 93901), ('\u{16eb3}', 93902), ('\u{16eb4}', 93903), ('\u{16eb5}', 93904), + ('\u{16eb6}', 93905), ('\u{16eb7}', 93906), ('\u{16eb8}', 93907), ('\u{1e900}', 125218), + ('\u{1e901}', 125219), ('\u{1e902}', 125220), ('\u{1e903}', 125221), ('\u{1e904}', 125222), + ('\u{1e905}', 125223), ('\u{1e906}', 125224), ('\u{1e907}', 125225), ('\u{1e908}', 125226), + ('\u{1e909}', 125227), ('\u{1e90a}', 125228), ('\u{1e90b}', 125229), ('\u{1e90c}', 125230), + ('\u{1e90d}', 125231), ('\u{1e90e}', 125232), ('\u{1e90f}', 125233), ('\u{1e910}', 125234), + ('\u{1e911}', 125235), ('\u{1e912}', 125236), ('\u{1e913}', 125237), ('\u{1e914}', 125238), + ('\u{1e915}', 125239), ('\u{1e916}', 125240), ('\u{1e917}', 125241), ('\u{1e918}', 125242), + ('\u{1e919}', 125243), ('\u{1e91a}', 125244), ('\u{1e91b}', 125245), ('\u{1e91c}', 125246), + ('\u{1e91d}', 125247), ('\u{1e91e}', 125248), ('\u{1e91f}', 125249), ('\u{1e920}', 125250), + ('\u{1e921}', 125251), + ]; + + static LOWERCASE_TABLE_MULTI: &[[char; 3]; 1] = &[ + ['i', '\u{307}', '\u{0}'], + ]; + + static UPPERCASE_TABLE: &[(char, u32); 1554] = &[ + ('\u{b5}', 924), ('\u{df}', 4194304), ('\u{e0}', 192), ('\u{e1}', 193), ('\u{e2}', 194), + ('\u{e3}', 195), ('\u{e4}', 196), ('\u{e5}', 197), ('\u{e6}', 198), ('\u{e7}', 199), + ('\u{e8}', 200), ('\u{e9}', 201), ('\u{ea}', 202), ('\u{eb}', 203), ('\u{ec}', 204), + ('\u{ed}', 205), ('\u{ee}', 206), ('\u{ef}', 207), ('\u{f0}', 208), ('\u{f1}', 209), + ('\u{f2}', 210), ('\u{f3}', 211), ('\u{f4}', 212), ('\u{f5}', 213), ('\u{f6}', 214), + ('\u{f8}', 216), ('\u{f9}', 217), ('\u{fa}', 218), ('\u{fb}', 219), ('\u{fc}', 220), + ('\u{fd}', 221), ('\u{fe}', 222), ('\u{ff}', 376), ('\u{101}', 256), ('\u{103}', 258), + ('\u{105}', 260), ('\u{107}', 262), ('\u{109}', 264), ('\u{10b}', 266), ('\u{10d}', 268), + ('\u{10f}', 270), ('\u{111}', 272), ('\u{113}', 274), ('\u{115}', 276), ('\u{117}', 278), + ('\u{119}', 280), ('\u{11b}', 282), ('\u{11d}', 284), ('\u{11f}', 286), ('\u{121}', 288), + ('\u{123}', 290), ('\u{125}', 292), ('\u{127}', 294), ('\u{129}', 296), ('\u{12b}', 298), + ('\u{12d}', 300), ('\u{12f}', 302), ('\u{131}', 73), ('\u{133}', 306), ('\u{135}', 308), + ('\u{137}', 310), ('\u{13a}', 313), ('\u{13c}', 315), ('\u{13e}', 317), ('\u{140}', 319), + ('\u{142}', 321), ('\u{144}', 323), ('\u{146}', 325), ('\u{148}', 327), + ('\u{149}', 4194305), ('\u{14b}', 330), ('\u{14d}', 332), ('\u{14f}', 334), + ('\u{151}', 336), ('\u{153}', 338), ('\u{155}', 340), ('\u{157}', 342), ('\u{159}', 344), + ('\u{15b}', 346), ('\u{15d}', 348), ('\u{15f}', 350), ('\u{161}', 352), ('\u{163}', 354), + ('\u{165}', 356), ('\u{167}', 358), ('\u{169}', 360), ('\u{16b}', 362), ('\u{16d}', 364), + ('\u{16f}', 366), ('\u{171}', 368), ('\u{173}', 370), ('\u{175}', 372), ('\u{177}', 374), + ('\u{17a}', 377), ('\u{17c}', 379), ('\u{17e}', 381), ('\u{17f}', 83), ('\u{180}', 579), + ('\u{183}', 386), ('\u{185}', 388), ('\u{188}', 391), ('\u{18c}', 395), ('\u{192}', 401), + ('\u{195}', 502), ('\u{199}', 408), ('\u{19a}', 573), ('\u{19b}', 42972), ('\u{19e}', 544), + ('\u{1a1}', 416), ('\u{1a3}', 418), ('\u{1a5}', 420), ('\u{1a8}', 423), ('\u{1ad}', 428), + ('\u{1b0}', 431), ('\u{1b4}', 435), ('\u{1b6}', 437), ('\u{1b9}', 440), ('\u{1bd}', 444), + ('\u{1bf}', 503), ('\u{1c5}', 452), ('\u{1c6}', 452), ('\u{1c8}', 455), ('\u{1c9}', 455), + ('\u{1cb}', 458), ('\u{1cc}', 458), ('\u{1ce}', 461), ('\u{1d0}', 463), ('\u{1d2}', 465), + ('\u{1d4}', 467), ('\u{1d6}', 469), ('\u{1d8}', 471), ('\u{1da}', 473), ('\u{1dc}', 475), + ('\u{1dd}', 398), ('\u{1df}', 478), ('\u{1e1}', 480), ('\u{1e3}', 482), ('\u{1e5}', 484), + ('\u{1e7}', 486), ('\u{1e9}', 488), ('\u{1eb}', 490), ('\u{1ed}', 492), ('\u{1ef}', 494), + ('\u{1f0}', 4194306), ('\u{1f2}', 497), ('\u{1f3}', 497), ('\u{1f5}', 500), + ('\u{1f9}', 504), ('\u{1fb}', 506), ('\u{1fd}', 508), ('\u{1ff}', 510), ('\u{201}', 512), + ('\u{203}', 514), ('\u{205}', 516), ('\u{207}', 518), ('\u{209}', 520), ('\u{20b}', 522), + ('\u{20d}', 524), ('\u{20f}', 526), ('\u{211}', 528), ('\u{213}', 530), ('\u{215}', 532), + ('\u{217}', 534), ('\u{219}', 536), ('\u{21b}', 538), ('\u{21d}', 540), ('\u{21f}', 542), + ('\u{223}', 546), ('\u{225}', 548), ('\u{227}', 550), ('\u{229}', 552), ('\u{22b}', 554), + ('\u{22d}', 556), ('\u{22f}', 558), ('\u{231}', 560), ('\u{233}', 562), ('\u{23c}', 571), + ('\u{23f}', 11390), ('\u{240}', 11391), ('\u{242}', 577), ('\u{247}', 582), + ('\u{249}', 584), ('\u{24b}', 586), ('\u{24d}', 588), ('\u{24f}', 590), ('\u{250}', 11375), + ('\u{251}', 11373), ('\u{252}', 11376), ('\u{253}', 385), ('\u{254}', 390), + ('\u{256}', 393), ('\u{257}', 394), ('\u{259}', 399), ('\u{25b}', 400), ('\u{25c}', 42923), + ('\u{260}', 403), ('\u{261}', 42924), ('\u{263}', 404), ('\u{264}', 42955), + ('\u{265}', 42893), ('\u{266}', 42922), ('\u{268}', 407), ('\u{269}', 406), + ('\u{26a}', 42926), ('\u{26b}', 11362), ('\u{26c}', 42925), ('\u{26f}', 412), + ('\u{271}', 11374), ('\u{272}', 413), ('\u{275}', 415), ('\u{27d}', 11364), + ('\u{280}', 422), ('\u{282}', 42949), ('\u{283}', 425), ('\u{287}', 42929), + ('\u{288}', 430), ('\u{289}', 580), ('\u{28a}', 433), ('\u{28b}', 434), ('\u{28c}', 581), + ('\u{292}', 439), ('\u{29d}', 42930), ('\u{29e}', 42928), ('\u{345}', 921), + ('\u{371}', 880), ('\u{373}', 882), ('\u{377}', 886), ('\u{37b}', 1021), ('\u{37c}', 1022), + ('\u{37d}', 1023), ('\u{390}', 4194307), ('\u{3ac}', 902), ('\u{3ad}', 904), + ('\u{3ae}', 905), ('\u{3af}', 906), ('\u{3b0}', 4194308), ('\u{3b1}', 913), + ('\u{3b2}', 914), ('\u{3b3}', 915), ('\u{3b4}', 916), ('\u{3b5}', 917), ('\u{3b6}', 918), + ('\u{3b7}', 919), ('\u{3b8}', 920), ('\u{3b9}', 921), ('\u{3ba}', 922), ('\u{3bb}', 923), + ('\u{3bc}', 924), ('\u{3bd}', 925), ('\u{3be}', 926), ('\u{3bf}', 927), ('\u{3c0}', 928), + ('\u{3c1}', 929), ('\u{3c2}', 931), ('\u{3c3}', 931), ('\u{3c4}', 932), ('\u{3c5}', 933), + ('\u{3c6}', 934), ('\u{3c7}', 935), ('\u{3c8}', 936), ('\u{3c9}', 937), ('\u{3ca}', 938), + ('\u{3cb}', 939), ('\u{3cc}', 908), ('\u{3cd}', 910), ('\u{3ce}', 911), ('\u{3d0}', 914), + ('\u{3d1}', 920), ('\u{3d5}', 934), ('\u{3d6}', 928), ('\u{3d7}', 975), ('\u{3d9}', 984), + ('\u{3db}', 986), ('\u{3dd}', 988), ('\u{3df}', 990), ('\u{3e1}', 992), ('\u{3e3}', 994), + ('\u{3e5}', 996), ('\u{3e7}', 998), ('\u{3e9}', 1000), ('\u{3eb}', 1002), ('\u{3ed}', 1004), + ('\u{3ef}', 1006), ('\u{3f0}', 922), ('\u{3f1}', 929), ('\u{3f2}', 1017), ('\u{3f3}', 895), + ('\u{3f5}', 917), ('\u{3f8}', 1015), ('\u{3fb}', 1018), ('\u{430}', 1040), + ('\u{431}', 1041), ('\u{432}', 1042), ('\u{433}', 1043), ('\u{434}', 1044), + ('\u{435}', 1045), ('\u{436}', 1046), ('\u{437}', 1047), ('\u{438}', 1048), + ('\u{439}', 1049), ('\u{43a}', 1050), ('\u{43b}', 1051), ('\u{43c}', 1052), + ('\u{43d}', 1053), ('\u{43e}', 1054), ('\u{43f}', 1055), ('\u{440}', 1056), + ('\u{441}', 1057), ('\u{442}', 1058), ('\u{443}', 1059), ('\u{444}', 1060), + ('\u{445}', 1061), ('\u{446}', 1062), ('\u{447}', 1063), ('\u{448}', 1064), + ('\u{449}', 1065), ('\u{44a}', 1066), ('\u{44b}', 1067), ('\u{44c}', 1068), + ('\u{44d}', 1069), ('\u{44e}', 1070), ('\u{44f}', 1071), ('\u{450}', 1024), + ('\u{451}', 1025), ('\u{452}', 1026), ('\u{453}', 1027), ('\u{454}', 1028), + ('\u{455}', 1029), ('\u{456}', 1030), ('\u{457}', 1031), ('\u{458}', 1032), + ('\u{459}', 1033), ('\u{45a}', 1034), ('\u{45b}', 1035), ('\u{45c}', 1036), + ('\u{45d}', 1037), ('\u{45e}', 1038), ('\u{45f}', 1039), ('\u{461}', 1120), + ('\u{463}', 1122), ('\u{465}', 1124), ('\u{467}', 1126), ('\u{469}', 1128), + ('\u{46b}', 1130), ('\u{46d}', 1132), ('\u{46f}', 1134), ('\u{471}', 1136), + ('\u{473}', 1138), ('\u{475}', 1140), ('\u{477}', 1142), ('\u{479}', 1144), + ('\u{47b}', 1146), ('\u{47d}', 1148), ('\u{47f}', 1150), ('\u{481}', 1152), + ('\u{48b}', 1162), ('\u{48d}', 1164), ('\u{48f}', 1166), ('\u{491}', 1168), + ('\u{493}', 1170), ('\u{495}', 1172), ('\u{497}', 1174), ('\u{499}', 1176), + ('\u{49b}', 1178), ('\u{49d}', 1180), ('\u{49f}', 1182), ('\u{4a1}', 1184), + ('\u{4a3}', 1186), ('\u{4a5}', 1188), ('\u{4a7}', 1190), ('\u{4a9}', 1192), + ('\u{4ab}', 1194), ('\u{4ad}', 1196), ('\u{4af}', 1198), ('\u{4b1}', 1200), + ('\u{4b3}', 1202), ('\u{4b5}', 1204), ('\u{4b7}', 1206), ('\u{4b9}', 1208), + ('\u{4bb}', 1210), ('\u{4bd}', 1212), ('\u{4bf}', 1214), ('\u{4c2}', 1217), + ('\u{4c4}', 1219), ('\u{4c6}', 1221), ('\u{4c8}', 1223), ('\u{4ca}', 1225), + ('\u{4cc}', 1227), ('\u{4ce}', 1229), ('\u{4cf}', 1216), ('\u{4d1}', 1232), + ('\u{4d3}', 1234), ('\u{4d5}', 1236), ('\u{4d7}', 1238), ('\u{4d9}', 1240), + ('\u{4db}', 1242), ('\u{4dd}', 1244), ('\u{4df}', 1246), ('\u{4e1}', 1248), + ('\u{4e3}', 1250), ('\u{4e5}', 1252), ('\u{4e7}', 1254), ('\u{4e9}', 1256), + ('\u{4eb}', 1258), ('\u{4ed}', 1260), ('\u{4ef}', 1262), ('\u{4f1}', 1264), + ('\u{4f3}', 1266), ('\u{4f5}', 1268), ('\u{4f7}', 1270), ('\u{4f9}', 1272), + ('\u{4fb}', 1274), ('\u{4fd}', 1276), ('\u{4ff}', 1278), ('\u{501}', 1280), + ('\u{503}', 1282), ('\u{505}', 1284), ('\u{507}', 1286), ('\u{509}', 1288), + ('\u{50b}', 1290), ('\u{50d}', 1292), ('\u{50f}', 1294), ('\u{511}', 1296), + ('\u{513}', 1298), ('\u{515}', 1300), ('\u{517}', 1302), ('\u{519}', 1304), + ('\u{51b}', 1306), ('\u{51d}', 1308), ('\u{51f}', 1310), ('\u{521}', 1312), + ('\u{523}', 1314), ('\u{525}', 1316), ('\u{527}', 1318), ('\u{529}', 1320), + ('\u{52b}', 1322), ('\u{52d}', 1324), ('\u{52f}', 1326), ('\u{561}', 1329), + ('\u{562}', 1330), ('\u{563}', 1331), ('\u{564}', 1332), ('\u{565}', 1333), + ('\u{566}', 1334), ('\u{567}', 1335), ('\u{568}', 1336), ('\u{569}', 1337), + ('\u{56a}', 1338), ('\u{56b}', 1339), ('\u{56c}', 1340), ('\u{56d}', 1341), + ('\u{56e}', 1342), ('\u{56f}', 1343), ('\u{570}', 1344), ('\u{571}', 1345), + ('\u{572}', 1346), ('\u{573}', 1347), ('\u{574}', 1348), ('\u{575}', 1349), + ('\u{576}', 1350), ('\u{577}', 1351), ('\u{578}', 1352), ('\u{579}', 1353), + ('\u{57a}', 1354), ('\u{57b}', 1355), ('\u{57c}', 1356), ('\u{57d}', 1357), + ('\u{57e}', 1358), ('\u{57f}', 1359), ('\u{580}', 1360), ('\u{581}', 1361), + ('\u{582}', 1362), ('\u{583}', 1363), ('\u{584}', 1364), ('\u{585}', 1365), + ('\u{586}', 1366), ('\u{587}', 4194309), ('\u{10d0}', 7312), ('\u{10d1}', 7313), + ('\u{10d2}', 7314), ('\u{10d3}', 7315), ('\u{10d4}', 7316), ('\u{10d5}', 7317), + ('\u{10d6}', 7318), ('\u{10d7}', 7319), ('\u{10d8}', 7320), ('\u{10d9}', 7321), + ('\u{10da}', 7322), ('\u{10db}', 7323), ('\u{10dc}', 7324), ('\u{10dd}', 7325), + ('\u{10de}', 7326), ('\u{10df}', 7327), ('\u{10e0}', 7328), ('\u{10e1}', 7329), + ('\u{10e2}', 7330), ('\u{10e3}', 7331), ('\u{10e4}', 7332), ('\u{10e5}', 7333), + ('\u{10e6}', 7334), ('\u{10e7}', 7335), ('\u{10e8}', 7336), ('\u{10e9}', 7337), + ('\u{10ea}', 7338), ('\u{10eb}', 7339), ('\u{10ec}', 7340), ('\u{10ed}', 7341), + ('\u{10ee}', 7342), ('\u{10ef}', 7343), ('\u{10f0}', 7344), ('\u{10f1}', 7345), + ('\u{10f2}', 7346), ('\u{10f3}', 7347), ('\u{10f4}', 7348), ('\u{10f5}', 7349), + ('\u{10f6}', 7350), ('\u{10f7}', 7351), ('\u{10f8}', 7352), ('\u{10f9}', 7353), + ('\u{10fa}', 7354), ('\u{10fd}', 7357), ('\u{10fe}', 7358), ('\u{10ff}', 7359), + ('\u{13f8}', 5104), ('\u{13f9}', 5105), ('\u{13fa}', 5106), ('\u{13fb}', 5107), + ('\u{13fc}', 5108), ('\u{13fd}', 5109), ('\u{1c80}', 1042), ('\u{1c81}', 1044), + ('\u{1c82}', 1054), ('\u{1c83}', 1057), ('\u{1c84}', 1058), ('\u{1c85}', 1058), + ('\u{1c86}', 1066), ('\u{1c87}', 1122), ('\u{1c88}', 42570), ('\u{1c8a}', 7305), + ('\u{1d79}', 42877), ('\u{1d7d}', 11363), ('\u{1d8e}', 42950), ('\u{1e01}', 7680), + ('\u{1e03}', 7682), ('\u{1e05}', 7684), ('\u{1e07}', 7686), ('\u{1e09}', 7688), + ('\u{1e0b}', 7690), ('\u{1e0d}', 7692), ('\u{1e0f}', 7694), ('\u{1e11}', 7696), + ('\u{1e13}', 7698), ('\u{1e15}', 7700), ('\u{1e17}', 7702), ('\u{1e19}', 7704), + ('\u{1e1b}', 7706), ('\u{1e1d}', 7708), ('\u{1e1f}', 7710), ('\u{1e21}', 7712), + ('\u{1e23}', 7714), ('\u{1e25}', 7716), ('\u{1e27}', 7718), ('\u{1e29}', 7720), + ('\u{1e2b}', 7722), ('\u{1e2d}', 7724), ('\u{1e2f}', 7726), ('\u{1e31}', 7728), + ('\u{1e33}', 7730), ('\u{1e35}', 7732), ('\u{1e37}', 7734), ('\u{1e39}', 7736), + ('\u{1e3b}', 7738), ('\u{1e3d}', 7740), ('\u{1e3f}', 7742), ('\u{1e41}', 7744), + ('\u{1e43}', 7746), ('\u{1e45}', 7748), ('\u{1e47}', 7750), ('\u{1e49}', 7752), + ('\u{1e4b}', 7754), ('\u{1e4d}', 7756), ('\u{1e4f}', 7758), ('\u{1e51}', 7760), + ('\u{1e53}', 7762), ('\u{1e55}', 7764), ('\u{1e57}', 7766), ('\u{1e59}', 7768), + ('\u{1e5b}', 7770), ('\u{1e5d}', 7772), ('\u{1e5f}', 7774), ('\u{1e61}', 7776), + ('\u{1e63}', 7778), ('\u{1e65}', 7780), ('\u{1e67}', 7782), ('\u{1e69}', 7784), + ('\u{1e6b}', 7786), ('\u{1e6d}', 7788), ('\u{1e6f}', 7790), ('\u{1e71}', 7792), + ('\u{1e73}', 7794), ('\u{1e75}', 7796), ('\u{1e77}', 7798), ('\u{1e79}', 7800), + ('\u{1e7b}', 7802), ('\u{1e7d}', 7804), ('\u{1e7f}', 7806), ('\u{1e81}', 7808), + ('\u{1e83}', 7810), ('\u{1e85}', 7812), ('\u{1e87}', 7814), ('\u{1e89}', 7816), + ('\u{1e8b}', 7818), ('\u{1e8d}', 7820), ('\u{1e8f}', 7822), ('\u{1e91}', 7824), + ('\u{1e93}', 7826), ('\u{1e95}', 7828), ('\u{1e96}', 4194310), ('\u{1e97}', 4194311), + ('\u{1e98}', 4194312), ('\u{1e99}', 4194313), ('\u{1e9a}', 4194314), ('\u{1e9b}', 7776), + ('\u{1ea1}', 7840), ('\u{1ea3}', 7842), ('\u{1ea5}', 7844), ('\u{1ea7}', 7846), + ('\u{1ea9}', 7848), ('\u{1eab}', 7850), ('\u{1ead}', 7852), ('\u{1eaf}', 7854), + ('\u{1eb1}', 7856), ('\u{1eb3}', 7858), ('\u{1eb5}', 7860), ('\u{1eb7}', 7862), + ('\u{1eb9}', 7864), ('\u{1ebb}', 7866), ('\u{1ebd}', 7868), ('\u{1ebf}', 7870), + ('\u{1ec1}', 7872), ('\u{1ec3}', 7874), ('\u{1ec5}', 7876), ('\u{1ec7}', 7878), + ('\u{1ec9}', 7880), ('\u{1ecb}', 7882), ('\u{1ecd}', 7884), ('\u{1ecf}', 7886), + ('\u{1ed1}', 7888), ('\u{1ed3}', 7890), ('\u{1ed5}', 7892), ('\u{1ed7}', 7894), + ('\u{1ed9}', 7896), ('\u{1edb}', 7898), ('\u{1edd}', 7900), ('\u{1edf}', 7902), + ('\u{1ee1}', 7904), ('\u{1ee3}', 7906), ('\u{1ee5}', 7908), ('\u{1ee7}', 7910), + ('\u{1ee9}', 7912), ('\u{1eeb}', 7914), ('\u{1eed}', 7916), ('\u{1eef}', 7918), + ('\u{1ef1}', 7920), ('\u{1ef3}', 7922), ('\u{1ef5}', 7924), ('\u{1ef7}', 7926), + ('\u{1ef9}', 7928), ('\u{1efb}', 7930), ('\u{1efd}', 7932), ('\u{1eff}', 7934), + ('\u{1f00}', 7944), ('\u{1f01}', 7945), ('\u{1f02}', 7946), ('\u{1f03}', 7947), + ('\u{1f04}', 7948), ('\u{1f05}', 7949), ('\u{1f06}', 7950), ('\u{1f07}', 7951), + ('\u{1f10}', 7960), ('\u{1f11}', 7961), ('\u{1f12}', 7962), ('\u{1f13}', 7963), + ('\u{1f14}', 7964), ('\u{1f15}', 7965), ('\u{1f20}', 7976), ('\u{1f21}', 7977), + ('\u{1f22}', 7978), ('\u{1f23}', 7979), ('\u{1f24}', 7980), ('\u{1f25}', 7981), + ('\u{1f26}', 7982), ('\u{1f27}', 7983), ('\u{1f30}', 7992), ('\u{1f31}', 7993), + ('\u{1f32}', 7994), ('\u{1f33}', 7995), ('\u{1f34}', 7996), ('\u{1f35}', 7997), + ('\u{1f36}', 7998), ('\u{1f37}', 7999), ('\u{1f40}', 8008), ('\u{1f41}', 8009), + ('\u{1f42}', 8010), ('\u{1f43}', 8011), ('\u{1f44}', 8012), ('\u{1f45}', 8013), + ('\u{1f50}', 4194315), ('\u{1f51}', 8025), ('\u{1f52}', 4194316), ('\u{1f53}', 8027), + ('\u{1f54}', 4194317), ('\u{1f55}', 8029), ('\u{1f56}', 4194318), ('\u{1f57}', 8031), + ('\u{1f60}', 8040), ('\u{1f61}', 8041), ('\u{1f62}', 8042), ('\u{1f63}', 8043), + ('\u{1f64}', 8044), ('\u{1f65}', 8045), ('\u{1f66}', 8046), ('\u{1f67}', 8047), + ('\u{1f70}', 8122), ('\u{1f71}', 8123), ('\u{1f72}', 8136), ('\u{1f73}', 8137), + ('\u{1f74}', 8138), ('\u{1f75}', 8139), ('\u{1f76}', 8154), ('\u{1f77}', 8155), + ('\u{1f78}', 8184), ('\u{1f79}', 8185), ('\u{1f7a}', 8170), ('\u{1f7b}', 8171), + ('\u{1f7c}', 8186), ('\u{1f7d}', 8187), ('\u{1f80}', 4194319), ('\u{1f81}', 4194320), + ('\u{1f82}', 4194321), ('\u{1f83}', 4194322), ('\u{1f84}', 4194323), ('\u{1f85}', 4194324), + ('\u{1f86}', 4194325), ('\u{1f87}', 4194326), ('\u{1f88}', 4194327), ('\u{1f89}', 4194328), + ('\u{1f8a}', 4194329), ('\u{1f8b}', 4194330), ('\u{1f8c}', 4194331), ('\u{1f8d}', 4194332), + ('\u{1f8e}', 4194333), ('\u{1f8f}', 4194334), ('\u{1f90}', 4194335), ('\u{1f91}', 4194336), + ('\u{1f92}', 4194337), ('\u{1f93}', 4194338), ('\u{1f94}', 4194339), ('\u{1f95}', 4194340), + ('\u{1f96}', 4194341), ('\u{1f97}', 4194342), ('\u{1f98}', 4194343), ('\u{1f99}', 4194344), + ('\u{1f9a}', 4194345), ('\u{1f9b}', 4194346), ('\u{1f9c}', 4194347), ('\u{1f9d}', 4194348), + ('\u{1f9e}', 4194349), ('\u{1f9f}', 4194350), ('\u{1fa0}', 4194351), ('\u{1fa1}', 4194352), + ('\u{1fa2}', 4194353), ('\u{1fa3}', 4194354), ('\u{1fa4}', 4194355), ('\u{1fa5}', 4194356), + ('\u{1fa6}', 4194357), ('\u{1fa7}', 4194358), ('\u{1fa8}', 4194359), ('\u{1fa9}', 4194360), + ('\u{1faa}', 4194361), ('\u{1fab}', 4194362), ('\u{1fac}', 4194363), ('\u{1fad}', 4194364), + ('\u{1fae}', 4194365), ('\u{1faf}', 4194366), ('\u{1fb0}', 8120), ('\u{1fb1}', 8121), + ('\u{1fb2}', 4194367), ('\u{1fb3}', 4194368), ('\u{1fb4}', 4194369), ('\u{1fb6}', 4194370), + ('\u{1fb7}', 4194371), ('\u{1fbc}', 4194372), ('\u{1fbe}', 921), ('\u{1fc2}', 4194373), + ('\u{1fc3}', 4194374), ('\u{1fc4}', 4194375), ('\u{1fc6}', 4194376), ('\u{1fc7}', 4194377), + ('\u{1fcc}', 4194378), ('\u{1fd0}', 8152), ('\u{1fd1}', 8153), ('\u{1fd2}', 4194379), + ('\u{1fd3}', 4194380), ('\u{1fd6}', 4194381), ('\u{1fd7}', 4194382), ('\u{1fe0}', 8168), + ('\u{1fe1}', 8169), ('\u{1fe2}', 4194383), ('\u{1fe3}', 4194384), ('\u{1fe4}', 4194385), + ('\u{1fe5}', 8172), ('\u{1fe6}', 4194386), ('\u{1fe7}', 4194387), ('\u{1ff2}', 4194388), + ('\u{1ff3}', 4194389), ('\u{1ff4}', 4194390), ('\u{1ff6}', 4194391), ('\u{1ff7}', 4194392), + ('\u{1ffc}', 4194393), ('\u{214e}', 8498), ('\u{2170}', 8544), ('\u{2171}', 8545), + ('\u{2172}', 8546), ('\u{2173}', 8547), ('\u{2174}', 8548), ('\u{2175}', 8549), + ('\u{2176}', 8550), ('\u{2177}', 8551), ('\u{2178}', 8552), ('\u{2179}', 8553), + ('\u{217a}', 8554), ('\u{217b}', 8555), ('\u{217c}', 8556), ('\u{217d}', 8557), + ('\u{217e}', 8558), ('\u{217f}', 8559), ('\u{2184}', 8579), ('\u{24d0}', 9398), + ('\u{24d1}', 9399), ('\u{24d2}', 9400), ('\u{24d3}', 9401), ('\u{24d4}', 9402), + ('\u{24d5}', 9403), ('\u{24d6}', 9404), ('\u{24d7}', 9405), ('\u{24d8}', 9406), + ('\u{24d9}', 9407), ('\u{24da}', 9408), ('\u{24db}', 9409), ('\u{24dc}', 9410), + ('\u{24dd}', 9411), ('\u{24de}', 9412), ('\u{24df}', 9413), ('\u{24e0}', 9414), + ('\u{24e1}', 9415), ('\u{24e2}', 9416), ('\u{24e3}', 9417), ('\u{24e4}', 9418), + ('\u{24e5}', 9419), ('\u{24e6}', 9420), ('\u{24e7}', 9421), ('\u{24e8}', 9422), + ('\u{24e9}', 9423), ('\u{2c30}', 11264), ('\u{2c31}', 11265), ('\u{2c32}', 11266), + ('\u{2c33}', 11267), ('\u{2c34}', 11268), ('\u{2c35}', 11269), ('\u{2c36}', 11270), + ('\u{2c37}', 11271), ('\u{2c38}', 11272), ('\u{2c39}', 11273), ('\u{2c3a}', 11274), + ('\u{2c3b}', 11275), ('\u{2c3c}', 11276), ('\u{2c3d}', 11277), ('\u{2c3e}', 11278), + ('\u{2c3f}', 11279), ('\u{2c40}', 11280), ('\u{2c41}', 11281), ('\u{2c42}', 11282), + ('\u{2c43}', 11283), ('\u{2c44}', 11284), ('\u{2c45}', 11285), ('\u{2c46}', 11286), + ('\u{2c47}', 11287), ('\u{2c48}', 11288), ('\u{2c49}', 11289), ('\u{2c4a}', 11290), + ('\u{2c4b}', 11291), ('\u{2c4c}', 11292), ('\u{2c4d}', 11293), ('\u{2c4e}', 11294), + ('\u{2c4f}', 11295), ('\u{2c50}', 11296), ('\u{2c51}', 11297), ('\u{2c52}', 11298), + ('\u{2c53}', 11299), ('\u{2c54}', 11300), ('\u{2c55}', 11301), ('\u{2c56}', 11302), + ('\u{2c57}', 11303), ('\u{2c58}', 11304), ('\u{2c59}', 11305), ('\u{2c5a}', 11306), + ('\u{2c5b}', 11307), ('\u{2c5c}', 11308), ('\u{2c5d}', 11309), ('\u{2c5e}', 11310), + ('\u{2c5f}', 11311), ('\u{2c61}', 11360), ('\u{2c65}', 570), ('\u{2c66}', 574), + ('\u{2c68}', 11367), ('\u{2c6a}', 11369), ('\u{2c6c}', 11371), ('\u{2c73}', 11378), + ('\u{2c76}', 11381), ('\u{2c81}', 11392), ('\u{2c83}', 11394), ('\u{2c85}', 11396), + ('\u{2c87}', 11398), ('\u{2c89}', 11400), ('\u{2c8b}', 11402), ('\u{2c8d}', 11404), + ('\u{2c8f}', 11406), ('\u{2c91}', 11408), ('\u{2c93}', 11410), ('\u{2c95}', 11412), + ('\u{2c97}', 11414), ('\u{2c99}', 11416), ('\u{2c9b}', 11418), ('\u{2c9d}', 11420), + ('\u{2c9f}', 11422), ('\u{2ca1}', 11424), ('\u{2ca3}', 11426), ('\u{2ca5}', 11428), + ('\u{2ca7}', 11430), ('\u{2ca9}', 11432), ('\u{2cab}', 11434), ('\u{2cad}', 11436), + ('\u{2caf}', 11438), ('\u{2cb1}', 11440), ('\u{2cb3}', 11442), ('\u{2cb5}', 11444), + ('\u{2cb7}', 11446), ('\u{2cb9}', 11448), ('\u{2cbb}', 11450), ('\u{2cbd}', 11452), + ('\u{2cbf}', 11454), ('\u{2cc1}', 11456), ('\u{2cc3}', 11458), ('\u{2cc5}', 11460), + ('\u{2cc7}', 11462), ('\u{2cc9}', 11464), ('\u{2ccb}', 11466), ('\u{2ccd}', 11468), + ('\u{2ccf}', 11470), ('\u{2cd1}', 11472), ('\u{2cd3}', 11474), ('\u{2cd5}', 11476), + ('\u{2cd7}', 11478), ('\u{2cd9}', 11480), ('\u{2cdb}', 11482), ('\u{2cdd}', 11484), + ('\u{2cdf}', 11486), ('\u{2ce1}', 11488), ('\u{2ce3}', 11490), ('\u{2cec}', 11499), + ('\u{2cee}', 11501), ('\u{2cf3}', 11506), ('\u{2d00}', 4256), ('\u{2d01}', 4257), + ('\u{2d02}', 4258), ('\u{2d03}', 4259), ('\u{2d04}', 4260), ('\u{2d05}', 4261), + ('\u{2d06}', 4262), ('\u{2d07}', 4263), ('\u{2d08}', 4264), ('\u{2d09}', 4265), + ('\u{2d0a}', 4266), ('\u{2d0b}', 4267), ('\u{2d0c}', 4268), ('\u{2d0d}', 4269), + ('\u{2d0e}', 4270), ('\u{2d0f}', 4271), ('\u{2d10}', 4272), ('\u{2d11}', 4273), + ('\u{2d12}', 4274), ('\u{2d13}', 4275), ('\u{2d14}', 4276), ('\u{2d15}', 4277), + ('\u{2d16}', 4278), ('\u{2d17}', 4279), ('\u{2d18}', 4280), ('\u{2d19}', 4281), + ('\u{2d1a}', 4282), ('\u{2d1b}', 4283), ('\u{2d1c}', 4284), ('\u{2d1d}', 4285), + ('\u{2d1e}', 4286), ('\u{2d1f}', 4287), ('\u{2d20}', 4288), ('\u{2d21}', 4289), + ('\u{2d22}', 4290), ('\u{2d23}', 4291), ('\u{2d24}', 4292), ('\u{2d25}', 4293), + ('\u{2d27}', 4295), ('\u{2d2d}', 4301), ('\u{a641}', 42560), ('\u{a643}', 42562), + ('\u{a645}', 42564), ('\u{a647}', 42566), ('\u{a649}', 42568), ('\u{a64b}', 42570), + ('\u{a64d}', 42572), ('\u{a64f}', 42574), ('\u{a651}', 42576), ('\u{a653}', 42578), + ('\u{a655}', 42580), ('\u{a657}', 42582), ('\u{a659}', 42584), ('\u{a65b}', 42586), + ('\u{a65d}', 42588), ('\u{a65f}', 42590), ('\u{a661}', 42592), ('\u{a663}', 42594), + ('\u{a665}', 42596), ('\u{a667}', 42598), ('\u{a669}', 42600), ('\u{a66b}', 42602), + ('\u{a66d}', 42604), ('\u{a681}', 42624), ('\u{a683}', 42626), ('\u{a685}', 42628), + ('\u{a687}', 42630), ('\u{a689}', 42632), ('\u{a68b}', 42634), ('\u{a68d}', 42636), + ('\u{a68f}', 42638), ('\u{a691}', 42640), ('\u{a693}', 42642), ('\u{a695}', 42644), + ('\u{a697}', 42646), ('\u{a699}', 42648), ('\u{a69b}', 42650), ('\u{a723}', 42786), + ('\u{a725}', 42788), ('\u{a727}', 42790), ('\u{a729}', 42792), ('\u{a72b}', 42794), + ('\u{a72d}', 42796), ('\u{a72f}', 42798), ('\u{a733}', 42802), ('\u{a735}', 42804), + ('\u{a737}', 42806), ('\u{a739}', 42808), ('\u{a73b}', 42810), ('\u{a73d}', 42812), + ('\u{a73f}', 42814), ('\u{a741}', 42816), ('\u{a743}', 42818), ('\u{a745}', 42820), + ('\u{a747}', 42822), ('\u{a749}', 42824), ('\u{a74b}', 42826), ('\u{a74d}', 42828), + ('\u{a74f}', 42830), ('\u{a751}', 42832), ('\u{a753}', 42834), ('\u{a755}', 42836), + ('\u{a757}', 42838), ('\u{a759}', 42840), ('\u{a75b}', 42842), ('\u{a75d}', 42844), + ('\u{a75f}', 42846), ('\u{a761}', 42848), ('\u{a763}', 42850), ('\u{a765}', 42852), + ('\u{a767}', 42854), ('\u{a769}', 42856), ('\u{a76b}', 42858), ('\u{a76d}', 42860), + ('\u{a76f}', 42862), ('\u{a77a}', 42873), ('\u{a77c}', 42875), ('\u{a77f}', 42878), + ('\u{a781}', 42880), ('\u{a783}', 42882), ('\u{a785}', 42884), ('\u{a787}', 42886), + ('\u{a78c}', 42891), ('\u{a791}', 42896), ('\u{a793}', 42898), ('\u{a794}', 42948), + ('\u{a797}', 42902), ('\u{a799}', 42904), ('\u{a79b}', 42906), ('\u{a79d}', 42908), + ('\u{a79f}', 42910), ('\u{a7a1}', 42912), ('\u{a7a3}', 42914), ('\u{a7a5}', 42916), + ('\u{a7a7}', 42918), ('\u{a7a9}', 42920), ('\u{a7b5}', 42932), ('\u{a7b7}', 42934), + ('\u{a7b9}', 42936), ('\u{a7bb}', 42938), ('\u{a7bd}', 42940), ('\u{a7bf}', 42942), + ('\u{a7c1}', 42944), ('\u{a7c3}', 42946), ('\u{a7c8}', 42951), ('\u{a7ca}', 42953), + ('\u{a7cd}', 42956), ('\u{a7cf}', 42958), ('\u{a7d1}', 42960), ('\u{a7d3}', 42962), + ('\u{a7d5}', 42964), ('\u{a7d7}', 42966), ('\u{a7d9}', 42968), ('\u{a7db}', 42970), + ('\u{a7f6}', 42997), ('\u{ab53}', 42931), ('\u{ab70}', 5024), ('\u{ab71}', 5025), + ('\u{ab72}', 5026), ('\u{ab73}', 5027), ('\u{ab74}', 5028), ('\u{ab75}', 5029), + ('\u{ab76}', 5030), ('\u{ab77}', 5031), ('\u{ab78}', 5032), ('\u{ab79}', 5033), + ('\u{ab7a}', 5034), ('\u{ab7b}', 5035), ('\u{ab7c}', 5036), ('\u{ab7d}', 5037), + ('\u{ab7e}', 5038), ('\u{ab7f}', 5039), ('\u{ab80}', 5040), ('\u{ab81}', 5041), + ('\u{ab82}', 5042), ('\u{ab83}', 5043), ('\u{ab84}', 5044), ('\u{ab85}', 5045), + ('\u{ab86}', 5046), ('\u{ab87}', 5047), ('\u{ab88}', 5048), ('\u{ab89}', 5049), + ('\u{ab8a}', 5050), ('\u{ab8b}', 5051), ('\u{ab8c}', 5052), ('\u{ab8d}', 5053), + ('\u{ab8e}', 5054), ('\u{ab8f}', 5055), ('\u{ab90}', 5056), ('\u{ab91}', 5057), + ('\u{ab92}', 5058), ('\u{ab93}', 5059), ('\u{ab94}', 5060), ('\u{ab95}', 5061), + ('\u{ab96}', 5062), ('\u{ab97}', 5063), ('\u{ab98}', 5064), ('\u{ab99}', 5065), + ('\u{ab9a}', 5066), ('\u{ab9b}', 5067), ('\u{ab9c}', 5068), ('\u{ab9d}', 5069), + ('\u{ab9e}', 5070), ('\u{ab9f}', 5071), ('\u{aba0}', 5072), ('\u{aba1}', 5073), + ('\u{aba2}', 5074), ('\u{aba3}', 5075), ('\u{aba4}', 5076), ('\u{aba5}', 5077), + ('\u{aba6}', 5078), ('\u{aba7}', 5079), ('\u{aba8}', 5080), ('\u{aba9}', 5081), + ('\u{abaa}', 5082), ('\u{abab}', 5083), ('\u{abac}', 5084), ('\u{abad}', 5085), + ('\u{abae}', 5086), ('\u{abaf}', 5087), ('\u{abb0}', 5088), ('\u{abb1}', 5089), + ('\u{abb2}', 5090), ('\u{abb3}', 5091), ('\u{abb4}', 5092), ('\u{abb5}', 5093), + ('\u{abb6}', 5094), ('\u{abb7}', 5095), ('\u{abb8}', 5096), ('\u{abb9}', 5097), + ('\u{abba}', 5098), ('\u{abbb}', 5099), ('\u{abbc}', 5100), ('\u{abbd}', 5101), + ('\u{abbe}', 5102), ('\u{abbf}', 5103), ('\u{fb00}', 4194394), ('\u{fb01}', 4194395), + ('\u{fb02}', 4194396), ('\u{fb03}', 4194397), ('\u{fb04}', 4194398), ('\u{fb05}', 4194399), + ('\u{fb06}', 4194400), ('\u{fb13}', 4194401), ('\u{fb14}', 4194402), ('\u{fb15}', 4194403), + ('\u{fb16}', 4194404), ('\u{fb17}', 4194405), ('\u{ff41}', 65313), ('\u{ff42}', 65314), + ('\u{ff43}', 65315), ('\u{ff44}', 65316), ('\u{ff45}', 65317), ('\u{ff46}', 65318), + ('\u{ff47}', 65319), ('\u{ff48}', 65320), ('\u{ff49}', 65321), ('\u{ff4a}', 65322), + ('\u{ff4b}', 65323), ('\u{ff4c}', 65324), ('\u{ff4d}', 65325), ('\u{ff4e}', 65326), + ('\u{ff4f}', 65327), ('\u{ff50}', 65328), ('\u{ff51}', 65329), ('\u{ff52}', 65330), + ('\u{ff53}', 65331), ('\u{ff54}', 65332), ('\u{ff55}', 65333), ('\u{ff56}', 65334), + ('\u{ff57}', 65335), ('\u{ff58}', 65336), ('\u{ff59}', 65337), ('\u{ff5a}', 65338), + ('\u{10428}', 66560), ('\u{10429}', 66561), ('\u{1042a}', 66562), ('\u{1042b}', 66563), + ('\u{1042c}', 66564), ('\u{1042d}', 66565), ('\u{1042e}', 66566), ('\u{1042f}', 66567), + ('\u{10430}', 66568), ('\u{10431}', 66569), ('\u{10432}', 66570), ('\u{10433}', 66571), + ('\u{10434}', 66572), ('\u{10435}', 66573), ('\u{10436}', 66574), ('\u{10437}', 66575), + ('\u{10438}', 66576), ('\u{10439}', 66577), ('\u{1043a}', 66578), ('\u{1043b}', 66579), + ('\u{1043c}', 66580), ('\u{1043d}', 66581), ('\u{1043e}', 66582), ('\u{1043f}', 66583), + ('\u{10440}', 66584), ('\u{10441}', 66585), ('\u{10442}', 66586), ('\u{10443}', 66587), + ('\u{10444}', 66588), ('\u{10445}', 66589), ('\u{10446}', 66590), ('\u{10447}', 66591), + ('\u{10448}', 66592), ('\u{10449}', 66593), ('\u{1044a}', 66594), ('\u{1044b}', 66595), + ('\u{1044c}', 66596), ('\u{1044d}', 66597), ('\u{1044e}', 66598), ('\u{1044f}', 66599), + ('\u{104d8}', 66736), ('\u{104d9}', 66737), ('\u{104da}', 66738), ('\u{104db}', 66739), + ('\u{104dc}', 66740), ('\u{104dd}', 66741), ('\u{104de}', 66742), ('\u{104df}', 66743), + ('\u{104e0}', 66744), ('\u{104e1}', 66745), ('\u{104e2}', 66746), ('\u{104e3}', 66747), + ('\u{104e4}', 66748), ('\u{104e5}', 66749), ('\u{104e6}', 66750), ('\u{104e7}', 66751), + ('\u{104e8}', 66752), ('\u{104e9}', 66753), ('\u{104ea}', 66754), ('\u{104eb}', 66755), + ('\u{104ec}', 66756), ('\u{104ed}', 66757), ('\u{104ee}', 66758), ('\u{104ef}', 66759), + ('\u{104f0}', 66760), ('\u{104f1}', 66761), ('\u{104f2}', 66762), ('\u{104f3}', 66763), + ('\u{104f4}', 66764), ('\u{104f5}', 66765), ('\u{104f6}', 66766), ('\u{104f7}', 66767), + ('\u{104f8}', 66768), ('\u{104f9}', 66769), ('\u{104fa}', 66770), ('\u{104fb}', 66771), + ('\u{10597}', 66928), ('\u{10598}', 66929), ('\u{10599}', 66930), ('\u{1059a}', 66931), + ('\u{1059b}', 66932), ('\u{1059c}', 66933), ('\u{1059d}', 66934), ('\u{1059e}', 66935), + ('\u{1059f}', 66936), ('\u{105a0}', 66937), ('\u{105a1}', 66938), ('\u{105a3}', 66940), + ('\u{105a4}', 66941), ('\u{105a5}', 66942), ('\u{105a6}', 66943), ('\u{105a7}', 66944), + ('\u{105a8}', 66945), ('\u{105a9}', 66946), ('\u{105aa}', 66947), ('\u{105ab}', 66948), + ('\u{105ac}', 66949), ('\u{105ad}', 66950), ('\u{105ae}', 66951), ('\u{105af}', 66952), + ('\u{105b0}', 66953), ('\u{105b1}', 66954), ('\u{105b3}', 66956), ('\u{105b4}', 66957), + ('\u{105b5}', 66958), ('\u{105b6}', 66959), ('\u{105b7}', 66960), ('\u{105b8}', 66961), + ('\u{105b9}', 66962), ('\u{105bb}', 66964), ('\u{105bc}', 66965), ('\u{10cc0}', 68736), + ('\u{10cc1}', 68737), ('\u{10cc2}', 68738), ('\u{10cc3}', 68739), ('\u{10cc4}', 68740), + ('\u{10cc5}', 68741), ('\u{10cc6}', 68742), ('\u{10cc7}', 68743), ('\u{10cc8}', 68744), + ('\u{10cc9}', 68745), ('\u{10cca}', 68746), ('\u{10ccb}', 68747), ('\u{10ccc}', 68748), + ('\u{10ccd}', 68749), ('\u{10cce}', 68750), ('\u{10ccf}', 68751), ('\u{10cd0}', 68752), + ('\u{10cd1}', 68753), ('\u{10cd2}', 68754), ('\u{10cd3}', 68755), ('\u{10cd4}', 68756), + ('\u{10cd5}', 68757), ('\u{10cd6}', 68758), ('\u{10cd7}', 68759), ('\u{10cd8}', 68760), + ('\u{10cd9}', 68761), ('\u{10cda}', 68762), ('\u{10cdb}', 68763), ('\u{10cdc}', 68764), + ('\u{10cdd}', 68765), ('\u{10cde}', 68766), ('\u{10cdf}', 68767), ('\u{10ce0}', 68768), + ('\u{10ce1}', 68769), ('\u{10ce2}', 68770), ('\u{10ce3}', 68771), ('\u{10ce4}', 68772), + ('\u{10ce5}', 68773), ('\u{10ce6}', 68774), ('\u{10ce7}', 68775), ('\u{10ce8}', 68776), + ('\u{10ce9}', 68777), ('\u{10cea}', 68778), ('\u{10ceb}', 68779), ('\u{10cec}', 68780), + ('\u{10ced}', 68781), ('\u{10cee}', 68782), ('\u{10cef}', 68783), ('\u{10cf0}', 68784), + ('\u{10cf1}', 68785), ('\u{10cf2}', 68786), ('\u{10d70}', 68944), ('\u{10d71}', 68945), + ('\u{10d72}', 68946), ('\u{10d73}', 68947), ('\u{10d74}', 68948), ('\u{10d75}', 68949), + ('\u{10d76}', 68950), ('\u{10d77}', 68951), ('\u{10d78}', 68952), ('\u{10d79}', 68953), + ('\u{10d7a}', 68954), ('\u{10d7b}', 68955), ('\u{10d7c}', 68956), ('\u{10d7d}', 68957), + ('\u{10d7e}', 68958), ('\u{10d7f}', 68959), ('\u{10d80}', 68960), ('\u{10d81}', 68961), + ('\u{10d82}', 68962), ('\u{10d83}', 68963), ('\u{10d84}', 68964), ('\u{10d85}', 68965), + ('\u{118c0}', 71840), ('\u{118c1}', 71841), ('\u{118c2}', 71842), ('\u{118c3}', 71843), + ('\u{118c4}', 71844), ('\u{118c5}', 71845), ('\u{118c6}', 71846), ('\u{118c7}', 71847), + ('\u{118c8}', 71848), ('\u{118c9}', 71849), ('\u{118ca}', 71850), ('\u{118cb}', 71851), + ('\u{118cc}', 71852), ('\u{118cd}', 71853), ('\u{118ce}', 71854), ('\u{118cf}', 71855), + ('\u{118d0}', 71856), ('\u{118d1}', 71857), ('\u{118d2}', 71858), ('\u{118d3}', 71859), + ('\u{118d4}', 71860), ('\u{118d5}', 71861), ('\u{118d6}', 71862), ('\u{118d7}', 71863), + ('\u{118d8}', 71864), ('\u{118d9}', 71865), ('\u{118da}', 71866), ('\u{118db}', 71867), + ('\u{118dc}', 71868), ('\u{118dd}', 71869), ('\u{118de}', 71870), ('\u{118df}', 71871), + ('\u{16e60}', 93760), ('\u{16e61}', 93761), ('\u{16e62}', 93762), ('\u{16e63}', 93763), + ('\u{16e64}', 93764), ('\u{16e65}', 93765), ('\u{16e66}', 93766), ('\u{16e67}', 93767), + ('\u{16e68}', 93768), ('\u{16e69}', 93769), ('\u{16e6a}', 93770), ('\u{16e6b}', 93771), + ('\u{16e6c}', 93772), ('\u{16e6d}', 93773), ('\u{16e6e}', 93774), ('\u{16e6f}', 93775), + ('\u{16e70}', 93776), ('\u{16e71}', 93777), ('\u{16e72}', 93778), ('\u{16e73}', 93779), + ('\u{16e74}', 93780), ('\u{16e75}', 93781), ('\u{16e76}', 93782), ('\u{16e77}', 93783), + ('\u{16e78}', 93784), ('\u{16e79}', 93785), ('\u{16e7a}', 93786), ('\u{16e7b}', 93787), + ('\u{16e7c}', 93788), ('\u{16e7d}', 93789), ('\u{16e7e}', 93790), ('\u{16e7f}', 93791), + ('\u{16ebb}', 93856), ('\u{16ebc}', 93857), ('\u{16ebd}', 93858), ('\u{16ebe}', 93859), + ('\u{16ebf}', 93860), ('\u{16ec0}', 93861), ('\u{16ec1}', 93862), ('\u{16ec2}', 93863), + ('\u{16ec3}', 93864), ('\u{16ec4}', 93865), ('\u{16ec5}', 93866), ('\u{16ec6}', 93867), + ('\u{16ec7}', 93868), ('\u{16ec8}', 93869), ('\u{16ec9}', 93870), ('\u{16eca}', 93871), + ('\u{16ecb}', 93872), ('\u{16ecc}', 93873), ('\u{16ecd}', 93874), ('\u{16ece}', 93875), + ('\u{16ecf}', 93876), ('\u{16ed0}', 93877), ('\u{16ed1}', 93878), ('\u{16ed2}', 93879), + ('\u{16ed3}', 93880), ('\u{1e922}', 125184), ('\u{1e923}', 125185), ('\u{1e924}', 125186), + ('\u{1e925}', 125187), ('\u{1e926}', 125188), ('\u{1e927}', 125189), ('\u{1e928}', 125190), + ('\u{1e929}', 125191), ('\u{1e92a}', 125192), ('\u{1e92b}', 125193), ('\u{1e92c}', 125194), + ('\u{1e92d}', 125195), ('\u{1e92e}', 125196), ('\u{1e92f}', 125197), ('\u{1e930}', 125198), + ('\u{1e931}', 125199), ('\u{1e932}', 125200), ('\u{1e933}', 125201), ('\u{1e934}', 125202), + ('\u{1e935}', 125203), ('\u{1e936}', 125204), ('\u{1e937}', 125205), ('\u{1e938}', 125206), + ('\u{1e939}', 125207), ('\u{1e93a}', 125208), ('\u{1e93b}', 125209), ('\u{1e93c}', 125210), + ('\u{1e93d}', 125211), ('\u{1e93e}', 125212), ('\u{1e93f}', 125213), ('\u{1e940}', 125214), + ('\u{1e941}', 125215), ('\u{1e942}', 125216), ('\u{1e943}', 125217), ]; - #[rustfmt::skip] static UPPERCASE_TABLE_MULTI: &[[char; 3]; 102] = &[ - ['\u{53}', '\u{53}', '\u{0}'], ['\u{2bc}', '\u{4e}', '\u{0}'], - ['\u{4a}', '\u{30c}', '\u{0}'], ['\u{399}', '\u{308}', '\u{301}'], - ['\u{3a5}', '\u{308}', '\u{301}'], ['\u{535}', '\u{552}', '\u{0}'], - ['\u{48}', '\u{331}', '\u{0}'], ['\u{54}', '\u{308}', '\u{0}'], - ['\u{57}', '\u{30a}', '\u{0}'], ['\u{59}', '\u{30a}', '\u{0}'], - ['\u{41}', '\u{2be}', '\u{0}'], ['\u{3a5}', '\u{313}', '\u{0}'], - ['\u{3a5}', '\u{313}', '\u{300}'], ['\u{3a5}', '\u{313}', '\u{301}'], - ['\u{3a5}', '\u{313}', '\u{342}'], ['\u{1f08}', '\u{399}', '\u{0}'], - ['\u{1f09}', '\u{399}', '\u{0}'], ['\u{1f0a}', '\u{399}', '\u{0}'], - ['\u{1f0b}', '\u{399}', '\u{0}'], ['\u{1f0c}', '\u{399}', '\u{0}'], - ['\u{1f0d}', '\u{399}', '\u{0}'], ['\u{1f0e}', '\u{399}', '\u{0}'], - ['\u{1f0f}', '\u{399}', '\u{0}'], ['\u{1f08}', '\u{399}', '\u{0}'], - ['\u{1f09}', '\u{399}', '\u{0}'], ['\u{1f0a}', '\u{399}', '\u{0}'], - ['\u{1f0b}', '\u{399}', '\u{0}'], ['\u{1f0c}', '\u{399}', '\u{0}'], - ['\u{1f0d}', '\u{399}', '\u{0}'], ['\u{1f0e}', '\u{399}', '\u{0}'], - ['\u{1f0f}', '\u{399}', '\u{0}'], ['\u{1f28}', '\u{399}', '\u{0}'], - ['\u{1f29}', '\u{399}', '\u{0}'], ['\u{1f2a}', '\u{399}', '\u{0}'], - ['\u{1f2b}', '\u{399}', '\u{0}'], ['\u{1f2c}', '\u{399}', '\u{0}'], - ['\u{1f2d}', '\u{399}', '\u{0}'], ['\u{1f2e}', '\u{399}', '\u{0}'], - ['\u{1f2f}', '\u{399}', '\u{0}'], ['\u{1f28}', '\u{399}', '\u{0}'], - ['\u{1f29}', '\u{399}', '\u{0}'], ['\u{1f2a}', '\u{399}', '\u{0}'], - ['\u{1f2b}', '\u{399}', '\u{0}'], ['\u{1f2c}', '\u{399}', '\u{0}'], - ['\u{1f2d}', '\u{399}', '\u{0}'], ['\u{1f2e}', '\u{399}', '\u{0}'], - ['\u{1f2f}', '\u{399}', '\u{0}'], ['\u{1f68}', '\u{399}', '\u{0}'], - ['\u{1f69}', '\u{399}', '\u{0}'], ['\u{1f6a}', '\u{399}', '\u{0}'], - ['\u{1f6b}', '\u{399}', '\u{0}'], ['\u{1f6c}', '\u{399}', '\u{0}'], - ['\u{1f6d}', '\u{399}', '\u{0}'], ['\u{1f6e}', '\u{399}', '\u{0}'], - ['\u{1f6f}', '\u{399}', '\u{0}'], ['\u{1f68}', '\u{399}', '\u{0}'], - ['\u{1f69}', '\u{399}', '\u{0}'], ['\u{1f6a}', '\u{399}', '\u{0}'], - ['\u{1f6b}', '\u{399}', '\u{0}'], ['\u{1f6c}', '\u{399}', '\u{0}'], - ['\u{1f6d}', '\u{399}', '\u{0}'], ['\u{1f6e}', '\u{399}', '\u{0}'], - ['\u{1f6f}', '\u{399}', '\u{0}'], ['\u{1fba}', '\u{399}', '\u{0}'], - ['\u{391}', '\u{399}', '\u{0}'], ['\u{386}', '\u{399}', '\u{0}'], - ['\u{391}', '\u{342}', '\u{0}'], ['\u{391}', '\u{342}', '\u{399}'], - ['\u{391}', '\u{399}', '\u{0}'], ['\u{1fca}', '\u{399}', '\u{0}'], - ['\u{397}', '\u{399}', '\u{0}'], ['\u{389}', '\u{399}', '\u{0}'], - ['\u{397}', '\u{342}', '\u{0}'], ['\u{397}', '\u{342}', '\u{399}'], - ['\u{397}', '\u{399}', '\u{0}'], ['\u{399}', '\u{308}', '\u{300}'], - ['\u{399}', '\u{308}', '\u{301}'], ['\u{399}', '\u{342}', '\u{0}'], - ['\u{399}', '\u{308}', '\u{342}'], ['\u{3a5}', '\u{308}', '\u{300}'], - ['\u{3a5}', '\u{308}', '\u{301}'], ['\u{3a1}', '\u{313}', '\u{0}'], - ['\u{3a5}', '\u{342}', '\u{0}'], ['\u{3a5}', '\u{308}', '\u{342}'], - ['\u{1ffa}', '\u{399}', '\u{0}'], ['\u{3a9}', '\u{399}', '\u{0}'], - ['\u{38f}', '\u{399}', '\u{0}'], ['\u{3a9}', '\u{342}', '\u{0}'], - ['\u{3a9}', '\u{342}', '\u{399}'], ['\u{3a9}', '\u{399}', '\u{0}'], - ['\u{46}', '\u{46}', '\u{0}'], ['\u{46}', '\u{49}', '\u{0}'], ['\u{46}', '\u{4c}', '\u{0}'], - ['\u{46}', '\u{46}', '\u{49}'], ['\u{46}', '\u{46}', '\u{4c}'], - ['\u{53}', '\u{54}', '\u{0}'], ['\u{53}', '\u{54}', '\u{0}'], - ['\u{544}', '\u{546}', '\u{0}'], ['\u{544}', '\u{535}', '\u{0}'], + ['S', 'S', '\u{0}'], ['\u{2bc}', 'N', '\u{0}'], ['J', '\u{30c}', '\u{0}'], + ['\u{399}', '\u{308}', '\u{301}'], ['\u{3a5}', '\u{308}', '\u{301}'], + ['\u{535}', '\u{552}', '\u{0}'], ['H', '\u{331}', '\u{0}'], ['T', '\u{308}', '\u{0}'], + ['W', '\u{30a}', '\u{0}'], ['Y', '\u{30a}', '\u{0}'], ['A', '\u{2be}', '\u{0}'], + ['\u{3a5}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{313}', '\u{300}'], + ['\u{3a5}', '\u{313}', '\u{301}'], ['\u{3a5}', '\u{313}', '\u{342}'], + ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], + ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], + ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], + ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], + ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], + ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], + ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], + ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], + ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], + ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], + ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], + ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], + ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], + ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], + ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], + ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], + ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], + ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], + ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], + ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], + ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], + ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], + ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], + ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], + ['\u{1fba}', '\u{399}', '\u{0}'], ['\u{391}', '\u{399}', '\u{0}'], + ['\u{386}', '\u{399}', '\u{0}'], ['\u{391}', '\u{342}', '\u{0}'], + ['\u{391}', '\u{342}', '\u{399}'], ['\u{391}', '\u{399}', '\u{0}'], + ['\u{1fca}', '\u{399}', '\u{0}'], ['\u{397}', '\u{399}', '\u{0}'], + ['\u{389}', '\u{399}', '\u{0}'], ['\u{397}', '\u{342}', '\u{0}'], + ['\u{397}', '\u{342}', '\u{399}'], ['\u{397}', '\u{399}', '\u{0}'], + ['\u{399}', '\u{308}', '\u{300}'], ['\u{399}', '\u{308}', '\u{301}'], + ['\u{399}', '\u{342}', '\u{0}'], ['\u{399}', '\u{308}', '\u{342}'], + ['\u{3a5}', '\u{308}', '\u{300}'], ['\u{3a5}', '\u{308}', '\u{301}'], + ['\u{3a1}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{342}', '\u{0}'], + ['\u{3a5}', '\u{308}', '\u{342}'], ['\u{1ffa}', '\u{399}', '\u{0}'], + ['\u{3a9}', '\u{399}', '\u{0}'], ['\u{38f}', '\u{399}', '\u{0}'], + ['\u{3a9}', '\u{342}', '\u{0}'], ['\u{3a9}', '\u{342}', '\u{399}'], + ['\u{3a9}', '\u{399}', '\u{0}'], ['F', 'F', '\u{0}'], ['F', 'I', '\u{0}'], + ['F', 'L', '\u{0}'], ['F', 'F', 'I'], ['F', 'F', 'L'], ['S', 'T', '\u{0}'], + ['S', 'T', '\u{0}'], ['\u{544}', '\u{546}', '\u{0}'], ['\u{544}', '\u{535}', '\u{0}'], ['\u{544}', '\u{53b}', '\u{0}'], ['\u{54e}', '\u{546}', '\u{0}'], ['\u{544}', '\u{53d}', '\u{0}'], ]; - - #[inline] - pub fn to_upper(c: char) -> [char; 3] { - const { - let mut i = 0; - while i < UPPERCASE_TABLE.len() { - let (_, val) = UPPERCASE_TABLE[i]; - if val & (1 << 22) == 0 { - assert!(char::from_u32(val).is_some()); - } else { - let index = val & ((1 << 22) - 1); - assert!((index as usize) < UPPERCASE_TABLE_MULTI.len()); - } - i += 1; - } - } - - // SAFETY: Just checked that the tables are valid - unsafe { - super::case_conversion( - c, - |c| c.to_ascii_uppercase(), - UPPERCASE_TABLE, - UPPERCASE_TABLE_MULTI, - ) - } - } } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 60a09986eb0a..80b62038c40e 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -116,7 +116,6 @@ #![feature(try_find)] #![feature(try_trait_v2)] #![feature(uint_bit_width)] -#![feature(unicode_internals)] #![feature(unsize)] #![feature(unwrap_infallible)] // tidy-alphabetical-end diff --git a/library/coretests/tests/unicode.rs b/library/coretests/tests/unicode.rs index 445175c68578..bbace0ef66ca 100644 --- a/library/coretests/tests/unicode.rs +++ b/library/coretests/tests/unicode.rs @@ -1,101 +1,5 @@ -use core::unicode::unicode_data; -use std::ops::RangeInclusive; - -mod test_data; - #[test] pub fn version() { let (major, _minor, _update) = core::char::UNICODE_VERSION; assert!(major >= 10); } - -#[track_caller] -fn test_boolean_property(ranges: &[RangeInclusive], lookup: fn(char) -> bool) { - let mut start = '\u{80}'; - for range in ranges { - for c in start..*range.start() { - assert!(!lookup(c), "{c:?}"); - } - for c in range.clone() { - assert!(lookup(c), "{c:?}"); - } - start = char::from_u32(*range.end() as u32 + 1).unwrap(); - } - for c in start..=char::MAX { - assert!(!lookup(c), "{c:?}"); - } -} - -#[track_caller] -fn test_case_mapping(ranges: &[(char, [char; 3])], lookup: fn(char) -> [char; 3]) { - let mut start = '\u{80}'; - for &(key, val) in ranges { - for c in start..key { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); - } - assert_eq!(lookup(key), val, "{key:?}"); - start = char::from_u32(key as u32 + 1).unwrap(); - } - for c in start..=char::MAX { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); - } -} - -#[test] -#[cfg_attr(miri, ignore)] -fn alphabetic() { - test_boolean_property(test_data::ALPHABETIC, unicode_data::alphabetic::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn case_ignorable() { - test_boolean_property(test_data::CASE_IGNORABLE, unicode_data::case_ignorable::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn cased() { - test_boolean_property(test_data::CASED, unicode_data::cased::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn grapheme_extend() { - test_boolean_property(test_data::GRAPHEME_EXTEND, unicode_data::grapheme_extend::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn lowercase() { - test_boolean_property(test_data::LOWERCASE, unicode_data::lowercase::lookup); -} - -#[test] -fn n() { - test_boolean_property(test_data::N, unicode_data::n::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn uppercase() { - test_boolean_property(test_data::UPPERCASE, unicode_data::uppercase::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn white_space() { - test_boolean_property(test_data::WHITE_SPACE, unicode_data::white_space::lookup); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn to_lowercase() { - test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower); -} - -#[test] -#[cfg_attr(miri, ignore)] -fn to_uppercase() { - test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper); -} diff --git a/library/coretests/tests/unicode/test_data.rs b/library/coretests/tests/unicode/test_data.rs deleted file mode 100644 index f53cd7dc2270..000000000000 --- a/library/coretests/tests/unicode/test_data.rs +++ /dev/null @@ -1,2928 +0,0 @@ -//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually! -// ignore-tidy-filelength - -use std::ops::RangeInclusive; - -#[rustfmt::skip] -pub(super) static ALPHABETIC: &[RangeInclusive; 759] = &[ - '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{c0}'..='\u{d6}', - '\u{d8}'..='\u{f6}', '\u{f8}'..='\u{2c1}', '\u{2c6}'..='\u{2d1}', '\u{2e0}'..='\u{2e4}', - '\u{2ec}'..='\u{2ec}', '\u{2ee}'..='\u{2ee}', '\u{345}'..='\u{345}', '\u{363}'..='\u{374}', - '\u{376}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{37f}'..='\u{37f}', '\u{386}'..='\u{386}', - '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{3a1}', '\u{3a3}'..='\u{3f5}', - '\u{3f7}'..='\u{481}', '\u{48a}'..='\u{52f}', '\u{531}'..='\u{556}', '\u{559}'..='\u{559}', - '\u{560}'..='\u{588}', '\u{5b0}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', '\u{5c1}'..='\u{5c2}', - '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{5d0}'..='\u{5ea}', '\u{5ef}'..='\u{5f2}', - '\u{610}'..='\u{61a}', '\u{620}'..='\u{657}', '\u{659}'..='\u{65f}', '\u{66e}'..='\u{6d3}', - '\u{6d5}'..='\u{6dc}', '\u{6e1}'..='\u{6e8}', '\u{6ed}'..='\u{6ef}', '\u{6fa}'..='\u{6fc}', - '\u{6ff}'..='\u{6ff}', '\u{710}'..='\u{73f}', '\u{74d}'..='\u{7b1}', '\u{7ca}'..='\u{7ea}', - '\u{7f4}'..='\u{7f5}', '\u{7fa}'..='\u{7fa}', '\u{800}'..='\u{817}', '\u{81a}'..='\u{82c}', - '\u{840}'..='\u{858}', '\u{860}'..='\u{86a}', '\u{870}'..='\u{887}', '\u{889}'..='\u{88f}', - '\u{897}'..='\u{897}', '\u{8a0}'..='\u{8c9}', '\u{8d4}'..='\u{8df}', '\u{8e3}'..='\u{8e9}', - '\u{8f0}'..='\u{93b}', '\u{93d}'..='\u{94c}', '\u{94e}'..='\u{950}', '\u{955}'..='\u{963}', - '\u{971}'..='\u{983}', '\u{985}'..='\u{98c}', '\u{98f}'..='\u{990}', '\u{993}'..='\u{9a8}', - '\u{9aa}'..='\u{9b0}', '\u{9b2}'..='\u{9b2}', '\u{9b6}'..='\u{9b9}', '\u{9bd}'..='\u{9c4}', - '\u{9c7}'..='\u{9c8}', '\u{9cb}'..='\u{9cc}', '\u{9ce}'..='\u{9ce}', '\u{9d7}'..='\u{9d7}', - '\u{9dc}'..='\u{9dd}', '\u{9df}'..='\u{9e3}', '\u{9f0}'..='\u{9f1}', '\u{9fc}'..='\u{9fc}', - '\u{a01}'..='\u{a03}', '\u{a05}'..='\u{a0a}', '\u{a0f}'..='\u{a10}', '\u{a13}'..='\u{a28}', - '\u{a2a}'..='\u{a30}', '\u{a32}'..='\u{a33}', '\u{a35}'..='\u{a36}', '\u{a38}'..='\u{a39}', - '\u{a3e}'..='\u{a42}', '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4c}', '\u{a51}'..='\u{a51}', - '\u{a59}'..='\u{a5c}', '\u{a5e}'..='\u{a5e}', '\u{a70}'..='\u{a75}', '\u{a81}'..='\u{a83}', - '\u{a85}'..='\u{a8d}', '\u{a8f}'..='\u{a91}', '\u{a93}'..='\u{aa8}', '\u{aaa}'..='\u{ab0}', - '\u{ab2}'..='\u{ab3}', '\u{ab5}'..='\u{ab9}', '\u{abd}'..='\u{ac5}', '\u{ac7}'..='\u{ac9}', - '\u{acb}'..='\u{acc}', '\u{ad0}'..='\u{ad0}', '\u{ae0}'..='\u{ae3}', '\u{af9}'..='\u{afc}', - '\u{b01}'..='\u{b03}', '\u{b05}'..='\u{b0c}', '\u{b0f}'..='\u{b10}', '\u{b13}'..='\u{b28}', - '\u{b2a}'..='\u{b30}', '\u{b32}'..='\u{b33}', '\u{b35}'..='\u{b39}', '\u{b3d}'..='\u{b44}', - '\u{b47}'..='\u{b48}', '\u{b4b}'..='\u{b4c}', '\u{b56}'..='\u{b57}', '\u{b5c}'..='\u{b5d}', - '\u{b5f}'..='\u{b63}', '\u{b71}'..='\u{b71}', '\u{b82}'..='\u{b83}', '\u{b85}'..='\u{b8a}', - '\u{b8e}'..='\u{b90}', '\u{b92}'..='\u{b95}', '\u{b99}'..='\u{b9a}', '\u{b9c}'..='\u{b9c}', - '\u{b9e}'..='\u{b9f}', '\u{ba3}'..='\u{ba4}', '\u{ba8}'..='\u{baa}', '\u{bae}'..='\u{bb9}', - '\u{bbe}'..='\u{bc2}', '\u{bc6}'..='\u{bc8}', '\u{bca}'..='\u{bcc}', '\u{bd0}'..='\u{bd0}', - '\u{bd7}'..='\u{bd7}', '\u{c00}'..='\u{c0c}', '\u{c0e}'..='\u{c10}', '\u{c12}'..='\u{c28}', - '\u{c2a}'..='\u{c39}', '\u{c3d}'..='\u{c44}', '\u{c46}'..='\u{c48}', '\u{c4a}'..='\u{c4c}', - '\u{c55}'..='\u{c56}', '\u{c58}'..='\u{c5a}', '\u{c5c}'..='\u{c5d}', '\u{c60}'..='\u{c63}', - '\u{c80}'..='\u{c83}', '\u{c85}'..='\u{c8c}', '\u{c8e}'..='\u{c90}', '\u{c92}'..='\u{ca8}', - '\u{caa}'..='\u{cb3}', '\u{cb5}'..='\u{cb9}', '\u{cbd}'..='\u{cc4}', '\u{cc6}'..='\u{cc8}', - '\u{cca}'..='\u{ccc}', '\u{cd5}'..='\u{cd6}', '\u{cdc}'..='\u{cde}', '\u{ce0}'..='\u{ce3}', - '\u{cf1}'..='\u{cf3}', '\u{d00}'..='\u{d0c}', '\u{d0e}'..='\u{d10}', '\u{d12}'..='\u{d3a}', - '\u{d3d}'..='\u{d44}', '\u{d46}'..='\u{d48}', '\u{d4a}'..='\u{d4c}', '\u{d4e}'..='\u{d4e}', - '\u{d54}'..='\u{d57}', '\u{d5f}'..='\u{d63}', '\u{d7a}'..='\u{d7f}', '\u{d81}'..='\u{d83}', - '\u{d85}'..='\u{d96}', '\u{d9a}'..='\u{db1}', '\u{db3}'..='\u{dbb}', '\u{dbd}'..='\u{dbd}', - '\u{dc0}'..='\u{dc6}', '\u{dcf}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', '\u{dd8}'..='\u{ddf}', - '\u{df2}'..='\u{df3}', '\u{e01}'..='\u{e3a}', '\u{e40}'..='\u{e46}', '\u{e4d}'..='\u{e4d}', - '\u{e81}'..='\u{e82}', '\u{e84}'..='\u{e84}', '\u{e86}'..='\u{e8a}', '\u{e8c}'..='\u{ea3}', - '\u{ea5}'..='\u{ea5}', '\u{ea7}'..='\u{eb9}', '\u{ebb}'..='\u{ebd}', '\u{ec0}'..='\u{ec4}', - '\u{ec6}'..='\u{ec6}', '\u{ecd}'..='\u{ecd}', '\u{edc}'..='\u{edf}', '\u{f00}'..='\u{f00}', - '\u{f40}'..='\u{f47}', '\u{f49}'..='\u{f6c}', '\u{f71}'..='\u{f83}', '\u{f88}'..='\u{f97}', - '\u{f99}'..='\u{fbc}', '\u{1000}'..='\u{1036}', '\u{1038}'..='\u{1038}', - '\u{103b}'..='\u{103f}', '\u{1050}'..='\u{108f}', '\u{109a}'..='\u{109d}', - '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', '\u{10cd}'..='\u{10cd}', - '\u{10d0}'..='\u{10fa}', '\u{10fc}'..='\u{1248}', '\u{124a}'..='\u{124d}', - '\u{1250}'..='\u{1256}', '\u{1258}'..='\u{1258}', '\u{125a}'..='\u{125d}', - '\u{1260}'..='\u{1288}', '\u{128a}'..='\u{128d}', '\u{1290}'..='\u{12b0}', - '\u{12b2}'..='\u{12b5}', '\u{12b8}'..='\u{12be}', '\u{12c0}'..='\u{12c0}', - '\u{12c2}'..='\u{12c5}', '\u{12c8}'..='\u{12d6}', '\u{12d8}'..='\u{1310}', - '\u{1312}'..='\u{1315}', '\u{1318}'..='\u{135a}', '\u{1380}'..='\u{138f}', - '\u{13a0}'..='\u{13f5}', '\u{13f8}'..='\u{13fd}', '\u{1401}'..='\u{166c}', - '\u{166f}'..='\u{167f}', '\u{1681}'..='\u{169a}', '\u{16a0}'..='\u{16ea}', - '\u{16ee}'..='\u{16f8}', '\u{1700}'..='\u{1713}', '\u{171f}'..='\u{1733}', - '\u{1740}'..='\u{1753}', '\u{1760}'..='\u{176c}', '\u{176e}'..='\u{1770}', - '\u{1772}'..='\u{1773}', '\u{1780}'..='\u{17b3}', '\u{17b6}'..='\u{17c8}', - '\u{17d7}'..='\u{17d7}', '\u{17dc}'..='\u{17dc}', '\u{1820}'..='\u{1878}', - '\u{1880}'..='\u{18aa}', '\u{18b0}'..='\u{18f5}', '\u{1900}'..='\u{191e}', - '\u{1920}'..='\u{192b}', '\u{1930}'..='\u{1938}', '\u{1950}'..='\u{196d}', - '\u{1970}'..='\u{1974}', '\u{1980}'..='\u{19ab}', '\u{19b0}'..='\u{19c9}', - '\u{1a00}'..='\u{1a1b}', '\u{1a20}'..='\u{1a5e}', '\u{1a61}'..='\u{1a74}', - '\u{1aa7}'..='\u{1aa7}', '\u{1abf}'..='\u{1ac0}', '\u{1acc}'..='\u{1ace}', - '\u{1b00}'..='\u{1b33}', '\u{1b35}'..='\u{1b43}', '\u{1b45}'..='\u{1b4c}', - '\u{1b80}'..='\u{1ba9}', '\u{1bac}'..='\u{1baf}', '\u{1bba}'..='\u{1be5}', - '\u{1be7}'..='\u{1bf1}', '\u{1c00}'..='\u{1c36}', '\u{1c4d}'..='\u{1c4f}', - '\u{1c5a}'..='\u{1c7d}', '\u{1c80}'..='\u{1c8a}', '\u{1c90}'..='\u{1cba}', - '\u{1cbd}'..='\u{1cbf}', '\u{1ce9}'..='\u{1cec}', '\u{1cee}'..='\u{1cf3}', - '\u{1cf5}'..='\u{1cf6}', '\u{1cfa}'..='\u{1cfa}', '\u{1d00}'..='\u{1dbf}', - '\u{1dd3}'..='\u{1df4}', '\u{1e00}'..='\u{1f15}', '\u{1f18}'..='\u{1f1d}', - '\u{1f20}'..='\u{1f45}', '\u{1f48}'..='\u{1f4d}', '\u{1f50}'..='\u{1f57}', - '\u{1f59}'..='\u{1f59}', '\u{1f5b}'..='\u{1f5b}', '\u{1f5d}'..='\u{1f5d}', - '\u{1f5f}'..='\u{1f7d}', '\u{1f80}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fbc}', - '\u{1fbe}'..='\u{1fbe}', '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fcc}', - '\u{1fd0}'..='\u{1fd3}', '\u{1fd6}'..='\u{1fdb}', '\u{1fe0}'..='\u{1fec}', - '\u{1ff2}'..='\u{1ff4}', '\u{1ff6}'..='\u{1ffc}', '\u{2071}'..='\u{2071}', - '\u{207f}'..='\u{207f}', '\u{2090}'..='\u{209c}', '\u{2102}'..='\u{2102}', - '\u{2107}'..='\u{2107}', '\u{210a}'..='\u{2113}', '\u{2115}'..='\u{2115}', - '\u{2119}'..='\u{211d}', '\u{2124}'..='\u{2124}', '\u{2126}'..='\u{2126}', - '\u{2128}'..='\u{2128}', '\u{212a}'..='\u{212d}', '\u{212f}'..='\u{2139}', - '\u{213c}'..='\u{213f}', '\u{2145}'..='\u{2149}', '\u{214e}'..='\u{214e}', - '\u{2160}'..='\u{2188}', '\u{24b6}'..='\u{24e9}', '\u{2c00}'..='\u{2ce4}', - '\u{2ceb}'..='\u{2cee}', '\u{2cf2}'..='\u{2cf3}', '\u{2d00}'..='\u{2d25}', - '\u{2d27}'..='\u{2d27}', '\u{2d2d}'..='\u{2d2d}', '\u{2d30}'..='\u{2d67}', - '\u{2d6f}'..='\u{2d6f}', '\u{2d80}'..='\u{2d96}', '\u{2da0}'..='\u{2da6}', - '\u{2da8}'..='\u{2dae}', '\u{2db0}'..='\u{2db6}', '\u{2db8}'..='\u{2dbe}', - '\u{2dc0}'..='\u{2dc6}', '\u{2dc8}'..='\u{2dce}', '\u{2dd0}'..='\u{2dd6}', - '\u{2dd8}'..='\u{2dde}', '\u{2de0}'..='\u{2dff}', '\u{2e2f}'..='\u{2e2f}', - '\u{3005}'..='\u{3007}', '\u{3021}'..='\u{3029}', '\u{3031}'..='\u{3035}', - '\u{3038}'..='\u{303c}', '\u{3041}'..='\u{3096}', '\u{309d}'..='\u{309f}', - '\u{30a1}'..='\u{30fa}', '\u{30fc}'..='\u{30ff}', '\u{3105}'..='\u{312f}', - '\u{3131}'..='\u{318e}', '\u{31a0}'..='\u{31bf}', '\u{31f0}'..='\u{31ff}', - '\u{3400}'..='\u{4dbf}', '\u{4e00}'..='\u{a48c}', '\u{a4d0}'..='\u{a4fd}', - '\u{a500}'..='\u{a60c}', '\u{a610}'..='\u{a61f}', '\u{a62a}'..='\u{a62b}', - '\u{a640}'..='\u{a66e}', '\u{a674}'..='\u{a67b}', '\u{a67f}'..='\u{a6ef}', - '\u{a717}'..='\u{a71f}', '\u{a722}'..='\u{a788}', '\u{a78b}'..='\u{a7dc}', - '\u{a7f1}'..='\u{a805}', '\u{a807}'..='\u{a827}', '\u{a840}'..='\u{a873}', - '\u{a880}'..='\u{a8c3}', '\u{a8c5}'..='\u{a8c5}', '\u{a8f2}'..='\u{a8f7}', - '\u{a8fb}'..='\u{a8fb}', '\u{a8fd}'..='\u{a8ff}', '\u{a90a}'..='\u{a92a}', - '\u{a930}'..='\u{a952}', '\u{a960}'..='\u{a97c}', '\u{a980}'..='\u{a9b2}', - '\u{a9b4}'..='\u{a9bf}', '\u{a9cf}'..='\u{a9cf}', '\u{a9e0}'..='\u{a9ef}', - '\u{a9fa}'..='\u{a9fe}', '\u{aa00}'..='\u{aa36}', '\u{aa40}'..='\u{aa4d}', - '\u{aa60}'..='\u{aa76}', '\u{aa7a}'..='\u{aabe}', '\u{aac0}'..='\u{aac0}', - '\u{aac2}'..='\u{aac2}', '\u{aadb}'..='\u{aadd}', '\u{aae0}'..='\u{aaef}', - '\u{aaf2}'..='\u{aaf5}', '\u{ab01}'..='\u{ab06}', '\u{ab09}'..='\u{ab0e}', - '\u{ab11}'..='\u{ab16}', '\u{ab20}'..='\u{ab26}', '\u{ab28}'..='\u{ab2e}', - '\u{ab30}'..='\u{ab5a}', '\u{ab5c}'..='\u{ab69}', '\u{ab70}'..='\u{abea}', - '\u{ac00}'..='\u{d7a3}', '\u{d7b0}'..='\u{d7c6}', '\u{d7cb}'..='\u{d7fb}', - '\u{f900}'..='\u{fa6d}', '\u{fa70}'..='\u{fad9}', '\u{fb00}'..='\u{fb06}', - '\u{fb13}'..='\u{fb17}', '\u{fb1d}'..='\u{fb28}', '\u{fb2a}'..='\u{fb36}', - '\u{fb38}'..='\u{fb3c}', '\u{fb3e}'..='\u{fb3e}', '\u{fb40}'..='\u{fb41}', - '\u{fb43}'..='\u{fb44}', '\u{fb46}'..='\u{fbb1}', '\u{fbd3}'..='\u{fd3d}', - '\u{fd50}'..='\u{fd8f}', '\u{fd92}'..='\u{fdc7}', '\u{fdf0}'..='\u{fdfb}', - '\u{fe70}'..='\u{fe74}', '\u{fe76}'..='\u{fefc}', '\u{ff21}'..='\u{ff3a}', - '\u{ff41}'..='\u{ff5a}', '\u{ff66}'..='\u{ffbe}', '\u{ffc2}'..='\u{ffc7}', - '\u{ffca}'..='\u{ffcf}', '\u{ffd2}'..='\u{ffd7}', '\u{ffda}'..='\u{ffdc}', - '\u{10000}'..='\u{1000b}', '\u{1000d}'..='\u{10026}', '\u{10028}'..='\u{1003a}', - '\u{1003c}'..='\u{1003d}', '\u{1003f}'..='\u{1004d}', '\u{10050}'..='\u{1005d}', - '\u{10080}'..='\u{100fa}', '\u{10140}'..='\u{10174}', '\u{10280}'..='\u{1029c}', - '\u{102a0}'..='\u{102d0}', '\u{10300}'..='\u{1031f}', '\u{1032d}'..='\u{1034a}', - '\u{10350}'..='\u{1037a}', '\u{10380}'..='\u{1039d}', '\u{103a0}'..='\u{103c3}', - '\u{103c8}'..='\u{103cf}', '\u{103d1}'..='\u{103d5}', '\u{10400}'..='\u{1049d}', - '\u{104b0}'..='\u{104d3}', '\u{104d8}'..='\u{104fb}', '\u{10500}'..='\u{10527}', - '\u{10530}'..='\u{10563}', '\u{10570}'..='\u{1057a}', '\u{1057c}'..='\u{1058a}', - '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', '\u{10597}'..='\u{105a1}', - '\u{105a3}'..='\u{105b1}', '\u{105b3}'..='\u{105b9}', '\u{105bb}'..='\u{105bc}', - '\u{105c0}'..='\u{105f3}', '\u{10600}'..='\u{10736}', '\u{10740}'..='\u{10755}', - '\u{10760}'..='\u{10767}', '\u{10780}'..='\u{10785}', '\u{10787}'..='\u{107b0}', - '\u{107b2}'..='\u{107ba}', '\u{10800}'..='\u{10805}', '\u{10808}'..='\u{10808}', - '\u{1080a}'..='\u{10835}', '\u{10837}'..='\u{10838}', '\u{1083c}'..='\u{1083c}', - '\u{1083f}'..='\u{10855}', '\u{10860}'..='\u{10876}', '\u{10880}'..='\u{1089e}', - '\u{108e0}'..='\u{108f2}', '\u{108f4}'..='\u{108f5}', '\u{10900}'..='\u{10915}', - '\u{10920}'..='\u{10939}', '\u{10940}'..='\u{10959}', '\u{10980}'..='\u{109b7}', - '\u{109be}'..='\u{109bf}', '\u{10a00}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', - '\u{10a0c}'..='\u{10a13}', '\u{10a15}'..='\u{10a17}', '\u{10a19}'..='\u{10a35}', - '\u{10a60}'..='\u{10a7c}', '\u{10a80}'..='\u{10a9c}', '\u{10ac0}'..='\u{10ac7}', - '\u{10ac9}'..='\u{10ae4}', '\u{10b00}'..='\u{10b35}', '\u{10b40}'..='\u{10b55}', - '\u{10b60}'..='\u{10b72}', '\u{10b80}'..='\u{10b91}', '\u{10c00}'..='\u{10c48}', - '\u{10c80}'..='\u{10cb2}', '\u{10cc0}'..='\u{10cf2}', '\u{10d00}'..='\u{10d27}', - '\u{10d4a}'..='\u{10d65}', '\u{10d69}'..='\u{10d69}', '\u{10d6f}'..='\u{10d85}', - '\u{10e80}'..='\u{10ea9}', '\u{10eab}'..='\u{10eac}', '\u{10eb0}'..='\u{10eb1}', - '\u{10ec2}'..='\u{10ec7}', '\u{10efa}'..='\u{10efc}', '\u{10f00}'..='\u{10f1c}', - '\u{10f27}'..='\u{10f27}', '\u{10f30}'..='\u{10f45}', '\u{10f70}'..='\u{10f81}', - '\u{10fb0}'..='\u{10fc4}', '\u{10fe0}'..='\u{10ff6}', '\u{11000}'..='\u{11045}', - '\u{11071}'..='\u{11075}', '\u{11080}'..='\u{110b8}', '\u{110c2}'..='\u{110c2}', - '\u{110d0}'..='\u{110e8}', '\u{11100}'..='\u{11132}', '\u{11144}'..='\u{11147}', - '\u{11150}'..='\u{11172}', '\u{11176}'..='\u{11176}', '\u{11180}'..='\u{111bf}', - '\u{111c1}'..='\u{111c4}', '\u{111ce}'..='\u{111cf}', '\u{111da}'..='\u{111da}', - '\u{111dc}'..='\u{111dc}', '\u{11200}'..='\u{11211}', '\u{11213}'..='\u{11234}', - '\u{11237}'..='\u{11237}', '\u{1123e}'..='\u{11241}', '\u{11280}'..='\u{11286}', - '\u{11288}'..='\u{11288}', '\u{1128a}'..='\u{1128d}', '\u{1128f}'..='\u{1129d}', - '\u{1129f}'..='\u{112a8}', '\u{112b0}'..='\u{112e8}', '\u{11300}'..='\u{11303}', - '\u{11305}'..='\u{1130c}', '\u{1130f}'..='\u{11310}', '\u{11313}'..='\u{11328}', - '\u{1132a}'..='\u{11330}', '\u{11332}'..='\u{11333}', '\u{11335}'..='\u{11339}', - '\u{1133d}'..='\u{11344}', '\u{11347}'..='\u{11348}', '\u{1134b}'..='\u{1134c}', - '\u{11350}'..='\u{11350}', '\u{11357}'..='\u{11357}', '\u{1135d}'..='\u{11363}', - '\u{11380}'..='\u{11389}', '\u{1138b}'..='\u{1138b}', '\u{1138e}'..='\u{1138e}', - '\u{11390}'..='\u{113b5}', '\u{113b7}'..='\u{113c0}', '\u{113c2}'..='\u{113c2}', - '\u{113c5}'..='\u{113c5}', '\u{113c7}'..='\u{113ca}', '\u{113cc}'..='\u{113cd}', - '\u{113d1}'..='\u{113d1}', '\u{113d3}'..='\u{113d3}', '\u{11400}'..='\u{11441}', - '\u{11443}'..='\u{11445}', '\u{11447}'..='\u{1144a}', '\u{1145f}'..='\u{11461}', - '\u{11480}'..='\u{114c1}', '\u{114c4}'..='\u{114c5}', '\u{114c7}'..='\u{114c7}', - '\u{11580}'..='\u{115b5}', '\u{115b8}'..='\u{115be}', '\u{115d8}'..='\u{115dd}', - '\u{11600}'..='\u{1163e}', '\u{11640}'..='\u{11640}', '\u{11644}'..='\u{11644}', - '\u{11680}'..='\u{116b5}', '\u{116b8}'..='\u{116b8}', '\u{11700}'..='\u{1171a}', - '\u{1171d}'..='\u{1172a}', '\u{11740}'..='\u{11746}', '\u{11800}'..='\u{11838}', - '\u{118a0}'..='\u{118df}', '\u{118ff}'..='\u{11906}', '\u{11909}'..='\u{11909}', - '\u{1190c}'..='\u{11913}', '\u{11915}'..='\u{11916}', '\u{11918}'..='\u{11935}', - '\u{11937}'..='\u{11938}', '\u{1193b}'..='\u{1193c}', '\u{1193f}'..='\u{11942}', - '\u{119a0}'..='\u{119a7}', '\u{119aa}'..='\u{119d7}', '\u{119da}'..='\u{119df}', - '\u{119e1}'..='\u{119e1}', '\u{119e3}'..='\u{119e4}', '\u{11a00}'..='\u{11a32}', - '\u{11a35}'..='\u{11a3e}', '\u{11a50}'..='\u{11a97}', '\u{11a9d}'..='\u{11a9d}', - '\u{11ab0}'..='\u{11af8}', '\u{11b60}'..='\u{11b67}', '\u{11bc0}'..='\u{11be0}', - '\u{11c00}'..='\u{11c08}', '\u{11c0a}'..='\u{11c36}', '\u{11c38}'..='\u{11c3e}', - '\u{11c40}'..='\u{11c40}', '\u{11c72}'..='\u{11c8f}', '\u{11c92}'..='\u{11ca7}', - '\u{11ca9}'..='\u{11cb6}', '\u{11d00}'..='\u{11d06}', '\u{11d08}'..='\u{11d09}', - '\u{11d0b}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', '\u{11d3c}'..='\u{11d3d}', - '\u{11d3f}'..='\u{11d41}', '\u{11d43}'..='\u{11d43}', '\u{11d46}'..='\u{11d47}', - '\u{11d60}'..='\u{11d65}', '\u{11d67}'..='\u{11d68}', '\u{11d6a}'..='\u{11d8e}', - '\u{11d90}'..='\u{11d91}', '\u{11d93}'..='\u{11d96}', '\u{11d98}'..='\u{11d98}', - '\u{11db0}'..='\u{11ddb}', '\u{11ee0}'..='\u{11ef6}', '\u{11f00}'..='\u{11f10}', - '\u{11f12}'..='\u{11f3a}', '\u{11f3e}'..='\u{11f40}', '\u{11fb0}'..='\u{11fb0}', - '\u{12000}'..='\u{12399}', '\u{12400}'..='\u{1246e}', '\u{12480}'..='\u{12543}', - '\u{12f90}'..='\u{12ff0}', '\u{13000}'..='\u{1342f}', '\u{13441}'..='\u{13446}', - '\u{13460}'..='\u{143fa}', '\u{14400}'..='\u{14646}', '\u{16100}'..='\u{1612e}', - '\u{16800}'..='\u{16a38}', '\u{16a40}'..='\u{16a5e}', '\u{16a70}'..='\u{16abe}', - '\u{16ad0}'..='\u{16aed}', '\u{16b00}'..='\u{16b2f}', '\u{16b40}'..='\u{16b43}', - '\u{16b63}'..='\u{16b77}', '\u{16b7d}'..='\u{16b8f}', '\u{16d40}'..='\u{16d6c}', - '\u{16e40}'..='\u{16e7f}', '\u{16ea0}'..='\u{16eb8}', '\u{16ebb}'..='\u{16ed3}', - '\u{16f00}'..='\u{16f4a}', '\u{16f4f}'..='\u{16f87}', '\u{16f8f}'..='\u{16f9f}', - '\u{16fe0}'..='\u{16fe1}', '\u{16fe3}'..='\u{16fe3}', '\u{16ff0}'..='\u{16ff6}', - '\u{17000}'..='\u{18cd5}', '\u{18cff}'..='\u{18d1e}', '\u{18d80}'..='\u{18df2}', - '\u{1aff0}'..='\u{1aff3}', '\u{1aff5}'..='\u{1affb}', '\u{1affd}'..='\u{1affe}', - '\u{1b000}'..='\u{1b122}', '\u{1b132}'..='\u{1b132}', '\u{1b150}'..='\u{1b152}', - '\u{1b155}'..='\u{1b155}', '\u{1b164}'..='\u{1b167}', '\u{1b170}'..='\u{1b2fb}', - '\u{1bc00}'..='\u{1bc6a}', '\u{1bc70}'..='\u{1bc7c}', '\u{1bc80}'..='\u{1bc88}', - '\u{1bc90}'..='\u{1bc99}', '\u{1bc9e}'..='\u{1bc9e}', '\u{1d400}'..='\u{1d454}', - '\u{1d456}'..='\u{1d49c}', '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', - '\u{1d4a5}'..='\u{1d4a6}', '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b9}', - '\u{1d4bb}'..='\u{1d4bb}', '\u{1d4bd}'..='\u{1d4c3}', '\u{1d4c5}'..='\u{1d505}', - '\u{1d507}'..='\u{1d50a}', '\u{1d50d}'..='\u{1d514}', '\u{1d516}'..='\u{1d51c}', - '\u{1d51e}'..='\u{1d539}', '\u{1d53b}'..='\u{1d53e}', '\u{1d540}'..='\u{1d544}', - '\u{1d546}'..='\u{1d546}', '\u{1d54a}'..='\u{1d550}', '\u{1d552}'..='\u{1d6a5}', - '\u{1d6a8}'..='\u{1d6c0}', '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6fa}', - '\u{1d6fc}'..='\u{1d714}', '\u{1d716}'..='\u{1d734}', '\u{1d736}'..='\u{1d74e}', - '\u{1d750}'..='\u{1d76e}', '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d7a8}', - '\u{1d7aa}'..='\u{1d7c2}', '\u{1d7c4}'..='\u{1d7cb}', '\u{1df00}'..='\u{1df1e}', - '\u{1df25}'..='\u{1df2a}', '\u{1e000}'..='\u{1e006}', '\u{1e008}'..='\u{1e018}', - '\u{1e01b}'..='\u{1e021}', '\u{1e023}'..='\u{1e024}', '\u{1e026}'..='\u{1e02a}', - '\u{1e030}'..='\u{1e06d}', '\u{1e08f}'..='\u{1e08f}', '\u{1e100}'..='\u{1e12c}', - '\u{1e137}'..='\u{1e13d}', '\u{1e14e}'..='\u{1e14e}', '\u{1e290}'..='\u{1e2ad}', - '\u{1e2c0}'..='\u{1e2eb}', '\u{1e4d0}'..='\u{1e4eb}', '\u{1e5d0}'..='\u{1e5ed}', - '\u{1e5f0}'..='\u{1e5f0}', '\u{1e6c0}'..='\u{1e6de}', '\u{1e6e0}'..='\u{1e6f5}', - '\u{1e6fe}'..='\u{1e6ff}', '\u{1e7e0}'..='\u{1e7e6}', '\u{1e7e8}'..='\u{1e7eb}', - '\u{1e7ed}'..='\u{1e7ee}', '\u{1e7f0}'..='\u{1e7fe}', '\u{1e800}'..='\u{1e8c4}', - '\u{1e900}'..='\u{1e943}', '\u{1e947}'..='\u{1e947}', '\u{1e94b}'..='\u{1e94b}', - '\u{1ee00}'..='\u{1ee03}', '\u{1ee05}'..='\u{1ee1f}', '\u{1ee21}'..='\u{1ee22}', - '\u{1ee24}'..='\u{1ee24}', '\u{1ee27}'..='\u{1ee27}', '\u{1ee29}'..='\u{1ee32}', - '\u{1ee34}'..='\u{1ee37}', '\u{1ee39}'..='\u{1ee39}', '\u{1ee3b}'..='\u{1ee3b}', - '\u{1ee42}'..='\u{1ee42}', '\u{1ee47}'..='\u{1ee47}', '\u{1ee49}'..='\u{1ee49}', - '\u{1ee4b}'..='\u{1ee4b}', '\u{1ee4d}'..='\u{1ee4f}', '\u{1ee51}'..='\u{1ee52}', - '\u{1ee54}'..='\u{1ee54}', '\u{1ee57}'..='\u{1ee57}', '\u{1ee59}'..='\u{1ee59}', - '\u{1ee5b}'..='\u{1ee5b}', '\u{1ee5d}'..='\u{1ee5d}', '\u{1ee5f}'..='\u{1ee5f}', - '\u{1ee61}'..='\u{1ee62}', '\u{1ee64}'..='\u{1ee64}', '\u{1ee67}'..='\u{1ee6a}', - '\u{1ee6c}'..='\u{1ee72}', '\u{1ee74}'..='\u{1ee77}', '\u{1ee79}'..='\u{1ee7c}', - '\u{1ee7e}'..='\u{1ee7e}', '\u{1ee80}'..='\u{1ee89}', '\u{1ee8b}'..='\u{1ee9b}', - '\u{1eea1}'..='\u{1eea3}', '\u{1eea5}'..='\u{1eea9}', '\u{1eeab}'..='\u{1eebb}', - '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', '\u{1f170}'..='\u{1f189}', - '\u{20000}'..='\u{2a6df}', '\u{2a700}'..='\u{2b81d}', '\u{2b820}'..='\u{2cead}', - '\u{2ceb0}'..='\u{2ebe0}', '\u{2ebf0}'..='\u{2ee5d}', '\u{2f800}'..='\u{2fa1d}', - '\u{30000}'..='\u{3134a}', '\u{31350}'..='\u{33479}', -]; - -#[rustfmt::skip] -pub(super) static CASE_IGNORABLE: &[RangeInclusive; 459] = &[ - '\u{a8}'..='\u{a8}', '\u{ad}'..='\u{ad}', '\u{af}'..='\u{af}', '\u{b4}'..='\u{b4}', - '\u{b7}'..='\u{b8}', '\u{2b0}'..='\u{36f}', '\u{374}'..='\u{375}', '\u{37a}'..='\u{37a}', - '\u{384}'..='\u{385}', '\u{387}'..='\u{387}', '\u{483}'..='\u{489}', '\u{559}'..='\u{559}', - '\u{55f}'..='\u{55f}', '\u{591}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', '\u{5c1}'..='\u{5c2}', - '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{5f4}'..='\u{5f4}', '\u{600}'..='\u{605}', - '\u{610}'..='\u{61a}', '\u{61c}'..='\u{61c}', '\u{640}'..='\u{640}', '\u{64b}'..='\u{65f}', - '\u{670}'..='\u{670}', '\u{6d6}'..='\u{6dd}', '\u{6df}'..='\u{6e8}', '\u{6ea}'..='\u{6ed}', - '\u{70f}'..='\u{70f}', '\u{711}'..='\u{711}', '\u{730}'..='\u{74a}', '\u{7a6}'..='\u{7b0}', - '\u{7eb}'..='\u{7f5}', '\u{7fa}'..='\u{7fa}', '\u{7fd}'..='\u{7fd}', '\u{816}'..='\u{82d}', - '\u{859}'..='\u{85b}', '\u{888}'..='\u{888}', '\u{890}'..='\u{891}', '\u{897}'..='\u{89f}', - '\u{8c9}'..='\u{902}', '\u{93a}'..='\u{93a}', '\u{93c}'..='\u{93c}', '\u{941}'..='\u{948}', - '\u{94d}'..='\u{94d}', '\u{951}'..='\u{957}', '\u{962}'..='\u{963}', '\u{971}'..='\u{971}', - '\u{981}'..='\u{981}', '\u{9bc}'..='\u{9bc}', '\u{9c1}'..='\u{9c4}', '\u{9cd}'..='\u{9cd}', - '\u{9e2}'..='\u{9e3}', '\u{9fe}'..='\u{9fe}', '\u{a01}'..='\u{a02}', '\u{a3c}'..='\u{a3c}', - '\u{a41}'..='\u{a42}', '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4d}', '\u{a51}'..='\u{a51}', - '\u{a70}'..='\u{a71}', '\u{a75}'..='\u{a75}', '\u{a81}'..='\u{a82}', '\u{abc}'..='\u{abc}', - '\u{ac1}'..='\u{ac5}', '\u{ac7}'..='\u{ac8}', '\u{acd}'..='\u{acd}', '\u{ae2}'..='\u{ae3}', - '\u{afa}'..='\u{aff}', '\u{b01}'..='\u{b01}', '\u{b3c}'..='\u{b3c}', '\u{b3f}'..='\u{b3f}', - '\u{b41}'..='\u{b44}', '\u{b4d}'..='\u{b4d}', '\u{b55}'..='\u{b56}', '\u{b62}'..='\u{b63}', - '\u{b82}'..='\u{b82}', '\u{bc0}'..='\u{bc0}', '\u{bcd}'..='\u{bcd}', '\u{c00}'..='\u{c00}', - '\u{c04}'..='\u{c04}', '\u{c3c}'..='\u{c3c}', '\u{c3e}'..='\u{c40}', '\u{c46}'..='\u{c48}', - '\u{c4a}'..='\u{c4d}', '\u{c55}'..='\u{c56}', '\u{c62}'..='\u{c63}', '\u{c81}'..='\u{c81}', - '\u{cbc}'..='\u{cbc}', '\u{cbf}'..='\u{cbf}', '\u{cc6}'..='\u{cc6}', '\u{ccc}'..='\u{ccd}', - '\u{ce2}'..='\u{ce3}', '\u{d00}'..='\u{d01}', '\u{d3b}'..='\u{d3c}', '\u{d41}'..='\u{d44}', - '\u{d4d}'..='\u{d4d}', '\u{d62}'..='\u{d63}', '\u{d81}'..='\u{d81}', '\u{dca}'..='\u{dca}', - '\u{dd2}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', '\u{e31}'..='\u{e31}', '\u{e34}'..='\u{e3a}', - '\u{e46}'..='\u{e4e}', '\u{eb1}'..='\u{eb1}', '\u{eb4}'..='\u{ebc}', '\u{ec6}'..='\u{ec6}', - '\u{ec8}'..='\u{ece}', '\u{f18}'..='\u{f19}', '\u{f35}'..='\u{f35}', '\u{f37}'..='\u{f37}', - '\u{f39}'..='\u{f39}', '\u{f71}'..='\u{f7e}', '\u{f80}'..='\u{f84}', '\u{f86}'..='\u{f87}', - '\u{f8d}'..='\u{f97}', '\u{f99}'..='\u{fbc}', '\u{fc6}'..='\u{fc6}', - '\u{102d}'..='\u{1030}', '\u{1032}'..='\u{1037}', '\u{1039}'..='\u{103a}', - '\u{103d}'..='\u{103e}', '\u{1058}'..='\u{1059}', '\u{105e}'..='\u{1060}', - '\u{1071}'..='\u{1074}', '\u{1082}'..='\u{1082}', '\u{1085}'..='\u{1086}', - '\u{108d}'..='\u{108d}', '\u{109d}'..='\u{109d}', '\u{10fc}'..='\u{10fc}', - '\u{135d}'..='\u{135f}', '\u{1712}'..='\u{1714}', '\u{1732}'..='\u{1733}', - '\u{1752}'..='\u{1753}', '\u{1772}'..='\u{1773}', '\u{17b4}'..='\u{17b5}', - '\u{17b7}'..='\u{17bd}', '\u{17c6}'..='\u{17c6}', '\u{17c9}'..='\u{17d3}', - '\u{17d7}'..='\u{17d7}', '\u{17dd}'..='\u{17dd}', '\u{180b}'..='\u{180f}', - '\u{1843}'..='\u{1843}', '\u{1885}'..='\u{1886}', '\u{18a9}'..='\u{18a9}', - '\u{1920}'..='\u{1922}', '\u{1927}'..='\u{1928}', '\u{1932}'..='\u{1932}', - '\u{1939}'..='\u{193b}', '\u{1a17}'..='\u{1a18}', '\u{1a1b}'..='\u{1a1b}', - '\u{1a56}'..='\u{1a56}', '\u{1a58}'..='\u{1a5e}', '\u{1a60}'..='\u{1a60}', - '\u{1a62}'..='\u{1a62}', '\u{1a65}'..='\u{1a6c}', '\u{1a73}'..='\u{1a7c}', - '\u{1a7f}'..='\u{1a7f}', '\u{1aa7}'..='\u{1aa7}', '\u{1ab0}'..='\u{1add}', - '\u{1ae0}'..='\u{1aeb}', '\u{1b00}'..='\u{1b03}', '\u{1b34}'..='\u{1b34}', - '\u{1b36}'..='\u{1b3a}', '\u{1b3c}'..='\u{1b3c}', '\u{1b42}'..='\u{1b42}', - '\u{1b6b}'..='\u{1b73}', '\u{1b80}'..='\u{1b81}', '\u{1ba2}'..='\u{1ba5}', - '\u{1ba8}'..='\u{1ba9}', '\u{1bab}'..='\u{1bad}', '\u{1be6}'..='\u{1be6}', - '\u{1be8}'..='\u{1be9}', '\u{1bed}'..='\u{1bed}', '\u{1bef}'..='\u{1bf1}', - '\u{1c2c}'..='\u{1c33}', '\u{1c36}'..='\u{1c37}', '\u{1c78}'..='\u{1c7d}', - '\u{1cd0}'..='\u{1cd2}', '\u{1cd4}'..='\u{1ce0}', '\u{1ce2}'..='\u{1ce8}', - '\u{1ced}'..='\u{1ced}', '\u{1cf4}'..='\u{1cf4}', '\u{1cf8}'..='\u{1cf9}', - '\u{1d2c}'..='\u{1d6a}', '\u{1d78}'..='\u{1d78}', '\u{1d9b}'..='\u{1dff}', - '\u{1fbd}'..='\u{1fbd}', '\u{1fbf}'..='\u{1fc1}', '\u{1fcd}'..='\u{1fcf}', - '\u{1fdd}'..='\u{1fdf}', '\u{1fed}'..='\u{1fef}', '\u{1ffd}'..='\u{1ffe}', - '\u{200b}'..='\u{200f}', '\u{2018}'..='\u{2019}', '\u{2024}'..='\u{2024}', - '\u{2027}'..='\u{2027}', '\u{202a}'..='\u{202e}', '\u{2060}'..='\u{2064}', - '\u{2066}'..='\u{206f}', '\u{2071}'..='\u{2071}', '\u{207f}'..='\u{207f}', - '\u{2090}'..='\u{209c}', '\u{20d0}'..='\u{20f0}', '\u{2c7c}'..='\u{2c7d}', - '\u{2cef}'..='\u{2cf1}', '\u{2d6f}'..='\u{2d6f}', '\u{2d7f}'..='\u{2d7f}', - '\u{2de0}'..='\u{2dff}', '\u{2e2f}'..='\u{2e2f}', '\u{3005}'..='\u{3005}', - '\u{302a}'..='\u{302d}', '\u{3031}'..='\u{3035}', '\u{303b}'..='\u{303b}', - '\u{3099}'..='\u{309e}', '\u{30fc}'..='\u{30fe}', '\u{a015}'..='\u{a015}', - '\u{a4f8}'..='\u{a4fd}', '\u{a60c}'..='\u{a60c}', '\u{a66f}'..='\u{a672}', - '\u{a674}'..='\u{a67d}', '\u{a67f}'..='\u{a67f}', '\u{a69c}'..='\u{a69f}', - '\u{a6f0}'..='\u{a6f1}', '\u{a700}'..='\u{a721}', '\u{a770}'..='\u{a770}', - '\u{a788}'..='\u{a78a}', '\u{a7f1}'..='\u{a7f4}', '\u{a7f8}'..='\u{a7f9}', - '\u{a802}'..='\u{a802}', '\u{a806}'..='\u{a806}', '\u{a80b}'..='\u{a80b}', - '\u{a825}'..='\u{a826}', '\u{a82c}'..='\u{a82c}', '\u{a8c4}'..='\u{a8c5}', - '\u{a8e0}'..='\u{a8f1}', '\u{a8ff}'..='\u{a8ff}', '\u{a926}'..='\u{a92d}', - '\u{a947}'..='\u{a951}', '\u{a980}'..='\u{a982}', '\u{a9b3}'..='\u{a9b3}', - '\u{a9b6}'..='\u{a9b9}', '\u{a9bc}'..='\u{a9bd}', '\u{a9cf}'..='\u{a9cf}', - '\u{a9e5}'..='\u{a9e6}', '\u{aa29}'..='\u{aa2e}', '\u{aa31}'..='\u{aa32}', - '\u{aa35}'..='\u{aa36}', '\u{aa43}'..='\u{aa43}', '\u{aa4c}'..='\u{aa4c}', - '\u{aa70}'..='\u{aa70}', '\u{aa7c}'..='\u{aa7c}', '\u{aab0}'..='\u{aab0}', - '\u{aab2}'..='\u{aab4}', '\u{aab7}'..='\u{aab8}', '\u{aabe}'..='\u{aabf}', - '\u{aac1}'..='\u{aac1}', '\u{aadd}'..='\u{aadd}', '\u{aaec}'..='\u{aaed}', - '\u{aaf3}'..='\u{aaf4}', '\u{aaf6}'..='\u{aaf6}', '\u{ab5b}'..='\u{ab5f}', - '\u{ab69}'..='\u{ab6b}', '\u{abe5}'..='\u{abe5}', '\u{abe8}'..='\u{abe8}', - '\u{abed}'..='\u{abed}', '\u{fb1e}'..='\u{fb1e}', '\u{fbb2}'..='\u{fbc2}', - '\u{fe00}'..='\u{fe0f}', '\u{fe13}'..='\u{fe13}', '\u{fe20}'..='\u{fe2f}', - '\u{fe52}'..='\u{fe52}', '\u{fe55}'..='\u{fe55}', '\u{feff}'..='\u{feff}', - '\u{ff07}'..='\u{ff07}', '\u{ff0e}'..='\u{ff0e}', '\u{ff1a}'..='\u{ff1a}', - '\u{ff3e}'..='\u{ff3e}', '\u{ff40}'..='\u{ff40}', '\u{ff70}'..='\u{ff70}', - '\u{ff9e}'..='\u{ff9f}', '\u{ffe3}'..='\u{ffe3}', '\u{fff9}'..='\u{fffb}', - '\u{101fd}'..='\u{101fd}', '\u{102e0}'..='\u{102e0}', '\u{10376}'..='\u{1037a}', - '\u{10780}'..='\u{10785}', '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', - '\u{10a01}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', '\u{10a0c}'..='\u{10a0f}', - '\u{10a38}'..='\u{10a3a}', '\u{10a3f}'..='\u{10a3f}', '\u{10ae5}'..='\u{10ae6}', - '\u{10d24}'..='\u{10d27}', '\u{10d4e}'..='\u{10d4e}', '\u{10d69}'..='\u{10d6d}', - '\u{10d6f}'..='\u{10d6f}', '\u{10eab}'..='\u{10eac}', '\u{10ec5}'..='\u{10ec5}', - '\u{10efa}'..='\u{10eff}', '\u{10f46}'..='\u{10f50}', '\u{10f82}'..='\u{10f85}', - '\u{11001}'..='\u{11001}', '\u{11038}'..='\u{11046}', '\u{11070}'..='\u{11070}', - '\u{11073}'..='\u{11074}', '\u{1107f}'..='\u{11081}', '\u{110b3}'..='\u{110b6}', - '\u{110b9}'..='\u{110ba}', '\u{110bd}'..='\u{110bd}', '\u{110c2}'..='\u{110c2}', - '\u{110cd}'..='\u{110cd}', '\u{11100}'..='\u{11102}', '\u{11127}'..='\u{1112b}', - '\u{1112d}'..='\u{11134}', '\u{11173}'..='\u{11173}', '\u{11180}'..='\u{11181}', - '\u{111b6}'..='\u{111be}', '\u{111c9}'..='\u{111cc}', '\u{111cf}'..='\u{111cf}', - '\u{1122f}'..='\u{11231}', '\u{11234}'..='\u{11234}', '\u{11236}'..='\u{11237}', - '\u{1123e}'..='\u{1123e}', '\u{11241}'..='\u{11241}', '\u{112df}'..='\u{112df}', - '\u{112e3}'..='\u{112ea}', '\u{11300}'..='\u{11301}', '\u{1133b}'..='\u{1133c}', - '\u{11340}'..='\u{11340}', '\u{11366}'..='\u{1136c}', '\u{11370}'..='\u{11374}', - '\u{113bb}'..='\u{113c0}', '\u{113ce}'..='\u{113ce}', '\u{113d0}'..='\u{113d0}', - '\u{113d2}'..='\u{113d2}', '\u{113e1}'..='\u{113e2}', '\u{11438}'..='\u{1143f}', - '\u{11442}'..='\u{11444}', '\u{11446}'..='\u{11446}', '\u{1145e}'..='\u{1145e}', - '\u{114b3}'..='\u{114b8}', '\u{114ba}'..='\u{114ba}', '\u{114bf}'..='\u{114c0}', - '\u{114c2}'..='\u{114c3}', '\u{115b2}'..='\u{115b5}', '\u{115bc}'..='\u{115bd}', - '\u{115bf}'..='\u{115c0}', '\u{115dc}'..='\u{115dd}', '\u{11633}'..='\u{1163a}', - '\u{1163d}'..='\u{1163d}', '\u{1163f}'..='\u{11640}', '\u{116ab}'..='\u{116ab}', - '\u{116ad}'..='\u{116ad}', '\u{116b0}'..='\u{116b5}', '\u{116b7}'..='\u{116b7}', - '\u{1171d}'..='\u{1171d}', '\u{1171f}'..='\u{1171f}', '\u{11722}'..='\u{11725}', - '\u{11727}'..='\u{1172b}', '\u{1182f}'..='\u{11837}', '\u{11839}'..='\u{1183a}', - '\u{1193b}'..='\u{1193c}', '\u{1193e}'..='\u{1193e}', '\u{11943}'..='\u{11943}', - '\u{119d4}'..='\u{119d7}', '\u{119da}'..='\u{119db}', '\u{119e0}'..='\u{119e0}', - '\u{11a01}'..='\u{11a0a}', '\u{11a33}'..='\u{11a38}', '\u{11a3b}'..='\u{11a3e}', - '\u{11a47}'..='\u{11a47}', '\u{11a51}'..='\u{11a56}', '\u{11a59}'..='\u{11a5b}', - '\u{11a8a}'..='\u{11a96}', '\u{11a98}'..='\u{11a99}', '\u{11b60}'..='\u{11b60}', - '\u{11b62}'..='\u{11b64}', '\u{11b66}'..='\u{11b66}', '\u{11c30}'..='\u{11c36}', - '\u{11c38}'..='\u{11c3d}', '\u{11c3f}'..='\u{11c3f}', '\u{11c92}'..='\u{11ca7}', - '\u{11caa}'..='\u{11cb0}', '\u{11cb2}'..='\u{11cb3}', '\u{11cb5}'..='\u{11cb6}', - '\u{11d31}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', '\u{11d3c}'..='\u{11d3d}', - '\u{11d3f}'..='\u{11d45}', '\u{11d47}'..='\u{11d47}', '\u{11d90}'..='\u{11d91}', - '\u{11d95}'..='\u{11d95}', '\u{11d97}'..='\u{11d97}', '\u{11dd9}'..='\u{11dd9}', - '\u{11ef3}'..='\u{11ef4}', '\u{11f00}'..='\u{11f01}', '\u{11f36}'..='\u{11f3a}', - '\u{11f40}'..='\u{11f40}', '\u{11f42}'..='\u{11f42}', '\u{11f5a}'..='\u{11f5a}', - '\u{13430}'..='\u{13440}', '\u{13447}'..='\u{13455}', '\u{1611e}'..='\u{16129}', - '\u{1612d}'..='\u{1612f}', '\u{16af0}'..='\u{16af4}', '\u{16b30}'..='\u{16b36}', - '\u{16b40}'..='\u{16b43}', '\u{16d40}'..='\u{16d42}', '\u{16d6b}'..='\u{16d6c}', - '\u{16f4f}'..='\u{16f4f}', '\u{16f8f}'..='\u{16f9f}', '\u{16fe0}'..='\u{16fe1}', - '\u{16fe3}'..='\u{16fe4}', '\u{16ff2}'..='\u{16ff3}', '\u{1aff0}'..='\u{1aff3}', - '\u{1aff5}'..='\u{1affb}', '\u{1affd}'..='\u{1affe}', '\u{1bc9d}'..='\u{1bc9e}', - '\u{1bca0}'..='\u{1bca3}', '\u{1cf00}'..='\u{1cf2d}', '\u{1cf30}'..='\u{1cf46}', - '\u{1d167}'..='\u{1d169}', '\u{1d173}'..='\u{1d182}', '\u{1d185}'..='\u{1d18b}', - '\u{1d1aa}'..='\u{1d1ad}', '\u{1d242}'..='\u{1d244}', '\u{1da00}'..='\u{1da36}', - '\u{1da3b}'..='\u{1da6c}', '\u{1da75}'..='\u{1da75}', '\u{1da84}'..='\u{1da84}', - '\u{1da9b}'..='\u{1da9f}', '\u{1daa1}'..='\u{1daaf}', '\u{1e000}'..='\u{1e006}', - '\u{1e008}'..='\u{1e018}', '\u{1e01b}'..='\u{1e021}', '\u{1e023}'..='\u{1e024}', - '\u{1e026}'..='\u{1e02a}', '\u{1e030}'..='\u{1e06d}', '\u{1e08f}'..='\u{1e08f}', - '\u{1e130}'..='\u{1e13d}', '\u{1e2ae}'..='\u{1e2ae}', '\u{1e2ec}'..='\u{1e2ef}', - '\u{1e4eb}'..='\u{1e4ef}', '\u{1e5ee}'..='\u{1e5ef}', '\u{1e6e3}'..='\u{1e6e3}', - '\u{1e6e6}'..='\u{1e6e6}', '\u{1e6ee}'..='\u{1e6ef}', '\u{1e6f5}'..='\u{1e6f5}', - '\u{1e6ff}'..='\u{1e6ff}', '\u{1e8d0}'..='\u{1e8d6}', '\u{1e944}'..='\u{1e94b}', - '\u{1f3fb}'..='\u{1f3ff}', '\u{e0001}'..='\u{e0001}', '\u{e0020}'..='\u{e007f}', - '\u{e0100}'..='\u{e01ef}', -]; - -#[rustfmt::skip] -pub(super) static CASED: &[RangeInclusive; 156] = &[ - '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{c0}'..='\u{d6}', - '\u{d8}'..='\u{f6}', '\u{f8}'..='\u{1ba}', '\u{1bc}'..='\u{1bf}', '\u{1c4}'..='\u{293}', - '\u{296}'..='\u{2b8}', '\u{2c0}'..='\u{2c1}', '\u{2e0}'..='\u{2e4}', '\u{345}'..='\u{345}', - '\u{370}'..='\u{373}', '\u{376}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{37f}'..='\u{37f}', - '\u{386}'..='\u{386}', '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{3a1}', - '\u{3a3}'..='\u{3f5}', '\u{3f7}'..='\u{481}', '\u{48a}'..='\u{52f}', '\u{531}'..='\u{556}', - '\u{560}'..='\u{588}', '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', - '\u{10cd}'..='\u{10cd}', '\u{10d0}'..='\u{10fa}', '\u{10fc}'..='\u{10ff}', - '\u{13a0}'..='\u{13f5}', '\u{13f8}'..='\u{13fd}', '\u{1c80}'..='\u{1c8a}', - '\u{1c90}'..='\u{1cba}', '\u{1cbd}'..='\u{1cbf}', '\u{1d00}'..='\u{1dbf}', - '\u{1e00}'..='\u{1f15}', '\u{1f18}'..='\u{1f1d}', '\u{1f20}'..='\u{1f45}', - '\u{1f48}'..='\u{1f4d}', '\u{1f50}'..='\u{1f57}', '\u{1f59}'..='\u{1f59}', - '\u{1f5b}'..='\u{1f5b}', '\u{1f5d}'..='\u{1f5d}', '\u{1f5f}'..='\u{1f7d}', - '\u{1f80}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fbc}', '\u{1fbe}'..='\u{1fbe}', - '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fcc}', '\u{1fd0}'..='\u{1fd3}', - '\u{1fd6}'..='\u{1fdb}', '\u{1fe0}'..='\u{1fec}', '\u{1ff2}'..='\u{1ff4}', - '\u{1ff6}'..='\u{1ffc}', '\u{2071}'..='\u{2071}', '\u{207f}'..='\u{207f}', - '\u{2090}'..='\u{209c}', '\u{2102}'..='\u{2102}', '\u{2107}'..='\u{2107}', - '\u{210a}'..='\u{2113}', '\u{2115}'..='\u{2115}', '\u{2119}'..='\u{211d}', - '\u{2124}'..='\u{2124}', '\u{2126}'..='\u{2126}', '\u{2128}'..='\u{2128}', - '\u{212a}'..='\u{212d}', '\u{212f}'..='\u{2134}', '\u{2139}'..='\u{2139}', - '\u{213c}'..='\u{213f}', '\u{2145}'..='\u{2149}', '\u{214e}'..='\u{214e}', - '\u{2160}'..='\u{217f}', '\u{2183}'..='\u{2184}', '\u{24b6}'..='\u{24e9}', - '\u{2c00}'..='\u{2ce4}', '\u{2ceb}'..='\u{2cee}', '\u{2cf2}'..='\u{2cf3}', - '\u{2d00}'..='\u{2d25}', '\u{2d27}'..='\u{2d27}', '\u{2d2d}'..='\u{2d2d}', - '\u{a640}'..='\u{a66d}', '\u{a680}'..='\u{a69d}', '\u{a722}'..='\u{a787}', - '\u{a78b}'..='\u{a78e}', '\u{a790}'..='\u{a7dc}', '\u{a7f1}'..='\u{a7f6}', - '\u{a7f8}'..='\u{a7fa}', '\u{ab30}'..='\u{ab5a}', '\u{ab5c}'..='\u{ab69}', - '\u{ab70}'..='\u{abbf}', '\u{fb00}'..='\u{fb06}', '\u{fb13}'..='\u{fb17}', - '\u{ff21}'..='\u{ff3a}', '\u{ff41}'..='\u{ff5a}', '\u{10400}'..='\u{1044f}', - '\u{104b0}'..='\u{104d3}', '\u{104d8}'..='\u{104fb}', '\u{10570}'..='\u{1057a}', - '\u{1057c}'..='\u{1058a}', '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', - '\u{10597}'..='\u{105a1}', '\u{105a3}'..='\u{105b1}', '\u{105b3}'..='\u{105b9}', - '\u{105bb}'..='\u{105bc}', '\u{10780}'..='\u{10780}', '\u{10783}'..='\u{10785}', - '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', '\u{10c80}'..='\u{10cb2}', - '\u{10cc0}'..='\u{10cf2}', '\u{10d50}'..='\u{10d65}', '\u{10d70}'..='\u{10d85}', - '\u{118a0}'..='\u{118df}', '\u{16e40}'..='\u{16e7f}', '\u{16ea0}'..='\u{16eb8}', - '\u{16ebb}'..='\u{16ed3}', '\u{1d400}'..='\u{1d454}', '\u{1d456}'..='\u{1d49c}', - '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', '\u{1d4a5}'..='\u{1d4a6}', - '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b9}', '\u{1d4bb}'..='\u{1d4bb}', - '\u{1d4bd}'..='\u{1d4c3}', '\u{1d4c5}'..='\u{1d505}', '\u{1d507}'..='\u{1d50a}', - '\u{1d50d}'..='\u{1d514}', '\u{1d516}'..='\u{1d51c}', '\u{1d51e}'..='\u{1d539}', - '\u{1d53b}'..='\u{1d53e}', '\u{1d540}'..='\u{1d544}', '\u{1d546}'..='\u{1d546}', - '\u{1d54a}'..='\u{1d550}', '\u{1d552}'..='\u{1d6a5}', '\u{1d6a8}'..='\u{1d6c0}', - '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6fa}', '\u{1d6fc}'..='\u{1d714}', - '\u{1d716}'..='\u{1d734}', '\u{1d736}'..='\u{1d74e}', '\u{1d750}'..='\u{1d76e}', - '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d7a8}', '\u{1d7aa}'..='\u{1d7c2}', - '\u{1d7c4}'..='\u{1d7cb}', '\u{1df00}'..='\u{1df09}', '\u{1df0b}'..='\u{1df1e}', - '\u{1df25}'..='\u{1df2a}', '\u{1e030}'..='\u{1e06d}', '\u{1e900}'..='\u{1e943}', - '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', '\u{1f170}'..='\u{1f189}', -]; - -#[rustfmt::skip] -pub(super) static GRAPHEME_EXTEND: &[RangeInclusive; 383] = &[ - '\u{300}'..='\u{36f}', '\u{483}'..='\u{489}', '\u{591}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', - '\u{5c1}'..='\u{5c2}', '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{610}'..='\u{61a}', - '\u{64b}'..='\u{65f}', '\u{670}'..='\u{670}', '\u{6d6}'..='\u{6dc}', '\u{6df}'..='\u{6e4}', - '\u{6e7}'..='\u{6e8}', '\u{6ea}'..='\u{6ed}', '\u{711}'..='\u{711}', '\u{730}'..='\u{74a}', - '\u{7a6}'..='\u{7b0}', '\u{7eb}'..='\u{7f3}', '\u{7fd}'..='\u{7fd}', '\u{816}'..='\u{819}', - '\u{81b}'..='\u{823}', '\u{825}'..='\u{827}', '\u{829}'..='\u{82d}', '\u{859}'..='\u{85b}', - '\u{897}'..='\u{89f}', '\u{8ca}'..='\u{8e1}', '\u{8e3}'..='\u{902}', '\u{93a}'..='\u{93a}', - '\u{93c}'..='\u{93c}', '\u{941}'..='\u{948}', '\u{94d}'..='\u{94d}', '\u{951}'..='\u{957}', - '\u{962}'..='\u{963}', '\u{981}'..='\u{981}', '\u{9bc}'..='\u{9bc}', '\u{9be}'..='\u{9be}', - '\u{9c1}'..='\u{9c4}', '\u{9cd}'..='\u{9cd}', '\u{9d7}'..='\u{9d7}', '\u{9e2}'..='\u{9e3}', - '\u{9fe}'..='\u{9fe}', '\u{a01}'..='\u{a02}', '\u{a3c}'..='\u{a3c}', '\u{a41}'..='\u{a42}', - '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4d}', '\u{a51}'..='\u{a51}', '\u{a70}'..='\u{a71}', - '\u{a75}'..='\u{a75}', '\u{a81}'..='\u{a82}', '\u{abc}'..='\u{abc}', '\u{ac1}'..='\u{ac5}', - '\u{ac7}'..='\u{ac8}', '\u{acd}'..='\u{acd}', '\u{ae2}'..='\u{ae3}', '\u{afa}'..='\u{aff}', - '\u{b01}'..='\u{b01}', '\u{b3c}'..='\u{b3c}', '\u{b3e}'..='\u{b3f}', '\u{b41}'..='\u{b44}', - '\u{b4d}'..='\u{b4d}', '\u{b55}'..='\u{b57}', '\u{b62}'..='\u{b63}', '\u{b82}'..='\u{b82}', - '\u{bbe}'..='\u{bbe}', '\u{bc0}'..='\u{bc0}', '\u{bcd}'..='\u{bcd}', '\u{bd7}'..='\u{bd7}', - '\u{c00}'..='\u{c00}', '\u{c04}'..='\u{c04}', '\u{c3c}'..='\u{c3c}', '\u{c3e}'..='\u{c40}', - '\u{c46}'..='\u{c48}', '\u{c4a}'..='\u{c4d}', '\u{c55}'..='\u{c56}', '\u{c62}'..='\u{c63}', - '\u{c81}'..='\u{c81}', '\u{cbc}'..='\u{cbc}', '\u{cbf}'..='\u{cc0}', '\u{cc2}'..='\u{cc2}', - '\u{cc6}'..='\u{cc8}', '\u{cca}'..='\u{ccd}', '\u{cd5}'..='\u{cd6}', '\u{ce2}'..='\u{ce3}', - '\u{d00}'..='\u{d01}', '\u{d3b}'..='\u{d3c}', '\u{d3e}'..='\u{d3e}', '\u{d41}'..='\u{d44}', - '\u{d4d}'..='\u{d4d}', '\u{d57}'..='\u{d57}', '\u{d62}'..='\u{d63}', '\u{d81}'..='\u{d81}', - '\u{dca}'..='\u{dca}', '\u{dcf}'..='\u{dcf}', '\u{dd2}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', - '\u{ddf}'..='\u{ddf}', '\u{e31}'..='\u{e31}', '\u{e34}'..='\u{e3a}', '\u{e47}'..='\u{e4e}', - '\u{eb1}'..='\u{eb1}', '\u{eb4}'..='\u{ebc}', '\u{ec8}'..='\u{ece}', '\u{f18}'..='\u{f19}', - '\u{f35}'..='\u{f35}', '\u{f37}'..='\u{f37}', '\u{f39}'..='\u{f39}', '\u{f71}'..='\u{f7e}', - '\u{f80}'..='\u{f84}', '\u{f86}'..='\u{f87}', '\u{f8d}'..='\u{f97}', '\u{f99}'..='\u{fbc}', - '\u{fc6}'..='\u{fc6}', '\u{102d}'..='\u{1030}', '\u{1032}'..='\u{1037}', - '\u{1039}'..='\u{103a}', '\u{103d}'..='\u{103e}', '\u{1058}'..='\u{1059}', - '\u{105e}'..='\u{1060}', '\u{1071}'..='\u{1074}', '\u{1082}'..='\u{1082}', - '\u{1085}'..='\u{1086}', '\u{108d}'..='\u{108d}', '\u{109d}'..='\u{109d}', - '\u{135d}'..='\u{135f}', '\u{1712}'..='\u{1715}', '\u{1732}'..='\u{1734}', - '\u{1752}'..='\u{1753}', '\u{1772}'..='\u{1773}', '\u{17b4}'..='\u{17b5}', - '\u{17b7}'..='\u{17bd}', '\u{17c6}'..='\u{17c6}', '\u{17c9}'..='\u{17d3}', - '\u{17dd}'..='\u{17dd}', '\u{180b}'..='\u{180d}', '\u{180f}'..='\u{180f}', - '\u{1885}'..='\u{1886}', '\u{18a9}'..='\u{18a9}', '\u{1920}'..='\u{1922}', - '\u{1927}'..='\u{1928}', '\u{1932}'..='\u{1932}', '\u{1939}'..='\u{193b}', - '\u{1a17}'..='\u{1a18}', '\u{1a1b}'..='\u{1a1b}', '\u{1a56}'..='\u{1a56}', - '\u{1a58}'..='\u{1a5e}', '\u{1a60}'..='\u{1a60}', '\u{1a62}'..='\u{1a62}', - '\u{1a65}'..='\u{1a6c}', '\u{1a73}'..='\u{1a7c}', '\u{1a7f}'..='\u{1a7f}', - '\u{1ab0}'..='\u{1add}', '\u{1ae0}'..='\u{1aeb}', '\u{1b00}'..='\u{1b03}', - '\u{1b34}'..='\u{1b3d}', '\u{1b42}'..='\u{1b44}', '\u{1b6b}'..='\u{1b73}', - '\u{1b80}'..='\u{1b81}', '\u{1ba2}'..='\u{1ba5}', '\u{1ba8}'..='\u{1bad}', - '\u{1be6}'..='\u{1be6}', '\u{1be8}'..='\u{1be9}', '\u{1bed}'..='\u{1bed}', - '\u{1bef}'..='\u{1bf3}', '\u{1c2c}'..='\u{1c33}', '\u{1c36}'..='\u{1c37}', - '\u{1cd0}'..='\u{1cd2}', '\u{1cd4}'..='\u{1ce0}', '\u{1ce2}'..='\u{1ce8}', - '\u{1ced}'..='\u{1ced}', '\u{1cf4}'..='\u{1cf4}', '\u{1cf8}'..='\u{1cf9}', - '\u{1dc0}'..='\u{1dff}', '\u{200c}'..='\u{200c}', '\u{20d0}'..='\u{20f0}', - '\u{2cef}'..='\u{2cf1}', '\u{2d7f}'..='\u{2d7f}', '\u{2de0}'..='\u{2dff}', - '\u{302a}'..='\u{302f}', '\u{3099}'..='\u{309a}', '\u{a66f}'..='\u{a672}', - '\u{a674}'..='\u{a67d}', '\u{a69e}'..='\u{a69f}', '\u{a6f0}'..='\u{a6f1}', - '\u{a802}'..='\u{a802}', '\u{a806}'..='\u{a806}', '\u{a80b}'..='\u{a80b}', - '\u{a825}'..='\u{a826}', '\u{a82c}'..='\u{a82c}', '\u{a8c4}'..='\u{a8c5}', - '\u{a8e0}'..='\u{a8f1}', '\u{a8ff}'..='\u{a8ff}', '\u{a926}'..='\u{a92d}', - '\u{a947}'..='\u{a951}', '\u{a953}'..='\u{a953}', '\u{a980}'..='\u{a982}', - '\u{a9b3}'..='\u{a9b3}', '\u{a9b6}'..='\u{a9b9}', '\u{a9bc}'..='\u{a9bd}', - '\u{a9c0}'..='\u{a9c0}', '\u{a9e5}'..='\u{a9e5}', '\u{aa29}'..='\u{aa2e}', - '\u{aa31}'..='\u{aa32}', '\u{aa35}'..='\u{aa36}', '\u{aa43}'..='\u{aa43}', - '\u{aa4c}'..='\u{aa4c}', '\u{aa7c}'..='\u{aa7c}', '\u{aab0}'..='\u{aab0}', - '\u{aab2}'..='\u{aab4}', '\u{aab7}'..='\u{aab8}', '\u{aabe}'..='\u{aabf}', - '\u{aac1}'..='\u{aac1}', '\u{aaec}'..='\u{aaed}', '\u{aaf6}'..='\u{aaf6}', - '\u{abe5}'..='\u{abe5}', '\u{abe8}'..='\u{abe8}', '\u{abed}'..='\u{abed}', - '\u{fb1e}'..='\u{fb1e}', '\u{fe00}'..='\u{fe0f}', '\u{fe20}'..='\u{fe2f}', - '\u{ff9e}'..='\u{ff9f}', '\u{101fd}'..='\u{101fd}', '\u{102e0}'..='\u{102e0}', - '\u{10376}'..='\u{1037a}', '\u{10a01}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', - '\u{10a0c}'..='\u{10a0f}', '\u{10a38}'..='\u{10a3a}', '\u{10a3f}'..='\u{10a3f}', - '\u{10ae5}'..='\u{10ae6}', '\u{10d24}'..='\u{10d27}', '\u{10d69}'..='\u{10d6d}', - '\u{10eab}'..='\u{10eac}', '\u{10efa}'..='\u{10eff}', '\u{10f46}'..='\u{10f50}', - '\u{10f82}'..='\u{10f85}', '\u{11001}'..='\u{11001}', '\u{11038}'..='\u{11046}', - '\u{11070}'..='\u{11070}', '\u{11073}'..='\u{11074}', '\u{1107f}'..='\u{11081}', - '\u{110b3}'..='\u{110b6}', '\u{110b9}'..='\u{110ba}', '\u{110c2}'..='\u{110c2}', - '\u{11100}'..='\u{11102}', '\u{11127}'..='\u{1112b}', '\u{1112d}'..='\u{11134}', - '\u{11173}'..='\u{11173}', '\u{11180}'..='\u{11181}', '\u{111b6}'..='\u{111be}', - '\u{111c0}'..='\u{111c0}', '\u{111c9}'..='\u{111cc}', '\u{111cf}'..='\u{111cf}', - '\u{1122f}'..='\u{11231}', '\u{11234}'..='\u{11237}', '\u{1123e}'..='\u{1123e}', - '\u{11241}'..='\u{11241}', '\u{112df}'..='\u{112df}', '\u{112e3}'..='\u{112ea}', - '\u{11300}'..='\u{11301}', '\u{1133b}'..='\u{1133c}', '\u{1133e}'..='\u{1133e}', - '\u{11340}'..='\u{11340}', '\u{1134d}'..='\u{1134d}', '\u{11357}'..='\u{11357}', - '\u{11366}'..='\u{1136c}', '\u{11370}'..='\u{11374}', '\u{113b8}'..='\u{113b8}', - '\u{113bb}'..='\u{113c0}', '\u{113c2}'..='\u{113c2}', '\u{113c5}'..='\u{113c5}', - '\u{113c7}'..='\u{113c9}', '\u{113ce}'..='\u{113d0}', '\u{113d2}'..='\u{113d2}', - '\u{113e1}'..='\u{113e2}', '\u{11438}'..='\u{1143f}', '\u{11442}'..='\u{11444}', - '\u{11446}'..='\u{11446}', '\u{1145e}'..='\u{1145e}', '\u{114b0}'..='\u{114b0}', - '\u{114b3}'..='\u{114b8}', '\u{114ba}'..='\u{114ba}', '\u{114bd}'..='\u{114bd}', - '\u{114bf}'..='\u{114c0}', '\u{114c2}'..='\u{114c3}', '\u{115af}'..='\u{115af}', - '\u{115b2}'..='\u{115b5}', '\u{115bc}'..='\u{115bd}', '\u{115bf}'..='\u{115c0}', - '\u{115dc}'..='\u{115dd}', '\u{11633}'..='\u{1163a}', '\u{1163d}'..='\u{1163d}', - '\u{1163f}'..='\u{11640}', '\u{116ab}'..='\u{116ab}', '\u{116ad}'..='\u{116ad}', - '\u{116b0}'..='\u{116b7}', '\u{1171d}'..='\u{1171d}', '\u{1171f}'..='\u{1171f}', - '\u{11722}'..='\u{11725}', '\u{11727}'..='\u{1172b}', '\u{1182f}'..='\u{11837}', - '\u{11839}'..='\u{1183a}', '\u{11930}'..='\u{11930}', '\u{1193b}'..='\u{1193e}', - '\u{11943}'..='\u{11943}', '\u{119d4}'..='\u{119d7}', '\u{119da}'..='\u{119db}', - '\u{119e0}'..='\u{119e0}', '\u{11a01}'..='\u{11a0a}', '\u{11a33}'..='\u{11a38}', - '\u{11a3b}'..='\u{11a3e}', '\u{11a47}'..='\u{11a47}', '\u{11a51}'..='\u{11a56}', - '\u{11a59}'..='\u{11a5b}', '\u{11a8a}'..='\u{11a96}', '\u{11a98}'..='\u{11a99}', - '\u{11b60}'..='\u{11b60}', '\u{11b62}'..='\u{11b64}', '\u{11b66}'..='\u{11b66}', - '\u{11c30}'..='\u{11c36}', '\u{11c38}'..='\u{11c3d}', '\u{11c3f}'..='\u{11c3f}', - '\u{11c92}'..='\u{11ca7}', '\u{11caa}'..='\u{11cb0}', '\u{11cb2}'..='\u{11cb3}', - '\u{11cb5}'..='\u{11cb6}', '\u{11d31}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', - '\u{11d3c}'..='\u{11d3d}', '\u{11d3f}'..='\u{11d45}', '\u{11d47}'..='\u{11d47}', - '\u{11d90}'..='\u{11d91}', '\u{11d95}'..='\u{11d95}', '\u{11d97}'..='\u{11d97}', - '\u{11ef3}'..='\u{11ef4}', '\u{11f00}'..='\u{11f01}', '\u{11f36}'..='\u{11f3a}', - '\u{11f40}'..='\u{11f42}', '\u{11f5a}'..='\u{11f5a}', '\u{13440}'..='\u{13440}', - '\u{13447}'..='\u{13455}', '\u{1611e}'..='\u{16129}', '\u{1612d}'..='\u{1612f}', - '\u{16af0}'..='\u{16af4}', '\u{16b30}'..='\u{16b36}', '\u{16f4f}'..='\u{16f4f}', - '\u{16f8f}'..='\u{16f92}', '\u{16fe4}'..='\u{16fe4}', '\u{16ff0}'..='\u{16ff1}', - '\u{1bc9d}'..='\u{1bc9e}', '\u{1cf00}'..='\u{1cf2d}', '\u{1cf30}'..='\u{1cf46}', - '\u{1d165}'..='\u{1d169}', '\u{1d16d}'..='\u{1d172}', '\u{1d17b}'..='\u{1d182}', - '\u{1d185}'..='\u{1d18b}', '\u{1d1aa}'..='\u{1d1ad}', '\u{1d242}'..='\u{1d244}', - '\u{1da00}'..='\u{1da36}', '\u{1da3b}'..='\u{1da6c}', '\u{1da75}'..='\u{1da75}', - '\u{1da84}'..='\u{1da84}', '\u{1da9b}'..='\u{1da9f}', '\u{1daa1}'..='\u{1daaf}', - '\u{1e000}'..='\u{1e006}', '\u{1e008}'..='\u{1e018}', '\u{1e01b}'..='\u{1e021}', - '\u{1e023}'..='\u{1e024}', '\u{1e026}'..='\u{1e02a}', '\u{1e08f}'..='\u{1e08f}', - '\u{1e130}'..='\u{1e136}', '\u{1e2ae}'..='\u{1e2ae}', '\u{1e2ec}'..='\u{1e2ef}', - '\u{1e4ec}'..='\u{1e4ef}', '\u{1e5ee}'..='\u{1e5ef}', '\u{1e6e3}'..='\u{1e6e3}', - '\u{1e6e6}'..='\u{1e6e6}', '\u{1e6ee}'..='\u{1e6ef}', '\u{1e6f5}'..='\u{1e6f5}', - '\u{1e8d0}'..='\u{1e8d6}', '\u{1e944}'..='\u{1e94a}', '\u{e0020}'..='\u{e007f}', - '\u{e0100}'..='\u{e01ef}', -]; - -#[rustfmt::skip] -pub(super) static LOWERCASE: &[RangeInclusive; 676] = &[ - '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{df}'..='\u{f6}', - '\u{f8}'..='\u{ff}', '\u{101}'..='\u{101}', '\u{103}'..='\u{103}', '\u{105}'..='\u{105}', - '\u{107}'..='\u{107}', '\u{109}'..='\u{109}', '\u{10b}'..='\u{10b}', '\u{10d}'..='\u{10d}', - '\u{10f}'..='\u{10f}', '\u{111}'..='\u{111}', '\u{113}'..='\u{113}', '\u{115}'..='\u{115}', - '\u{117}'..='\u{117}', '\u{119}'..='\u{119}', '\u{11b}'..='\u{11b}', '\u{11d}'..='\u{11d}', - '\u{11f}'..='\u{11f}', '\u{121}'..='\u{121}', '\u{123}'..='\u{123}', '\u{125}'..='\u{125}', - '\u{127}'..='\u{127}', '\u{129}'..='\u{129}', '\u{12b}'..='\u{12b}', '\u{12d}'..='\u{12d}', - '\u{12f}'..='\u{12f}', '\u{131}'..='\u{131}', '\u{133}'..='\u{133}', '\u{135}'..='\u{135}', - '\u{137}'..='\u{138}', '\u{13a}'..='\u{13a}', '\u{13c}'..='\u{13c}', '\u{13e}'..='\u{13e}', - '\u{140}'..='\u{140}', '\u{142}'..='\u{142}', '\u{144}'..='\u{144}', '\u{146}'..='\u{146}', - '\u{148}'..='\u{149}', '\u{14b}'..='\u{14b}', '\u{14d}'..='\u{14d}', '\u{14f}'..='\u{14f}', - '\u{151}'..='\u{151}', '\u{153}'..='\u{153}', '\u{155}'..='\u{155}', '\u{157}'..='\u{157}', - '\u{159}'..='\u{159}', '\u{15b}'..='\u{15b}', '\u{15d}'..='\u{15d}', '\u{15f}'..='\u{15f}', - '\u{161}'..='\u{161}', '\u{163}'..='\u{163}', '\u{165}'..='\u{165}', '\u{167}'..='\u{167}', - '\u{169}'..='\u{169}', '\u{16b}'..='\u{16b}', '\u{16d}'..='\u{16d}', '\u{16f}'..='\u{16f}', - '\u{171}'..='\u{171}', '\u{173}'..='\u{173}', '\u{175}'..='\u{175}', '\u{177}'..='\u{177}', - '\u{17a}'..='\u{17a}', '\u{17c}'..='\u{17c}', '\u{17e}'..='\u{180}', '\u{183}'..='\u{183}', - '\u{185}'..='\u{185}', '\u{188}'..='\u{188}', '\u{18c}'..='\u{18d}', '\u{192}'..='\u{192}', - '\u{195}'..='\u{195}', '\u{199}'..='\u{19b}', '\u{19e}'..='\u{19e}', '\u{1a1}'..='\u{1a1}', - '\u{1a3}'..='\u{1a3}', '\u{1a5}'..='\u{1a5}', '\u{1a8}'..='\u{1a8}', '\u{1aa}'..='\u{1ab}', - '\u{1ad}'..='\u{1ad}', '\u{1b0}'..='\u{1b0}', '\u{1b4}'..='\u{1b4}', '\u{1b6}'..='\u{1b6}', - '\u{1b9}'..='\u{1ba}', '\u{1bd}'..='\u{1bf}', '\u{1c6}'..='\u{1c6}', '\u{1c9}'..='\u{1c9}', - '\u{1cc}'..='\u{1cc}', '\u{1ce}'..='\u{1ce}', '\u{1d0}'..='\u{1d0}', '\u{1d2}'..='\u{1d2}', - '\u{1d4}'..='\u{1d4}', '\u{1d6}'..='\u{1d6}', '\u{1d8}'..='\u{1d8}', '\u{1da}'..='\u{1da}', - '\u{1dc}'..='\u{1dd}', '\u{1df}'..='\u{1df}', '\u{1e1}'..='\u{1e1}', '\u{1e3}'..='\u{1e3}', - '\u{1e5}'..='\u{1e5}', '\u{1e7}'..='\u{1e7}', '\u{1e9}'..='\u{1e9}', '\u{1eb}'..='\u{1eb}', - '\u{1ed}'..='\u{1ed}', '\u{1ef}'..='\u{1f0}', '\u{1f3}'..='\u{1f3}', '\u{1f5}'..='\u{1f5}', - '\u{1f9}'..='\u{1f9}', '\u{1fb}'..='\u{1fb}', '\u{1fd}'..='\u{1fd}', '\u{1ff}'..='\u{1ff}', - '\u{201}'..='\u{201}', '\u{203}'..='\u{203}', '\u{205}'..='\u{205}', '\u{207}'..='\u{207}', - '\u{209}'..='\u{209}', '\u{20b}'..='\u{20b}', '\u{20d}'..='\u{20d}', '\u{20f}'..='\u{20f}', - '\u{211}'..='\u{211}', '\u{213}'..='\u{213}', '\u{215}'..='\u{215}', '\u{217}'..='\u{217}', - '\u{219}'..='\u{219}', '\u{21b}'..='\u{21b}', '\u{21d}'..='\u{21d}', '\u{21f}'..='\u{21f}', - '\u{221}'..='\u{221}', '\u{223}'..='\u{223}', '\u{225}'..='\u{225}', '\u{227}'..='\u{227}', - '\u{229}'..='\u{229}', '\u{22b}'..='\u{22b}', '\u{22d}'..='\u{22d}', '\u{22f}'..='\u{22f}', - '\u{231}'..='\u{231}', '\u{233}'..='\u{239}', '\u{23c}'..='\u{23c}', '\u{23f}'..='\u{240}', - '\u{242}'..='\u{242}', '\u{247}'..='\u{247}', '\u{249}'..='\u{249}', '\u{24b}'..='\u{24b}', - '\u{24d}'..='\u{24d}', '\u{24f}'..='\u{293}', '\u{296}'..='\u{2b8}', '\u{2c0}'..='\u{2c1}', - '\u{2e0}'..='\u{2e4}', '\u{345}'..='\u{345}', '\u{371}'..='\u{371}', '\u{373}'..='\u{373}', - '\u{377}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{390}'..='\u{390}', '\u{3ac}'..='\u{3ce}', - '\u{3d0}'..='\u{3d1}', '\u{3d5}'..='\u{3d7}', '\u{3d9}'..='\u{3d9}', '\u{3db}'..='\u{3db}', - '\u{3dd}'..='\u{3dd}', '\u{3df}'..='\u{3df}', '\u{3e1}'..='\u{3e1}', '\u{3e3}'..='\u{3e3}', - '\u{3e5}'..='\u{3e5}', '\u{3e7}'..='\u{3e7}', '\u{3e9}'..='\u{3e9}', '\u{3eb}'..='\u{3eb}', - '\u{3ed}'..='\u{3ed}', '\u{3ef}'..='\u{3f3}', '\u{3f5}'..='\u{3f5}', '\u{3f8}'..='\u{3f8}', - '\u{3fb}'..='\u{3fc}', '\u{430}'..='\u{45f}', '\u{461}'..='\u{461}', '\u{463}'..='\u{463}', - '\u{465}'..='\u{465}', '\u{467}'..='\u{467}', '\u{469}'..='\u{469}', '\u{46b}'..='\u{46b}', - '\u{46d}'..='\u{46d}', '\u{46f}'..='\u{46f}', '\u{471}'..='\u{471}', '\u{473}'..='\u{473}', - '\u{475}'..='\u{475}', '\u{477}'..='\u{477}', '\u{479}'..='\u{479}', '\u{47b}'..='\u{47b}', - '\u{47d}'..='\u{47d}', '\u{47f}'..='\u{47f}', '\u{481}'..='\u{481}', '\u{48b}'..='\u{48b}', - '\u{48d}'..='\u{48d}', '\u{48f}'..='\u{48f}', '\u{491}'..='\u{491}', '\u{493}'..='\u{493}', - '\u{495}'..='\u{495}', '\u{497}'..='\u{497}', '\u{499}'..='\u{499}', '\u{49b}'..='\u{49b}', - '\u{49d}'..='\u{49d}', '\u{49f}'..='\u{49f}', '\u{4a1}'..='\u{4a1}', '\u{4a3}'..='\u{4a3}', - '\u{4a5}'..='\u{4a5}', '\u{4a7}'..='\u{4a7}', '\u{4a9}'..='\u{4a9}', '\u{4ab}'..='\u{4ab}', - '\u{4ad}'..='\u{4ad}', '\u{4af}'..='\u{4af}', '\u{4b1}'..='\u{4b1}', '\u{4b3}'..='\u{4b3}', - '\u{4b5}'..='\u{4b5}', '\u{4b7}'..='\u{4b7}', '\u{4b9}'..='\u{4b9}', '\u{4bb}'..='\u{4bb}', - '\u{4bd}'..='\u{4bd}', '\u{4bf}'..='\u{4bf}', '\u{4c2}'..='\u{4c2}', '\u{4c4}'..='\u{4c4}', - '\u{4c6}'..='\u{4c6}', '\u{4c8}'..='\u{4c8}', '\u{4ca}'..='\u{4ca}', '\u{4cc}'..='\u{4cc}', - '\u{4ce}'..='\u{4cf}', '\u{4d1}'..='\u{4d1}', '\u{4d3}'..='\u{4d3}', '\u{4d5}'..='\u{4d5}', - '\u{4d7}'..='\u{4d7}', '\u{4d9}'..='\u{4d9}', '\u{4db}'..='\u{4db}', '\u{4dd}'..='\u{4dd}', - '\u{4df}'..='\u{4df}', '\u{4e1}'..='\u{4e1}', '\u{4e3}'..='\u{4e3}', '\u{4e5}'..='\u{4e5}', - '\u{4e7}'..='\u{4e7}', '\u{4e9}'..='\u{4e9}', '\u{4eb}'..='\u{4eb}', '\u{4ed}'..='\u{4ed}', - '\u{4ef}'..='\u{4ef}', '\u{4f1}'..='\u{4f1}', '\u{4f3}'..='\u{4f3}', '\u{4f5}'..='\u{4f5}', - '\u{4f7}'..='\u{4f7}', '\u{4f9}'..='\u{4f9}', '\u{4fb}'..='\u{4fb}', '\u{4fd}'..='\u{4fd}', - '\u{4ff}'..='\u{4ff}', '\u{501}'..='\u{501}', '\u{503}'..='\u{503}', '\u{505}'..='\u{505}', - '\u{507}'..='\u{507}', '\u{509}'..='\u{509}', '\u{50b}'..='\u{50b}', '\u{50d}'..='\u{50d}', - '\u{50f}'..='\u{50f}', '\u{511}'..='\u{511}', '\u{513}'..='\u{513}', '\u{515}'..='\u{515}', - '\u{517}'..='\u{517}', '\u{519}'..='\u{519}', '\u{51b}'..='\u{51b}', '\u{51d}'..='\u{51d}', - '\u{51f}'..='\u{51f}', '\u{521}'..='\u{521}', '\u{523}'..='\u{523}', '\u{525}'..='\u{525}', - '\u{527}'..='\u{527}', '\u{529}'..='\u{529}', '\u{52b}'..='\u{52b}', '\u{52d}'..='\u{52d}', - '\u{52f}'..='\u{52f}', '\u{560}'..='\u{588}', '\u{10d0}'..='\u{10fa}', - '\u{10fc}'..='\u{10ff}', '\u{13f8}'..='\u{13fd}', '\u{1c80}'..='\u{1c88}', - '\u{1c8a}'..='\u{1c8a}', '\u{1d00}'..='\u{1dbf}', '\u{1e01}'..='\u{1e01}', - '\u{1e03}'..='\u{1e03}', '\u{1e05}'..='\u{1e05}', '\u{1e07}'..='\u{1e07}', - '\u{1e09}'..='\u{1e09}', '\u{1e0b}'..='\u{1e0b}', '\u{1e0d}'..='\u{1e0d}', - '\u{1e0f}'..='\u{1e0f}', '\u{1e11}'..='\u{1e11}', '\u{1e13}'..='\u{1e13}', - '\u{1e15}'..='\u{1e15}', '\u{1e17}'..='\u{1e17}', '\u{1e19}'..='\u{1e19}', - '\u{1e1b}'..='\u{1e1b}', '\u{1e1d}'..='\u{1e1d}', '\u{1e1f}'..='\u{1e1f}', - '\u{1e21}'..='\u{1e21}', '\u{1e23}'..='\u{1e23}', '\u{1e25}'..='\u{1e25}', - '\u{1e27}'..='\u{1e27}', '\u{1e29}'..='\u{1e29}', '\u{1e2b}'..='\u{1e2b}', - '\u{1e2d}'..='\u{1e2d}', '\u{1e2f}'..='\u{1e2f}', '\u{1e31}'..='\u{1e31}', - '\u{1e33}'..='\u{1e33}', '\u{1e35}'..='\u{1e35}', '\u{1e37}'..='\u{1e37}', - '\u{1e39}'..='\u{1e39}', '\u{1e3b}'..='\u{1e3b}', '\u{1e3d}'..='\u{1e3d}', - '\u{1e3f}'..='\u{1e3f}', '\u{1e41}'..='\u{1e41}', '\u{1e43}'..='\u{1e43}', - '\u{1e45}'..='\u{1e45}', '\u{1e47}'..='\u{1e47}', '\u{1e49}'..='\u{1e49}', - '\u{1e4b}'..='\u{1e4b}', '\u{1e4d}'..='\u{1e4d}', '\u{1e4f}'..='\u{1e4f}', - '\u{1e51}'..='\u{1e51}', '\u{1e53}'..='\u{1e53}', '\u{1e55}'..='\u{1e55}', - '\u{1e57}'..='\u{1e57}', '\u{1e59}'..='\u{1e59}', '\u{1e5b}'..='\u{1e5b}', - '\u{1e5d}'..='\u{1e5d}', '\u{1e5f}'..='\u{1e5f}', '\u{1e61}'..='\u{1e61}', - '\u{1e63}'..='\u{1e63}', '\u{1e65}'..='\u{1e65}', '\u{1e67}'..='\u{1e67}', - '\u{1e69}'..='\u{1e69}', '\u{1e6b}'..='\u{1e6b}', '\u{1e6d}'..='\u{1e6d}', - '\u{1e6f}'..='\u{1e6f}', '\u{1e71}'..='\u{1e71}', '\u{1e73}'..='\u{1e73}', - '\u{1e75}'..='\u{1e75}', '\u{1e77}'..='\u{1e77}', '\u{1e79}'..='\u{1e79}', - '\u{1e7b}'..='\u{1e7b}', '\u{1e7d}'..='\u{1e7d}', '\u{1e7f}'..='\u{1e7f}', - '\u{1e81}'..='\u{1e81}', '\u{1e83}'..='\u{1e83}', '\u{1e85}'..='\u{1e85}', - '\u{1e87}'..='\u{1e87}', '\u{1e89}'..='\u{1e89}', '\u{1e8b}'..='\u{1e8b}', - '\u{1e8d}'..='\u{1e8d}', '\u{1e8f}'..='\u{1e8f}', '\u{1e91}'..='\u{1e91}', - '\u{1e93}'..='\u{1e93}', '\u{1e95}'..='\u{1e9d}', '\u{1e9f}'..='\u{1e9f}', - '\u{1ea1}'..='\u{1ea1}', '\u{1ea3}'..='\u{1ea3}', '\u{1ea5}'..='\u{1ea5}', - '\u{1ea7}'..='\u{1ea7}', '\u{1ea9}'..='\u{1ea9}', '\u{1eab}'..='\u{1eab}', - '\u{1ead}'..='\u{1ead}', '\u{1eaf}'..='\u{1eaf}', '\u{1eb1}'..='\u{1eb1}', - '\u{1eb3}'..='\u{1eb3}', '\u{1eb5}'..='\u{1eb5}', '\u{1eb7}'..='\u{1eb7}', - '\u{1eb9}'..='\u{1eb9}', '\u{1ebb}'..='\u{1ebb}', '\u{1ebd}'..='\u{1ebd}', - '\u{1ebf}'..='\u{1ebf}', '\u{1ec1}'..='\u{1ec1}', '\u{1ec3}'..='\u{1ec3}', - '\u{1ec5}'..='\u{1ec5}', '\u{1ec7}'..='\u{1ec7}', '\u{1ec9}'..='\u{1ec9}', - '\u{1ecb}'..='\u{1ecb}', '\u{1ecd}'..='\u{1ecd}', '\u{1ecf}'..='\u{1ecf}', - '\u{1ed1}'..='\u{1ed1}', '\u{1ed3}'..='\u{1ed3}', '\u{1ed5}'..='\u{1ed5}', - '\u{1ed7}'..='\u{1ed7}', '\u{1ed9}'..='\u{1ed9}', '\u{1edb}'..='\u{1edb}', - '\u{1edd}'..='\u{1edd}', '\u{1edf}'..='\u{1edf}', '\u{1ee1}'..='\u{1ee1}', - '\u{1ee3}'..='\u{1ee3}', '\u{1ee5}'..='\u{1ee5}', '\u{1ee7}'..='\u{1ee7}', - '\u{1ee9}'..='\u{1ee9}', '\u{1eeb}'..='\u{1eeb}', '\u{1eed}'..='\u{1eed}', - '\u{1eef}'..='\u{1eef}', '\u{1ef1}'..='\u{1ef1}', '\u{1ef3}'..='\u{1ef3}', - '\u{1ef5}'..='\u{1ef5}', '\u{1ef7}'..='\u{1ef7}', '\u{1ef9}'..='\u{1ef9}', - '\u{1efb}'..='\u{1efb}', '\u{1efd}'..='\u{1efd}', '\u{1eff}'..='\u{1f07}', - '\u{1f10}'..='\u{1f15}', '\u{1f20}'..='\u{1f27}', '\u{1f30}'..='\u{1f37}', - '\u{1f40}'..='\u{1f45}', '\u{1f50}'..='\u{1f57}', '\u{1f60}'..='\u{1f67}', - '\u{1f70}'..='\u{1f7d}', '\u{1f80}'..='\u{1f87}', '\u{1f90}'..='\u{1f97}', - '\u{1fa0}'..='\u{1fa7}', '\u{1fb0}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fb7}', - '\u{1fbe}'..='\u{1fbe}', '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fc7}', - '\u{1fd0}'..='\u{1fd3}', '\u{1fd6}'..='\u{1fd7}', '\u{1fe0}'..='\u{1fe7}', - '\u{1ff2}'..='\u{1ff4}', '\u{1ff6}'..='\u{1ff7}', '\u{2071}'..='\u{2071}', - '\u{207f}'..='\u{207f}', '\u{2090}'..='\u{209c}', '\u{210a}'..='\u{210a}', - '\u{210e}'..='\u{210f}', '\u{2113}'..='\u{2113}', '\u{212f}'..='\u{212f}', - '\u{2134}'..='\u{2134}', '\u{2139}'..='\u{2139}', '\u{213c}'..='\u{213d}', - '\u{2146}'..='\u{2149}', '\u{214e}'..='\u{214e}', '\u{2170}'..='\u{217f}', - '\u{2184}'..='\u{2184}', '\u{24d0}'..='\u{24e9}', '\u{2c30}'..='\u{2c5f}', - '\u{2c61}'..='\u{2c61}', '\u{2c65}'..='\u{2c66}', '\u{2c68}'..='\u{2c68}', - '\u{2c6a}'..='\u{2c6a}', '\u{2c6c}'..='\u{2c6c}', '\u{2c71}'..='\u{2c71}', - '\u{2c73}'..='\u{2c74}', '\u{2c76}'..='\u{2c7d}', '\u{2c81}'..='\u{2c81}', - '\u{2c83}'..='\u{2c83}', '\u{2c85}'..='\u{2c85}', '\u{2c87}'..='\u{2c87}', - '\u{2c89}'..='\u{2c89}', '\u{2c8b}'..='\u{2c8b}', '\u{2c8d}'..='\u{2c8d}', - '\u{2c8f}'..='\u{2c8f}', '\u{2c91}'..='\u{2c91}', '\u{2c93}'..='\u{2c93}', - '\u{2c95}'..='\u{2c95}', '\u{2c97}'..='\u{2c97}', '\u{2c99}'..='\u{2c99}', - '\u{2c9b}'..='\u{2c9b}', '\u{2c9d}'..='\u{2c9d}', '\u{2c9f}'..='\u{2c9f}', - '\u{2ca1}'..='\u{2ca1}', '\u{2ca3}'..='\u{2ca3}', '\u{2ca5}'..='\u{2ca5}', - '\u{2ca7}'..='\u{2ca7}', '\u{2ca9}'..='\u{2ca9}', '\u{2cab}'..='\u{2cab}', - '\u{2cad}'..='\u{2cad}', '\u{2caf}'..='\u{2caf}', '\u{2cb1}'..='\u{2cb1}', - '\u{2cb3}'..='\u{2cb3}', '\u{2cb5}'..='\u{2cb5}', '\u{2cb7}'..='\u{2cb7}', - '\u{2cb9}'..='\u{2cb9}', '\u{2cbb}'..='\u{2cbb}', '\u{2cbd}'..='\u{2cbd}', - '\u{2cbf}'..='\u{2cbf}', '\u{2cc1}'..='\u{2cc1}', '\u{2cc3}'..='\u{2cc3}', - '\u{2cc5}'..='\u{2cc5}', '\u{2cc7}'..='\u{2cc7}', '\u{2cc9}'..='\u{2cc9}', - '\u{2ccb}'..='\u{2ccb}', '\u{2ccd}'..='\u{2ccd}', '\u{2ccf}'..='\u{2ccf}', - '\u{2cd1}'..='\u{2cd1}', '\u{2cd3}'..='\u{2cd3}', '\u{2cd5}'..='\u{2cd5}', - '\u{2cd7}'..='\u{2cd7}', '\u{2cd9}'..='\u{2cd9}', '\u{2cdb}'..='\u{2cdb}', - '\u{2cdd}'..='\u{2cdd}', '\u{2cdf}'..='\u{2cdf}', '\u{2ce1}'..='\u{2ce1}', - '\u{2ce3}'..='\u{2ce4}', '\u{2cec}'..='\u{2cec}', '\u{2cee}'..='\u{2cee}', - '\u{2cf3}'..='\u{2cf3}', '\u{2d00}'..='\u{2d25}', '\u{2d27}'..='\u{2d27}', - '\u{2d2d}'..='\u{2d2d}', '\u{a641}'..='\u{a641}', '\u{a643}'..='\u{a643}', - '\u{a645}'..='\u{a645}', '\u{a647}'..='\u{a647}', '\u{a649}'..='\u{a649}', - '\u{a64b}'..='\u{a64b}', '\u{a64d}'..='\u{a64d}', '\u{a64f}'..='\u{a64f}', - '\u{a651}'..='\u{a651}', '\u{a653}'..='\u{a653}', '\u{a655}'..='\u{a655}', - '\u{a657}'..='\u{a657}', '\u{a659}'..='\u{a659}', '\u{a65b}'..='\u{a65b}', - '\u{a65d}'..='\u{a65d}', '\u{a65f}'..='\u{a65f}', '\u{a661}'..='\u{a661}', - '\u{a663}'..='\u{a663}', '\u{a665}'..='\u{a665}', '\u{a667}'..='\u{a667}', - '\u{a669}'..='\u{a669}', '\u{a66b}'..='\u{a66b}', '\u{a66d}'..='\u{a66d}', - '\u{a681}'..='\u{a681}', '\u{a683}'..='\u{a683}', '\u{a685}'..='\u{a685}', - '\u{a687}'..='\u{a687}', '\u{a689}'..='\u{a689}', '\u{a68b}'..='\u{a68b}', - '\u{a68d}'..='\u{a68d}', '\u{a68f}'..='\u{a68f}', '\u{a691}'..='\u{a691}', - '\u{a693}'..='\u{a693}', '\u{a695}'..='\u{a695}', '\u{a697}'..='\u{a697}', - '\u{a699}'..='\u{a699}', '\u{a69b}'..='\u{a69d}', '\u{a723}'..='\u{a723}', - '\u{a725}'..='\u{a725}', '\u{a727}'..='\u{a727}', '\u{a729}'..='\u{a729}', - '\u{a72b}'..='\u{a72b}', '\u{a72d}'..='\u{a72d}', '\u{a72f}'..='\u{a731}', - '\u{a733}'..='\u{a733}', '\u{a735}'..='\u{a735}', '\u{a737}'..='\u{a737}', - '\u{a739}'..='\u{a739}', '\u{a73b}'..='\u{a73b}', '\u{a73d}'..='\u{a73d}', - '\u{a73f}'..='\u{a73f}', '\u{a741}'..='\u{a741}', '\u{a743}'..='\u{a743}', - '\u{a745}'..='\u{a745}', '\u{a747}'..='\u{a747}', '\u{a749}'..='\u{a749}', - '\u{a74b}'..='\u{a74b}', '\u{a74d}'..='\u{a74d}', '\u{a74f}'..='\u{a74f}', - '\u{a751}'..='\u{a751}', '\u{a753}'..='\u{a753}', '\u{a755}'..='\u{a755}', - '\u{a757}'..='\u{a757}', '\u{a759}'..='\u{a759}', '\u{a75b}'..='\u{a75b}', - '\u{a75d}'..='\u{a75d}', '\u{a75f}'..='\u{a75f}', '\u{a761}'..='\u{a761}', - '\u{a763}'..='\u{a763}', '\u{a765}'..='\u{a765}', '\u{a767}'..='\u{a767}', - '\u{a769}'..='\u{a769}', '\u{a76b}'..='\u{a76b}', '\u{a76d}'..='\u{a76d}', - '\u{a76f}'..='\u{a778}', '\u{a77a}'..='\u{a77a}', '\u{a77c}'..='\u{a77c}', - '\u{a77f}'..='\u{a77f}', '\u{a781}'..='\u{a781}', '\u{a783}'..='\u{a783}', - '\u{a785}'..='\u{a785}', '\u{a787}'..='\u{a787}', '\u{a78c}'..='\u{a78c}', - '\u{a78e}'..='\u{a78e}', '\u{a791}'..='\u{a791}', '\u{a793}'..='\u{a795}', - '\u{a797}'..='\u{a797}', '\u{a799}'..='\u{a799}', '\u{a79b}'..='\u{a79b}', - '\u{a79d}'..='\u{a79d}', '\u{a79f}'..='\u{a79f}', '\u{a7a1}'..='\u{a7a1}', - '\u{a7a3}'..='\u{a7a3}', '\u{a7a5}'..='\u{a7a5}', '\u{a7a7}'..='\u{a7a7}', - '\u{a7a9}'..='\u{a7a9}', '\u{a7af}'..='\u{a7af}', '\u{a7b5}'..='\u{a7b5}', - '\u{a7b7}'..='\u{a7b7}', '\u{a7b9}'..='\u{a7b9}', '\u{a7bb}'..='\u{a7bb}', - '\u{a7bd}'..='\u{a7bd}', '\u{a7bf}'..='\u{a7bf}', '\u{a7c1}'..='\u{a7c1}', - '\u{a7c3}'..='\u{a7c3}', '\u{a7c8}'..='\u{a7c8}', '\u{a7ca}'..='\u{a7ca}', - '\u{a7cd}'..='\u{a7cd}', '\u{a7cf}'..='\u{a7cf}', '\u{a7d1}'..='\u{a7d1}', - '\u{a7d3}'..='\u{a7d3}', '\u{a7d5}'..='\u{a7d5}', '\u{a7d7}'..='\u{a7d7}', - '\u{a7d9}'..='\u{a7d9}', '\u{a7db}'..='\u{a7db}', '\u{a7f1}'..='\u{a7f4}', - '\u{a7f6}'..='\u{a7f6}', '\u{a7f8}'..='\u{a7fa}', '\u{ab30}'..='\u{ab5a}', - '\u{ab5c}'..='\u{ab69}', '\u{ab70}'..='\u{abbf}', '\u{fb00}'..='\u{fb06}', - '\u{fb13}'..='\u{fb17}', '\u{ff41}'..='\u{ff5a}', '\u{10428}'..='\u{1044f}', - '\u{104d8}'..='\u{104fb}', '\u{10597}'..='\u{105a1}', '\u{105a3}'..='\u{105b1}', - '\u{105b3}'..='\u{105b9}', '\u{105bb}'..='\u{105bc}', '\u{10780}'..='\u{10780}', - '\u{10783}'..='\u{10785}', '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', - '\u{10cc0}'..='\u{10cf2}', '\u{10d70}'..='\u{10d85}', '\u{118c0}'..='\u{118df}', - '\u{16e60}'..='\u{16e7f}', '\u{16ebb}'..='\u{16ed3}', '\u{1d41a}'..='\u{1d433}', - '\u{1d44e}'..='\u{1d454}', '\u{1d456}'..='\u{1d467}', '\u{1d482}'..='\u{1d49b}', - '\u{1d4b6}'..='\u{1d4b9}', '\u{1d4bb}'..='\u{1d4bb}', '\u{1d4bd}'..='\u{1d4c3}', - '\u{1d4c5}'..='\u{1d4cf}', '\u{1d4ea}'..='\u{1d503}', '\u{1d51e}'..='\u{1d537}', - '\u{1d552}'..='\u{1d56b}', '\u{1d586}'..='\u{1d59f}', '\u{1d5ba}'..='\u{1d5d3}', - '\u{1d5ee}'..='\u{1d607}', '\u{1d622}'..='\u{1d63b}', '\u{1d656}'..='\u{1d66f}', - '\u{1d68a}'..='\u{1d6a5}', '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6e1}', - '\u{1d6fc}'..='\u{1d714}', '\u{1d716}'..='\u{1d71b}', '\u{1d736}'..='\u{1d74e}', - '\u{1d750}'..='\u{1d755}', '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d78f}', - '\u{1d7aa}'..='\u{1d7c2}', '\u{1d7c4}'..='\u{1d7c9}', '\u{1d7cb}'..='\u{1d7cb}', - '\u{1df00}'..='\u{1df09}', '\u{1df0b}'..='\u{1df1e}', '\u{1df25}'..='\u{1df2a}', - '\u{1e030}'..='\u{1e06d}', '\u{1e922}'..='\u{1e943}', -]; - -#[rustfmt::skip] -pub(super) static N: &[RangeInclusive; 145] = &[ - '\u{b2}'..='\u{b3}', '\u{b9}'..='\u{b9}', '\u{bc}'..='\u{be}', '\u{660}'..='\u{669}', - '\u{6f0}'..='\u{6f9}', '\u{7c0}'..='\u{7c9}', '\u{966}'..='\u{96f}', '\u{9e6}'..='\u{9ef}', - '\u{9f4}'..='\u{9f9}', '\u{a66}'..='\u{a6f}', '\u{ae6}'..='\u{aef}', '\u{b66}'..='\u{b6f}', - '\u{b72}'..='\u{b77}', '\u{be6}'..='\u{bf2}', '\u{c66}'..='\u{c6f}', '\u{c78}'..='\u{c7e}', - '\u{ce6}'..='\u{cef}', '\u{d58}'..='\u{d5e}', '\u{d66}'..='\u{d78}', '\u{de6}'..='\u{def}', - '\u{e50}'..='\u{e59}', '\u{ed0}'..='\u{ed9}', '\u{f20}'..='\u{f33}', - '\u{1040}'..='\u{1049}', '\u{1090}'..='\u{1099}', '\u{1369}'..='\u{137c}', - '\u{16ee}'..='\u{16f0}', '\u{17e0}'..='\u{17e9}', '\u{17f0}'..='\u{17f9}', - '\u{1810}'..='\u{1819}', '\u{1946}'..='\u{194f}', '\u{19d0}'..='\u{19da}', - '\u{1a80}'..='\u{1a89}', '\u{1a90}'..='\u{1a99}', '\u{1b50}'..='\u{1b59}', - '\u{1bb0}'..='\u{1bb9}', '\u{1c40}'..='\u{1c49}', '\u{1c50}'..='\u{1c59}', - '\u{2070}'..='\u{2070}', '\u{2074}'..='\u{2079}', '\u{2080}'..='\u{2089}', - '\u{2150}'..='\u{2182}', '\u{2185}'..='\u{2189}', '\u{2460}'..='\u{249b}', - '\u{24ea}'..='\u{24ff}', '\u{2776}'..='\u{2793}', '\u{2cfd}'..='\u{2cfd}', - '\u{3007}'..='\u{3007}', '\u{3021}'..='\u{3029}', '\u{3038}'..='\u{303a}', - '\u{3192}'..='\u{3195}', '\u{3220}'..='\u{3229}', '\u{3248}'..='\u{324f}', - '\u{3251}'..='\u{325f}', '\u{3280}'..='\u{3289}', '\u{32b1}'..='\u{32bf}', - '\u{a620}'..='\u{a629}', '\u{a6e6}'..='\u{a6ef}', '\u{a830}'..='\u{a835}', - '\u{a8d0}'..='\u{a8d9}', '\u{a900}'..='\u{a909}', '\u{a9d0}'..='\u{a9d9}', - '\u{a9f0}'..='\u{a9f9}', '\u{aa50}'..='\u{aa59}', '\u{abf0}'..='\u{abf9}', - '\u{ff10}'..='\u{ff19}', '\u{10107}'..='\u{10133}', '\u{10140}'..='\u{10178}', - '\u{1018a}'..='\u{1018b}', '\u{102e1}'..='\u{102fb}', '\u{10320}'..='\u{10323}', - '\u{10341}'..='\u{10341}', '\u{1034a}'..='\u{1034a}', '\u{103d1}'..='\u{103d5}', - '\u{104a0}'..='\u{104a9}', '\u{10858}'..='\u{1085f}', '\u{10879}'..='\u{1087f}', - '\u{108a7}'..='\u{108af}', '\u{108fb}'..='\u{108ff}', '\u{10916}'..='\u{1091b}', - '\u{109bc}'..='\u{109bd}', '\u{109c0}'..='\u{109cf}', '\u{109d2}'..='\u{109ff}', - '\u{10a40}'..='\u{10a48}', '\u{10a7d}'..='\u{10a7e}', '\u{10a9d}'..='\u{10a9f}', - '\u{10aeb}'..='\u{10aef}', '\u{10b58}'..='\u{10b5f}', '\u{10b78}'..='\u{10b7f}', - '\u{10ba9}'..='\u{10baf}', '\u{10cfa}'..='\u{10cff}', '\u{10d30}'..='\u{10d39}', - '\u{10d40}'..='\u{10d49}', '\u{10e60}'..='\u{10e7e}', '\u{10f1d}'..='\u{10f26}', - '\u{10f51}'..='\u{10f54}', '\u{10fc5}'..='\u{10fcb}', '\u{11052}'..='\u{1106f}', - '\u{110f0}'..='\u{110f9}', '\u{11136}'..='\u{1113f}', '\u{111d0}'..='\u{111d9}', - '\u{111e1}'..='\u{111f4}', '\u{112f0}'..='\u{112f9}', '\u{11450}'..='\u{11459}', - '\u{114d0}'..='\u{114d9}', '\u{11650}'..='\u{11659}', '\u{116c0}'..='\u{116c9}', - '\u{116d0}'..='\u{116e3}', '\u{11730}'..='\u{1173b}', '\u{118e0}'..='\u{118f2}', - '\u{11950}'..='\u{11959}', '\u{11bf0}'..='\u{11bf9}', '\u{11c50}'..='\u{11c6c}', - '\u{11d50}'..='\u{11d59}', '\u{11da0}'..='\u{11da9}', '\u{11de0}'..='\u{11de9}', - '\u{11f50}'..='\u{11f59}', '\u{11fc0}'..='\u{11fd4}', '\u{12400}'..='\u{1246e}', - '\u{16130}'..='\u{16139}', '\u{16a60}'..='\u{16a69}', '\u{16ac0}'..='\u{16ac9}', - '\u{16b50}'..='\u{16b59}', '\u{16b5b}'..='\u{16b61}', '\u{16d70}'..='\u{16d79}', - '\u{16e80}'..='\u{16e96}', '\u{16ff4}'..='\u{16ff6}', '\u{1ccf0}'..='\u{1ccf9}', - '\u{1d2c0}'..='\u{1d2d3}', '\u{1d2e0}'..='\u{1d2f3}', '\u{1d360}'..='\u{1d378}', - '\u{1d7ce}'..='\u{1d7ff}', '\u{1e140}'..='\u{1e149}', '\u{1e2f0}'..='\u{1e2f9}', - '\u{1e4f0}'..='\u{1e4f9}', '\u{1e5f1}'..='\u{1e5fa}', '\u{1e8c7}'..='\u{1e8cf}', - '\u{1e950}'..='\u{1e959}', '\u{1ec71}'..='\u{1ecab}', '\u{1ecad}'..='\u{1ecaf}', - '\u{1ecb1}'..='\u{1ecb4}', '\u{1ed01}'..='\u{1ed2d}', '\u{1ed2f}'..='\u{1ed3d}', - '\u{1f100}'..='\u{1f10c}', '\u{1fbf0}'..='\u{1fbf9}', -]; - -#[rustfmt::skip] -pub(super) static UPPERCASE: &[RangeInclusive; 659] = &[ - '\u{c0}'..='\u{d6}', '\u{d8}'..='\u{de}', '\u{100}'..='\u{100}', '\u{102}'..='\u{102}', - '\u{104}'..='\u{104}', '\u{106}'..='\u{106}', '\u{108}'..='\u{108}', '\u{10a}'..='\u{10a}', - '\u{10c}'..='\u{10c}', '\u{10e}'..='\u{10e}', '\u{110}'..='\u{110}', '\u{112}'..='\u{112}', - '\u{114}'..='\u{114}', '\u{116}'..='\u{116}', '\u{118}'..='\u{118}', '\u{11a}'..='\u{11a}', - '\u{11c}'..='\u{11c}', '\u{11e}'..='\u{11e}', '\u{120}'..='\u{120}', '\u{122}'..='\u{122}', - '\u{124}'..='\u{124}', '\u{126}'..='\u{126}', '\u{128}'..='\u{128}', '\u{12a}'..='\u{12a}', - '\u{12c}'..='\u{12c}', '\u{12e}'..='\u{12e}', '\u{130}'..='\u{130}', '\u{132}'..='\u{132}', - '\u{134}'..='\u{134}', '\u{136}'..='\u{136}', '\u{139}'..='\u{139}', '\u{13b}'..='\u{13b}', - '\u{13d}'..='\u{13d}', '\u{13f}'..='\u{13f}', '\u{141}'..='\u{141}', '\u{143}'..='\u{143}', - '\u{145}'..='\u{145}', '\u{147}'..='\u{147}', '\u{14a}'..='\u{14a}', '\u{14c}'..='\u{14c}', - '\u{14e}'..='\u{14e}', '\u{150}'..='\u{150}', '\u{152}'..='\u{152}', '\u{154}'..='\u{154}', - '\u{156}'..='\u{156}', '\u{158}'..='\u{158}', '\u{15a}'..='\u{15a}', '\u{15c}'..='\u{15c}', - '\u{15e}'..='\u{15e}', '\u{160}'..='\u{160}', '\u{162}'..='\u{162}', '\u{164}'..='\u{164}', - '\u{166}'..='\u{166}', '\u{168}'..='\u{168}', '\u{16a}'..='\u{16a}', '\u{16c}'..='\u{16c}', - '\u{16e}'..='\u{16e}', '\u{170}'..='\u{170}', '\u{172}'..='\u{172}', '\u{174}'..='\u{174}', - '\u{176}'..='\u{176}', '\u{178}'..='\u{179}', '\u{17b}'..='\u{17b}', '\u{17d}'..='\u{17d}', - '\u{181}'..='\u{182}', '\u{184}'..='\u{184}', '\u{186}'..='\u{187}', '\u{189}'..='\u{18b}', - '\u{18e}'..='\u{191}', '\u{193}'..='\u{194}', '\u{196}'..='\u{198}', '\u{19c}'..='\u{19d}', - '\u{19f}'..='\u{1a0}', '\u{1a2}'..='\u{1a2}', '\u{1a4}'..='\u{1a4}', '\u{1a6}'..='\u{1a7}', - '\u{1a9}'..='\u{1a9}', '\u{1ac}'..='\u{1ac}', '\u{1ae}'..='\u{1af}', '\u{1b1}'..='\u{1b3}', - '\u{1b5}'..='\u{1b5}', '\u{1b7}'..='\u{1b8}', '\u{1bc}'..='\u{1bc}', '\u{1c4}'..='\u{1c4}', - '\u{1c7}'..='\u{1c7}', '\u{1ca}'..='\u{1ca}', '\u{1cd}'..='\u{1cd}', '\u{1cf}'..='\u{1cf}', - '\u{1d1}'..='\u{1d1}', '\u{1d3}'..='\u{1d3}', '\u{1d5}'..='\u{1d5}', '\u{1d7}'..='\u{1d7}', - '\u{1d9}'..='\u{1d9}', '\u{1db}'..='\u{1db}', '\u{1de}'..='\u{1de}', '\u{1e0}'..='\u{1e0}', - '\u{1e2}'..='\u{1e2}', '\u{1e4}'..='\u{1e4}', '\u{1e6}'..='\u{1e6}', '\u{1e8}'..='\u{1e8}', - '\u{1ea}'..='\u{1ea}', '\u{1ec}'..='\u{1ec}', '\u{1ee}'..='\u{1ee}', '\u{1f1}'..='\u{1f1}', - '\u{1f4}'..='\u{1f4}', '\u{1f6}'..='\u{1f8}', '\u{1fa}'..='\u{1fa}', '\u{1fc}'..='\u{1fc}', - '\u{1fe}'..='\u{1fe}', '\u{200}'..='\u{200}', '\u{202}'..='\u{202}', '\u{204}'..='\u{204}', - '\u{206}'..='\u{206}', '\u{208}'..='\u{208}', '\u{20a}'..='\u{20a}', '\u{20c}'..='\u{20c}', - '\u{20e}'..='\u{20e}', '\u{210}'..='\u{210}', '\u{212}'..='\u{212}', '\u{214}'..='\u{214}', - '\u{216}'..='\u{216}', '\u{218}'..='\u{218}', '\u{21a}'..='\u{21a}', '\u{21c}'..='\u{21c}', - '\u{21e}'..='\u{21e}', '\u{220}'..='\u{220}', '\u{222}'..='\u{222}', '\u{224}'..='\u{224}', - '\u{226}'..='\u{226}', '\u{228}'..='\u{228}', '\u{22a}'..='\u{22a}', '\u{22c}'..='\u{22c}', - '\u{22e}'..='\u{22e}', '\u{230}'..='\u{230}', '\u{232}'..='\u{232}', '\u{23a}'..='\u{23b}', - '\u{23d}'..='\u{23e}', '\u{241}'..='\u{241}', '\u{243}'..='\u{246}', '\u{248}'..='\u{248}', - '\u{24a}'..='\u{24a}', '\u{24c}'..='\u{24c}', '\u{24e}'..='\u{24e}', '\u{370}'..='\u{370}', - '\u{372}'..='\u{372}', '\u{376}'..='\u{376}', '\u{37f}'..='\u{37f}', '\u{386}'..='\u{386}', - '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{38f}', '\u{391}'..='\u{3a1}', - '\u{3a3}'..='\u{3ab}', '\u{3cf}'..='\u{3cf}', '\u{3d2}'..='\u{3d4}', '\u{3d8}'..='\u{3d8}', - '\u{3da}'..='\u{3da}', '\u{3dc}'..='\u{3dc}', '\u{3de}'..='\u{3de}', '\u{3e0}'..='\u{3e0}', - '\u{3e2}'..='\u{3e2}', '\u{3e4}'..='\u{3e4}', '\u{3e6}'..='\u{3e6}', '\u{3e8}'..='\u{3e8}', - '\u{3ea}'..='\u{3ea}', '\u{3ec}'..='\u{3ec}', '\u{3ee}'..='\u{3ee}', '\u{3f4}'..='\u{3f4}', - '\u{3f7}'..='\u{3f7}', '\u{3f9}'..='\u{3fa}', '\u{3fd}'..='\u{42f}', '\u{460}'..='\u{460}', - '\u{462}'..='\u{462}', '\u{464}'..='\u{464}', '\u{466}'..='\u{466}', '\u{468}'..='\u{468}', - '\u{46a}'..='\u{46a}', '\u{46c}'..='\u{46c}', '\u{46e}'..='\u{46e}', '\u{470}'..='\u{470}', - '\u{472}'..='\u{472}', '\u{474}'..='\u{474}', '\u{476}'..='\u{476}', '\u{478}'..='\u{478}', - '\u{47a}'..='\u{47a}', '\u{47c}'..='\u{47c}', '\u{47e}'..='\u{47e}', '\u{480}'..='\u{480}', - '\u{48a}'..='\u{48a}', '\u{48c}'..='\u{48c}', '\u{48e}'..='\u{48e}', '\u{490}'..='\u{490}', - '\u{492}'..='\u{492}', '\u{494}'..='\u{494}', '\u{496}'..='\u{496}', '\u{498}'..='\u{498}', - '\u{49a}'..='\u{49a}', '\u{49c}'..='\u{49c}', '\u{49e}'..='\u{49e}', '\u{4a0}'..='\u{4a0}', - '\u{4a2}'..='\u{4a2}', '\u{4a4}'..='\u{4a4}', '\u{4a6}'..='\u{4a6}', '\u{4a8}'..='\u{4a8}', - '\u{4aa}'..='\u{4aa}', '\u{4ac}'..='\u{4ac}', '\u{4ae}'..='\u{4ae}', '\u{4b0}'..='\u{4b0}', - '\u{4b2}'..='\u{4b2}', '\u{4b4}'..='\u{4b4}', '\u{4b6}'..='\u{4b6}', '\u{4b8}'..='\u{4b8}', - '\u{4ba}'..='\u{4ba}', '\u{4bc}'..='\u{4bc}', '\u{4be}'..='\u{4be}', '\u{4c0}'..='\u{4c1}', - '\u{4c3}'..='\u{4c3}', '\u{4c5}'..='\u{4c5}', '\u{4c7}'..='\u{4c7}', '\u{4c9}'..='\u{4c9}', - '\u{4cb}'..='\u{4cb}', '\u{4cd}'..='\u{4cd}', '\u{4d0}'..='\u{4d0}', '\u{4d2}'..='\u{4d2}', - '\u{4d4}'..='\u{4d4}', '\u{4d6}'..='\u{4d6}', '\u{4d8}'..='\u{4d8}', '\u{4da}'..='\u{4da}', - '\u{4dc}'..='\u{4dc}', '\u{4de}'..='\u{4de}', '\u{4e0}'..='\u{4e0}', '\u{4e2}'..='\u{4e2}', - '\u{4e4}'..='\u{4e4}', '\u{4e6}'..='\u{4e6}', '\u{4e8}'..='\u{4e8}', '\u{4ea}'..='\u{4ea}', - '\u{4ec}'..='\u{4ec}', '\u{4ee}'..='\u{4ee}', '\u{4f0}'..='\u{4f0}', '\u{4f2}'..='\u{4f2}', - '\u{4f4}'..='\u{4f4}', '\u{4f6}'..='\u{4f6}', '\u{4f8}'..='\u{4f8}', '\u{4fa}'..='\u{4fa}', - '\u{4fc}'..='\u{4fc}', '\u{4fe}'..='\u{4fe}', '\u{500}'..='\u{500}', '\u{502}'..='\u{502}', - '\u{504}'..='\u{504}', '\u{506}'..='\u{506}', '\u{508}'..='\u{508}', '\u{50a}'..='\u{50a}', - '\u{50c}'..='\u{50c}', '\u{50e}'..='\u{50e}', '\u{510}'..='\u{510}', '\u{512}'..='\u{512}', - '\u{514}'..='\u{514}', '\u{516}'..='\u{516}', '\u{518}'..='\u{518}', '\u{51a}'..='\u{51a}', - '\u{51c}'..='\u{51c}', '\u{51e}'..='\u{51e}', '\u{520}'..='\u{520}', '\u{522}'..='\u{522}', - '\u{524}'..='\u{524}', '\u{526}'..='\u{526}', '\u{528}'..='\u{528}', '\u{52a}'..='\u{52a}', - '\u{52c}'..='\u{52c}', '\u{52e}'..='\u{52e}', '\u{531}'..='\u{556}', - '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', '\u{10cd}'..='\u{10cd}', - '\u{13a0}'..='\u{13f5}', '\u{1c89}'..='\u{1c89}', '\u{1c90}'..='\u{1cba}', - '\u{1cbd}'..='\u{1cbf}', '\u{1e00}'..='\u{1e00}', '\u{1e02}'..='\u{1e02}', - '\u{1e04}'..='\u{1e04}', '\u{1e06}'..='\u{1e06}', '\u{1e08}'..='\u{1e08}', - '\u{1e0a}'..='\u{1e0a}', '\u{1e0c}'..='\u{1e0c}', '\u{1e0e}'..='\u{1e0e}', - '\u{1e10}'..='\u{1e10}', '\u{1e12}'..='\u{1e12}', '\u{1e14}'..='\u{1e14}', - '\u{1e16}'..='\u{1e16}', '\u{1e18}'..='\u{1e18}', '\u{1e1a}'..='\u{1e1a}', - '\u{1e1c}'..='\u{1e1c}', '\u{1e1e}'..='\u{1e1e}', '\u{1e20}'..='\u{1e20}', - '\u{1e22}'..='\u{1e22}', '\u{1e24}'..='\u{1e24}', '\u{1e26}'..='\u{1e26}', - '\u{1e28}'..='\u{1e28}', '\u{1e2a}'..='\u{1e2a}', '\u{1e2c}'..='\u{1e2c}', - '\u{1e2e}'..='\u{1e2e}', '\u{1e30}'..='\u{1e30}', '\u{1e32}'..='\u{1e32}', - '\u{1e34}'..='\u{1e34}', '\u{1e36}'..='\u{1e36}', '\u{1e38}'..='\u{1e38}', - '\u{1e3a}'..='\u{1e3a}', '\u{1e3c}'..='\u{1e3c}', '\u{1e3e}'..='\u{1e3e}', - '\u{1e40}'..='\u{1e40}', '\u{1e42}'..='\u{1e42}', '\u{1e44}'..='\u{1e44}', - '\u{1e46}'..='\u{1e46}', '\u{1e48}'..='\u{1e48}', '\u{1e4a}'..='\u{1e4a}', - '\u{1e4c}'..='\u{1e4c}', '\u{1e4e}'..='\u{1e4e}', '\u{1e50}'..='\u{1e50}', - '\u{1e52}'..='\u{1e52}', '\u{1e54}'..='\u{1e54}', '\u{1e56}'..='\u{1e56}', - '\u{1e58}'..='\u{1e58}', '\u{1e5a}'..='\u{1e5a}', '\u{1e5c}'..='\u{1e5c}', - '\u{1e5e}'..='\u{1e5e}', '\u{1e60}'..='\u{1e60}', '\u{1e62}'..='\u{1e62}', - '\u{1e64}'..='\u{1e64}', '\u{1e66}'..='\u{1e66}', '\u{1e68}'..='\u{1e68}', - '\u{1e6a}'..='\u{1e6a}', '\u{1e6c}'..='\u{1e6c}', '\u{1e6e}'..='\u{1e6e}', - '\u{1e70}'..='\u{1e70}', '\u{1e72}'..='\u{1e72}', '\u{1e74}'..='\u{1e74}', - '\u{1e76}'..='\u{1e76}', '\u{1e78}'..='\u{1e78}', '\u{1e7a}'..='\u{1e7a}', - '\u{1e7c}'..='\u{1e7c}', '\u{1e7e}'..='\u{1e7e}', '\u{1e80}'..='\u{1e80}', - '\u{1e82}'..='\u{1e82}', '\u{1e84}'..='\u{1e84}', '\u{1e86}'..='\u{1e86}', - '\u{1e88}'..='\u{1e88}', '\u{1e8a}'..='\u{1e8a}', '\u{1e8c}'..='\u{1e8c}', - '\u{1e8e}'..='\u{1e8e}', '\u{1e90}'..='\u{1e90}', '\u{1e92}'..='\u{1e92}', - '\u{1e94}'..='\u{1e94}', '\u{1e9e}'..='\u{1e9e}', '\u{1ea0}'..='\u{1ea0}', - '\u{1ea2}'..='\u{1ea2}', '\u{1ea4}'..='\u{1ea4}', '\u{1ea6}'..='\u{1ea6}', - '\u{1ea8}'..='\u{1ea8}', '\u{1eaa}'..='\u{1eaa}', '\u{1eac}'..='\u{1eac}', - '\u{1eae}'..='\u{1eae}', '\u{1eb0}'..='\u{1eb0}', '\u{1eb2}'..='\u{1eb2}', - '\u{1eb4}'..='\u{1eb4}', '\u{1eb6}'..='\u{1eb6}', '\u{1eb8}'..='\u{1eb8}', - '\u{1eba}'..='\u{1eba}', '\u{1ebc}'..='\u{1ebc}', '\u{1ebe}'..='\u{1ebe}', - '\u{1ec0}'..='\u{1ec0}', '\u{1ec2}'..='\u{1ec2}', '\u{1ec4}'..='\u{1ec4}', - '\u{1ec6}'..='\u{1ec6}', '\u{1ec8}'..='\u{1ec8}', '\u{1eca}'..='\u{1eca}', - '\u{1ecc}'..='\u{1ecc}', '\u{1ece}'..='\u{1ece}', '\u{1ed0}'..='\u{1ed0}', - '\u{1ed2}'..='\u{1ed2}', '\u{1ed4}'..='\u{1ed4}', '\u{1ed6}'..='\u{1ed6}', - '\u{1ed8}'..='\u{1ed8}', '\u{1eda}'..='\u{1eda}', '\u{1edc}'..='\u{1edc}', - '\u{1ede}'..='\u{1ede}', '\u{1ee0}'..='\u{1ee0}', '\u{1ee2}'..='\u{1ee2}', - '\u{1ee4}'..='\u{1ee4}', '\u{1ee6}'..='\u{1ee6}', '\u{1ee8}'..='\u{1ee8}', - '\u{1eea}'..='\u{1eea}', '\u{1eec}'..='\u{1eec}', '\u{1eee}'..='\u{1eee}', - '\u{1ef0}'..='\u{1ef0}', '\u{1ef2}'..='\u{1ef2}', '\u{1ef4}'..='\u{1ef4}', - '\u{1ef6}'..='\u{1ef6}', '\u{1ef8}'..='\u{1ef8}', '\u{1efa}'..='\u{1efa}', - '\u{1efc}'..='\u{1efc}', '\u{1efe}'..='\u{1efe}', '\u{1f08}'..='\u{1f0f}', - '\u{1f18}'..='\u{1f1d}', '\u{1f28}'..='\u{1f2f}', '\u{1f38}'..='\u{1f3f}', - '\u{1f48}'..='\u{1f4d}', '\u{1f59}'..='\u{1f59}', '\u{1f5b}'..='\u{1f5b}', - '\u{1f5d}'..='\u{1f5d}', '\u{1f5f}'..='\u{1f5f}', '\u{1f68}'..='\u{1f6f}', - '\u{1fb8}'..='\u{1fbb}', '\u{1fc8}'..='\u{1fcb}', '\u{1fd8}'..='\u{1fdb}', - '\u{1fe8}'..='\u{1fec}', '\u{1ff8}'..='\u{1ffb}', '\u{2102}'..='\u{2102}', - '\u{2107}'..='\u{2107}', '\u{210b}'..='\u{210d}', '\u{2110}'..='\u{2112}', - '\u{2115}'..='\u{2115}', '\u{2119}'..='\u{211d}', '\u{2124}'..='\u{2124}', - '\u{2126}'..='\u{2126}', '\u{2128}'..='\u{2128}', '\u{212a}'..='\u{212d}', - '\u{2130}'..='\u{2133}', '\u{213e}'..='\u{213f}', '\u{2145}'..='\u{2145}', - '\u{2160}'..='\u{216f}', '\u{2183}'..='\u{2183}', '\u{24b6}'..='\u{24cf}', - '\u{2c00}'..='\u{2c2f}', '\u{2c60}'..='\u{2c60}', '\u{2c62}'..='\u{2c64}', - '\u{2c67}'..='\u{2c67}', '\u{2c69}'..='\u{2c69}', '\u{2c6b}'..='\u{2c6b}', - '\u{2c6d}'..='\u{2c70}', '\u{2c72}'..='\u{2c72}', '\u{2c75}'..='\u{2c75}', - '\u{2c7e}'..='\u{2c80}', '\u{2c82}'..='\u{2c82}', '\u{2c84}'..='\u{2c84}', - '\u{2c86}'..='\u{2c86}', '\u{2c88}'..='\u{2c88}', '\u{2c8a}'..='\u{2c8a}', - '\u{2c8c}'..='\u{2c8c}', '\u{2c8e}'..='\u{2c8e}', '\u{2c90}'..='\u{2c90}', - '\u{2c92}'..='\u{2c92}', '\u{2c94}'..='\u{2c94}', '\u{2c96}'..='\u{2c96}', - '\u{2c98}'..='\u{2c98}', '\u{2c9a}'..='\u{2c9a}', '\u{2c9c}'..='\u{2c9c}', - '\u{2c9e}'..='\u{2c9e}', '\u{2ca0}'..='\u{2ca0}', '\u{2ca2}'..='\u{2ca2}', - '\u{2ca4}'..='\u{2ca4}', '\u{2ca6}'..='\u{2ca6}', '\u{2ca8}'..='\u{2ca8}', - '\u{2caa}'..='\u{2caa}', '\u{2cac}'..='\u{2cac}', '\u{2cae}'..='\u{2cae}', - '\u{2cb0}'..='\u{2cb0}', '\u{2cb2}'..='\u{2cb2}', '\u{2cb4}'..='\u{2cb4}', - '\u{2cb6}'..='\u{2cb6}', '\u{2cb8}'..='\u{2cb8}', '\u{2cba}'..='\u{2cba}', - '\u{2cbc}'..='\u{2cbc}', '\u{2cbe}'..='\u{2cbe}', '\u{2cc0}'..='\u{2cc0}', - '\u{2cc2}'..='\u{2cc2}', '\u{2cc4}'..='\u{2cc4}', '\u{2cc6}'..='\u{2cc6}', - '\u{2cc8}'..='\u{2cc8}', '\u{2cca}'..='\u{2cca}', '\u{2ccc}'..='\u{2ccc}', - '\u{2cce}'..='\u{2cce}', '\u{2cd0}'..='\u{2cd0}', '\u{2cd2}'..='\u{2cd2}', - '\u{2cd4}'..='\u{2cd4}', '\u{2cd6}'..='\u{2cd6}', '\u{2cd8}'..='\u{2cd8}', - '\u{2cda}'..='\u{2cda}', '\u{2cdc}'..='\u{2cdc}', '\u{2cde}'..='\u{2cde}', - '\u{2ce0}'..='\u{2ce0}', '\u{2ce2}'..='\u{2ce2}', '\u{2ceb}'..='\u{2ceb}', - '\u{2ced}'..='\u{2ced}', '\u{2cf2}'..='\u{2cf2}', '\u{a640}'..='\u{a640}', - '\u{a642}'..='\u{a642}', '\u{a644}'..='\u{a644}', '\u{a646}'..='\u{a646}', - '\u{a648}'..='\u{a648}', '\u{a64a}'..='\u{a64a}', '\u{a64c}'..='\u{a64c}', - '\u{a64e}'..='\u{a64e}', '\u{a650}'..='\u{a650}', '\u{a652}'..='\u{a652}', - '\u{a654}'..='\u{a654}', '\u{a656}'..='\u{a656}', '\u{a658}'..='\u{a658}', - '\u{a65a}'..='\u{a65a}', '\u{a65c}'..='\u{a65c}', '\u{a65e}'..='\u{a65e}', - '\u{a660}'..='\u{a660}', '\u{a662}'..='\u{a662}', '\u{a664}'..='\u{a664}', - '\u{a666}'..='\u{a666}', '\u{a668}'..='\u{a668}', '\u{a66a}'..='\u{a66a}', - '\u{a66c}'..='\u{a66c}', '\u{a680}'..='\u{a680}', '\u{a682}'..='\u{a682}', - '\u{a684}'..='\u{a684}', '\u{a686}'..='\u{a686}', '\u{a688}'..='\u{a688}', - '\u{a68a}'..='\u{a68a}', '\u{a68c}'..='\u{a68c}', '\u{a68e}'..='\u{a68e}', - '\u{a690}'..='\u{a690}', '\u{a692}'..='\u{a692}', '\u{a694}'..='\u{a694}', - '\u{a696}'..='\u{a696}', '\u{a698}'..='\u{a698}', '\u{a69a}'..='\u{a69a}', - '\u{a722}'..='\u{a722}', '\u{a724}'..='\u{a724}', '\u{a726}'..='\u{a726}', - '\u{a728}'..='\u{a728}', '\u{a72a}'..='\u{a72a}', '\u{a72c}'..='\u{a72c}', - '\u{a72e}'..='\u{a72e}', '\u{a732}'..='\u{a732}', '\u{a734}'..='\u{a734}', - '\u{a736}'..='\u{a736}', '\u{a738}'..='\u{a738}', '\u{a73a}'..='\u{a73a}', - '\u{a73c}'..='\u{a73c}', '\u{a73e}'..='\u{a73e}', '\u{a740}'..='\u{a740}', - '\u{a742}'..='\u{a742}', '\u{a744}'..='\u{a744}', '\u{a746}'..='\u{a746}', - '\u{a748}'..='\u{a748}', '\u{a74a}'..='\u{a74a}', '\u{a74c}'..='\u{a74c}', - '\u{a74e}'..='\u{a74e}', '\u{a750}'..='\u{a750}', '\u{a752}'..='\u{a752}', - '\u{a754}'..='\u{a754}', '\u{a756}'..='\u{a756}', '\u{a758}'..='\u{a758}', - '\u{a75a}'..='\u{a75a}', '\u{a75c}'..='\u{a75c}', '\u{a75e}'..='\u{a75e}', - '\u{a760}'..='\u{a760}', '\u{a762}'..='\u{a762}', '\u{a764}'..='\u{a764}', - '\u{a766}'..='\u{a766}', '\u{a768}'..='\u{a768}', '\u{a76a}'..='\u{a76a}', - '\u{a76c}'..='\u{a76c}', '\u{a76e}'..='\u{a76e}', '\u{a779}'..='\u{a779}', - '\u{a77b}'..='\u{a77b}', '\u{a77d}'..='\u{a77e}', '\u{a780}'..='\u{a780}', - '\u{a782}'..='\u{a782}', '\u{a784}'..='\u{a784}', '\u{a786}'..='\u{a786}', - '\u{a78b}'..='\u{a78b}', '\u{a78d}'..='\u{a78d}', '\u{a790}'..='\u{a790}', - '\u{a792}'..='\u{a792}', '\u{a796}'..='\u{a796}', '\u{a798}'..='\u{a798}', - '\u{a79a}'..='\u{a79a}', '\u{a79c}'..='\u{a79c}', '\u{a79e}'..='\u{a79e}', - '\u{a7a0}'..='\u{a7a0}', '\u{a7a2}'..='\u{a7a2}', '\u{a7a4}'..='\u{a7a4}', - '\u{a7a6}'..='\u{a7a6}', '\u{a7a8}'..='\u{a7a8}', '\u{a7aa}'..='\u{a7ae}', - '\u{a7b0}'..='\u{a7b4}', '\u{a7b6}'..='\u{a7b6}', '\u{a7b8}'..='\u{a7b8}', - '\u{a7ba}'..='\u{a7ba}', '\u{a7bc}'..='\u{a7bc}', '\u{a7be}'..='\u{a7be}', - '\u{a7c0}'..='\u{a7c0}', '\u{a7c2}'..='\u{a7c2}', '\u{a7c4}'..='\u{a7c7}', - '\u{a7c9}'..='\u{a7c9}', '\u{a7cb}'..='\u{a7cc}', '\u{a7ce}'..='\u{a7ce}', - '\u{a7d0}'..='\u{a7d0}', '\u{a7d2}'..='\u{a7d2}', '\u{a7d4}'..='\u{a7d4}', - '\u{a7d6}'..='\u{a7d6}', '\u{a7d8}'..='\u{a7d8}', '\u{a7da}'..='\u{a7da}', - '\u{a7dc}'..='\u{a7dc}', '\u{a7f5}'..='\u{a7f5}', '\u{ff21}'..='\u{ff3a}', - '\u{10400}'..='\u{10427}', '\u{104b0}'..='\u{104d3}', '\u{10570}'..='\u{1057a}', - '\u{1057c}'..='\u{1058a}', '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', - '\u{10c80}'..='\u{10cb2}', '\u{10d50}'..='\u{10d65}', '\u{118a0}'..='\u{118bf}', - '\u{16e40}'..='\u{16e5f}', '\u{16ea0}'..='\u{16eb8}', '\u{1d400}'..='\u{1d419}', - '\u{1d434}'..='\u{1d44d}', '\u{1d468}'..='\u{1d481}', '\u{1d49c}'..='\u{1d49c}', - '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', '\u{1d4a5}'..='\u{1d4a6}', - '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b5}', '\u{1d4d0}'..='\u{1d4e9}', - '\u{1d504}'..='\u{1d505}', '\u{1d507}'..='\u{1d50a}', '\u{1d50d}'..='\u{1d514}', - '\u{1d516}'..='\u{1d51c}', '\u{1d538}'..='\u{1d539}', '\u{1d53b}'..='\u{1d53e}', - '\u{1d540}'..='\u{1d544}', '\u{1d546}'..='\u{1d546}', '\u{1d54a}'..='\u{1d550}', - '\u{1d56c}'..='\u{1d585}', '\u{1d5a0}'..='\u{1d5b9}', '\u{1d5d4}'..='\u{1d5ed}', - '\u{1d608}'..='\u{1d621}', '\u{1d63c}'..='\u{1d655}', '\u{1d670}'..='\u{1d689}', - '\u{1d6a8}'..='\u{1d6c0}', '\u{1d6e2}'..='\u{1d6fa}', '\u{1d71c}'..='\u{1d734}', - '\u{1d756}'..='\u{1d76e}', '\u{1d790}'..='\u{1d7a8}', '\u{1d7ca}'..='\u{1d7ca}', - '\u{1e900}'..='\u{1e921}', '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', - '\u{1f170}'..='\u{1f189}', -]; - -#[rustfmt::skip] -pub(super) static WHITE_SPACE: &[RangeInclusive; 8] = &[ - '\u{85}'..='\u{85}', '\u{a0}'..='\u{a0}', '\u{1680}'..='\u{1680}', '\u{2000}'..='\u{200a}', - '\u{2028}'..='\u{2029}', '\u{202f}'..='\u{202f}', '\u{205f}'..='\u{205f}', - '\u{3000}'..='\u{3000}', -]; - -#[rustfmt::skip] -pub(super) static TO_LOWER: &[(char, [char; 3]); 1488] = &[ - ('\u{41}', ['\u{61}', '\u{0}', '\u{0}']), ('\u{42}', ['\u{62}', '\u{0}', '\u{0}']), - ('\u{43}', ['\u{63}', '\u{0}', '\u{0}']), ('\u{44}', ['\u{64}', '\u{0}', '\u{0}']), - ('\u{45}', ['\u{65}', '\u{0}', '\u{0}']), ('\u{46}', ['\u{66}', '\u{0}', '\u{0}']), - ('\u{47}', ['\u{67}', '\u{0}', '\u{0}']), ('\u{48}', ['\u{68}', '\u{0}', '\u{0}']), - ('\u{49}', ['\u{69}', '\u{0}', '\u{0}']), ('\u{4a}', ['\u{6a}', '\u{0}', '\u{0}']), - ('\u{4b}', ['\u{6b}', '\u{0}', '\u{0}']), ('\u{4c}', ['\u{6c}', '\u{0}', '\u{0}']), - ('\u{4d}', ['\u{6d}', '\u{0}', '\u{0}']), ('\u{4e}', ['\u{6e}', '\u{0}', '\u{0}']), - ('\u{4f}', ['\u{6f}', '\u{0}', '\u{0}']), ('\u{50}', ['\u{70}', '\u{0}', '\u{0}']), - ('\u{51}', ['\u{71}', '\u{0}', '\u{0}']), ('\u{52}', ['\u{72}', '\u{0}', '\u{0}']), - ('\u{53}', ['\u{73}', '\u{0}', '\u{0}']), ('\u{54}', ['\u{74}', '\u{0}', '\u{0}']), - ('\u{55}', ['\u{75}', '\u{0}', '\u{0}']), ('\u{56}', ['\u{76}', '\u{0}', '\u{0}']), - ('\u{57}', ['\u{77}', '\u{0}', '\u{0}']), ('\u{58}', ['\u{78}', '\u{0}', '\u{0}']), - ('\u{59}', ['\u{79}', '\u{0}', '\u{0}']), ('\u{5a}', ['\u{7a}', '\u{0}', '\u{0}']), - ('\u{c0}', ['\u{e0}', '\u{0}', '\u{0}']), ('\u{c1}', ['\u{e1}', '\u{0}', '\u{0}']), - ('\u{c2}', ['\u{e2}', '\u{0}', '\u{0}']), ('\u{c3}', ['\u{e3}', '\u{0}', '\u{0}']), - ('\u{c4}', ['\u{e4}', '\u{0}', '\u{0}']), ('\u{c5}', ['\u{e5}', '\u{0}', '\u{0}']), - ('\u{c6}', ['\u{e6}', '\u{0}', '\u{0}']), ('\u{c7}', ['\u{e7}', '\u{0}', '\u{0}']), - ('\u{c8}', ['\u{e8}', '\u{0}', '\u{0}']), ('\u{c9}', ['\u{e9}', '\u{0}', '\u{0}']), - ('\u{ca}', ['\u{ea}', '\u{0}', '\u{0}']), ('\u{cb}', ['\u{eb}', '\u{0}', '\u{0}']), - ('\u{cc}', ['\u{ec}', '\u{0}', '\u{0}']), ('\u{cd}', ['\u{ed}', '\u{0}', '\u{0}']), - ('\u{ce}', ['\u{ee}', '\u{0}', '\u{0}']), ('\u{cf}', ['\u{ef}', '\u{0}', '\u{0}']), - ('\u{d0}', ['\u{f0}', '\u{0}', '\u{0}']), ('\u{d1}', ['\u{f1}', '\u{0}', '\u{0}']), - ('\u{d2}', ['\u{f2}', '\u{0}', '\u{0}']), ('\u{d3}', ['\u{f3}', '\u{0}', '\u{0}']), - ('\u{d4}', ['\u{f4}', '\u{0}', '\u{0}']), ('\u{d5}', ['\u{f5}', '\u{0}', '\u{0}']), - ('\u{d6}', ['\u{f6}', '\u{0}', '\u{0}']), ('\u{d8}', ['\u{f8}', '\u{0}', '\u{0}']), - ('\u{d9}', ['\u{f9}', '\u{0}', '\u{0}']), ('\u{da}', ['\u{fa}', '\u{0}', '\u{0}']), - ('\u{db}', ['\u{fb}', '\u{0}', '\u{0}']), ('\u{dc}', ['\u{fc}', '\u{0}', '\u{0}']), - ('\u{dd}', ['\u{fd}', '\u{0}', '\u{0}']), ('\u{de}', ['\u{fe}', '\u{0}', '\u{0}']), - ('\u{100}', ['\u{101}', '\u{0}', '\u{0}']), ('\u{102}', ['\u{103}', '\u{0}', '\u{0}']), - ('\u{104}', ['\u{105}', '\u{0}', '\u{0}']), ('\u{106}', ['\u{107}', '\u{0}', '\u{0}']), - ('\u{108}', ['\u{109}', '\u{0}', '\u{0}']), ('\u{10a}', ['\u{10b}', '\u{0}', '\u{0}']), - ('\u{10c}', ['\u{10d}', '\u{0}', '\u{0}']), ('\u{10e}', ['\u{10f}', '\u{0}', '\u{0}']), - ('\u{110}', ['\u{111}', '\u{0}', '\u{0}']), ('\u{112}', ['\u{113}', '\u{0}', '\u{0}']), - ('\u{114}', ['\u{115}', '\u{0}', '\u{0}']), ('\u{116}', ['\u{117}', '\u{0}', '\u{0}']), - ('\u{118}', ['\u{119}', '\u{0}', '\u{0}']), ('\u{11a}', ['\u{11b}', '\u{0}', '\u{0}']), - ('\u{11c}', ['\u{11d}', '\u{0}', '\u{0}']), ('\u{11e}', ['\u{11f}', '\u{0}', '\u{0}']), - ('\u{120}', ['\u{121}', '\u{0}', '\u{0}']), ('\u{122}', ['\u{123}', '\u{0}', '\u{0}']), - ('\u{124}', ['\u{125}', '\u{0}', '\u{0}']), ('\u{126}', ['\u{127}', '\u{0}', '\u{0}']), - ('\u{128}', ['\u{129}', '\u{0}', '\u{0}']), ('\u{12a}', ['\u{12b}', '\u{0}', '\u{0}']), - ('\u{12c}', ['\u{12d}', '\u{0}', '\u{0}']), ('\u{12e}', ['\u{12f}', '\u{0}', '\u{0}']), - ('\u{130}', ['\u{69}', '\u{307}', '\u{0}']), ('\u{132}', ['\u{133}', '\u{0}', '\u{0}']), - ('\u{134}', ['\u{135}', '\u{0}', '\u{0}']), ('\u{136}', ['\u{137}', '\u{0}', '\u{0}']), - ('\u{139}', ['\u{13a}', '\u{0}', '\u{0}']), ('\u{13b}', ['\u{13c}', '\u{0}', '\u{0}']), - ('\u{13d}', ['\u{13e}', '\u{0}', '\u{0}']), ('\u{13f}', ['\u{140}', '\u{0}', '\u{0}']), - ('\u{141}', ['\u{142}', '\u{0}', '\u{0}']), ('\u{143}', ['\u{144}', '\u{0}', '\u{0}']), - ('\u{145}', ['\u{146}', '\u{0}', '\u{0}']), ('\u{147}', ['\u{148}', '\u{0}', '\u{0}']), - ('\u{14a}', ['\u{14b}', '\u{0}', '\u{0}']), ('\u{14c}', ['\u{14d}', '\u{0}', '\u{0}']), - ('\u{14e}', ['\u{14f}', '\u{0}', '\u{0}']), ('\u{150}', ['\u{151}', '\u{0}', '\u{0}']), - ('\u{152}', ['\u{153}', '\u{0}', '\u{0}']), ('\u{154}', ['\u{155}', '\u{0}', '\u{0}']), - ('\u{156}', ['\u{157}', '\u{0}', '\u{0}']), ('\u{158}', ['\u{159}', '\u{0}', '\u{0}']), - ('\u{15a}', ['\u{15b}', '\u{0}', '\u{0}']), ('\u{15c}', ['\u{15d}', '\u{0}', '\u{0}']), - ('\u{15e}', ['\u{15f}', '\u{0}', '\u{0}']), ('\u{160}', ['\u{161}', '\u{0}', '\u{0}']), - ('\u{162}', ['\u{163}', '\u{0}', '\u{0}']), ('\u{164}', ['\u{165}', '\u{0}', '\u{0}']), - ('\u{166}', ['\u{167}', '\u{0}', '\u{0}']), ('\u{168}', ['\u{169}', '\u{0}', '\u{0}']), - ('\u{16a}', ['\u{16b}', '\u{0}', '\u{0}']), ('\u{16c}', ['\u{16d}', '\u{0}', '\u{0}']), - ('\u{16e}', ['\u{16f}', '\u{0}', '\u{0}']), ('\u{170}', ['\u{171}', '\u{0}', '\u{0}']), - ('\u{172}', ['\u{173}', '\u{0}', '\u{0}']), ('\u{174}', ['\u{175}', '\u{0}', '\u{0}']), - ('\u{176}', ['\u{177}', '\u{0}', '\u{0}']), ('\u{178}', ['\u{ff}', '\u{0}', '\u{0}']), - ('\u{179}', ['\u{17a}', '\u{0}', '\u{0}']), ('\u{17b}', ['\u{17c}', '\u{0}', '\u{0}']), - ('\u{17d}', ['\u{17e}', '\u{0}', '\u{0}']), ('\u{181}', ['\u{253}', '\u{0}', '\u{0}']), - ('\u{182}', ['\u{183}', '\u{0}', '\u{0}']), ('\u{184}', ['\u{185}', '\u{0}', '\u{0}']), - ('\u{186}', ['\u{254}', '\u{0}', '\u{0}']), ('\u{187}', ['\u{188}', '\u{0}', '\u{0}']), - ('\u{189}', ['\u{256}', '\u{0}', '\u{0}']), ('\u{18a}', ['\u{257}', '\u{0}', '\u{0}']), - ('\u{18b}', ['\u{18c}', '\u{0}', '\u{0}']), ('\u{18e}', ['\u{1dd}', '\u{0}', '\u{0}']), - ('\u{18f}', ['\u{259}', '\u{0}', '\u{0}']), ('\u{190}', ['\u{25b}', '\u{0}', '\u{0}']), - ('\u{191}', ['\u{192}', '\u{0}', '\u{0}']), ('\u{193}', ['\u{260}', '\u{0}', '\u{0}']), - ('\u{194}', ['\u{263}', '\u{0}', '\u{0}']), ('\u{196}', ['\u{269}', '\u{0}', '\u{0}']), - ('\u{197}', ['\u{268}', '\u{0}', '\u{0}']), ('\u{198}', ['\u{199}', '\u{0}', '\u{0}']), - ('\u{19c}', ['\u{26f}', '\u{0}', '\u{0}']), ('\u{19d}', ['\u{272}', '\u{0}', '\u{0}']), - ('\u{19f}', ['\u{275}', '\u{0}', '\u{0}']), ('\u{1a0}', ['\u{1a1}', '\u{0}', '\u{0}']), - ('\u{1a2}', ['\u{1a3}', '\u{0}', '\u{0}']), ('\u{1a4}', ['\u{1a5}', '\u{0}', '\u{0}']), - ('\u{1a6}', ['\u{280}', '\u{0}', '\u{0}']), ('\u{1a7}', ['\u{1a8}', '\u{0}', '\u{0}']), - ('\u{1a9}', ['\u{283}', '\u{0}', '\u{0}']), ('\u{1ac}', ['\u{1ad}', '\u{0}', '\u{0}']), - ('\u{1ae}', ['\u{288}', '\u{0}', '\u{0}']), ('\u{1af}', ['\u{1b0}', '\u{0}', '\u{0}']), - ('\u{1b1}', ['\u{28a}', '\u{0}', '\u{0}']), ('\u{1b2}', ['\u{28b}', '\u{0}', '\u{0}']), - ('\u{1b3}', ['\u{1b4}', '\u{0}', '\u{0}']), ('\u{1b5}', ['\u{1b6}', '\u{0}', '\u{0}']), - ('\u{1b7}', ['\u{292}', '\u{0}', '\u{0}']), ('\u{1b8}', ['\u{1b9}', '\u{0}', '\u{0}']), - ('\u{1bc}', ['\u{1bd}', '\u{0}', '\u{0}']), ('\u{1c4}', ['\u{1c6}', '\u{0}', '\u{0}']), - ('\u{1c5}', ['\u{1c6}', '\u{0}', '\u{0}']), ('\u{1c7}', ['\u{1c9}', '\u{0}', '\u{0}']), - ('\u{1c8}', ['\u{1c9}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cc}', '\u{0}', '\u{0}']), - ('\u{1cb}', ['\u{1cc}', '\u{0}', '\u{0}']), ('\u{1cd}', ['\u{1ce}', '\u{0}', '\u{0}']), - ('\u{1cf}', ['\u{1d0}', '\u{0}', '\u{0}']), ('\u{1d1}', ['\u{1d2}', '\u{0}', '\u{0}']), - ('\u{1d3}', ['\u{1d4}', '\u{0}', '\u{0}']), ('\u{1d5}', ['\u{1d6}', '\u{0}', '\u{0}']), - ('\u{1d7}', ['\u{1d8}', '\u{0}', '\u{0}']), ('\u{1d9}', ['\u{1da}', '\u{0}', '\u{0}']), - ('\u{1db}', ['\u{1dc}', '\u{0}', '\u{0}']), ('\u{1de}', ['\u{1df}', '\u{0}', '\u{0}']), - ('\u{1e0}', ['\u{1e1}', '\u{0}', '\u{0}']), ('\u{1e2}', ['\u{1e3}', '\u{0}', '\u{0}']), - ('\u{1e4}', ['\u{1e5}', '\u{0}', '\u{0}']), ('\u{1e6}', ['\u{1e7}', '\u{0}', '\u{0}']), - ('\u{1e8}', ['\u{1e9}', '\u{0}', '\u{0}']), ('\u{1ea}', ['\u{1eb}', '\u{0}', '\u{0}']), - ('\u{1ec}', ['\u{1ed}', '\u{0}', '\u{0}']), ('\u{1ee}', ['\u{1ef}', '\u{0}', '\u{0}']), - ('\u{1f1}', ['\u{1f3}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f3}', '\u{0}', '\u{0}']), - ('\u{1f4}', ['\u{1f5}', '\u{0}', '\u{0}']), ('\u{1f6}', ['\u{195}', '\u{0}', '\u{0}']), - ('\u{1f7}', ['\u{1bf}', '\u{0}', '\u{0}']), ('\u{1f8}', ['\u{1f9}', '\u{0}', '\u{0}']), - ('\u{1fa}', ['\u{1fb}', '\u{0}', '\u{0}']), ('\u{1fc}', ['\u{1fd}', '\u{0}', '\u{0}']), - ('\u{1fe}', ['\u{1ff}', '\u{0}', '\u{0}']), ('\u{200}', ['\u{201}', '\u{0}', '\u{0}']), - ('\u{202}', ['\u{203}', '\u{0}', '\u{0}']), ('\u{204}', ['\u{205}', '\u{0}', '\u{0}']), - ('\u{206}', ['\u{207}', '\u{0}', '\u{0}']), ('\u{208}', ['\u{209}', '\u{0}', '\u{0}']), - ('\u{20a}', ['\u{20b}', '\u{0}', '\u{0}']), ('\u{20c}', ['\u{20d}', '\u{0}', '\u{0}']), - ('\u{20e}', ['\u{20f}', '\u{0}', '\u{0}']), ('\u{210}', ['\u{211}', '\u{0}', '\u{0}']), - ('\u{212}', ['\u{213}', '\u{0}', '\u{0}']), ('\u{214}', ['\u{215}', '\u{0}', '\u{0}']), - ('\u{216}', ['\u{217}', '\u{0}', '\u{0}']), ('\u{218}', ['\u{219}', '\u{0}', '\u{0}']), - ('\u{21a}', ['\u{21b}', '\u{0}', '\u{0}']), ('\u{21c}', ['\u{21d}', '\u{0}', '\u{0}']), - ('\u{21e}', ['\u{21f}', '\u{0}', '\u{0}']), ('\u{220}', ['\u{19e}', '\u{0}', '\u{0}']), - ('\u{222}', ['\u{223}', '\u{0}', '\u{0}']), ('\u{224}', ['\u{225}', '\u{0}', '\u{0}']), - ('\u{226}', ['\u{227}', '\u{0}', '\u{0}']), ('\u{228}', ['\u{229}', '\u{0}', '\u{0}']), - ('\u{22a}', ['\u{22b}', '\u{0}', '\u{0}']), ('\u{22c}', ['\u{22d}', '\u{0}', '\u{0}']), - ('\u{22e}', ['\u{22f}', '\u{0}', '\u{0}']), ('\u{230}', ['\u{231}', '\u{0}', '\u{0}']), - ('\u{232}', ['\u{233}', '\u{0}', '\u{0}']), ('\u{23a}', ['\u{2c65}', '\u{0}', '\u{0}']), - ('\u{23b}', ['\u{23c}', '\u{0}', '\u{0}']), ('\u{23d}', ['\u{19a}', '\u{0}', '\u{0}']), - ('\u{23e}', ['\u{2c66}', '\u{0}', '\u{0}']), ('\u{241}', ['\u{242}', '\u{0}', '\u{0}']), - ('\u{243}', ['\u{180}', '\u{0}', '\u{0}']), ('\u{244}', ['\u{289}', '\u{0}', '\u{0}']), - ('\u{245}', ['\u{28c}', '\u{0}', '\u{0}']), ('\u{246}', ['\u{247}', '\u{0}', '\u{0}']), - ('\u{248}', ['\u{249}', '\u{0}', '\u{0}']), ('\u{24a}', ['\u{24b}', '\u{0}', '\u{0}']), - ('\u{24c}', ['\u{24d}', '\u{0}', '\u{0}']), ('\u{24e}', ['\u{24f}', '\u{0}', '\u{0}']), - ('\u{370}', ['\u{371}', '\u{0}', '\u{0}']), ('\u{372}', ['\u{373}', '\u{0}', '\u{0}']), - ('\u{376}', ['\u{377}', '\u{0}', '\u{0}']), ('\u{37f}', ['\u{3f3}', '\u{0}', '\u{0}']), - ('\u{386}', ['\u{3ac}', '\u{0}', '\u{0}']), ('\u{388}', ['\u{3ad}', '\u{0}', '\u{0}']), - ('\u{389}', ['\u{3ae}', '\u{0}', '\u{0}']), ('\u{38a}', ['\u{3af}', '\u{0}', '\u{0}']), - ('\u{38c}', ['\u{3cc}', '\u{0}', '\u{0}']), ('\u{38e}', ['\u{3cd}', '\u{0}', '\u{0}']), - ('\u{38f}', ['\u{3ce}', '\u{0}', '\u{0}']), ('\u{391}', ['\u{3b1}', '\u{0}', '\u{0}']), - ('\u{392}', ['\u{3b2}', '\u{0}', '\u{0}']), ('\u{393}', ['\u{3b3}', '\u{0}', '\u{0}']), - ('\u{394}', ['\u{3b4}', '\u{0}', '\u{0}']), ('\u{395}', ['\u{3b5}', '\u{0}', '\u{0}']), - ('\u{396}', ['\u{3b6}', '\u{0}', '\u{0}']), ('\u{397}', ['\u{3b7}', '\u{0}', '\u{0}']), - ('\u{398}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{399}', ['\u{3b9}', '\u{0}', '\u{0}']), - ('\u{39a}', ['\u{3ba}', '\u{0}', '\u{0}']), ('\u{39b}', ['\u{3bb}', '\u{0}', '\u{0}']), - ('\u{39c}', ['\u{3bc}', '\u{0}', '\u{0}']), ('\u{39d}', ['\u{3bd}', '\u{0}', '\u{0}']), - ('\u{39e}', ['\u{3be}', '\u{0}', '\u{0}']), ('\u{39f}', ['\u{3bf}', '\u{0}', '\u{0}']), - ('\u{3a0}', ['\u{3c0}', '\u{0}', '\u{0}']), ('\u{3a1}', ['\u{3c1}', '\u{0}', '\u{0}']), - ('\u{3a3}', ['\u{3c3}', '\u{0}', '\u{0}']), ('\u{3a4}', ['\u{3c4}', '\u{0}', '\u{0}']), - ('\u{3a5}', ['\u{3c5}', '\u{0}', '\u{0}']), ('\u{3a6}', ['\u{3c6}', '\u{0}', '\u{0}']), - ('\u{3a7}', ['\u{3c7}', '\u{0}', '\u{0}']), ('\u{3a8}', ['\u{3c8}', '\u{0}', '\u{0}']), - ('\u{3a9}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{3aa}', ['\u{3ca}', '\u{0}', '\u{0}']), - ('\u{3ab}', ['\u{3cb}', '\u{0}', '\u{0}']), ('\u{3cf}', ['\u{3d7}', '\u{0}', '\u{0}']), - ('\u{3d8}', ['\u{3d9}', '\u{0}', '\u{0}']), ('\u{3da}', ['\u{3db}', '\u{0}', '\u{0}']), - ('\u{3dc}', ['\u{3dd}', '\u{0}', '\u{0}']), ('\u{3de}', ['\u{3df}', '\u{0}', '\u{0}']), - ('\u{3e0}', ['\u{3e1}', '\u{0}', '\u{0}']), ('\u{3e2}', ['\u{3e3}', '\u{0}', '\u{0}']), - ('\u{3e4}', ['\u{3e5}', '\u{0}', '\u{0}']), ('\u{3e6}', ['\u{3e7}', '\u{0}', '\u{0}']), - ('\u{3e8}', ['\u{3e9}', '\u{0}', '\u{0}']), ('\u{3ea}', ['\u{3eb}', '\u{0}', '\u{0}']), - ('\u{3ec}', ['\u{3ed}', '\u{0}', '\u{0}']), ('\u{3ee}', ['\u{3ef}', '\u{0}', '\u{0}']), - ('\u{3f4}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{3f7}', ['\u{3f8}', '\u{0}', '\u{0}']), - ('\u{3f9}', ['\u{3f2}', '\u{0}', '\u{0}']), ('\u{3fa}', ['\u{3fb}', '\u{0}', '\u{0}']), - ('\u{3fd}', ['\u{37b}', '\u{0}', '\u{0}']), ('\u{3fe}', ['\u{37c}', '\u{0}', '\u{0}']), - ('\u{3ff}', ['\u{37d}', '\u{0}', '\u{0}']), ('\u{400}', ['\u{450}', '\u{0}', '\u{0}']), - ('\u{401}', ['\u{451}', '\u{0}', '\u{0}']), ('\u{402}', ['\u{452}', '\u{0}', '\u{0}']), - ('\u{403}', ['\u{453}', '\u{0}', '\u{0}']), ('\u{404}', ['\u{454}', '\u{0}', '\u{0}']), - ('\u{405}', ['\u{455}', '\u{0}', '\u{0}']), ('\u{406}', ['\u{456}', '\u{0}', '\u{0}']), - ('\u{407}', ['\u{457}', '\u{0}', '\u{0}']), ('\u{408}', ['\u{458}', '\u{0}', '\u{0}']), - ('\u{409}', ['\u{459}', '\u{0}', '\u{0}']), ('\u{40a}', ['\u{45a}', '\u{0}', '\u{0}']), - ('\u{40b}', ['\u{45b}', '\u{0}', '\u{0}']), ('\u{40c}', ['\u{45c}', '\u{0}', '\u{0}']), - ('\u{40d}', ['\u{45d}', '\u{0}', '\u{0}']), ('\u{40e}', ['\u{45e}', '\u{0}', '\u{0}']), - ('\u{40f}', ['\u{45f}', '\u{0}', '\u{0}']), ('\u{410}', ['\u{430}', '\u{0}', '\u{0}']), - ('\u{411}', ['\u{431}', '\u{0}', '\u{0}']), ('\u{412}', ['\u{432}', '\u{0}', '\u{0}']), - ('\u{413}', ['\u{433}', '\u{0}', '\u{0}']), ('\u{414}', ['\u{434}', '\u{0}', '\u{0}']), - ('\u{415}', ['\u{435}', '\u{0}', '\u{0}']), ('\u{416}', ['\u{436}', '\u{0}', '\u{0}']), - ('\u{417}', ['\u{437}', '\u{0}', '\u{0}']), ('\u{418}', ['\u{438}', '\u{0}', '\u{0}']), - ('\u{419}', ['\u{439}', '\u{0}', '\u{0}']), ('\u{41a}', ['\u{43a}', '\u{0}', '\u{0}']), - ('\u{41b}', ['\u{43b}', '\u{0}', '\u{0}']), ('\u{41c}', ['\u{43c}', '\u{0}', '\u{0}']), - ('\u{41d}', ['\u{43d}', '\u{0}', '\u{0}']), ('\u{41e}', ['\u{43e}', '\u{0}', '\u{0}']), - ('\u{41f}', ['\u{43f}', '\u{0}', '\u{0}']), ('\u{420}', ['\u{440}', '\u{0}', '\u{0}']), - ('\u{421}', ['\u{441}', '\u{0}', '\u{0}']), ('\u{422}', ['\u{442}', '\u{0}', '\u{0}']), - ('\u{423}', ['\u{443}', '\u{0}', '\u{0}']), ('\u{424}', ['\u{444}', '\u{0}', '\u{0}']), - ('\u{425}', ['\u{445}', '\u{0}', '\u{0}']), ('\u{426}', ['\u{446}', '\u{0}', '\u{0}']), - ('\u{427}', ['\u{447}', '\u{0}', '\u{0}']), ('\u{428}', ['\u{448}', '\u{0}', '\u{0}']), - ('\u{429}', ['\u{449}', '\u{0}', '\u{0}']), ('\u{42a}', ['\u{44a}', '\u{0}', '\u{0}']), - ('\u{42b}', ['\u{44b}', '\u{0}', '\u{0}']), ('\u{42c}', ['\u{44c}', '\u{0}', '\u{0}']), - ('\u{42d}', ['\u{44d}', '\u{0}', '\u{0}']), ('\u{42e}', ['\u{44e}', '\u{0}', '\u{0}']), - ('\u{42f}', ['\u{44f}', '\u{0}', '\u{0}']), ('\u{460}', ['\u{461}', '\u{0}', '\u{0}']), - ('\u{462}', ['\u{463}', '\u{0}', '\u{0}']), ('\u{464}', ['\u{465}', '\u{0}', '\u{0}']), - ('\u{466}', ['\u{467}', '\u{0}', '\u{0}']), ('\u{468}', ['\u{469}', '\u{0}', '\u{0}']), - ('\u{46a}', ['\u{46b}', '\u{0}', '\u{0}']), ('\u{46c}', ['\u{46d}', '\u{0}', '\u{0}']), - ('\u{46e}', ['\u{46f}', '\u{0}', '\u{0}']), ('\u{470}', ['\u{471}', '\u{0}', '\u{0}']), - ('\u{472}', ['\u{473}', '\u{0}', '\u{0}']), ('\u{474}', ['\u{475}', '\u{0}', '\u{0}']), - ('\u{476}', ['\u{477}', '\u{0}', '\u{0}']), ('\u{478}', ['\u{479}', '\u{0}', '\u{0}']), - ('\u{47a}', ['\u{47b}', '\u{0}', '\u{0}']), ('\u{47c}', ['\u{47d}', '\u{0}', '\u{0}']), - ('\u{47e}', ['\u{47f}', '\u{0}', '\u{0}']), ('\u{480}', ['\u{481}', '\u{0}', '\u{0}']), - ('\u{48a}', ['\u{48b}', '\u{0}', '\u{0}']), ('\u{48c}', ['\u{48d}', '\u{0}', '\u{0}']), - ('\u{48e}', ['\u{48f}', '\u{0}', '\u{0}']), ('\u{490}', ['\u{491}', '\u{0}', '\u{0}']), - ('\u{492}', ['\u{493}', '\u{0}', '\u{0}']), ('\u{494}', ['\u{495}', '\u{0}', '\u{0}']), - ('\u{496}', ['\u{497}', '\u{0}', '\u{0}']), ('\u{498}', ['\u{499}', '\u{0}', '\u{0}']), - ('\u{49a}', ['\u{49b}', '\u{0}', '\u{0}']), ('\u{49c}', ['\u{49d}', '\u{0}', '\u{0}']), - ('\u{49e}', ['\u{49f}', '\u{0}', '\u{0}']), ('\u{4a0}', ['\u{4a1}', '\u{0}', '\u{0}']), - ('\u{4a2}', ['\u{4a3}', '\u{0}', '\u{0}']), ('\u{4a4}', ['\u{4a5}', '\u{0}', '\u{0}']), - ('\u{4a6}', ['\u{4a7}', '\u{0}', '\u{0}']), ('\u{4a8}', ['\u{4a9}', '\u{0}', '\u{0}']), - ('\u{4aa}', ['\u{4ab}', '\u{0}', '\u{0}']), ('\u{4ac}', ['\u{4ad}', '\u{0}', '\u{0}']), - ('\u{4ae}', ['\u{4af}', '\u{0}', '\u{0}']), ('\u{4b0}', ['\u{4b1}', '\u{0}', '\u{0}']), - ('\u{4b2}', ['\u{4b3}', '\u{0}', '\u{0}']), ('\u{4b4}', ['\u{4b5}', '\u{0}', '\u{0}']), - ('\u{4b6}', ['\u{4b7}', '\u{0}', '\u{0}']), ('\u{4b8}', ['\u{4b9}', '\u{0}', '\u{0}']), - ('\u{4ba}', ['\u{4bb}', '\u{0}', '\u{0}']), ('\u{4bc}', ['\u{4bd}', '\u{0}', '\u{0}']), - ('\u{4be}', ['\u{4bf}', '\u{0}', '\u{0}']), ('\u{4c0}', ['\u{4cf}', '\u{0}', '\u{0}']), - ('\u{4c1}', ['\u{4c2}', '\u{0}', '\u{0}']), ('\u{4c3}', ['\u{4c4}', '\u{0}', '\u{0}']), - ('\u{4c5}', ['\u{4c6}', '\u{0}', '\u{0}']), ('\u{4c7}', ['\u{4c8}', '\u{0}', '\u{0}']), - ('\u{4c9}', ['\u{4ca}', '\u{0}', '\u{0}']), ('\u{4cb}', ['\u{4cc}', '\u{0}', '\u{0}']), - ('\u{4cd}', ['\u{4ce}', '\u{0}', '\u{0}']), ('\u{4d0}', ['\u{4d1}', '\u{0}', '\u{0}']), - ('\u{4d2}', ['\u{4d3}', '\u{0}', '\u{0}']), ('\u{4d4}', ['\u{4d5}', '\u{0}', '\u{0}']), - ('\u{4d6}', ['\u{4d7}', '\u{0}', '\u{0}']), ('\u{4d8}', ['\u{4d9}', '\u{0}', '\u{0}']), - ('\u{4da}', ['\u{4db}', '\u{0}', '\u{0}']), ('\u{4dc}', ['\u{4dd}', '\u{0}', '\u{0}']), - ('\u{4de}', ['\u{4df}', '\u{0}', '\u{0}']), ('\u{4e0}', ['\u{4e1}', '\u{0}', '\u{0}']), - ('\u{4e2}', ['\u{4e3}', '\u{0}', '\u{0}']), ('\u{4e4}', ['\u{4e5}', '\u{0}', '\u{0}']), - ('\u{4e6}', ['\u{4e7}', '\u{0}', '\u{0}']), ('\u{4e8}', ['\u{4e9}', '\u{0}', '\u{0}']), - ('\u{4ea}', ['\u{4eb}', '\u{0}', '\u{0}']), ('\u{4ec}', ['\u{4ed}', '\u{0}', '\u{0}']), - ('\u{4ee}', ['\u{4ef}', '\u{0}', '\u{0}']), ('\u{4f0}', ['\u{4f1}', '\u{0}', '\u{0}']), - ('\u{4f2}', ['\u{4f3}', '\u{0}', '\u{0}']), ('\u{4f4}', ['\u{4f5}', '\u{0}', '\u{0}']), - ('\u{4f6}', ['\u{4f7}', '\u{0}', '\u{0}']), ('\u{4f8}', ['\u{4f9}', '\u{0}', '\u{0}']), - ('\u{4fa}', ['\u{4fb}', '\u{0}', '\u{0}']), ('\u{4fc}', ['\u{4fd}', '\u{0}', '\u{0}']), - ('\u{4fe}', ['\u{4ff}', '\u{0}', '\u{0}']), ('\u{500}', ['\u{501}', '\u{0}', '\u{0}']), - ('\u{502}', ['\u{503}', '\u{0}', '\u{0}']), ('\u{504}', ['\u{505}', '\u{0}', '\u{0}']), - ('\u{506}', ['\u{507}', '\u{0}', '\u{0}']), ('\u{508}', ['\u{509}', '\u{0}', '\u{0}']), - ('\u{50a}', ['\u{50b}', '\u{0}', '\u{0}']), ('\u{50c}', ['\u{50d}', '\u{0}', '\u{0}']), - ('\u{50e}', ['\u{50f}', '\u{0}', '\u{0}']), ('\u{510}', ['\u{511}', '\u{0}', '\u{0}']), - ('\u{512}', ['\u{513}', '\u{0}', '\u{0}']), ('\u{514}', ['\u{515}', '\u{0}', '\u{0}']), - ('\u{516}', ['\u{517}', '\u{0}', '\u{0}']), ('\u{518}', ['\u{519}', '\u{0}', '\u{0}']), - ('\u{51a}', ['\u{51b}', '\u{0}', '\u{0}']), ('\u{51c}', ['\u{51d}', '\u{0}', '\u{0}']), - ('\u{51e}', ['\u{51f}', '\u{0}', '\u{0}']), ('\u{520}', ['\u{521}', '\u{0}', '\u{0}']), - ('\u{522}', ['\u{523}', '\u{0}', '\u{0}']), ('\u{524}', ['\u{525}', '\u{0}', '\u{0}']), - ('\u{526}', ['\u{527}', '\u{0}', '\u{0}']), ('\u{528}', ['\u{529}', '\u{0}', '\u{0}']), - ('\u{52a}', ['\u{52b}', '\u{0}', '\u{0}']), ('\u{52c}', ['\u{52d}', '\u{0}', '\u{0}']), - ('\u{52e}', ['\u{52f}', '\u{0}', '\u{0}']), ('\u{531}', ['\u{561}', '\u{0}', '\u{0}']), - ('\u{532}', ['\u{562}', '\u{0}', '\u{0}']), ('\u{533}', ['\u{563}', '\u{0}', '\u{0}']), - ('\u{534}', ['\u{564}', '\u{0}', '\u{0}']), ('\u{535}', ['\u{565}', '\u{0}', '\u{0}']), - ('\u{536}', ['\u{566}', '\u{0}', '\u{0}']), ('\u{537}', ['\u{567}', '\u{0}', '\u{0}']), - ('\u{538}', ['\u{568}', '\u{0}', '\u{0}']), ('\u{539}', ['\u{569}', '\u{0}', '\u{0}']), - ('\u{53a}', ['\u{56a}', '\u{0}', '\u{0}']), ('\u{53b}', ['\u{56b}', '\u{0}', '\u{0}']), - ('\u{53c}', ['\u{56c}', '\u{0}', '\u{0}']), ('\u{53d}', ['\u{56d}', '\u{0}', '\u{0}']), - ('\u{53e}', ['\u{56e}', '\u{0}', '\u{0}']), ('\u{53f}', ['\u{56f}', '\u{0}', '\u{0}']), - ('\u{540}', ['\u{570}', '\u{0}', '\u{0}']), ('\u{541}', ['\u{571}', '\u{0}', '\u{0}']), - ('\u{542}', ['\u{572}', '\u{0}', '\u{0}']), ('\u{543}', ['\u{573}', '\u{0}', '\u{0}']), - ('\u{544}', ['\u{574}', '\u{0}', '\u{0}']), ('\u{545}', ['\u{575}', '\u{0}', '\u{0}']), - ('\u{546}', ['\u{576}', '\u{0}', '\u{0}']), ('\u{547}', ['\u{577}', '\u{0}', '\u{0}']), - ('\u{548}', ['\u{578}', '\u{0}', '\u{0}']), ('\u{549}', ['\u{579}', '\u{0}', '\u{0}']), - ('\u{54a}', ['\u{57a}', '\u{0}', '\u{0}']), ('\u{54b}', ['\u{57b}', '\u{0}', '\u{0}']), - ('\u{54c}', ['\u{57c}', '\u{0}', '\u{0}']), ('\u{54d}', ['\u{57d}', '\u{0}', '\u{0}']), - ('\u{54e}', ['\u{57e}', '\u{0}', '\u{0}']), ('\u{54f}', ['\u{57f}', '\u{0}', '\u{0}']), - ('\u{550}', ['\u{580}', '\u{0}', '\u{0}']), ('\u{551}', ['\u{581}', '\u{0}', '\u{0}']), - ('\u{552}', ['\u{582}', '\u{0}', '\u{0}']), ('\u{553}', ['\u{583}', '\u{0}', '\u{0}']), - ('\u{554}', ['\u{584}', '\u{0}', '\u{0}']), ('\u{555}', ['\u{585}', '\u{0}', '\u{0}']), - ('\u{556}', ['\u{586}', '\u{0}', '\u{0}']), ('\u{10a0}', ['\u{2d00}', '\u{0}', '\u{0}']), - ('\u{10a1}', ['\u{2d01}', '\u{0}', '\u{0}']), ('\u{10a2}', ['\u{2d02}', '\u{0}', '\u{0}']), - ('\u{10a3}', ['\u{2d03}', '\u{0}', '\u{0}']), ('\u{10a4}', ['\u{2d04}', '\u{0}', '\u{0}']), - ('\u{10a5}', ['\u{2d05}', '\u{0}', '\u{0}']), ('\u{10a6}', ['\u{2d06}', '\u{0}', '\u{0}']), - ('\u{10a7}', ['\u{2d07}', '\u{0}', '\u{0}']), ('\u{10a8}', ['\u{2d08}', '\u{0}', '\u{0}']), - ('\u{10a9}', ['\u{2d09}', '\u{0}', '\u{0}']), ('\u{10aa}', ['\u{2d0a}', '\u{0}', '\u{0}']), - ('\u{10ab}', ['\u{2d0b}', '\u{0}', '\u{0}']), ('\u{10ac}', ['\u{2d0c}', '\u{0}', '\u{0}']), - ('\u{10ad}', ['\u{2d0d}', '\u{0}', '\u{0}']), ('\u{10ae}', ['\u{2d0e}', '\u{0}', '\u{0}']), - ('\u{10af}', ['\u{2d0f}', '\u{0}', '\u{0}']), ('\u{10b0}', ['\u{2d10}', '\u{0}', '\u{0}']), - ('\u{10b1}', ['\u{2d11}', '\u{0}', '\u{0}']), ('\u{10b2}', ['\u{2d12}', '\u{0}', '\u{0}']), - ('\u{10b3}', ['\u{2d13}', '\u{0}', '\u{0}']), ('\u{10b4}', ['\u{2d14}', '\u{0}', '\u{0}']), - ('\u{10b5}', ['\u{2d15}', '\u{0}', '\u{0}']), ('\u{10b6}', ['\u{2d16}', '\u{0}', '\u{0}']), - ('\u{10b7}', ['\u{2d17}', '\u{0}', '\u{0}']), ('\u{10b8}', ['\u{2d18}', '\u{0}', '\u{0}']), - ('\u{10b9}', ['\u{2d19}', '\u{0}', '\u{0}']), ('\u{10ba}', ['\u{2d1a}', '\u{0}', '\u{0}']), - ('\u{10bb}', ['\u{2d1b}', '\u{0}', '\u{0}']), ('\u{10bc}', ['\u{2d1c}', '\u{0}', '\u{0}']), - ('\u{10bd}', ['\u{2d1d}', '\u{0}', '\u{0}']), ('\u{10be}', ['\u{2d1e}', '\u{0}', '\u{0}']), - ('\u{10bf}', ['\u{2d1f}', '\u{0}', '\u{0}']), ('\u{10c0}', ['\u{2d20}', '\u{0}', '\u{0}']), - ('\u{10c1}', ['\u{2d21}', '\u{0}', '\u{0}']), ('\u{10c2}', ['\u{2d22}', '\u{0}', '\u{0}']), - ('\u{10c3}', ['\u{2d23}', '\u{0}', '\u{0}']), ('\u{10c4}', ['\u{2d24}', '\u{0}', '\u{0}']), - ('\u{10c5}', ['\u{2d25}', '\u{0}', '\u{0}']), ('\u{10c7}', ['\u{2d27}', '\u{0}', '\u{0}']), - ('\u{10cd}', ['\u{2d2d}', '\u{0}', '\u{0}']), ('\u{13a0}', ['\u{ab70}', '\u{0}', '\u{0}']), - ('\u{13a1}', ['\u{ab71}', '\u{0}', '\u{0}']), ('\u{13a2}', ['\u{ab72}', '\u{0}', '\u{0}']), - ('\u{13a3}', ['\u{ab73}', '\u{0}', '\u{0}']), ('\u{13a4}', ['\u{ab74}', '\u{0}', '\u{0}']), - ('\u{13a5}', ['\u{ab75}', '\u{0}', '\u{0}']), ('\u{13a6}', ['\u{ab76}', '\u{0}', '\u{0}']), - ('\u{13a7}', ['\u{ab77}', '\u{0}', '\u{0}']), ('\u{13a8}', ['\u{ab78}', '\u{0}', '\u{0}']), - ('\u{13a9}', ['\u{ab79}', '\u{0}', '\u{0}']), ('\u{13aa}', ['\u{ab7a}', '\u{0}', '\u{0}']), - ('\u{13ab}', ['\u{ab7b}', '\u{0}', '\u{0}']), ('\u{13ac}', ['\u{ab7c}', '\u{0}', '\u{0}']), - ('\u{13ad}', ['\u{ab7d}', '\u{0}', '\u{0}']), ('\u{13ae}', ['\u{ab7e}', '\u{0}', '\u{0}']), - ('\u{13af}', ['\u{ab7f}', '\u{0}', '\u{0}']), ('\u{13b0}', ['\u{ab80}', '\u{0}', '\u{0}']), - ('\u{13b1}', ['\u{ab81}', '\u{0}', '\u{0}']), ('\u{13b2}', ['\u{ab82}', '\u{0}', '\u{0}']), - ('\u{13b3}', ['\u{ab83}', '\u{0}', '\u{0}']), ('\u{13b4}', ['\u{ab84}', '\u{0}', '\u{0}']), - ('\u{13b5}', ['\u{ab85}', '\u{0}', '\u{0}']), ('\u{13b6}', ['\u{ab86}', '\u{0}', '\u{0}']), - ('\u{13b7}', ['\u{ab87}', '\u{0}', '\u{0}']), ('\u{13b8}', ['\u{ab88}', '\u{0}', '\u{0}']), - ('\u{13b9}', ['\u{ab89}', '\u{0}', '\u{0}']), ('\u{13ba}', ['\u{ab8a}', '\u{0}', '\u{0}']), - ('\u{13bb}', ['\u{ab8b}', '\u{0}', '\u{0}']), ('\u{13bc}', ['\u{ab8c}', '\u{0}', '\u{0}']), - ('\u{13bd}', ['\u{ab8d}', '\u{0}', '\u{0}']), ('\u{13be}', ['\u{ab8e}', '\u{0}', '\u{0}']), - ('\u{13bf}', ['\u{ab8f}', '\u{0}', '\u{0}']), ('\u{13c0}', ['\u{ab90}', '\u{0}', '\u{0}']), - ('\u{13c1}', ['\u{ab91}', '\u{0}', '\u{0}']), ('\u{13c2}', ['\u{ab92}', '\u{0}', '\u{0}']), - ('\u{13c3}', ['\u{ab93}', '\u{0}', '\u{0}']), ('\u{13c4}', ['\u{ab94}', '\u{0}', '\u{0}']), - ('\u{13c5}', ['\u{ab95}', '\u{0}', '\u{0}']), ('\u{13c6}', ['\u{ab96}', '\u{0}', '\u{0}']), - ('\u{13c7}', ['\u{ab97}', '\u{0}', '\u{0}']), ('\u{13c8}', ['\u{ab98}', '\u{0}', '\u{0}']), - ('\u{13c9}', ['\u{ab99}', '\u{0}', '\u{0}']), ('\u{13ca}', ['\u{ab9a}', '\u{0}', '\u{0}']), - ('\u{13cb}', ['\u{ab9b}', '\u{0}', '\u{0}']), ('\u{13cc}', ['\u{ab9c}', '\u{0}', '\u{0}']), - ('\u{13cd}', ['\u{ab9d}', '\u{0}', '\u{0}']), ('\u{13ce}', ['\u{ab9e}', '\u{0}', '\u{0}']), - ('\u{13cf}', ['\u{ab9f}', '\u{0}', '\u{0}']), ('\u{13d0}', ['\u{aba0}', '\u{0}', '\u{0}']), - ('\u{13d1}', ['\u{aba1}', '\u{0}', '\u{0}']), ('\u{13d2}', ['\u{aba2}', '\u{0}', '\u{0}']), - ('\u{13d3}', ['\u{aba3}', '\u{0}', '\u{0}']), ('\u{13d4}', ['\u{aba4}', '\u{0}', '\u{0}']), - ('\u{13d5}', ['\u{aba5}', '\u{0}', '\u{0}']), ('\u{13d6}', ['\u{aba6}', '\u{0}', '\u{0}']), - ('\u{13d7}', ['\u{aba7}', '\u{0}', '\u{0}']), ('\u{13d8}', ['\u{aba8}', '\u{0}', '\u{0}']), - ('\u{13d9}', ['\u{aba9}', '\u{0}', '\u{0}']), ('\u{13da}', ['\u{abaa}', '\u{0}', '\u{0}']), - ('\u{13db}', ['\u{abab}', '\u{0}', '\u{0}']), ('\u{13dc}', ['\u{abac}', '\u{0}', '\u{0}']), - ('\u{13dd}', ['\u{abad}', '\u{0}', '\u{0}']), ('\u{13de}', ['\u{abae}', '\u{0}', '\u{0}']), - ('\u{13df}', ['\u{abaf}', '\u{0}', '\u{0}']), ('\u{13e0}', ['\u{abb0}', '\u{0}', '\u{0}']), - ('\u{13e1}', ['\u{abb1}', '\u{0}', '\u{0}']), ('\u{13e2}', ['\u{abb2}', '\u{0}', '\u{0}']), - ('\u{13e3}', ['\u{abb3}', '\u{0}', '\u{0}']), ('\u{13e4}', ['\u{abb4}', '\u{0}', '\u{0}']), - ('\u{13e5}', ['\u{abb5}', '\u{0}', '\u{0}']), ('\u{13e6}', ['\u{abb6}', '\u{0}', '\u{0}']), - ('\u{13e7}', ['\u{abb7}', '\u{0}', '\u{0}']), ('\u{13e8}', ['\u{abb8}', '\u{0}', '\u{0}']), - ('\u{13e9}', ['\u{abb9}', '\u{0}', '\u{0}']), ('\u{13ea}', ['\u{abba}', '\u{0}', '\u{0}']), - ('\u{13eb}', ['\u{abbb}', '\u{0}', '\u{0}']), ('\u{13ec}', ['\u{abbc}', '\u{0}', '\u{0}']), - ('\u{13ed}', ['\u{abbd}', '\u{0}', '\u{0}']), ('\u{13ee}', ['\u{abbe}', '\u{0}', '\u{0}']), - ('\u{13ef}', ['\u{abbf}', '\u{0}', '\u{0}']), ('\u{13f0}', ['\u{13f8}', '\u{0}', '\u{0}']), - ('\u{13f1}', ['\u{13f9}', '\u{0}', '\u{0}']), ('\u{13f2}', ['\u{13fa}', '\u{0}', '\u{0}']), - ('\u{13f3}', ['\u{13fb}', '\u{0}', '\u{0}']), ('\u{13f4}', ['\u{13fc}', '\u{0}', '\u{0}']), - ('\u{13f5}', ['\u{13fd}', '\u{0}', '\u{0}']), ('\u{1c89}', ['\u{1c8a}', '\u{0}', '\u{0}']), - ('\u{1c90}', ['\u{10d0}', '\u{0}', '\u{0}']), ('\u{1c91}', ['\u{10d1}', '\u{0}', '\u{0}']), - ('\u{1c92}', ['\u{10d2}', '\u{0}', '\u{0}']), ('\u{1c93}', ['\u{10d3}', '\u{0}', '\u{0}']), - ('\u{1c94}', ['\u{10d4}', '\u{0}', '\u{0}']), ('\u{1c95}', ['\u{10d5}', '\u{0}', '\u{0}']), - ('\u{1c96}', ['\u{10d6}', '\u{0}', '\u{0}']), ('\u{1c97}', ['\u{10d7}', '\u{0}', '\u{0}']), - ('\u{1c98}', ['\u{10d8}', '\u{0}', '\u{0}']), ('\u{1c99}', ['\u{10d9}', '\u{0}', '\u{0}']), - ('\u{1c9a}', ['\u{10da}', '\u{0}', '\u{0}']), ('\u{1c9b}', ['\u{10db}', '\u{0}', '\u{0}']), - ('\u{1c9c}', ['\u{10dc}', '\u{0}', '\u{0}']), ('\u{1c9d}', ['\u{10dd}', '\u{0}', '\u{0}']), - ('\u{1c9e}', ['\u{10de}', '\u{0}', '\u{0}']), ('\u{1c9f}', ['\u{10df}', '\u{0}', '\u{0}']), - ('\u{1ca0}', ['\u{10e0}', '\u{0}', '\u{0}']), ('\u{1ca1}', ['\u{10e1}', '\u{0}', '\u{0}']), - ('\u{1ca2}', ['\u{10e2}', '\u{0}', '\u{0}']), ('\u{1ca3}', ['\u{10e3}', '\u{0}', '\u{0}']), - ('\u{1ca4}', ['\u{10e4}', '\u{0}', '\u{0}']), ('\u{1ca5}', ['\u{10e5}', '\u{0}', '\u{0}']), - ('\u{1ca6}', ['\u{10e6}', '\u{0}', '\u{0}']), ('\u{1ca7}', ['\u{10e7}', '\u{0}', '\u{0}']), - ('\u{1ca8}', ['\u{10e8}', '\u{0}', '\u{0}']), ('\u{1ca9}', ['\u{10e9}', '\u{0}', '\u{0}']), - ('\u{1caa}', ['\u{10ea}', '\u{0}', '\u{0}']), ('\u{1cab}', ['\u{10eb}', '\u{0}', '\u{0}']), - ('\u{1cac}', ['\u{10ec}', '\u{0}', '\u{0}']), ('\u{1cad}', ['\u{10ed}', '\u{0}', '\u{0}']), - ('\u{1cae}', ['\u{10ee}', '\u{0}', '\u{0}']), ('\u{1caf}', ['\u{10ef}', '\u{0}', '\u{0}']), - ('\u{1cb0}', ['\u{10f0}', '\u{0}', '\u{0}']), ('\u{1cb1}', ['\u{10f1}', '\u{0}', '\u{0}']), - ('\u{1cb2}', ['\u{10f2}', '\u{0}', '\u{0}']), ('\u{1cb3}', ['\u{10f3}', '\u{0}', '\u{0}']), - ('\u{1cb4}', ['\u{10f4}', '\u{0}', '\u{0}']), ('\u{1cb5}', ['\u{10f5}', '\u{0}', '\u{0}']), - ('\u{1cb6}', ['\u{10f6}', '\u{0}', '\u{0}']), ('\u{1cb7}', ['\u{10f7}', '\u{0}', '\u{0}']), - ('\u{1cb8}', ['\u{10f8}', '\u{0}', '\u{0}']), ('\u{1cb9}', ['\u{10f9}', '\u{0}', '\u{0}']), - ('\u{1cba}', ['\u{10fa}', '\u{0}', '\u{0}']), ('\u{1cbd}', ['\u{10fd}', '\u{0}', '\u{0}']), - ('\u{1cbe}', ['\u{10fe}', '\u{0}', '\u{0}']), ('\u{1cbf}', ['\u{10ff}', '\u{0}', '\u{0}']), - ('\u{1e00}', ['\u{1e01}', '\u{0}', '\u{0}']), ('\u{1e02}', ['\u{1e03}', '\u{0}', '\u{0}']), - ('\u{1e04}', ['\u{1e05}', '\u{0}', '\u{0}']), ('\u{1e06}', ['\u{1e07}', '\u{0}', '\u{0}']), - ('\u{1e08}', ['\u{1e09}', '\u{0}', '\u{0}']), ('\u{1e0a}', ['\u{1e0b}', '\u{0}', '\u{0}']), - ('\u{1e0c}', ['\u{1e0d}', '\u{0}', '\u{0}']), ('\u{1e0e}', ['\u{1e0f}', '\u{0}', '\u{0}']), - ('\u{1e10}', ['\u{1e11}', '\u{0}', '\u{0}']), ('\u{1e12}', ['\u{1e13}', '\u{0}', '\u{0}']), - ('\u{1e14}', ['\u{1e15}', '\u{0}', '\u{0}']), ('\u{1e16}', ['\u{1e17}', '\u{0}', '\u{0}']), - ('\u{1e18}', ['\u{1e19}', '\u{0}', '\u{0}']), ('\u{1e1a}', ['\u{1e1b}', '\u{0}', '\u{0}']), - ('\u{1e1c}', ['\u{1e1d}', '\u{0}', '\u{0}']), ('\u{1e1e}', ['\u{1e1f}', '\u{0}', '\u{0}']), - ('\u{1e20}', ['\u{1e21}', '\u{0}', '\u{0}']), ('\u{1e22}', ['\u{1e23}', '\u{0}', '\u{0}']), - ('\u{1e24}', ['\u{1e25}', '\u{0}', '\u{0}']), ('\u{1e26}', ['\u{1e27}', '\u{0}', '\u{0}']), - ('\u{1e28}', ['\u{1e29}', '\u{0}', '\u{0}']), ('\u{1e2a}', ['\u{1e2b}', '\u{0}', '\u{0}']), - ('\u{1e2c}', ['\u{1e2d}', '\u{0}', '\u{0}']), ('\u{1e2e}', ['\u{1e2f}', '\u{0}', '\u{0}']), - ('\u{1e30}', ['\u{1e31}', '\u{0}', '\u{0}']), ('\u{1e32}', ['\u{1e33}', '\u{0}', '\u{0}']), - ('\u{1e34}', ['\u{1e35}', '\u{0}', '\u{0}']), ('\u{1e36}', ['\u{1e37}', '\u{0}', '\u{0}']), - ('\u{1e38}', ['\u{1e39}', '\u{0}', '\u{0}']), ('\u{1e3a}', ['\u{1e3b}', '\u{0}', '\u{0}']), - ('\u{1e3c}', ['\u{1e3d}', '\u{0}', '\u{0}']), ('\u{1e3e}', ['\u{1e3f}', '\u{0}', '\u{0}']), - ('\u{1e40}', ['\u{1e41}', '\u{0}', '\u{0}']), ('\u{1e42}', ['\u{1e43}', '\u{0}', '\u{0}']), - ('\u{1e44}', ['\u{1e45}', '\u{0}', '\u{0}']), ('\u{1e46}', ['\u{1e47}', '\u{0}', '\u{0}']), - ('\u{1e48}', ['\u{1e49}', '\u{0}', '\u{0}']), ('\u{1e4a}', ['\u{1e4b}', '\u{0}', '\u{0}']), - ('\u{1e4c}', ['\u{1e4d}', '\u{0}', '\u{0}']), ('\u{1e4e}', ['\u{1e4f}', '\u{0}', '\u{0}']), - ('\u{1e50}', ['\u{1e51}', '\u{0}', '\u{0}']), ('\u{1e52}', ['\u{1e53}', '\u{0}', '\u{0}']), - ('\u{1e54}', ['\u{1e55}', '\u{0}', '\u{0}']), ('\u{1e56}', ['\u{1e57}', '\u{0}', '\u{0}']), - ('\u{1e58}', ['\u{1e59}', '\u{0}', '\u{0}']), ('\u{1e5a}', ['\u{1e5b}', '\u{0}', '\u{0}']), - ('\u{1e5c}', ['\u{1e5d}', '\u{0}', '\u{0}']), ('\u{1e5e}', ['\u{1e5f}', '\u{0}', '\u{0}']), - ('\u{1e60}', ['\u{1e61}', '\u{0}', '\u{0}']), ('\u{1e62}', ['\u{1e63}', '\u{0}', '\u{0}']), - ('\u{1e64}', ['\u{1e65}', '\u{0}', '\u{0}']), ('\u{1e66}', ['\u{1e67}', '\u{0}', '\u{0}']), - ('\u{1e68}', ['\u{1e69}', '\u{0}', '\u{0}']), ('\u{1e6a}', ['\u{1e6b}', '\u{0}', '\u{0}']), - ('\u{1e6c}', ['\u{1e6d}', '\u{0}', '\u{0}']), ('\u{1e6e}', ['\u{1e6f}', '\u{0}', '\u{0}']), - ('\u{1e70}', ['\u{1e71}', '\u{0}', '\u{0}']), ('\u{1e72}', ['\u{1e73}', '\u{0}', '\u{0}']), - ('\u{1e74}', ['\u{1e75}', '\u{0}', '\u{0}']), ('\u{1e76}', ['\u{1e77}', '\u{0}', '\u{0}']), - ('\u{1e78}', ['\u{1e79}', '\u{0}', '\u{0}']), ('\u{1e7a}', ['\u{1e7b}', '\u{0}', '\u{0}']), - ('\u{1e7c}', ['\u{1e7d}', '\u{0}', '\u{0}']), ('\u{1e7e}', ['\u{1e7f}', '\u{0}', '\u{0}']), - ('\u{1e80}', ['\u{1e81}', '\u{0}', '\u{0}']), ('\u{1e82}', ['\u{1e83}', '\u{0}', '\u{0}']), - ('\u{1e84}', ['\u{1e85}', '\u{0}', '\u{0}']), ('\u{1e86}', ['\u{1e87}', '\u{0}', '\u{0}']), - ('\u{1e88}', ['\u{1e89}', '\u{0}', '\u{0}']), ('\u{1e8a}', ['\u{1e8b}', '\u{0}', '\u{0}']), - ('\u{1e8c}', ['\u{1e8d}', '\u{0}', '\u{0}']), ('\u{1e8e}', ['\u{1e8f}', '\u{0}', '\u{0}']), - ('\u{1e90}', ['\u{1e91}', '\u{0}', '\u{0}']), ('\u{1e92}', ['\u{1e93}', '\u{0}', '\u{0}']), - ('\u{1e94}', ['\u{1e95}', '\u{0}', '\u{0}']), ('\u{1e9e}', ['\u{df}', '\u{0}', '\u{0}']), - ('\u{1ea0}', ['\u{1ea1}', '\u{0}', '\u{0}']), ('\u{1ea2}', ['\u{1ea3}', '\u{0}', '\u{0}']), - ('\u{1ea4}', ['\u{1ea5}', '\u{0}', '\u{0}']), ('\u{1ea6}', ['\u{1ea7}', '\u{0}', '\u{0}']), - ('\u{1ea8}', ['\u{1ea9}', '\u{0}', '\u{0}']), ('\u{1eaa}', ['\u{1eab}', '\u{0}', '\u{0}']), - ('\u{1eac}', ['\u{1ead}', '\u{0}', '\u{0}']), ('\u{1eae}', ['\u{1eaf}', '\u{0}', '\u{0}']), - ('\u{1eb0}', ['\u{1eb1}', '\u{0}', '\u{0}']), ('\u{1eb2}', ['\u{1eb3}', '\u{0}', '\u{0}']), - ('\u{1eb4}', ['\u{1eb5}', '\u{0}', '\u{0}']), ('\u{1eb6}', ['\u{1eb7}', '\u{0}', '\u{0}']), - ('\u{1eb8}', ['\u{1eb9}', '\u{0}', '\u{0}']), ('\u{1eba}', ['\u{1ebb}', '\u{0}', '\u{0}']), - ('\u{1ebc}', ['\u{1ebd}', '\u{0}', '\u{0}']), ('\u{1ebe}', ['\u{1ebf}', '\u{0}', '\u{0}']), - ('\u{1ec0}', ['\u{1ec1}', '\u{0}', '\u{0}']), ('\u{1ec2}', ['\u{1ec3}', '\u{0}', '\u{0}']), - ('\u{1ec4}', ['\u{1ec5}', '\u{0}', '\u{0}']), ('\u{1ec6}', ['\u{1ec7}', '\u{0}', '\u{0}']), - ('\u{1ec8}', ['\u{1ec9}', '\u{0}', '\u{0}']), ('\u{1eca}', ['\u{1ecb}', '\u{0}', '\u{0}']), - ('\u{1ecc}', ['\u{1ecd}', '\u{0}', '\u{0}']), ('\u{1ece}', ['\u{1ecf}', '\u{0}', '\u{0}']), - ('\u{1ed0}', ['\u{1ed1}', '\u{0}', '\u{0}']), ('\u{1ed2}', ['\u{1ed3}', '\u{0}', '\u{0}']), - ('\u{1ed4}', ['\u{1ed5}', '\u{0}', '\u{0}']), ('\u{1ed6}', ['\u{1ed7}', '\u{0}', '\u{0}']), - ('\u{1ed8}', ['\u{1ed9}', '\u{0}', '\u{0}']), ('\u{1eda}', ['\u{1edb}', '\u{0}', '\u{0}']), - ('\u{1edc}', ['\u{1edd}', '\u{0}', '\u{0}']), ('\u{1ede}', ['\u{1edf}', '\u{0}', '\u{0}']), - ('\u{1ee0}', ['\u{1ee1}', '\u{0}', '\u{0}']), ('\u{1ee2}', ['\u{1ee3}', '\u{0}', '\u{0}']), - ('\u{1ee4}', ['\u{1ee5}', '\u{0}', '\u{0}']), ('\u{1ee6}', ['\u{1ee7}', '\u{0}', '\u{0}']), - ('\u{1ee8}', ['\u{1ee9}', '\u{0}', '\u{0}']), ('\u{1eea}', ['\u{1eeb}', '\u{0}', '\u{0}']), - ('\u{1eec}', ['\u{1eed}', '\u{0}', '\u{0}']), ('\u{1eee}', ['\u{1eef}', '\u{0}', '\u{0}']), - ('\u{1ef0}', ['\u{1ef1}', '\u{0}', '\u{0}']), ('\u{1ef2}', ['\u{1ef3}', '\u{0}', '\u{0}']), - ('\u{1ef4}', ['\u{1ef5}', '\u{0}', '\u{0}']), ('\u{1ef6}', ['\u{1ef7}', '\u{0}', '\u{0}']), - ('\u{1ef8}', ['\u{1ef9}', '\u{0}', '\u{0}']), ('\u{1efa}', ['\u{1efb}', '\u{0}', '\u{0}']), - ('\u{1efc}', ['\u{1efd}', '\u{0}', '\u{0}']), ('\u{1efe}', ['\u{1eff}', '\u{0}', '\u{0}']), - ('\u{1f08}', ['\u{1f00}', '\u{0}', '\u{0}']), ('\u{1f09}', ['\u{1f01}', '\u{0}', '\u{0}']), - ('\u{1f0a}', ['\u{1f02}', '\u{0}', '\u{0}']), ('\u{1f0b}', ['\u{1f03}', '\u{0}', '\u{0}']), - ('\u{1f0c}', ['\u{1f04}', '\u{0}', '\u{0}']), ('\u{1f0d}', ['\u{1f05}', '\u{0}', '\u{0}']), - ('\u{1f0e}', ['\u{1f06}', '\u{0}', '\u{0}']), ('\u{1f0f}', ['\u{1f07}', '\u{0}', '\u{0}']), - ('\u{1f18}', ['\u{1f10}', '\u{0}', '\u{0}']), ('\u{1f19}', ['\u{1f11}', '\u{0}', '\u{0}']), - ('\u{1f1a}', ['\u{1f12}', '\u{0}', '\u{0}']), ('\u{1f1b}', ['\u{1f13}', '\u{0}', '\u{0}']), - ('\u{1f1c}', ['\u{1f14}', '\u{0}', '\u{0}']), ('\u{1f1d}', ['\u{1f15}', '\u{0}', '\u{0}']), - ('\u{1f28}', ['\u{1f20}', '\u{0}', '\u{0}']), ('\u{1f29}', ['\u{1f21}', '\u{0}', '\u{0}']), - ('\u{1f2a}', ['\u{1f22}', '\u{0}', '\u{0}']), ('\u{1f2b}', ['\u{1f23}', '\u{0}', '\u{0}']), - ('\u{1f2c}', ['\u{1f24}', '\u{0}', '\u{0}']), ('\u{1f2d}', ['\u{1f25}', '\u{0}', '\u{0}']), - ('\u{1f2e}', ['\u{1f26}', '\u{0}', '\u{0}']), ('\u{1f2f}', ['\u{1f27}', '\u{0}', '\u{0}']), - ('\u{1f38}', ['\u{1f30}', '\u{0}', '\u{0}']), ('\u{1f39}', ['\u{1f31}', '\u{0}', '\u{0}']), - ('\u{1f3a}', ['\u{1f32}', '\u{0}', '\u{0}']), ('\u{1f3b}', ['\u{1f33}', '\u{0}', '\u{0}']), - ('\u{1f3c}', ['\u{1f34}', '\u{0}', '\u{0}']), ('\u{1f3d}', ['\u{1f35}', '\u{0}', '\u{0}']), - ('\u{1f3e}', ['\u{1f36}', '\u{0}', '\u{0}']), ('\u{1f3f}', ['\u{1f37}', '\u{0}', '\u{0}']), - ('\u{1f48}', ['\u{1f40}', '\u{0}', '\u{0}']), ('\u{1f49}', ['\u{1f41}', '\u{0}', '\u{0}']), - ('\u{1f4a}', ['\u{1f42}', '\u{0}', '\u{0}']), ('\u{1f4b}', ['\u{1f43}', '\u{0}', '\u{0}']), - ('\u{1f4c}', ['\u{1f44}', '\u{0}', '\u{0}']), ('\u{1f4d}', ['\u{1f45}', '\u{0}', '\u{0}']), - ('\u{1f59}', ['\u{1f51}', '\u{0}', '\u{0}']), ('\u{1f5b}', ['\u{1f53}', '\u{0}', '\u{0}']), - ('\u{1f5d}', ['\u{1f55}', '\u{0}', '\u{0}']), ('\u{1f5f}', ['\u{1f57}', '\u{0}', '\u{0}']), - ('\u{1f68}', ['\u{1f60}', '\u{0}', '\u{0}']), ('\u{1f69}', ['\u{1f61}', '\u{0}', '\u{0}']), - ('\u{1f6a}', ['\u{1f62}', '\u{0}', '\u{0}']), ('\u{1f6b}', ['\u{1f63}', '\u{0}', '\u{0}']), - ('\u{1f6c}', ['\u{1f64}', '\u{0}', '\u{0}']), ('\u{1f6d}', ['\u{1f65}', '\u{0}', '\u{0}']), - ('\u{1f6e}', ['\u{1f66}', '\u{0}', '\u{0}']), ('\u{1f6f}', ['\u{1f67}', '\u{0}', '\u{0}']), - ('\u{1f88}', ['\u{1f80}', '\u{0}', '\u{0}']), ('\u{1f89}', ['\u{1f81}', '\u{0}', '\u{0}']), - ('\u{1f8a}', ['\u{1f82}', '\u{0}', '\u{0}']), ('\u{1f8b}', ['\u{1f83}', '\u{0}', '\u{0}']), - ('\u{1f8c}', ['\u{1f84}', '\u{0}', '\u{0}']), ('\u{1f8d}', ['\u{1f85}', '\u{0}', '\u{0}']), - ('\u{1f8e}', ['\u{1f86}', '\u{0}', '\u{0}']), ('\u{1f8f}', ['\u{1f87}', '\u{0}', '\u{0}']), - ('\u{1f98}', ['\u{1f90}', '\u{0}', '\u{0}']), ('\u{1f99}', ['\u{1f91}', '\u{0}', '\u{0}']), - ('\u{1f9a}', ['\u{1f92}', '\u{0}', '\u{0}']), ('\u{1f9b}', ['\u{1f93}', '\u{0}', '\u{0}']), - ('\u{1f9c}', ['\u{1f94}', '\u{0}', '\u{0}']), ('\u{1f9d}', ['\u{1f95}', '\u{0}', '\u{0}']), - ('\u{1f9e}', ['\u{1f96}', '\u{0}', '\u{0}']), ('\u{1f9f}', ['\u{1f97}', '\u{0}', '\u{0}']), - ('\u{1fa8}', ['\u{1fa0}', '\u{0}', '\u{0}']), ('\u{1fa9}', ['\u{1fa1}', '\u{0}', '\u{0}']), - ('\u{1faa}', ['\u{1fa2}', '\u{0}', '\u{0}']), ('\u{1fab}', ['\u{1fa3}', '\u{0}', '\u{0}']), - ('\u{1fac}', ['\u{1fa4}', '\u{0}', '\u{0}']), ('\u{1fad}', ['\u{1fa5}', '\u{0}', '\u{0}']), - ('\u{1fae}', ['\u{1fa6}', '\u{0}', '\u{0}']), ('\u{1faf}', ['\u{1fa7}', '\u{0}', '\u{0}']), - ('\u{1fb8}', ['\u{1fb0}', '\u{0}', '\u{0}']), ('\u{1fb9}', ['\u{1fb1}', '\u{0}', '\u{0}']), - ('\u{1fba}', ['\u{1f70}', '\u{0}', '\u{0}']), ('\u{1fbb}', ['\u{1f71}', '\u{0}', '\u{0}']), - ('\u{1fbc}', ['\u{1fb3}', '\u{0}', '\u{0}']), ('\u{1fc8}', ['\u{1f72}', '\u{0}', '\u{0}']), - ('\u{1fc9}', ['\u{1f73}', '\u{0}', '\u{0}']), ('\u{1fca}', ['\u{1f74}', '\u{0}', '\u{0}']), - ('\u{1fcb}', ['\u{1f75}', '\u{0}', '\u{0}']), ('\u{1fcc}', ['\u{1fc3}', '\u{0}', '\u{0}']), - ('\u{1fd8}', ['\u{1fd0}', '\u{0}', '\u{0}']), ('\u{1fd9}', ['\u{1fd1}', '\u{0}', '\u{0}']), - ('\u{1fda}', ['\u{1f76}', '\u{0}', '\u{0}']), ('\u{1fdb}', ['\u{1f77}', '\u{0}', '\u{0}']), - ('\u{1fe8}', ['\u{1fe0}', '\u{0}', '\u{0}']), ('\u{1fe9}', ['\u{1fe1}', '\u{0}', '\u{0}']), - ('\u{1fea}', ['\u{1f7a}', '\u{0}', '\u{0}']), ('\u{1feb}', ['\u{1f7b}', '\u{0}', '\u{0}']), - ('\u{1fec}', ['\u{1fe5}', '\u{0}', '\u{0}']), ('\u{1ff8}', ['\u{1f78}', '\u{0}', '\u{0}']), - ('\u{1ff9}', ['\u{1f79}', '\u{0}', '\u{0}']), ('\u{1ffa}', ['\u{1f7c}', '\u{0}', '\u{0}']), - ('\u{1ffb}', ['\u{1f7d}', '\u{0}', '\u{0}']), ('\u{1ffc}', ['\u{1ff3}', '\u{0}', '\u{0}']), - ('\u{2126}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{212a}', ['\u{6b}', '\u{0}', '\u{0}']), - ('\u{212b}', ['\u{e5}', '\u{0}', '\u{0}']), ('\u{2132}', ['\u{214e}', '\u{0}', '\u{0}']), - ('\u{2160}', ['\u{2170}', '\u{0}', '\u{0}']), ('\u{2161}', ['\u{2171}', '\u{0}', '\u{0}']), - ('\u{2162}', ['\u{2172}', '\u{0}', '\u{0}']), ('\u{2163}', ['\u{2173}', '\u{0}', '\u{0}']), - ('\u{2164}', ['\u{2174}', '\u{0}', '\u{0}']), ('\u{2165}', ['\u{2175}', '\u{0}', '\u{0}']), - ('\u{2166}', ['\u{2176}', '\u{0}', '\u{0}']), ('\u{2167}', ['\u{2177}', '\u{0}', '\u{0}']), - ('\u{2168}', ['\u{2178}', '\u{0}', '\u{0}']), ('\u{2169}', ['\u{2179}', '\u{0}', '\u{0}']), - ('\u{216a}', ['\u{217a}', '\u{0}', '\u{0}']), ('\u{216b}', ['\u{217b}', '\u{0}', '\u{0}']), - ('\u{216c}', ['\u{217c}', '\u{0}', '\u{0}']), ('\u{216d}', ['\u{217d}', '\u{0}', '\u{0}']), - ('\u{216e}', ['\u{217e}', '\u{0}', '\u{0}']), ('\u{216f}', ['\u{217f}', '\u{0}', '\u{0}']), - ('\u{2183}', ['\u{2184}', '\u{0}', '\u{0}']), ('\u{24b6}', ['\u{24d0}', '\u{0}', '\u{0}']), - ('\u{24b7}', ['\u{24d1}', '\u{0}', '\u{0}']), ('\u{24b8}', ['\u{24d2}', '\u{0}', '\u{0}']), - ('\u{24b9}', ['\u{24d3}', '\u{0}', '\u{0}']), ('\u{24ba}', ['\u{24d4}', '\u{0}', '\u{0}']), - ('\u{24bb}', ['\u{24d5}', '\u{0}', '\u{0}']), ('\u{24bc}', ['\u{24d6}', '\u{0}', '\u{0}']), - ('\u{24bd}', ['\u{24d7}', '\u{0}', '\u{0}']), ('\u{24be}', ['\u{24d8}', '\u{0}', '\u{0}']), - ('\u{24bf}', ['\u{24d9}', '\u{0}', '\u{0}']), ('\u{24c0}', ['\u{24da}', '\u{0}', '\u{0}']), - ('\u{24c1}', ['\u{24db}', '\u{0}', '\u{0}']), ('\u{24c2}', ['\u{24dc}', '\u{0}', '\u{0}']), - ('\u{24c3}', ['\u{24dd}', '\u{0}', '\u{0}']), ('\u{24c4}', ['\u{24de}', '\u{0}', '\u{0}']), - ('\u{24c5}', ['\u{24df}', '\u{0}', '\u{0}']), ('\u{24c6}', ['\u{24e0}', '\u{0}', '\u{0}']), - ('\u{24c7}', ['\u{24e1}', '\u{0}', '\u{0}']), ('\u{24c8}', ['\u{24e2}', '\u{0}', '\u{0}']), - ('\u{24c9}', ['\u{24e3}', '\u{0}', '\u{0}']), ('\u{24ca}', ['\u{24e4}', '\u{0}', '\u{0}']), - ('\u{24cb}', ['\u{24e5}', '\u{0}', '\u{0}']), ('\u{24cc}', ['\u{24e6}', '\u{0}', '\u{0}']), - ('\u{24cd}', ['\u{24e7}', '\u{0}', '\u{0}']), ('\u{24ce}', ['\u{24e8}', '\u{0}', '\u{0}']), - ('\u{24cf}', ['\u{24e9}', '\u{0}', '\u{0}']), ('\u{2c00}', ['\u{2c30}', '\u{0}', '\u{0}']), - ('\u{2c01}', ['\u{2c31}', '\u{0}', '\u{0}']), ('\u{2c02}', ['\u{2c32}', '\u{0}', '\u{0}']), - ('\u{2c03}', ['\u{2c33}', '\u{0}', '\u{0}']), ('\u{2c04}', ['\u{2c34}', '\u{0}', '\u{0}']), - ('\u{2c05}', ['\u{2c35}', '\u{0}', '\u{0}']), ('\u{2c06}', ['\u{2c36}', '\u{0}', '\u{0}']), - ('\u{2c07}', ['\u{2c37}', '\u{0}', '\u{0}']), ('\u{2c08}', ['\u{2c38}', '\u{0}', '\u{0}']), - ('\u{2c09}', ['\u{2c39}', '\u{0}', '\u{0}']), ('\u{2c0a}', ['\u{2c3a}', '\u{0}', '\u{0}']), - ('\u{2c0b}', ['\u{2c3b}', '\u{0}', '\u{0}']), ('\u{2c0c}', ['\u{2c3c}', '\u{0}', '\u{0}']), - ('\u{2c0d}', ['\u{2c3d}', '\u{0}', '\u{0}']), ('\u{2c0e}', ['\u{2c3e}', '\u{0}', '\u{0}']), - ('\u{2c0f}', ['\u{2c3f}', '\u{0}', '\u{0}']), ('\u{2c10}', ['\u{2c40}', '\u{0}', '\u{0}']), - ('\u{2c11}', ['\u{2c41}', '\u{0}', '\u{0}']), ('\u{2c12}', ['\u{2c42}', '\u{0}', '\u{0}']), - ('\u{2c13}', ['\u{2c43}', '\u{0}', '\u{0}']), ('\u{2c14}', ['\u{2c44}', '\u{0}', '\u{0}']), - ('\u{2c15}', ['\u{2c45}', '\u{0}', '\u{0}']), ('\u{2c16}', ['\u{2c46}', '\u{0}', '\u{0}']), - ('\u{2c17}', ['\u{2c47}', '\u{0}', '\u{0}']), ('\u{2c18}', ['\u{2c48}', '\u{0}', '\u{0}']), - ('\u{2c19}', ['\u{2c49}', '\u{0}', '\u{0}']), ('\u{2c1a}', ['\u{2c4a}', '\u{0}', '\u{0}']), - ('\u{2c1b}', ['\u{2c4b}', '\u{0}', '\u{0}']), ('\u{2c1c}', ['\u{2c4c}', '\u{0}', '\u{0}']), - ('\u{2c1d}', ['\u{2c4d}', '\u{0}', '\u{0}']), ('\u{2c1e}', ['\u{2c4e}', '\u{0}', '\u{0}']), - ('\u{2c1f}', ['\u{2c4f}', '\u{0}', '\u{0}']), ('\u{2c20}', ['\u{2c50}', '\u{0}', '\u{0}']), - ('\u{2c21}', ['\u{2c51}', '\u{0}', '\u{0}']), ('\u{2c22}', ['\u{2c52}', '\u{0}', '\u{0}']), - ('\u{2c23}', ['\u{2c53}', '\u{0}', '\u{0}']), ('\u{2c24}', ['\u{2c54}', '\u{0}', '\u{0}']), - ('\u{2c25}', ['\u{2c55}', '\u{0}', '\u{0}']), ('\u{2c26}', ['\u{2c56}', '\u{0}', '\u{0}']), - ('\u{2c27}', ['\u{2c57}', '\u{0}', '\u{0}']), ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), - ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']), ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), - ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']), ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), - ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']), ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), - ('\u{2c2f}', ['\u{2c5f}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), - ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), - ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), - ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), - ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), - ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), - ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), - ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), - ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), - ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), - ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), - ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), - ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), - ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), - ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), - ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), - ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), - ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), - ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), - ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), - ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), - ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), - ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), - ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), - ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), - ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), - ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), - ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), - ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), - ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), - ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), - ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), - ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), - ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), - ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), - ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), - ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), - ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), - ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), - ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), - ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), - ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), - ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), - ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), - ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), - ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), - ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), - ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), - ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), - ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), - ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), - ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), - ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), - ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), - ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), - ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), - ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), - ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), - ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), - ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), - ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), - ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), - ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), - ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), - ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), - ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), - ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), - ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), - ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), - ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), - ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), - ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), - ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), - ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), - ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), - ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), - ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), - ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), - ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), - ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), - ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), - ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), - ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), - ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), - ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), - ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), - ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), - ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), - ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), - ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), - ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c0}', ['\u{a7c1}', '\u{0}', '\u{0}']), - ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']), ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), - ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']), ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), - ('\u{a7c7}', ['\u{a7c8}', '\u{0}', '\u{0}']), ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), - ('\u{a7cb}', ['\u{264}', '\u{0}', '\u{0}']), ('\u{a7cc}', ['\u{a7cd}', '\u{0}', '\u{0}']), - ('\u{a7ce}', ['\u{a7cf}', '\u{0}', '\u{0}']), ('\u{a7d0}', ['\u{a7d1}', '\u{0}', '\u{0}']), - ('\u{a7d2}', ['\u{a7d3}', '\u{0}', '\u{0}']), ('\u{a7d4}', ['\u{a7d5}', '\u{0}', '\u{0}']), - ('\u{a7d6}', ['\u{a7d7}', '\u{0}', '\u{0}']), ('\u{a7d8}', ['\u{a7d9}', '\u{0}', '\u{0}']), - ('\u{a7da}', ['\u{a7db}', '\u{0}', '\u{0}']), ('\u{a7dc}', ['\u{19b}', '\u{0}', '\u{0}']), - ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), - ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), - ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), - ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), - ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), - ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), - ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), - ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), - ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), - ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), - ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), - ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), - ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), - ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']), - ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']), - ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']), - ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']), - ('\u{10403}', ['\u{1042b}', '\u{0}', '\u{0}']), - ('\u{10404}', ['\u{1042c}', '\u{0}', '\u{0}']), - ('\u{10405}', ['\u{1042d}', '\u{0}', '\u{0}']), - ('\u{10406}', ['\u{1042e}', '\u{0}', '\u{0}']), - ('\u{10407}', ['\u{1042f}', '\u{0}', '\u{0}']), - ('\u{10408}', ['\u{10430}', '\u{0}', '\u{0}']), - ('\u{10409}', ['\u{10431}', '\u{0}', '\u{0}']), - ('\u{1040a}', ['\u{10432}', '\u{0}', '\u{0}']), - ('\u{1040b}', ['\u{10433}', '\u{0}', '\u{0}']), - ('\u{1040c}', ['\u{10434}', '\u{0}', '\u{0}']), - ('\u{1040d}', ['\u{10435}', '\u{0}', '\u{0}']), - ('\u{1040e}', ['\u{10436}', '\u{0}', '\u{0}']), - ('\u{1040f}', ['\u{10437}', '\u{0}', '\u{0}']), - ('\u{10410}', ['\u{10438}', '\u{0}', '\u{0}']), - ('\u{10411}', ['\u{10439}', '\u{0}', '\u{0}']), - ('\u{10412}', ['\u{1043a}', '\u{0}', '\u{0}']), - ('\u{10413}', ['\u{1043b}', '\u{0}', '\u{0}']), - ('\u{10414}', ['\u{1043c}', '\u{0}', '\u{0}']), - ('\u{10415}', ['\u{1043d}', '\u{0}', '\u{0}']), - ('\u{10416}', ['\u{1043e}', '\u{0}', '\u{0}']), - ('\u{10417}', ['\u{1043f}', '\u{0}', '\u{0}']), - ('\u{10418}', ['\u{10440}', '\u{0}', '\u{0}']), - ('\u{10419}', ['\u{10441}', '\u{0}', '\u{0}']), - ('\u{1041a}', ['\u{10442}', '\u{0}', '\u{0}']), - ('\u{1041b}', ['\u{10443}', '\u{0}', '\u{0}']), - ('\u{1041c}', ['\u{10444}', '\u{0}', '\u{0}']), - ('\u{1041d}', ['\u{10445}', '\u{0}', '\u{0}']), - ('\u{1041e}', ['\u{10446}', '\u{0}', '\u{0}']), - ('\u{1041f}', ['\u{10447}', '\u{0}', '\u{0}']), - ('\u{10420}', ['\u{10448}', '\u{0}', '\u{0}']), - ('\u{10421}', ['\u{10449}', '\u{0}', '\u{0}']), - ('\u{10422}', ['\u{1044a}', '\u{0}', '\u{0}']), - ('\u{10423}', ['\u{1044b}', '\u{0}', '\u{0}']), - ('\u{10424}', ['\u{1044c}', '\u{0}', '\u{0}']), - ('\u{10425}', ['\u{1044d}', '\u{0}', '\u{0}']), - ('\u{10426}', ['\u{1044e}', '\u{0}', '\u{0}']), - ('\u{10427}', ['\u{1044f}', '\u{0}', '\u{0}']), - ('\u{104b0}', ['\u{104d8}', '\u{0}', '\u{0}']), - ('\u{104b1}', ['\u{104d9}', '\u{0}', '\u{0}']), - ('\u{104b2}', ['\u{104da}', '\u{0}', '\u{0}']), - ('\u{104b3}', ['\u{104db}', '\u{0}', '\u{0}']), - ('\u{104b4}', ['\u{104dc}', '\u{0}', '\u{0}']), - ('\u{104b5}', ['\u{104dd}', '\u{0}', '\u{0}']), - ('\u{104b6}', ['\u{104de}', '\u{0}', '\u{0}']), - ('\u{104b7}', ['\u{104df}', '\u{0}', '\u{0}']), - ('\u{104b8}', ['\u{104e0}', '\u{0}', '\u{0}']), - ('\u{104b9}', ['\u{104e1}', '\u{0}', '\u{0}']), - ('\u{104ba}', ['\u{104e2}', '\u{0}', '\u{0}']), - ('\u{104bb}', ['\u{104e3}', '\u{0}', '\u{0}']), - ('\u{104bc}', ['\u{104e4}', '\u{0}', '\u{0}']), - ('\u{104bd}', ['\u{104e5}', '\u{0}', '\u{0}']), - ('\u{104be}', ['\u{104e6}', '\u{0}', '\u{0}']), - ('\u{104bf}', ['\u{104e7}', '\u{0}', '\u{0}']), - ('\u{104c0}', ['\u{104e8}', '\u{0}', '\u{0}']), - ('\u{104c1}', ['\u{104e9}', '\u{0}', '\u{0}']), - ('\u{104c2}', ['\u{104ea}', '\u{0}', '\u{0}']), - ('\u{104c3}', ['\u{104eb}', '\u{0}', '\u{0}']), - ('\u{104c4}', ['\u{104ec}', '\u{0}', '\u{0}']), - ('\u{104c5}', ['\u{104ed}', '\u{0}', '\u{0}']), - ('\u{104c6}', ['\u{104ee}', '\u{0}', '\u{0}']), - ('\u{104c7}', ['\u{104ef}', '\u{0}', '\u{0}']), - ('\u{104c8}', ['\u{104f0}', '\u{0}', '\u{0}']), - ('\u{104c9}', ['\u{104f1}', '\u{0}', '\u{0}']), - ('\u{104ca}', ['\u{104f2}', '\u{0}', '\u{0}']), - ('\u{104cb}', ['\u{104f3}', '\u{0}', '\u{0}']), - ('\u{104cc}', ['\u{104f4}', '\u{0}', '\u{0}']), - ('\u{104cd}', ['\u{104f5}', '\u{0}', '\u{0}']), - ('\u{104ce}', ['\u{104f6}', '\u{0}', '\u{0}']), - ('\u{104cf}', ['\u{104f7}', '\u{0}', '\u{0}']), - ('\u{104d0}', ['\u{104f8}', '\u{0}', '\u{0}']), - ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']), - ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']), - ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']), - ('\u{10570}', ['\u{10597}', '\u{0}', '\u{0}']), - ('\u{10571}', ['\u{10598}', '\u{0}', '\u{0}']), - ('\u{10572}', ['\u{10599}', '\u{0}', '\u{0}']), - ('\u{10573}', ['\u{1059a}', '\u{0}', '\u{0}']), - ('\u{10574}', ['\u{1059b}', '\u{0}', '\u{0}']), - ('\u{10575}', ['\u{1059c}', '\u{0}', '\u{0}']), - ('\u{10576}', ['\u{1059d}', '\u{0}', '\u{0}']), - ('\u{10577}', ['\u{1059e}', '\u{0}', '\u{0}']), - ('\u{10578}', ['\u{1059f}', '\u{0}', '\u{0}']), - ('\u{10579}', ['\u{105a0}', '\u{0}', '\u{0}']), - ('\u{1057a}', ['\u{105a1}', '\u{0}', '\u{0}']), - ('\u{1057c}', ['\u{105a3}', '\u{0}', '\u{0}']), - ('\u{1057d}', ['\u{105a4}', '\u{0}', '\u{0}']), - ('\u{1057e}', ['\u{105a5}', '\u{0}', '\u{0}']), - ('\u{1057f}', ['\u{105a6}', '\u{0}', '\u{0}']), - ('\u{10580}', ['\u{105a7}', '\u{0}', '\u{0}']), - ('\u{10581}', ['\u{105a8}', '\u{0}', '\u{0}']), - ('\u{10582}', ['\u{105a9}', '\u{0}', '\u{0}']), - ('\u{10583}', ['\u{105aa}', '\u{0}', '\u{0}']), - ('\u{10584}', ['\u{105ab}', '\u{0}', '\u{0}']), - ('\u{10585}', ['\u{105ac}', '\u{0}', '\u{0}']), - ('\u{10586}', ['\u{105ad}', '\u{0}', '\u{0}']), - ('\u{10587}', ['\u{105ae}', '\u{0}', '\u{0}']), - ('\u{10588}', ['\u{105af}', '\u{0}', '\u{0}']), - ('\u{10589}', ['\u{105b0}', '\u{0}', '\u{0}']), - ('\u{1058a}', ['\u{105b1}', '\u{0}', '\u{0}']), - ('\u{1058c}', ['\u{105b3}', '\u{0}', '\u{0}']), - ('\u{1058d}', ['\u{105b4}', '\u{0}', '\u{0}']), - ('\u{1058e}', ['\u{105b5}', '\u{0}', '\u{0}']), - ('\u{1058f}', ['\u{105b6}', '\u{0}', '\u{0}']), - ('\u{10590}', ['\u{105b7}', '\u{0}', '\u{0}']), - ('\u{10591}', ['\u{105b8}', '\u{0}', '\u{0}']), - ('\u{10592}', ['\u{105b9}', '\u{0}', '\u{0}']), - ('\u{10594}', ['\u{105bb}', '\u{0}', '\u{0}']), - ('\u{10595}', ['\u{105bc}', '\u{0}', '\u{0}']), - ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']), - ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']), - ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']), - ('\u{10c83}', ['\u{10cc3}', '\u{0}', '\u{0}']), - ('\u{10c84}', ['\u{10cc4}', '\u{0}', '\u{0}']), - ('\u{10c85}', ['\u{10cc5}', '\u{0}', '\u{0}']), - ('\u{10c86}', ['\u{10cc6}', '\u{0}', '\u{0}']), - ('\u{10c87}', ['\u{10cc7}', '\u{0}', '\u{0}']), - ('\u{10c88}', ['\u{10cc8}', '\u{0}', '\u{0}']), - ('\u{10c89}', ['\u{10cc9}', '\u{0}', '\u{0}']), - ('\u{10c8a}', ['\u{10cca}', '\u{0}', '\u{0}']), - ('\u{10c8b}', ['\u{10ccb}', '\u{0}', '\u{0}']), - ('\u{10c8c}', ['\u{10ccc}', '\u{0}', '\u{0}']), - ('\u{10c8d}', ['\u{10ccd}', '\u{0}', '\u{0}']), - ('\u{10c8e}', ['\u{10cce}', '\u{0}', '\u{0}']), - ('\u{10c8f}', ['\u{10ccf}', '\u{0}', '\u{0}']), - ('\u{10c90}', ['\u{10cd0}', '\u{0}', '\u{0}']), - ('\u{10c91}', ['\u{10cd1}', '\u{0}', '\u{0}']), - ('\u{10c92}', ['\u{10cd2}', '\u{0}', '\u{0}']), - ('\u{10c93}', ['\u{10cd3}', '\u{0}', '\u{0}']), - ('\u{10c94}', ['\u{10cd4}', '\u{0}', '\u{0}']), - ('\u{10c95}', ['\u{10cd5}', '\u{0}', '\u{0}']), - ('\u{10c96}', ['\u{10cd6}', '\u{0}', '\u{0}']), - ('\u{10c97}', ['\u{10cd7}', '\u{0}', '\u{0}']), - ('\u{10c98}', ['\u{10cd8}', '\u{0}', '\u{0}']), - ('\u{10c99}', ['\u{10cd9}', '\u{0}', '\u{0}']), - ('\u{10c9a}', ['\u{10cda}', '\u{0}', '\u{0}']), - ('\u{10c9b}', ['\u{10cdb}', '\u{0}', '\u{0}']), - ('\u{10c9c}', ['\u{10cdc}', '\u{0}', '\u{0}']), - ('\u{10c9d}', ['\u{10cdd}', '\u{0}', '\u{0}']), - ('\u{10c9e}', ['\u{10cde}', '\u{0}', '\u{0}']), - ('\u{10c9f}', ['\u{10cdf}', '\u{0}', '\u{0}']), - ('\u{10ca0}', ['\u{10ce0}', '\u{0}', '\u{0}']), - ('\u{10ca1}', ['\u{10ce1}', '\u{0}', '\u{0}']), - ('\u{10ca2}', ['\u{10ce2}', '\u{0}', '\u{0}']), - ('\u{10ca3}', ['\u{10ce3}', '\u{0}', '\u{0}']), - ('\u{10ca4}', ['\u{10ce4}', '\u{0}', '\u{0}']), - ('\u{10ca5}', ['\u{10ce5}', '\u{0}', '\u{0}']), - ('\u{10ca6}', ['\u{10ce6}', '\u{0}', '\u{0}']), - ('\u{10ca7}', ['\u{10ce7}', '\u{0}', '\u{0}']), - ('\u{10ca8}', ['\u{10ce8}', '\u{0}', '\u{0}']), - ('\u{10ca9}', ['\u{10ce9}', '\u{0}', '\u{0}']), - ('\u{10caa}', ['\u{10cea}', '\u{0}', '\u{0}']), - ('\u{10cab}', ['\u{10ceb}', '\u{0}', '\u{0}']), - ('\u{10cac}', ['\u{10cec}', '\u{0}', '\u{0}']), - ('\u{10cad}', ['\u{10ced}', '\u{0}', '\u{0}']), - ('\u{10cae}', ['\u{10cee}', '\u{0}', '\u{0}']), - ('\u{10caf}', ['\u{10cef}', '\u{0}', '\u{0}']), - ('\u{10cb0}', ['\u{10cf0}', '\u{0}', '\u{0}']), - ('\u{10cb1}', ['\u{10cf1}', '\u{0}', '\u{0}']), - ('\u{10cb2}', ['\u{10cf2}', '\u{0}', '\u{0}']), - ('\u{10d50}', ['\u{10d70}', '\u{0}', '\u{0}']), - ('\u{10d51}', ['\u{10d71}', '\u{0}', '\u{0}']), - ('\u{10d52}', ['\u{10d72}', '\u{0}', '\u{0}']), - ('\u{10d53}', ['\u{10d73}', '\u{0}', '\u{0}']), - ('\u{10d54}', ['\u{10d74}', '\u{0}', '\u{0}']), - ('\u{10d55}', ['\u{10d75}', '\u{0}', '\u{0}']), - ('\u{10d56}', ['\u{10d76}', '\u{0}', '\u{0}']), - ('\u{10d57}', ['\u{10d77}', '\u{0}', '\u{0}']), - ('\u{10d58}', ['\u{10d78}', '\u{0}', '\u{0}']), - ('\u{10d59}', ['\u{10d79}', '\u{0}', '\u{0}']), - ('\u{10d5a}', ['\u{10d7a}', '\u{0}', '\u{0}']), - ('\u{10d5b}', ['\u{10d7b}', '\u{0}', '\u{0}']), - ('\u{10d5c}', ['\u{10d7c}', '\u{0}', '\u{0}']), - ('\u{10d5d}', ['\u{10d7d}', '\u{0}', '\u{0}']), - ('\u{10d5e}', ['\u{10d7e}', '\u{0}', '\u{0}']), - ('\u{10d5f}', ['\u{10d7f}', '\u{0}', '\u{0}']), - ('\u{10d60}', ['\u{10d80}', '\u{0}', '\u{0}']), - ('\u{10d61}', ['\u{10d81}', '\u{0}', '\u{0}']), - ('\u{10d62}', ['\u{10d82}', '\u{0}', '\u{0}']), - ('\u{10d63}', ['\u{10d83}', '\u{0}', '\u{0}']), - ('\u{10d64}', ['\u{10d84}', '\u{0}', '\u{0}']), - ('\u{10d65}', ['\u{10d85}', '\u{0}', '\u{0}']), - ('\u{118a0}', ['\u{118c0}', '\u{0}', '\u{0}']), - ('\u{118a1}', ['\u{118c1}', '\u{0}', '\u{0}']), - ('\u{118a2}', ['\u{118c2}', '\u{0}', '\u{0}']), - ('\u{118a3}', ['\u{118c3}', '\u{0}', '\u{0}']), - ('\u{118a4}', ['\u{118c4}', '\u{0}', '\u{0}']), - ('\u{118a5}', ['\u{118c5}', '\u{0}', '\u{0}']), - ('\u{118a6}', ['\u{118c6}', '\u{0}', '\u{0}']), - ('\u{118a7}', ['\u{118c7}', '\u{0}', '\u{0}']), - ('\u{118a8}', ['\u{118c8}', '\u{0}', '\u{0}']), - ('\u{118a9}', ['\u{118c9}', '\u{0}', '\u{0}']), - ('\u{118aa}', ['\u{118ca}', '\u{0}', '\u{0}']), - ('\u{118ab}', ['\u{118cb}', '\u{0}', '\u{0}']), - ('\u{118ac}', ['\u{118cc}', '\u{0}', '\u{0}']), - ('\u{118ad}', ['\u{118cd}', '\u{0}', '\u{0}']), - ('\u{118ae}', ['\u{118ce}', '\u{0}', '\u{0}']), - ('\u{118af}', ['\u{118cf}', '\u{0}', '\u{0}']), - ('\u{118b0}', ['\u{118d0}', '\u{0}', '\u{0}']), - ('\u{118b1}', ['\u{118d1}', '\u{0}', '\u{0}']), - ('\u{118b2}', ['\u{118d2}', '\u{0}', '\u{0}']), - ('\u{118b3}', ['\u{118d3}', '\u{0}', '\u{0}']), - ('\u{118b4}', ['\u{118d4}', '\u{0}', '\u{0}']), - ('\u{118b5}', ['\u{118d5}', '\u{0}', '\u{0}']), - ('\u{118b6}', ['\u{118d6}', '\u{0}', '\u{0}']), - ('\u{118b7}', ['\u{118d7}', '\u{0}', '\u{0}']), - ('\u{118b8}', ['\u{118d8}', '\u{0}', '\u{0}']), - ('\u{118b9}', ['\u{118d9}', '\u{0}', '\u{0}']), - ('\u{118ba}', ['\u{118da}', '\u{0}', '\u{0}']), - ('\u{118bb}', ['\u{118db}', '\u{0}', '\u{0}']), - ('\u{118bc}', ['\u{118dc}', '\u{0}', '\u{0}']), - ('\u{118bd}', ['\u{118dd}', '\u{0}', '\u{0}']), - ('\u{118be}', ['\u{118de}', '\u{0}', '\u{0}']), - ('\u{118bf}', ['\u{118df}', '\u{0}', '\u{0}']), - ('\u{16e40}', ['\u{16e60}', '\u{0}', '\u{0}']), - ('\u{16e41}', ['\u{16e61}', '\u{0}', '\u{0}']), - ('\u{16e42}', ['\u{16e62}', '\u{0}', '\u{0}']), - ('\u{16e43}', ['\u{16e63}', '\u{0}', '\u{0}']), - ('\u{16e44}', ['\u{16e64}', '\u{0}', '\u{0}']), - ('\u{16e45}', ['\u{16e65}', '\u{0}', '\u{0}']), - ('\u{16e46}', ['\u{16e66}', '\u{0}', '\u{0}']), - ('\u{16e47}', ['\u{16e67}', '\u{0}', '\u{0}']), - ('\u{16e48}', ['\u{16e68}', '\u{0}', '\u{0}']), - ('\u{16e49}', ['\u{16e69}', '\u{0}', '\u{0}']), - ('\u{16e4a}', ['\u{16e6a}', '\u{0}', '\u{0}']), - ('\u{16e4b}', ['\u{16e6b}', '\u{0}', '\u{0}']), - ('\u{16e4c}', ['\u{16e6c}', '\u{0}', '\u{0}']), - ('\u{16e4d}', ['\u{16e6d}', '\u{0}', '\u{0}']), - ('\u{16e4e}', ['\u{16e6e}', '\u{0}', '\u{0}']), - ('\u{16e4f}', ['\u{16e6f}', '\u{0}', '\u{0}']), - ('\u{16e50}', ['\u{16e70}', '\u{0}', '\u{0}']), - ('\u{16e51}', ['\u{16e71}', '\u{0}', '\u{0}']), - ('\u{16e52}', ['\u{16e72}', '\u{0}', '\u{0}']), - ('\u{16e53}', ['\u{16e73}', '\u{0}', '\u{0}']), - ('\u{16e54}', ['\u{16e74}', '\u{0}', '\u{0}']), - ('\u{16e55}', ['\u{16e75}', '\u{0}', '\u{0}']), - ('\u{16e56}', ['\u{16e76}', '\u{0}', '\u{0}']), - ('\u{16e57}', ['\u{16e77}', '\u{0}', '\u{0}']), - ('\u{16e58}', ['\u{16e78}', '\u{0}', '\u{0}']), - ('\u{16e59}', ['\u{16e79}', '\u{0}', '\u{0}']), - ('\u{16e5a}', ['\u{16e7a}', '\u{0}', '\u{0}']), - ('\u{16e5b}', ['\u{16e7b}', '\u{0}', '\u{0}']), - ('\u{16e5c}', ['\u{16e7c}', '\u{0}', '\u{0}']), - ('\u{16e5d}', ['\u{16e7d}', '\u{0}', '\u{0}']), - ('\u{16e5e}', ['\u{16e7e}', '\u{0}', '\u{0}']), - ('\u{16e5f}', ['\u{16e7f}', '\u{0}', '\u{0}']), - ('\u{16ea0}', ['\u{16ebb}', '\u{0}', '\u{0}']), - ('\u{16ea1}', ['\u{16ebc}', '\u{0}', '\u{0}']), - ('\u{16ea2}', ['\u{16ebd}', '\u{0}', '\u{0}']), - ('\u{16ea3}', ['\u{16ebe}', '\u{0}', '\u{0}']), - ('\u{16ea4}', ['\u{16ebf}', '\u{0}', '\u{0}']), - ('\u{16ea5}', ['\u{16ec0}', '\u{0}', '\u{0}']), - ('\u{16ea6}', ['\u{16ec1}', '\u{0}', '\u{0}']), - ('\u{16ea7}', ['\u{16ec2}', '\u{0}', '\u{0}']), - ('\u{16ea8}', ['\u{16ec3}', '\u{0}', '\u{0}']), - ('\u{16ea9}', ['\u{16ec4}', '\u{0}', '\u{0}']), - ('\u{16eaa}', ['\u{16ec5}', '\u{0}', '\u{0}']), - ('\u{16eab}', ['\u{16ec6}', '\u{0}', '\u{0}']), - ('\u{16eac}', ['\u{16ec7}', '\u{0}', '\u{0}']), - ('\u{16ead}', ['\u{16ec8}', '\u{0}', '\u{0}']), - ('\u{16eae}', ['\u{16ec9}', '\u{0}', '\u{0}']), - ('\u{16eaf}', ['\u{16eca}', '\u{0}', '\u{0}']), - ('\u{16eb0}', ['\u{16ecb}', '\u{0}', '\u{0}']), - ('\u{16eb1}', ['\u{16ecc}', '\u{0}', '\u{0}']), - ('\u{16eb2}', ['\u{16ecd}', '\u{0}', '\u{0}']), - ('\u{16eb3}', ['\u{16ece}', '\u{0}', '\u{0}']), - ('\u{16eb4}', ['\u{16ecf}', '\u{0}', '\u{0}']), - ('\u{16eb5}', ['\u{16ed0}', '\u{0}', '\u{0}']), - ('\u{16eb6}', ['\u{16ed1}', '\u{0}', '\u{0}']), - ('\u{16eb7}', ['\u{16ed2}', '\u{0}', '\u{0}']), - ('\u{16eb8}', ['\u{16ed3}', '\u{0}', '\u{0}']), - ('\u{1e900}', ['\u{1e922}', '\u{0}', '\u{0}']), - ('\u{1e901}', ['\u{1e923}', '\u{0}', '\u{0}']), - ('\u{1e902}', ['\u{1e924}', '\u{0}', '\u{0}']), - ('\u{1e903}', ['\u{1e925}', '\u{0}', '\u{0}']), - ('\u{1e904}', ['\u{1e926}', '\u{0}', '\u{0}']), - ('\u{1e905}', ['\u{1e927}', '\u{0}', '\u{0}']), - ('\u{1e906}', ['\u{1e928}', '\u{0}', '\u{0}']), - ('\u{1e907}', ['\u{1e929}', '\u{0}', '\u{0}']), - ('\u{1e908}', ['\u{1e92a}', '\u{0}', '\u{0}']), - ('\u{1e909}', ['\u{1e92b}', '\u{0}', '\u{0}']), - ('\u{1e90a}', ['\u{1e92c}', '\u{0}', '\u{0}']), - ('\u{1e90b}', ['\u{1e92d}', '\u{0}', '\u{0}']), - ('\u{1e90c}', ['\u{1e92e}', '\u{0}', '\u{0}']), - ('\u{1e90d}', ['\u{1e92f}', '\u{0}', '\u{0}']), - ('\u{1e90e}', ['\u{1e930}', '\u{0}', '\u{0}']), - ('\u{1e90f}', ['\u{1e931}', '\u{0}', '\u{0}']), - ('\u{1e910}', ['\u{1e932}', '\u{0}', '\u{0}']), - ('\u{1e911}', ['\u{1e933}', '\u{0}', '\u{0}']), - ('\u{1e912}', ['\u{1e934}', '\u{0}', '\u{0}']), - ('\u{1e913}', ['\u{1e935}', '\u{0}', '\u{0}']), - ('\u{1e914}', ['\u{1e936}', '\u{0}', '\u{0}']), - ('\u{1e915}', ['\u{1e937}', '\u{0}', '\u{0}']), - ('\u{1e916}', ['\u{1e938}', '\u{0}', '\u{0}']), - ('\u{1e917}', ['\u{1e939}', '\u{0}', '\u{0}']), - ('\u{1e918}', ['\u{1e93a}', '\u{0}', '\u{0}']), - ('\u{1e919}', ['\u{1e93b}', '\u{0}', '\u{0}']), - ('\u{1e91a}', ['\u{1e93c}', '\u{0}', '\u{0}']), - ('\u{1e91b}', ['\u{1e93d}', '\u{0}', '\u{0}']), - ('\u{1e91c}', ['\u{1e93e}', '\u{0}', '\u{0}']), - ('\u{1e91d}', ['\u{1e93f}', '\u{0}', '\u{0}']), - ('\u{1e91e}', ['\u{1e940}', '\u{0}', '\u{0}']), - ('\u{1e91f}', ['\u{1e941}', '\u{0}', '\u{0}']), - ('\u{1e920}', ['\u{1e942}', '\u{0}', '\u{0}']), - ('\u{1e921}', ['\u{1e943}', '\u{0}', '\u{0}']), -]; - -#[rustfmt::skip] -pub(super) static TO_UPPER: &[(char, [char; 3]); 1580] = &[ - ('\u{61}', ['\u{41}', '\u{0}', '\u{0}']), ('\u{62}', ['\u{42}', '\u{0}', '\u{0}']), - ('\u{63}', ['\u{43}', '\u{0}', '\u{0}']), ('\u{64}', ['\u{44}', '\u{0}', '\u{0}']), - ('\u{65}', ['\u{45}', '\u{0}', '\u{0}']), ('\u{66}', ['\u{46}', '\u{0}', '\u{0}']), - ('\u{67}', ['\u{47}', '\u{0}', '\u{0}']), ('\u{68}', ['\u{48}', '\u{0}', '\u{0}']), - ('\u{69}', ['\u{49}', '\u{0}', '\u{0}']), ('\u{6a}', ['\u{4a}', '\u{0}', '\u{0}']), - ('\u{6b}', ['\u{4b}', '\u{0}', '\u{0}']), ('\u{6c}', ['\u{4c}', '\u{0}', '\u{0}']), - ('\u{6d}', ['\u{4d}', '\u{0}', '\u{0}']), ('\u{6e}', ['\u{4e}', '\u{0}', '\u{0}']), - ('\u{6f}', ['\u{4f}', '\u{0}', '\u{0}']), ('\u{70}', ['\u{50}', '\u{0}', '\u{0}']), - ('\u{71}', ['\u{51}', '\u{0}', '\u{0}']), ('\u{72}', ['\u{52}', '\u{0}', '\u{0}']), - ('\u{73}', ['\u{53}', '\u{0}', '\u{0}']), ('\u{74}', ['\u{54}', '\u{0}', '\u{0}']), - ('\u{75}', ['\u{55}', '\u{0}', '\u{0}']), ('\u{76}', ['\u{56}', '\u{0}', '\u{0}']), - ('\u{77}', ['\u{57}', '\u{0}', '\u{0}']), ('\u{78}', ['\u{58}', '\u{0}', '\u{0}']), - ('\u{79}', ['\u{59}', '\u{0}', '\u{0}']), ('\u{7a}', ['\u{5a}', '\u{0}', '\u{0}']), - ('\u{b5}', ['\u{39c}', '\u{0}', '\u{0}']), ('\u{df}', ['\u{53}', '\u{53}', '\u{0}']), - ('\u{e0}', ['\u{c0}', '\u{0}', '\u{0}']), ('\u{e1}', ['\u{c1}', '\u{0}', '\u{0}']), - ('\u{e2}', ['\u{c2}', '\u{0}', '\u{0}']), ('\u{e3}', ['\u{c3}', '\u{0}', '\u{0}']), - ('\u{e4}', ['\u{c4}', '\u{0}', '\u{0}']), ('\u{e5}', ['\u{c5}', '\u{0}', '\u{0}']), - ('\u{e6}', ['\u{c6}', '\u{0}', '\u{0}']), ('\u{e7}', ['\u{c7}', '\u{0}', '\u{0}']), - ('\u{e8}', ['\u{c8}', '\u{0}', '\u{0}']), ('\u{e9}', ['\u{c9}', '\u{0}', '\u{0}']), - ('\u{ea}', ['\u{ca}', '\u{0}', '\u{0}']), ('\u{eb}', ['\u{cb}', '\u{0}', '\u{0}']), - ('\u{ec}', ['\u{cc}', '\u{0}', '\u{0}']), ('\u{ed}', ['\u{cd}', '\u{0}', '\u{0}']), - ('\u{ee}', ['\u{ce}', '\u{0}', '\u{0}']), ('\u{ef}', ['\u{cf}', '\u{0}', '\u{0}']), - ('\u{f0}', ['\u{d0}', '\u{0}', '\u{0}']), ('\u{f1}', ['\u{d1}', '\u{0}', '\u{0}']), - ('\u{f2}', ['\u{d2}', '\u{0}', '\u{0}']), ('\u{f3}', ['\u{d3}', '\u{0}', '\u{0}']), - ('\u{f4}', ['\u{d4}', '\u{0}', '\u{0}']), ('\u{f5}', ['\u{d5}', '\u{0}', '\u{0}']), - ('\u{f6}', ['\u{d6}', '\u{0}', '\u{0}']), ('\u{f8}', ['\u{d8}', '\u{0}', '\u{0}']), - ('\u{f9}', ['\u{d9}', '\u{0}', '\u{0}']), ('\u{fa}', ['\u{da}', '\u{0}', '\u{0}']), - ('\u{fb}', ['\u{db}', '\u{0}', '\u{0}']), ('\u{fc}', ['\u{dc}', '\u{0}', '\u{0}']), - ('\u{fd}', ['\u{dd}', '\u{0}', '\u{0}']), ('\u{fe}', ['\u{de}', '\u{0}', '\u{0}']), - ('\u{ff}', ['\u{178}', '\u{0}', '\u{0}']), ('\u{101}', ['\u{100}', '\u{0}', '\u{0}']), - ('\u{103}', ['\u{102}', '\u{0}', '\u{0}']), ('\u{105}', ['\u{104}', '\u{0}', '\u{0}']), - ('\u{107}', ['\u{106}', '\u{0}', '\u{0}']), ('\u{109}', ['\u{108}', '\u{0}', '\u{0}']), - ('\u{10b}', ['\u{10a}', '\u{0}', '\u{0}']), ('\u{10d}', ['\u{10c}', '\u{0}', '\u{0}']), - ('\u{10f}', ['\u{10e}', '\u{0}', '\u{0}']), ('\u{111}', ['\u{110}', '\u{0}', '\u{0}']), - ('\u{113}', ['\u{112}', '\u{0}', '\u{0}']), ('\u{115}', ['\u{114}', '\u{0}', '\u{0}']), - ('\u{117}', ['\u{116}', '\u{0}', '\u{0}']), ('\u{119}', ['\u{118}', '\u{0}', '\u{0}']), - ('\u{11b}', ['\u{11a}', '\u{0}', '\u{0}']), ('\u{11d}', ['\u{11c}', '\u{0}', '\u{0}']), - ('\u{11f}', ['\u{11e}', '\u{0}', '\u{0}']), ('\u{121}', ['\u{120}', '\u{0}', '\u{0}']), - ('\u{123}', ['\u{122}', '\u{0}', '\u{0}']), ('\u{125}', ['\u{124}', '\u{0}', '\u{0}']), - ('\u{127}', ['\u{126}', '\u{0}', '\u{0}']), ('\u{129}', ['\u{128}', '\u{0}', '\u{0}']), - ('\u{12b}', ['\u{12a}', '\u{0}', '\u{0}']), ('\u{12d}', ['\u{12c}', '\u{0}', '\u{0}']), - ('\u{12f}', ['\u{12e}', '\u{0}', '\u{0}']), ('\u{131}', ['\u{49}', '\u{0}', '\u{0}']), - ('\u{133}', ['\u{132}', '\u{0}', '\u{0}']), ('\u{135}', ['\u{134}', '\u{0}', '\u{0}']), - ('\u{137}', ['\u{136}', '\u{0}', '\u{0}']), ('\u{13a}', ['\u{139}', '\u{0}', '\u{0}']), - ('\u{13c}', ['\u{13b}', '\u{0}', '\u{0}']), ('\u{13e}', ['\u{13d}', '\u{0}', '\u{0}']), - ('\u{140}', ['\u{13f}', '\u{0}', '\u{0}']), ('\u{142}', ['\u{141}', '\u{0}', '\u{0}']), - ('\u{144}', ['\u{143}', '\u{0}', '\u{0}']), ('\u{146}', ['\u{145}', '\u{0}', '\u{0}']), - ('\u{148}', ['\u{147}', '\u{0}', '\u{0}']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\u{0}']), - ('\u{14b}', ['\u{14a}', '\u{0}', '\u{0}']), ('\u{14d}', ['\u{14c}', '\u{0}', '\u{0}']), - ('\u{14f}', ['\u{14e}', '\u{0}', '\u{0}']), ('\u{151}', ['\u{150}', '\u{0}', '\u{0}']), - ('\u{153}', ['\u{152}', '\u{0}', '\u{0}']), ('\u{155}', ['\u{154}', '\u{0}', '\u{0}']), - ('\u{157}', ['\u{156}', '\u{0}', '\u{0}']), ('\u{159}', ['\u{158}', '\u{0}', '\u{0}']), - ('\u{15b}', ['\u{15a}', '\u{0}', '\u{0}']), ('\u{15d}', ['\u{15c}', '\u{0}', '\u{0}']), - ('\u{15f}', ['\u{15e}', '\u{0}', '\u{0}']), ('\u{161}', ['\u{160}', '\u{0}', '\u{0}']), - ('\u{163}', ['\u{162}', '\u{0}', '\u{0}']), ('\u{165}', ['\u{164}', '\u{0}', '\u{0}']), - ('\u{167}', ['\u{166}', '\u{0}', '\u{0}']), ('\u{169}', ['\u{168}', '\u{0}', '\u{0}']), - ('\u{16b}', ['\u{16a}', '\u{0}', '\u{0}']), ('\u{16d}', ['\u{16c}', '\u{0}', '\u{0}']), - ('\u{16f}', ['\u{16e}', '\u{0}', '\u{0}']), ('\u{171}', ['\u{170}', '\u{0}', '\u{0}']), - ('\u{173}', ['\u{172}', '\u{0}', '\u{0}']), ('\u{175}', ['\u{174}', '\u{0}', '\u{0}']), - ('\u{177}', ['\u{176}', '\u{0}', '\u{0}']), ('\u{17a}', ['\u{179}', '\u{0}', '\u{0}']), - ('\u{17c}', ['\u{17b}', '\u{0}', '\u{0}']), ('\u{17e}', ['\u{17d}', '\u{0}', '\u{0}']), - ('\u{17f}', ['\u{53}', '\u{0}', '\u{0}']), ('\u{180}', ['\u{243}', '\u{0}', '\u{0}']), - ('\u{183}', ['\u{182}', '\u{0}', '\u{0}']), ('\u{185}', ['\u{184}', '\u{0}', '\u{0}']), - ('\u{188}', ['\u{187}', '\u{0}', '\u{0}']), ('\u{18c}', ['\u{18b}', '\u{0}', '\u{0}']), - ('\u{192}', ['\u{191}', '\u{0}', '\u{0}']), ('\u{195}', ['\u{1f6}', '\u{0}', '\u{0}']), - ('\u{199}', ['\u{198}', '\u{0}', '\u{0}']), ('\u{19a}', ['\u{23d}', '\u{0}', '\u{0}']), - ('\u{19b}', ['\u{a7dc}', '\u{0}', '\u{0}']), ('\u{19e}', ['\u{220}', '\u{0}', '\u{0}']), - ('\u{1a1}', ['\u{1a0}', '\u{0}', '\u{0}']), ('\u{1a3}', ['\u{1a2}', '\u{0}', '\u{0}']), - ('\u{1a5}', ['\u{1a4}', '\u{0}', '\u{0}']), ('\u{1a8}', ['\u{1a7}', '\u{0}', '\u{0}']), - ('\u{1ad}', ['\u{1ac}', '\u{0}', '\u{0}']), ('\u{1b0}', ['\u{1af}', '\u{0}', '\u{0}']), - ('\u{1b4}', ['\u{1b3}', '\u{0}', '\u{0}']), ('\u{1b6}', ['\u{1b5}', '\u{0}', '\u{0}']), - ('\u{1b9}', ['\u{1b8}', '\u{0}', '\u{0}']), ('\u{1bd}', ['\u{1bc}', '\u{0}', '\u{0}']), - ('\u{1bf}', ['\u{1f7}', '\u{0}', '\u{0}']), ('\u{1c5}', ['\u{1c4}', '\u{0}', '\u{0}']), - ('\u{1c6}', ['\u{1c4}', '\u{0}', '\u{0}']), ('\u{1c8}', ['\u{1c7}', '\u{0}', '\u{0}']), - ('\u{1c9}', ['\u{1c7}', '\u{0}', '\u{0}']), ('\u{1cb}', ['\u{1ca}', '\u{0}', '\u{0}']), - ('\u{1cc}', ['\u{1ca}', '\u{0}', '\u{0}']), ('\u{1ce}', ['\u{1cd}', '\u{0}', '\u{0}']), - ('\u{1d0}', ['\u{1cf}', '\u{0}', '\u{0}']), ('\u{1d2}', ['\u{1d1}', '\u{0}', '\u{0}']), - ('\u{1d4}', ['\u{1d3}', '\u{0}', '\u{0}']), ('\u{1d6}', ['\u{1d5}', '\u{0}', '\u{0}']), - ('\u{1d8}', ['\u{1d7}', '\u{0}', '\u{0}']), ('\u{1da}', ['\u{1d9}', '\u{0}', '\u{0}']), - ('\u{1dc}', ['\u{1db}', '\u{0}', '\u{0}']), ('\u{1dd}', ['\u{18e}', '\u{0}', '\u{0}']), - ('\u{1df}', ['\u{1de}', '\u{0}', '\u{0}']), ('\u{1e1}', ['\u{1e0}', '\u{0}', '\u{0}']), - ('\u{1e3}', ['\u{1e2}', '\u{0}', '\u{0}']), ('\u{1e5}', ['\u{1e4}', '\u{0}', '\u{0}']), - ('\u{1e7}', ['\u{1e6}', '\u{0}', '\u{0}']), ('\u{1e9}', ['\u{1e8}', '\u{0}', '\u{0}']), - ('\u{1eb}', ['\u{1ea}', '\u{0}', '\u{0}']), ('\u{1ed}', ['\u{1ec}', '\u{0}', '\u{0}']), - ('\u{1ef}', ['\u{1ee}', '\u{0}', '\u{0}']), ('\u{1f0}', ['\u{4a}', '\u{30c}', '\u{0}']), - ('\u{1f2}', ['\u{1f1}', '\u{0}', '\u{0}']), ('\u{1f3}', ['\u{1f1}', '\u{0}', '\u{0}']), - ('\u{1f5}', ['\u{1f4}', '\u{0}', '\u{0}']), ('\u{1f9}', ['\u{1f8}', '\u{0}', '\u{0}']), - ('\u{1fb}', ['\u{1fa}', '\u{0}', '\u{0}']), ('\u{1fd}', ['\u{1fc}', '\u{0}', '\u{0}']), - ('\u{1ff}', ['\u{1fe}', '\u{0}', '\u{0}']), ('\u{201}', ['\u{200}', '\u{0}', '\u{0}']), - ('\u{203}', ['\u{202}', '\u{0}', '\u{0}']), ('\u{205}', ['\u{204}', '\u{0}', '\u{0}']), - ('\u{207}', ['\u{206}', '\u{0}', '\u{0}']), ('\u{209}', ['\u{208}', '\u{0}', '\u{0}']), - ('\u{20b}', ['\u{20a}', '\u{0}', '\u{0}']), ('\u{20d}', ['\u{20c}', '\u{0}', '\u{0}']), - ('\u{20f}', ['\u{20e}', '\u{0}', '\u{0}']), ('\u{211}', ['\u{210}', '\u{0}', '\u{0}']), - ('\u{213}', ['\u{212}', '\u{0}', '\u{0}']), ('\u{215}', ['\u{214}', '\u{0}', '\u{0}']), - ('\u{217}', ['\u{216}', '\u{0}', '\u{0}']), ('\u{219}', ['\u{218}', '\u{0}', '\u{0}']), - ('\u{21b}', ['\u{21a}', '\u{0}', '\u{0}']), ('\u{21d}', ['\u{21c}', '\u{0}', '\u{0}']), - ('\u{21f}', ['\u{21e}', '\u{0}', '\u{0}']), ('\u{223}', ['\u{222}', '\u{0}', '\u{0}']), - ('\u{225}', ['\u{224}', '\u{0}', '\u{0}']), ('\u{227}', ['\u{226}', '\u{0}', '\u{0}']), - ('\u{229}', ['\u{228}', '\u{0}', '\u{0}']), ('\u{22b}', ['\u{22a}', '\u{0}', '\u{0}']), - ('\u{22d}', ['\u{22c}', '\u{0}', '\u{0}']), ('\u{22f}', ['\u{22e}', '\u{0}', '\u{0}']), - ('\u{231}', ['\u{230}', '\u{0}', '\u{0}']), ('\u{233}', ['\u{232}', '\u{0}', '\u{0}']), - ('\u{23c}', ['\u{23b}', '\u{0}', '\u{0}']), ('\u{23f}', ['\u{2c7e}', '\u{0}', '\u{0}']), - ('\u{240}', ['\u{2c7f}', '\u{0}', '\u{0}']), ('\u{242}', ['\u{241}', '\u{0}', '\u{0}']), - ('\u{247}', ['\u{246}', '\u{0}', '\u{0}']), ('\u{249}', ['\u{248}', '\u{0}', '\u{0}']), - ('\u{24b}', ['\u{24a}', '\u{0}', '\u{0}']), ('\u{24d}', ['\u{24c}', '\u{0}', '\u{0}']), - ('\u{24f}', ['\u{24e}', '\u{0}', '\u{0}']), ('\u{250}', ['\u{2c6f}', '\u{0}', '\u{0}']), - ('\u{251}', ['\u{2c6d}', '\u{0}', '\u{0}']), ('\u{252}', ['\u{2c70}', '\u{0}', '\u{0}']), - ('\u{253}', ['\u{181}', '\u{0}', '\u{0}']), ('\u{254}', ['\u{186}', '\u{0}', '\u{0}']), - ('\u{256}', ['\u{189}', '\u{0}', '\u{0}']), ('\u{257}', ['\u{18a}', '\u{0}', '\u{0}']), - ('\u{259}', ['\u{18f}', '\u{0}', '\u{0}']), ('\u{25b}', ['\u{190}', '\u{0}', '\u{0}']), - ('\u{25c}', ['\u{a7ab}', '\u{0}', '\u{0}']), ('\u{260}', ['\u{193}', '\u{0}', '\u{0}']), - ('\u{261}', ['\u{a7ac}', '\u{0}', '\u{0}']), ('\u{263}', ['\u{194}', '\u{0}', '\u{0}']), - ('\u{264}', ['\u{a7cb}', '\u{0}', '\u{0}']), ('\u{265}', ['\u{a78d}', '\u{0}', '\u{0}']), - ('\u{266}', ['\u{a7aa}', '\u{0}', '\u{0}']), ('\u{268}', ['\u{197}', '\u{0}', '\u{0}']), - ('\u{269}', ['\u{196}', '\u{0}', '\u{0}']), ('\u{26a}', ['\u{a7ae}', '\u{0}', '\u{0}']), - ('\u{26b}', ['\u{2c62}', '\u{0}', '\u{0}']), ('\u{26c}', ['\u{a7ad}', '\u{0}', '\u{0}']), - ('\u{26f}', ['\u{19c}', '\u{0}', '\u{0}']), ('\u{271}', ['\u{2c6e}', '\u{0}', '\u{0}']), - ('\u{272}', ['\u{19d}', '\u{0}', '\u{0}']), ('\u{275}', ['\u{19f}', '\u{0}', '\u{0}']), - ('\u{27d}', ['\u{2c64}', '\u{0}', '\u{0}']), ('\u{280}', ['\u{1a6}', '\u{0}', '\u{0}']), - ('\u{282}', ['\u{a7c5}', '\u{0}', '\u{0}']), ('\u{283}', ['\u{1a9}', '\u{0}', '\u{0}']), - ('\u{287}', ['\u{a7b1}', '\u{0}', '\u{0}']), ('\u{288}', ['\u{1ae}', '\u{0}', '\u{0}']), - ('\u{289}', ['\u{244}', '\u{0}', '\u{0}']), ('\u{28a}', ['\u{1b1}', '\u{0}', '\u{0}']), - ('\u{28b}', ['\u{1b2}', '\u{0}', '\u{0}']), ('\u{28c}', ['\u{245}', '\u{0}', '\u{0}']), - ('\u{292}', ['\u{1b7}', '\u{0}', '\u{0}']), ('\u{29d}', ['\u{a7b2}', '\u{0}', '\u{0}']), - ('\u{29e}', ['\u{a7b0}', '\u{0}', '\u{0}']), ('\u{345}', ['\u{399}', '\u{0}', '\u{0}']), - ('\u{371}', ['\u{370}', '\u{0}', '\u{0}']), ('\u{373}', ['\u{372}', '\u{0}', '\u{0}']), - ('\u{377}', ['\u{376}', '\u{0}', '\u{0}']), ('\u{37b}', ['\u{3fd}', '\u{0}', '\u{0}']), - ('\u{37c}', ['\u{3fe}', '\u{0}', '\u{0}']), ('\u{37d}', ['\u{3ff}', '\u{0}', '\u{0}']), - ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\u{0}', '\u{0}']), - ('\u{3ad}', ['\u{388}', '\u{0}', '\u{0}']), ('\u{3ae}', ['\u{389}', '\u{0}', '\u{0}']), - ('\u{3af}', ['\u{38a}', '\u{0}', '\u{0}']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{3b1}', ['\u{391}', '\u{0}', '\u{0}']), ('\u{3b2}', ['\u{392}', '\u{0}', '\u{0}']), - ('\u{3b3}', ['\u{393}', '\u{0}', '\u{0}']), ('\u{3b4}', ['\u{394}', '\u{0}', '\u{0}']), - ('\u{3b5}', ['\u{395}', '\u{0}', '\u{0}']), ('\u{3b6}', ['\u{396}', '\u{0}', '\u{0}']), - ('\u{3b7}', ['\u{397}', '\u{0}', '\u{0}']), ('\u{3b8}', ['\u{398}', '\u{0}', '\u{0}']), - ('\u{3b9}', ['\u{399}', '\u{0}', '\u{0}']), ('\u{3ba}', ['\u{39a}', '\u{0}', '\u{0}']), - ('\u{3bb}', ['\u{39b}', '\u{0}', '\u{0}']), ('\u{3bc}', ['\u{39c}', '\u{0}', '\u{0}']), - ('\u{3bd}', ['\u{39d}', '\u{0}', '\u{0}']), ('\u{3be}', ['\u{39e}', '\u{0}', '\u{0}']), - ('\u{3bf}', ['\u{39f}', '\u{0}', '\u{0}']), ('\u{3c0}', ['\u{3a0}', '\u{0}', '\u{0}']), - ('\u{3c1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3c2}', ['\u{3a3}', '\u{0}', '\u{0}']), - ('\u{3c3}', ['\u{3a3}', '\u{0}', '\u{0}']), ('\u{3c4}', ['\u{3a4}', '\u{0}', '\u{0}']), - ('\u{3c5}', ['\u{3a5}', '\u{0}', '\u{0}']), ('\u{3c6}', ['\u{3a6}', '\u{0}', '\u{0}']), - ('\u{3c7}', ['\u{3a7}', '\u{0}', '\u{0}']), ('\u{3c8}', ['\u{3a8}', '\u{0}', '\u{0}']), - ('\u{3c9}', ['\u{3a9}', '\u{0}', '\u{0}']), ('\u{3ca}', ['\u{3aa}', '\u{0}', '\u{0}']), - ('\u{3cb}', ['\u{3ab}', '\u{0}', '\u{0}']), ('\u{3cc}', ['\u{38c}', '\u{0}', '\u{0}']), - ('\u{3cd}', ['\u{38e}', '\u{0}', '\u{0}']), ('\u{3ce}', ['\u{38f}', '\u{0}', '\u{0}']), - ('\u{3d0}', ['\u{392}', '\u{0}', '\u{0}']), ('\u{3d1}', ['\u{398}', '\u{0}', '\u{0}']), - ('\u{3d5}', ['\u{3a6}', '\u{0}', '\u{0}']), ('\u{3d6}', ['\u{3a0}', '\u{0}', '\u{0}']), - ('\u{3d7}', ['\u{3cf}', '\u{0}', '\u{0}']), ('\u{3d9}', ['\u{3d8}', '\u{0}', '\u{0}']), - ('\u{3db}', ['\u{3da}', '\u{0}', '\u{0}']), ('\u{3dd}', ['\u{3dc}', '\u{0}', '\u{0}']), - ('\u{3df}', ['\u{3de}', '\u{0}', '\u{0}']), ('\u{3e1}', ['\u{3e0}', '\u{0}', '\u{0}']), - ('\u{3e3}', ['\u{3e2}', '\u{0}', '\u{0}']), ('\u{3e5}', ['\u{3e4}', '\u{0}', '\u{0}']), - ('\u{3e7}', ['\u{3e6}', '\u{0}', '\u{0}']), ('\u{3e9}', ['\u{3e8}', '\u{0}', '\u{0}']), - ('\u{3eb}', ['\u{3ea}', '\u{0}', '\u{0}']), ('\u{3ed}', ['\u{3ec}', '\u{0}', '\u{0}']), - ('\u{3ef}', ['\u{3ee}', '\u{0}', '\u{0}']), ('\u{3f0}', ['\u{39a}', '\u{0}', '\u{0}']), - ('\u{3f1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3f2}', ['\u{3f9}', '\u{0}', '\u{0}']), - ('\u{3f3}', ['\u{37f}', '\u{0}', '\u{0}']), ('\u{3f5}', ['\u{395}', '\u{0}', '\u{0}']), - ('\u{3f8}', ['\u{3f7}', '\u{0}', '\u{0}']), ('\u{3fb}', ['\u{3fa}', '\u{0}', '\u{0}']), - ('\u{430}', ['\u{410}', '\u{0}', '\u{0}']), ('\u{431}', ['\u{411}', '\u{0}', '\u{0}']), - ('\u{432}', ['\u{412}', '\u{0}', '\u{0}']), ('\u{433}', ['\u{413}', '\u{0}', '\u{0}']), - ('\u{434}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{435}', ['\u{415}', '\u{0}', '\u{0}']), - ('\u{436}', ['\u{416}', '\u{0}', '\u{0}']), ('\u{437}', ['\u{417}', '\u{0}', '\u{0}']), - ('\u{438}', ['\u{418}', '\u{0}', '\u{0}']), ('\u{439}', ['\u{419}', '\u{0}', '\u{0}']), - ('\u{43a}', ['\u{41a}', '\u{0}', '\u{0}']), ('\u{43b}', ['\u{41b}', '\u{0}', '\u{0}']), - ('\u{43c}', ['\u{41c}', '\u{0}', '\u{0}']), ('\u{43d}', ['\u{41d}', '\u{0}', '\u{0}']), - ('\u{43e}', ['\u{41e}', '\u{0}', '\u{0}']), ('\u{43f}', ['\u{41f}', '\u{0}', '\u{0}']), - ('\u{440}', ['\u{420}', '\u{0}', '\u{0}']), ('\u{441}', ['\u{421}', '\u{0}', '\u{0}']), - ('\u{442}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{443}', ['\u{423}', '\u{0}', '\u{0}']), - ('\u{444}', ['\u{424}', '\u{0}', '\u{0}']), ('\u{445}', ['\u{425}', '\u{0}', '\u{0}']), - ('\u{446}', ['\u{426}', '\u{0}', '\u{0}']), ('\u{447}', ['\u{427}', '\u{0}', '\u{0}']), - ('\u{448}', ['\u{428}', '\u{0}', '\u{0}']), ('\u{449}', ['\u{429}', '\u{0}', '\u{0}']), - ('\u{44a}', ['\u{42a}', '\u{0}', '\u{0}']), ('\u{44b}', ['\u{42b}', '\u{0}', '\u{0}']), - ('\u{44c}', ['\u{42c}', '\u{0}', '\u{0}']), ('\u{44d}', ['\u{42d}', '\u{0}', '\u{0}']), - ('\u{44e}', ['\u{42e}', '\u{0}', '\u{0}']), ('\u{44f}', ['\u{42f}', '\u{0}', '\u{0}']), - ('\u{450}', ['\u{400}', '\u{0}', '\u{0}']), ('\u{451}', ['\u{401}', '\u{0}', '\u{0}']), - ('\u{452}', ['\u{402}', '\u{0}', '\u{0}']), ('\u{453}', ['\u{403}', '\u{0}', '\u{0}']), - ('\u{454}', ['\u{404}', '\u{0}', '\u{0}']), ('\u{455}', ['\u{405}', '\u{0}', '\u{0}']), - ('\u{456}', ['\u{406}', '\u{0}', '\u{0}']), ('\u{457}', ['\u{407}', '\u{0}', '\u{0}']), - ('\u{458}', ['\u{408}', '\u{0}', '\u{0}']), ('\u{459}', ['\u{409}', '\u{0}', '\u{0}']), - ('\u{45a}', ['\u{40a}', '\u{0}', '\u{0}']), ('\u{45b}', ['\u{40b}', '\u{0}', '\u{0}']), - ('\u{45c}', ['\u{40c}', '\u{0}', '\u{0}']), ('\u{45d}', ['\u{40d}', '\u{0}', '\u{0}']), - ('\u{45e}', ['\u{40e}', '\u{0}', '\u{0}']), ('\u{45f}', ['\u{40f}', '\u{0}', '\u{0}']), - ('\u{461}', ['\u{460}', '\u{0}', '\u{0}']), ('\u{463}', ['\u{462}', '\u{0}', '\u{0}']), - ('\u{465}', ['\u{464}', '\u{0}', '\u{0}']), ('\u{467}', ['\u{466}', '\u{0}', '\u{0}']), - ('\u{469}', ['\u{468}', '\u{0}', '\u{0}']), ('\u{46b}', ['\u{46a}', '\u{0}', '\u{0}']), - ('\u{46d}', ['\u{46c}', '\u{0}', '\u{0}']), ('\u{46f}', ['\u{46e}', '\u{0}', '\u{0}']), - ('\u{471}', ['\u{470}', '\u{0}', '\u{0}']), ('\u{473}', ['\u{472}', '\u{0}', '\u{0}']), - ('\u{475}', ['\u{474}', '\u{0}', '\u{0}']), ('\u{477}', ['\u{476}', '\u{0}', '\u{0}']), - ('\u{479}', ['\u{478}', '\u{0}', '\u{0}']), ('\u{47b}', ['\u{47a}', '\u{0}', '\u{0}']), - ('\u{47d}', ['\u{47c}', '\u{0}', '\u{0}']), ('\u{47f}', ['\u{47e}', '\u{0}', '\u{0}']), - ('\u{481}', ['\u{480}', '\u{0}', '\u{0}']), ('\u{48b}', ['\u{48a}', '\u{0}', '\u{0}']), - ('\u{48d}', ['\u{48c}', '\u{0}', '\u{0}']), ('\u{48f}', ['\u{48e}', '\u{0}', '\u{0}']), - ('\u{491}', ['\u{490}', '\u{0}', '\u{0}']), ('\u{493}', ['\u{492}', '\u{0}', '\u{0}']), - ('\u{495}', ['\u{494}', '\u{0}', '\u{0}']), ('\u{497}', ['\u{496}', '\u{0}', '\u{0}']), - ('\u{499}', ['\u{498}', '\u{0}', '\u{0}']), ('\u{49b}', ['\u{49a}', '\u{0}', '\u{0}']), - ('\u{49d}', ['\u{49c}', '\u{0}', '\u{0}']), ('\u{49f}', ['\u{49e}', '\u{0}', '\u{0}']), - ('\u{4a1}', ['\u{4a0}', '\u{0}', '\u{0}']), ('\u{4a3}', ['\u{4a2}', '\u{0}', '\u{0}']), - ('\u{4a5}', ['\u{4a4}', '\u{0}', '\u{0}']), ('\u{4a7}', ['\u{4a6}', '\u{0}', '\u{0}']), - ('\u{4a9}', ['\u{4a8}', '\u{0}', '\u{0}']), ('\u{4ab}', ['\u{4aa}', '\u{0}', '\u{0}']), - ('\u{4ad}', ['\u{4ac}', '\u{0}', '\u{0}']), ('\u{4af}', ['\u{4ae}', '\u{0}', '\u{0}']), - ('\u{4b1}', ['\u{4b0}', '\u{0}', '\u{0}']), ('\u{4b3}', ['\u{4b2}', '\u{0}', '\u{0}']), - ('\u{4b5}', ['\u{4b4}', '\u{0}', '\u{0}']), ('\u{4b7}', ['\u{4b6}', '\u{0}', '\u{0}']), - ('\u{4b9}', ['\u{4b8}', '\u{0}', '\u{0}']), ('\u{4bb}', ['\u{4ba}', '\u{0}', '\u{0}']), - ('\u{4bd}', ['\u{4bc}', '\u{0}', '\u{0}']), ('\u{4bf}', ['\u{4be}', '\u{0}', '\u{0}']), - ('\u{4c2}', ['\u{4c1}', '\u{0}', '\u{0}']), ('\u{4c4}', ['\u{4c3}', '\u{0}', '\u{0}']), - ('\u{4c6}', ['\u{4c5}', '\u{0}', '\u{0}']), ('\u{4c8}', ['\u{4c7}', '\u{0}', '\u{0}']), - ('\u{4ca}', ['\u{4c9}', '\u{0}', '\u{0}']), ('\u{4cc}', ['\u{4cb}', '\u{0}', '\u{0}']), - ('\u{4ce}', ['\u{4cd}', '\u{0}', '\u{0}']), ('\u{4cf}', ['\u{4c0}', '\u{0}', '\u{0}']), - ('\u{4d1}', ['\u{4d0}', '\u{0}', '\u{0}']), ('\u{4d3}', ['\u{4d2}', '\u{0}', '\u{0}']), - ('\u{4d5}', ['\u{4d4}', '\u{0}', '\u{0}']), ('\u{4d7}', ['\u{4d6}', '\u{0}', '\u{0}']), - ('\u{4d9}', ['\u{4d8}', '\u{0}', '\u{0}']), ('\u{4db}', ['\u{4da}', '\u{0}', '\u{0}']), - ('\u{4dd}', ['\u{4dc}', '\u{0}', '\u{0}']), ('\u{4df}', ['\u{4de}', '\u{0}', '\u{0}']), - ('\u{4e1}', ['\u{4e0}', '\u{0}', '\u{0}']), ('\u{4e3}', ['\u{4e2}', '\u{0}', '\u{0}']), - ('\u{4e5}', ['\u{4e4}', '\u{0}', '\u{0}']), ('\u{4e7}', ['\u{4e6}', '\u{0}', '\u{0}']), - ('\u{4e9}', ['\u{4e8}', '\u{0}', '\u{0}']), ('\u{4eb}', ['\u{4ea}', '\u{0}', '\u{0}']), - ('\u{4ed}', ['\u{4ec}', '\u{0}', '\u{0}']), ('\u{4ef}', ['\u{4ee}', '\u{0}', '\u{0}']), - ('\u{4f1}', ['\u{4f0}', '\u{0}', '\u{0}']), ('\u{4f3}', ['\u{4f2}', '\u{0}', '\u{0}']), - ('\u{4f5}', ['\u{4f4}', '\u{0}', '\u{0}']), ('\u{4f7}', ['\u{4f6}', '\u{0}', '\u{0}']), - ('\u{4f9}', ['\u{4f8}', '\u{0}', '\u{0}']), ('\u{4fb}', ['\u{4fa}', '\u{0}', '\u{0}']), - ('\u{4fd}', ['\u{4fc}', '\u{0}', '\u{0}']), ('\u{4ff}', ['\u{4fe}', '\u{0}', '\u{0}']), - ('\u{501}', ['\u{500}', '\u{0}', '\u{0}']), ('\u{503}', ['\u{502}', '\u{0}', '\u{0}']), - ('\u{505}', ['\u{504}', '\u{0}', '\u{0}']), ('\u{507}', ['\u{506}', '\u{0}', '\u{0}']), - ('\u{509}', ['\u{508}', '\u{0}', '\u{0}']), ('\u{50b}', ['\u{50a}', '\u{0}', '\u{0}']), - ('\u{50d}', ['\u{50c}', '\u{0}', '\u{0}']), ('\u{50f}', ['\u{50e}', '\u{0}', '\u{0}']), - ('\u{511}', ['\u{510}', '\u{0}', '\u{0}']), ('\u{513}', ['\u{512}', '\u{0}', '\u{0}']), - ('\u{515}', ['\u{514}', '\u{0}', '\u{0}']), ('\u{517}', ['\u{516}', '\u{0}', '\u{0}']), - ('\u{519}', ['\u{518}', '\u{0}', '\u{0}']), ('\u{51b}', ['\u{51a}', '\u{0}', '\u{0}']), - ('\u{51d}', ['\u{51c}', '\u{0}', '\u{0}']), ('\u{51f}', ['\u{51e}', '\u{0}', '\u{0}']), - ('\u{521}', ['\u{520}', '\u{0}', '\u{0}']), ('\u{523}', ['\u{522}', '\u{0}', '\u{0}']), - ('\u{525}', ['\u{524}', '\u{0}', '\u{0}']), ('\u{527}', ['\u{526}', '\u{0}', '\u{0}']), - ('\u{529}', ['\u{528}', '\u{0}', '\u{0}']), ('\u{52b}', ['\u{52a}', '\u{0}', '\u{0}']), - ('\u{52d}', ['\u{52c}', '\u{0}', '\u{0}']), ('\u{52f}', ['\u{52e}', '\u{0}', '\u{0}']), - ('\u{561}', ['\u{531}', '\u{0}', '\u{0}']), ('\u{562}', ['\u{532}', '\u{0}', '\u{0}']), - ('\u{563}', ['\u{533}', '\u{0}', '\u{0}']), ('\u{564}', ['\u{534}', '\u{0}', '\u{0}']), - ('\u{565}', ['\u{535}', '\u{0}', '\u{0}']), ('\u{566}', ['\u{536}', '\u{0}', '\u{0}']), - ('\u{567}', ['\u{537}', '\u{0}', '\u{0}']), ('\u{568}', ['\u{538}', '\u{0}', '\u{0}']), - ('\u{569}', ['\u{539}', '\u{0}', '\u{0}']), ('\u{56a}', ['\u{53a}', '\u{0}', '\u{0}']), - ('\u{56b}', ['\u{53b}', '\u{0}', '\u{0}']), ('\u{56c}', ['\u{53c}', '\u{0}', '\u{0}']), - ('\u{56d}', ['\u{53d}', '\u{0}', '\u{0}']), ('\u{56e}', ['\u{53e}', '\u{0}', '\u{0}']), - ('\u{56f}', ['\u{53f}', '\u{0}', '\u{0}']), ('\u{570}', ['\u{540}', '\u{0}', '\u{0}']), - ('\u{571}', ['\u{541}', '\u{0}', '\u{0}']), ('\u{572}', ['\u{542}', '\u{0}', '\u{0}']), - ('\u{573}', ['\u{543}', '\u{0}', '\u{0}']), ('\u{574}', ['\u{544}', '\u{0}', '\u{0}']), - ('\u{575}', ['\u{545}', '\u{0}', '\u{0}']), ('\u{576}', ['\u{546}', '\u{0}', '\u{0}']), - ('\u{577}', ['\u{547}', '\u{0}', '\u{0}']), ('\u{578}', ['\u{548}', '\u{0}', '\u{0}']), - ('\u{579}', ['\u{549}', '\u{0}', '\u{0}']), ('\u{57a}', ['\u{54a}', '\u{0}', '\u{0}']), - ('\u{57b}', ['\u{54b}', '\u{0}', '\u{0}']), ('\u{57c}', ['\u{54c}', '\u{0}', '\u{0}']), - ('\u{57d}', ['\u{54d}', '\u{0}', '\u{0}']), ('\u{57e}', ['\u{54e}', '\u{0}', '\u{0}']), - ('\u{57f}', ['\u{54f}', '\u{0}', '\u{0}']), ('\u{580}', ['\u{550}', '\u{0}', '\u{0}']), - ('\u{581}', ['\u{551}', '\u{0}', '\u{0}']), ('\u{582}', ['\u{552}', '\u{0}', '\u{0}']), - ('\u{583}', ['\u{553}', '\u{0}', '\u{0}']), ('\u{584}', ['\u{554}', '\u{0}', '\u{0}']), - ('\u{585}', ['\u{555}', '\u{0}', '\u{0}']), ('\u{586}', ['\u{556}', '\u{0}', '\u{0}']), - ('\u{587}', ['\u{535}', '\u{552}', '\u{0}']), ('\u{10d0}', ['\u{1c90}', '\u{0}', '\u{0}']), - ('\u{10d1}', ['\u{1c91}', '\u{0}', '\u{0}']), ('\u{10d2}', ['\u{1c92}', '\u{0}', '\u{0}']), - ('\u{10d3}', ['\u{1c93}', '\u{0}', '\u{0}']), ('\u{10d4}', ['\u{1c94}', '\u{0}', '\u{0}']), - ('\u{10d5}', ['\u{1c95}', '\u{0}', '\u{0}']), ('\u{10d6}', ['\u{1c96}', '\u{0}', '\u{0}']), - ('\u{10d7}', ['\u{1c97}', '\u{0}', '\u{0}']), ('\u{10d8}', ['\u{1c98}', '\u{0}', '\u{0}']), - ('\u{10d9}', ['\u{1c99}', '\u{0}', '\u{0}']), ('\u{10da}', ['\u{1c9a}', '\u{0}', '\u{0}']), - ('\u{10db}', ['\u{1c9b}', '\u{0}', '\u{0}']), ('\u{10dc}', ['\u{1c9c}', '\u{0}', '\u{0}']), - ('\u{10dd}', ['\u{1c9d}', '\u{0}', '\u{0}']), ('\u{10de}', ['\u{1c9e}', '\u{0}', '\u{0}']), - ('\u{10df}', ['\u{1c9f}', '\u{0}', '\u{0}']), ('\u{10e0}', ['\u{1ca0}', '\u{0}', '\u{0}']), - ('\u{10e1}', ['\u{1ca1}', '\u{0}', '\u{0}']), ('\u{10e2}', ['\u{1ca2}', '\u{0}', '\u{0}']), - ('\u{10e3}', ['\u{1ca3}', '\u{0}', '\u{0}']), ('\u{10e4}', ['\u{1ca4}', '\u{0}', '\u{0}']), - ('\u{10e5}', ['\u{1ca5}', '\u{0}', '\u{0}']), ('\u{10e6}', ['\u{1ca6}', '\u{0}', '\u{0}']), - ('\u{10e7}', ['\u{1ca7}', '\u{0}', '\u{0}']), ('\u{10e8}', ['\u{1ca8}', '\u{0}', '\u{0}']), - ('\u{10e9}', ['\u{1ca9}', '\u{0}', '\u{0}']), ('\u{10ea}', ['\u{1caa}', '\u{0}', '\u{0}']), - ('\u{10eb}', ['\u{1cab}', '\u{0}', '\u{0}']), ('\u{10ec}', ['\u{1cac}', '\u{0}', '\u{0}']), - ('\u{10ed}', ['\u{1cad}', '\u{0}', '\u{0}']), ('\u{10ee}', ['\u{1cae}', '\u{0}', '\u{0}']), - ('\u{10ef}', ['\u{1caf}', '\u{0}', '\u{0}']), ('\u{10f0}', ['\u{1cb0}', '\u{0}', '\u{0}']), - ('\u{10f1}', ['\u{1cb1}', '\u{0}', '\u{0}']), ('\u{10f2}', ['\u{1cb2}', '\u{0}', '\u{0}']), - ('\u{10f3}', ['\u{1cb3}', '\u{0}', '\u{0}']), ('\u{10f4}', ['\u{1cb4}', '\u{0}', '\u{0}']), - ('\u{10f5}', ['\u{1cb5}', '\u{0}', '\u{0}']), ('\u{10f6}', ['\u{1cb6}', '\u{0}', '\u{0}']), - ('\u{10f7}', ['\u{1cb7}', '\u{0}', '\u{0}']), ('\u{10f8}', ['\u{1cb8}', '\u{0}', '\u{0}']), - ('\u{10f9}', ['\u{1cb9}', '\u{0}', '\u{0}']), ('\u{10fa}', ['\u{1cba}', '\u{0}', '\u{0}']), - ('\u{10fd}', ['\u{1cbd}', '\u{0}', '\u{0}']), ('\u{10fe}', ['\u{1cbe}', '\u{0}', '\u{0}']), - ('\u{10ff}', ['\u{1cbf}', '\u{0}', '\u{0}']), ('\u{13f8}', ['\u{13f0}', '\u{0}', '\u{0}']), - ('\u{13f9}', ['\u{13f1}', '\u{0}', '\u{0}']), ('\u{13fa}', ['\u{13f2}', '\u{0}', '\u{0}']), - ('\u{13fb}', ['\u{13f3}', '\u{0}', '\u{0}']), ('\u{13fc}', ['\u{13f4}', '\u{0}', '\u{0}']), - ('\u{13fd}', ['\u{13f5}', '\u{0}', '\u{0}']), ('\u{1c80}', ['\u{412}', '\u{0}', '\u{0}']), - ('\u{1c81}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{1c82}', ['\u{41e}', '\u{0}', '\u{0}']), - ('\u{1c83}', ['\u{421}', '\u{0}', '\u{0}']), ('\u{1c84}', ['\u{422}', '\u{0}', '\u{0}']), - ('\u{1c85}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{1c86}', ['\u{42a}', '\u{0}', '\u{0}']), - ('\u{1c87}', ['\u{462}', '\u{0}', '\u{0}']), ('\u{1c88}', ['\u{a64a}', '\u{0}', '\u{0}']), - ('\u{1c8a}', ['\u{1c89}', '\u{0}', '\u{0}']), ('\u{1d79}', ['\u{a77d}', '\u{0}', '\u{0}']), - ('\u{1d7d}', ['\u{2c63}', '\u{0}', '\u{0}']), ('\u{1d8e}', ['\u{a7c6}', '\u{0}', '\u{0}']), - ('\u{1e01}', ['\u{1e00}', '\u{0}', '\u{0}']), ('\u{1e03}', ['\u{1e02}', '\u{0}', '\u{0}']), - ('\u{1e05}', ['\u{1e04}', '\u{0}', '\u{0}']), ('\u{1e07}', ['\u{1e06}', '\u{0}', '\u{0}']), - ('\u{1e09}', ['\u{1e08}', '\u{0}', '\u{0}']), ('\u{1e0b}', ['\u{1e0a}', '\u{0}', '\u{0}']), - ('\u{1e0d}', ['\u{1e0c}', '\u{0}', '\u{0}']), ('\u{1e0f}', ['\u{1e0e}', '\u{0}', '\u{0}']), - ('\u{1e11}', ['\u{1e10}', '\u{0}', '\u{0}']), ('\u{1e13}', ['\u{1e12}', '\u{0}', '\u{0}']), - ('\u{1e15}', ['\u{1e14}', '\u{0}', '\u{0}']), ('\u{1e17}', ['\u{1e16}', '\u{0}', '\u{0}']), - ('\u{1e19}', ['\u{1e18}', '\u{0}', '\u{0}']), ('\u{1e1b}', ['\u{1e1a}', '\u{0}', '\u{0}']), - ('\u{1e1d}', ['\u{1e1c}', '\u{0}', '\u{0}']), ('\u{1e1f}', ['\u{1e1e}', '\u{0}', '\u{0}']), - ('\u{1e21}', ['\u{1e20}', '\u{0}', '\u{0}']), ('\u{1e23}', ['\u{1e22}', '\u{0}', '\u{0}']), - ('\u{1e25}', ['\u{1e24}', '\u{0}', '\u{0}']), ('\u{1e27}', ['\u{1e26}', '\u{0}', '\u{0}']), - ('\u{1e29}', ['\u{1e28}', '\u{0}', '\u{0}']), ('\u{1e2b}', ['\u{1e2a}', '\u{0}', '\u{0}']), - ('\u{1e2d}', ['\u{1e2c}', '\u{0}', '\u{0}']), ('\u{1e2f}', ['\u{1e2e}', '\u{0}', '\u{0}']), - ('\u{1e31}', ['\u{1e30}', '\u{0}', '\u{0}']), ('\u{1e33}', ['\u{1e32}', '\u{0}', '\u{0}']), - ('\u{1e35}', ['\u{1e34}', '\u{0}', '\u{0}']), ('\u{1e37}', ['\u{1e36}', '\u{0}', '\u{0}']), - ('\u{1e39}', ['\u{1e38}', '\u{0}', '\u{0}']), ('\u{1e3b}', ['\u{1e3a}', '\u{0}', '\u{0}']), - ('\u{1e3d}', ['\u{1e3c}', '\u{0}', '\u{0}']), ('\u{1e3f}', ['\u{1e3e}', '\u{0}', '\u{0}']), - ('\u{1e41}', ['\u{1e40}', '\u{0}', '\u{0}']), ('\u{1e43}', ['\u{1e42}', '\u{0}', '\u{0}']), - ('\u{1e45}', ['\u{1e44}', '\u{0}', '\u{0}']), ('\u{1e47}', ['\u{1e46}', '\u{0}', '\u{0}']), - ('\u{1e49}', ['\u{1e48}', '\u{0}', '\u{0}']), ('\u{1e4b}', ['\u{1e4a}', '\u{0}', '\u{0}']), - ('\u{1e4d}', ['\u{1e4c}', '\u{0}', '\u{0}']), ('\u{1e4f}', ['\u{1e4e}', '\u{0}', '\u{0}']), - ('\u{1e51}', ['\u{1e50}', '\u{0}', '\u{0}']), ('\u{1e53}', ['\u{1e52}', '\u{0}', '\u{0}']), - ('\u{1e55}', ['\u{1e54}', '\u{0}', '\u{0}']), ('\u{1e57}', ['\u{1e56}', '\u{0}', '\u{0}']), - ('\u{1e59}', ['\u{1e58}', '\u{0}', '\u{0}']), ('\u{1e5b}', ['\u{1e5a}', '\u{0}', '\u{0}']), - ('\u{1e5d}', ['\u{1e5c}', '\u{0}', '\u{0}']), ('\u{1e5f}', ['\u{1e5e}', '\u{0}', '\u{0}']), - ('\u{1e61}', ['\u{1e60}', '\u{0}', '\u{0}']), ('\u{1e63}', ['\u{1e62}', '\u{0}', '\u{0}']), - ('\u{1e65}', ['\u{1e64}', '\u{0}', '\u{0}']), ('\u{1e67}', ['\u{1e66}', '\u{0}', '\u{0}']), - ('\u{1e69}', ['\u{1e68}', '\u{0}', '\u{0}']), ('\u{1e6b}', ['\u{1e6a}', '\u{0}', '\u{0}']), - ('\u{1e6d}', ['\u{1e6c}', '\u{0}', '\u{0}']), ('\u{1e6f}', ['\u{1e6e}', '\u{0}', '\u{0}']), - ('\u{1e71}', ['\u{1e70}', '\u{0}', '\u{0}']), ('\u{1e73}', ['\u{1e72}', '\u{0}', '\u{0}']), - ('\u{1e75}', ['\u{1e74}', '\u{0}', '\u{0}']), ('\u{1e77}', ['\u{1e76}', '\u{0}', '\u{0}']), - ('\u{1e79}', ['\u{1e78}', '\u{0}', '\u{0}']), ('\u{1e7b}', ['\u{1e7a}', '\u{0}', '\u{0}']), - ('\u{1e7d}', ['\u{1e7c}', '\u{0}', '\u{0}']), ('\u{1e7f}', ['\u{1e7e}', '\u{0}', '\u{0}']), - ('\u{1e81}', ['\u{1e80}', '\u{0}', '\u{0}']), ('\u{1e83}', ['\u{1e82}', '\u{0}', '\u{0}']), - ('\u{1e85}', ['\u{1e84}', '\u{0}', '\u{0}']), ('\u{1e87}', ['\u{1e86}', '\u{0}', '\u{0}']), - ('\u{1e89}', ['\u{1e88}', '\u{0}', '\u{0}']), ('\u{1e8b}', ['\u{1e8a}', '\u{0}', '\u{0}']), - ('\u{1e8d}', ['\u{1e8c}', '\u{0}', '\u{0}']), ('\u{1e8f}', ['\u{1e8e}', '\u{0}', '\u{0}']), - ('\u{1e91}', ['\u{1e90}', '\u{0}', '\u{0}']), ('\u{1e93}', ['\u{1e92}', '\u{0}', '\u{0}']), - ('\u{1e95}', ['\u{1e94}', '\u{0}', '\u{0}']), ('\u{1e96}', ['\u{48}', '\u{331}', '\u{0}']), - ('\u{1e97}', ['\u{54}', '\u{308}', '\u{0}']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\u{0}']), - ('\u{1e99}', ['\u{59}', '\u{30a}', '\u{0}']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\u{0}']), - ('\u{1e9b}', ['\u{1e60}', '\u{0}', '\u{0}']), ('\u{1ea1}', ['\u{1ea0}', '\u{0}', '\u{0}']), - ('\u{1ea3}', ['\u{1ea2}', '\u{0}', '\u{0}']), ('\u{1ea5}', ['\u{1ea4}', '\u{0}', '\u{0}']), - ('\u{1ea7}', ['\u{1ea6}', '\u{0}', '\u{0}']), ('\u{1ea9}', ['\u{1ea8}', '\u{0}', '\u{0}']), - ('\u{1eab}', ['\u{1eaa}', '\u{0}', '\u{0}']), ('\u{1ead}', ['\u{1eac}', '\u{0}', '\u{0}']), - ('\u{1eaf}', ['\u{1eae}', '\u{0}', '\u{0}']), ('\u{1eb1}', ['\u{1eb0}', '\u{0}', '\u{0}']), - ('\u{1eb3}', ['\u{1eb2}', '\u{0}', '\u{0}']), ('\u{1eb5}', ['\u{1eb4}', '\u{0}', '\u{0}']), - ('\u{1eb7}', ['\u{1eb6}', '\u{0}', '\u{0}']), ('\u{1eb9}', ['\u{1eb8}', '\u{0}', '\u{0}']), - ('\u{1ebb}', ['\u{1eba}', '\u{0}', '\u{0}']), ('\u{1ebd}', ['\u{1ebc}', '\u{0}', '\u{0}']), - ('\u{1ebf}', ['\u{1ebe}', '\u{0}', '\u{0}']), ('\u{1ec1}', ['\u{1ec0}', '\u{0}', '\u{0}']), - ('\u{1ec3}', ['\u{1ec2}', '\u{0}', '\u{0}']), ('\u{1ec5}', ['\u{1ec4}', '\u{0}', '\u{0}']), - ('\u{1ec7}', ['\u{1ec6}', '\u{0}', '\u{0}']), ('\u{1ec9}', ['\u{1ec8}', '\u{0}', '\u{0}']), - ('\u{1ecb}', ['\u{1eca}', '\u{0}', '\u{0}']), ('\u{1ecd}', ['\u{1ecc}', '\u{0}', '\u{0}']), - ('\u{1ecf}', ['\u{1ece}', '\u{0}', '\u{0}']), ('\u{1ed1}', ['\u{1ed0}', '\u{0}', '\u{0}']), - ('\u{1ed3}', ['\u{1ed2}', '\u{0}', '\u{0}']), ('\u{1ed5}', ['\u{1ed4}', '\u{0}', '\u{0}']), - ('\u{1ed7}', ['\u{1ed6}', '\u{0}', '\u{0}']), ('\u{1ed9}', ['\u{1ed8}', '\u{0}', '\u{0}']), - ('\u{1edb}', ['\u{1eda}', '\u{0}', '\u{0}']), ('\u{1edd}', ['\u{1edc}', '\u{0}', '\u{0}']), - ('\u{1edf}', ['\u{1ede}', '\u{0}', '\u{0}']), ('\u{1ee1}', ['\u{1ee0}', '\u{0}', '\u{0}']), - ('\u{1ee3}', ['\u{1ee2}', '\u{0}', '\u{0}']), ('\u{1ee5}', ['\u{1ee4}', '\u{0}', '\u{0}']), - ('\u{1ee7}', ['\u{1ee6}', '\u{0}', '\u{0}']), ('\u{1ee9}', ['\u{1ee8}', '\u{0}', '\u{0}']), - ('\u{1eeb}', ['\u{1eea}', '\u{0}', '\u{0}']), ('\u{1eed}', ['\u{1eec}', '\u{0}', '\u{0}']), - ('\u{1eef}', ['\u{1eee}', '\u{0}', '\u{0}']), ('\u{1ef1}', ['\u{1ef0}', '\u{0}', '\u{0}']), - ('\u{1ef3}', ['\u{1ef2}', '\u{0}', '\u{0}']), ('\u{1ef5}', ['\u{1ef4}', '\u{0}', '\u{0}']), - ('\u{1ef7}', ['\u{1ef6}', '\u{0}', '\u{0}']), ('\u{1ef9}', ['\u{1ef8}', '\u{0}', '\u{0}']), - ('\u{1efb}', ['\u{1efa}', '\u{0}', '\u{0}']), ('\u{1efd}', ['\u{1efc}', '\u{0}', '\u{0}']), - ('\u{1eff}', ['\u{1efe}', '\u{0}', '\u{0}']), ('\u{1f00}', ['\u{1f08}', '\u{0}', '\u{0}']), - ('\u{1f01}', ['\u{1f09}', '\u{0}', '\u{0}']), ('\u{1f02}', ['\u{1f0a}', '\u{0}', '\u{0}']), - ('\u{1f03}', ['\u{1f0b}', '\u{0}', '\u{0}']), ('\u{1f04}', ['\u{1f0c}', '\u{0}', '\u{0}']), - ('\u{1f05}', ['\u{1f0d}', '\u{0}', '\u{0}']), ('\u{1f06}', ['\u{1f0e}', '\u{0}', '\u{0}']), - ('\u{1f07}', ['\u{1f0f}', '\u{0}', '\u{0}']), ('\u{1f10}', ['\u{1f18}', '\u{0}', '\u{0}']), - ('\u{1f11}', ['\u{1f19}', '\u{0}', '\u{0}']), ('\u{1f12}', ['\u{1f1a}', '\u{0}', '\u{0}']), - ('\u{1f13}', ['\u{1f1b}', '\u{0}', '\u{0}']), ('\u{1f14}', ['\u{1f1c}', '\u{0}', '\u{0}']), - ('\u{1f15}', ['\u{1f1d}', '\u{0}', '\u{0}']), ('\u{1f20}', ['\u{1f28}', '\u{0}', '\u{0}']), - ('\u{1f21}', ['\u{1f29}', '\u{0}', '\u{0}']), ('\u{1f22}', ['\u{1f2a}', '\u{0}', '\u{0}']), - ('\u{1f23}', ['\u{1f2b}', '\u{0}', '\u{0}']), ('\u{1f24}', ['\u{1f2c}', '\u{0}', '\u{0}']), - ('\u{1f25}', ['\u{1f2d}', '\u{0}', '\u{0}']), ('\u{1f26}', ['\u{1f2e}', '\u{0}', '\u{0}']), - ('\u{1f27}', ['\u{1f2f}', '\u{0}', '\u{0}']), ('\u{1f30}', ['\u{1f38}', '\u{0}', '\u{0}']), - ('\u{1f31}', ['\u{1f39}', '\u{0}', '\u{0}']), ('\u{1f32}', ['\u{1f3a}', '\u{0}', '\u{0}']), - ('\u{1f33}', ['\u{1f3b}', '\u{0}', '\u{0}']), ('\u{1f34}', ['\u{1f3c}', '\u{0}', '\u{0}']), - ('\u{1f35}', ['\u{1f3d}', '\u{0}', '\u{0}']), ('\u{1f36}', ['\u{1f3e}', '\u{0}', '\u{0}']), - ('\u{1f37}', ['\u{1f3f}', '\u{0}', '\u{0}']), ('\u{1f40}', ['\u{1f48}', '\u{0}', '\u{0}']), - ('\u{1f41}', ['\u{1f49}', '\u{0}', '\u{0}']), ('\u{1f42}', ['\u{1f4a}', '\u{0}', '\u{0}']), - ('\u{1f43}', ['\u{1f4b}', '\u{0}', '\u{0}']), ('\u{1f44}', ['\u{1f4c}', '\u{0}', '\u{0}']), - ('\u{1f45}', ['\u{1f4d}', '\u{0}', '\u{0}']), ('\u{1f50}', ['\u{3a5}', '\u{313}', '\u{0}']), - ('\u{1f51}', ['\u{1f59}', '\u{0}', '\u{0}']), - ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), - ('\u{1f53}', ['\u{1f5b}', '\u{0}', '\u{0}']), - ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), - ('\u{1f55}', ['\u{1f5d}', '\u{0}', '\u{0}']), - ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), - ('\u{1f57}', ['\u{1f5f}', '\u{0}', '\u{0}']), ('\u{1f60}', ['\u{1f68}', '\u{0}', '\u{0}']), - ('\u{1f61}', ['\u{1f69}', '\u{0}', '\u{0}']), ('\u{1f62}', ['\u{1f6a}', '\u{0}', '\u{0}']), - ('\u{1f63}', ['\u{1f6b}', '\u{0}', '\u{0}']), ('\u{1f64}', ['\u{1f6c}', '\u{0}', '\u{0}']), - ('\u{1f65}', ['\u{1f6d}', '\u{0}', '\u{0}']), ('\u{1f66}', ['\u{1f6e}', '\u{0}', '\u{0}']), - ('\u{1f67}', ['\u{1f6f}', '\u{0}', '\u{0}']), ('\u{1f70}', ['\u{1fba}', '\u{0}', '\u{0}']), - ('\u{1f71}', ['\u{1fbb}', '\u{0}', '\u{0}']), ('\u{1f72}', ['\u{1fc8}', '\u{0}', '\u{0}']), - ('\u{1f73}', ['\u{1fc9}', '\u{0}', '\u{0}']), ('\u{1f74}', ['\u{1fca}', '\u{0}', '\u{0}']), - ('\u{1f75}', ['\u{1fcb}', '\u{0}', '\u{0}']), ('\u{1f76}', ['\u{1fda}', '\u{0}', '\u{0}']), - ('\u{1f77}', ['\u{1fdb}', '\u{0}', '\u{0}']), ('\u{1f78}', ['\u{1ff8}', '\u{0}', '\u{0}']), - ('\u{1f79}', ['\u{1ff9}', '\u{0}', '\u{0}']), ('\u{1f7a}', ['\u{1fea}', '\u{0}', '\u{0}']), - ('\u{1f7b}', ['\u{1feb}', '\u{0}', '\u{0}']), ('\u{1f7c}', ['\u{1ffa}', '\u{0}', '\u{0}']), - ('\u{1f7d}', ['\u{1ffb}', '\u{0}', '\u{0}']), - ('\u{1f80}', ['\u{1f08}', '\u{399}', '\u{0}']), - ('\u{1f81}', ['\u{1f09}', '\u{399}', '\u{0}']), - ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\u{0}']), - ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\u{0}']), - ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\u{0}']), - ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\u{0}']), - ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\u{0}']), - ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\u{0}']), - ('\u{1f88}', ['\u{1f08}', '\u{399}', '\u{0}']), - ('\u{1f89}', ['\u{1f09}', '\u{399}', '\u{0}']), - ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\u{0}']), - ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\u{0}']), - ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\u{0}']), - ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\u{0}']), - ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\u{0}']), - ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\u{0}']), - ('\u{1f90}', ['\u{1f28}', '\u{399}', '\u{0}']), - ('\u{1f91}', ['\u{1f29}', '\u{399}', '\u{0}']), - ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\u{0}']), - ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\u{0}']), - ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\u{0}']), - ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\u{0}']), - ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\u{0}']), - ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\u{0}']), - ('\u{1f98}', ['\u{1f28}', '\u{399}', '\u{0}']), - ('\u{1f99}', ['\u{1f29}', '\u{399}', '\u{0}']), - ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\u{0}']), - ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\u{0}']), - ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\u{0}']), - ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\u{0}']), - ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\u{0}']), - ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\u{0}']), - ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\u{0}']), - ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\u{0}']), - ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\u{0}']), - ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\u{0}']), - ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\u{0}']), - ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\u{0}']), - ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\u{0}']), - ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\u{0}']), - ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\u{0}']), - ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\u{0}']), - ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\u{0}']), - ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\u{0}']), - ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\u{0}']), - ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\u{0}']), - ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\u{0}']), - ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\u{0}']), - ('\u{1fb0}', ['\u{1fb8}', '\u{0}', '\u{0}']), ('\u{1fb1}', ['\u{1fb9}', '\u{0}', '\u{0}']), - ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\u{0}']), - ('\u{1fb3}', ['\u{391}', '\u{399}', '\u{0}']), - ('\u{1fb4}', ['\u{386}', '\u{399}', '\u{0}']), - ('\u{1fb6}', ['\u{391}', '\u{342}', '\u{0}']), - ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), - ('\u{1fbc}', ['\u{391}', '\u{399}', '\u{0}']), ('\u{1fbe}', ['\u{399}', '\u{0}', '\u{0}']), - ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\u{0}']), - ('\u{1fc3}', ['\u{397}', '\u{399}', '\u{0}']), - ('\u{1fc4}', ['\u{389}', '\u{399}', '\u{0}']), - ('\u{1fc6}', ['\u{397}', '\u{342}', '\u{0}']), - ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), - ('\u{1fcc}', ['\u{397}', '\u{399}', '\u{0}']), ('\u{1fd0}', ['\u{1fd8}', '\u{0}', '\u{0}']), - ('\u{1fd1}', ['\u{1fd9}', '\u{0}', '\u{0}']), - ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), - ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), - ('\u{1fd6}', ['\u{399}', '\u{342}', '\u{0}']), - ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), - ('\u{1fe0}', ['\u{1fe8}', '\u{0}', '\u{0}']), ('\u{1fe1}', ['\u{1fe9}', '\u{0}', '\u{0}']), - ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), - ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\u{0}']), ('\u{1fe5}', ['\u{1fec}', '\u{0}', '\u{0}']), - ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\u{0}']), - ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), - ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\u{0}']), - ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\u{0}']), - ('\u{1ff4}', ['\u{38f}', '\u{399}', '\u{0}']), - ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\u{0}']), - ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), - ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\u{0}']), ('\u{214e}', ['\u{2132}', '\u{0}', '\u{0}']), - ('\u{2170}', ['\u{2160}', '\u{0}', '\u{0}']), ('\u{2171}', ['\u{2161}', '\u{0}', '\u{0}']), - ('\u{2172}', ['\u{2162}', '\u{0}', '\u{0}']), ('\u{2173}', ['\u{2163}', '\u{0}', '\u{0}']), - ('\u{2174}', ['\u{2164}', '\u{0}', '\u{0}']), ('\u{2175}', ['\u{2165}', '\u{0}', '\u{0}']), - ('\u{2176}', ['\u{2166}', '\u{0}', '\u{0}']), ('\u{2177}', ['\u{2167}', '\u{0}', '\u{0}']), - ('\u{2178}', ['\u{2168}', '\u{0}', '\u{0}']), ('\u{2179}', ['\u{2169}', '\u{0}', '\u{0}']), - ('\u{217a}', ['\u{216a}', '\u{0}', '\u{0}']), ('\u{217b}', ['\u{216b}', '\u{0}', '\u{0}']), - ('\u{217c}', ['\u{216c}', '\u{0}', '\u{0}']), ('\u{217d}', ['\u{216d}', '\u{0}', '\u{0}']), - ('\u{217e}', ['\u{216e}', '\u{0}', '\u{0}']), ('\u{217f}', ['\u{216f}', '\u{0}', '\u{0}']), - ('\u{2184}', ['\u{2183}', '\u{0}', '\u{0}']), ('\u{24d0}', ['\u{24b6}', '\u{0}', '\u{0}']), - ('\u{24d1}', ['\u{24b7}', '\u{0}', '\u{0}']), ('\u{24d2}', ['\u{24b8}', '\u{0}', '\u{0}']), - ('\u{24d3}', ['\u{24b9}', '\u{0}', '\u{0}']), ('\u{24d4}', ['\u{24ba}', '\u{0}', '\u{0}']), - ('\u{24d5}', ['\u{24bb}', '\u{0}', '\u{0}']), ('\u{24d6}', ['\u{24bc}', '\u{0}', '\u{0}']), - ('\u{24d7}', ['\u{24bd}', '\u{0}', '\u{0}']), ('\u{24d8}', ['\u{24be}', '\u{0}', '\u{0}']), - ('\u{24d9}', ['\u{24bf}', '\u{0}', '\u{0}']), ('\u{24da}', ['\u{24c0}', '\u{0}', '\u{0}']), - ('\u{24db}', ['\u{24c1}', '\u{0}', '\u{0}']), ('\u{24dc}', ['\u{24c2}', '\u{0}', '\u{0}']), - ('\u{24dd}', ['\u{24c3}', '\u{0}', '\u{0}']), ('\u{24de}', ['\u{24c4}', '\u{0}', '\u{0}']), - ('\u{24df}', ['\u{24c5}', '\u{0}', '\u{0}']), ('\u{24e0}', ['\u{24c6}', '\u{0}', '\u{0}']), - ('\u{24e1}', ['\u{24c7}', '\u{0}', '\u{0}']), ('\u{24e2}', ['\u{24c8}', '\u{0}', '\u{0}']), - ('\u{24e3}', ['\u{24c9}', '\u{0}', '\u{0}']), ('\u{24e4}', ['\u{24ca}', '\u{0}', '\u{0}']), - ('\u{24e5}', ['\u{24cb}', '\u{0}', '\u{0}']), ('\u{24e6}', ['\u{24cc}', '\u{0}', '\u{0}']), - ('\u{24e7}', ['\u{24cd}', '\u{0}', '\u{0}']), ('\u{24e8}', ['\u{24ce}', '\u{0}', '\u{0}']), - ('\u{24e9}', ['\u{24cf}', '\u{0}', '\u{0}']), ('\u{2c30}', ['\u{2c00}', '\u{0}', '\u{0}']), - ('\u{2c31}', ['\u{2c01}', '\u{0}', '\u{0}']), ('\u{2c32}', ['\u{2c02}', '\u{0}', '\u{0}']), - ('\u{2c33}', ['\u{2c03}', '\u{0}', '\u{0}']), ('\u{2c34}', ['\u{2c04}', '\u{0}', '\u{0}']), - ('\u{2c35}', ['\u{2c05}', '\u{0}', '\u{0}']), ('\u{2c36}', ['\u{2c06}', '\u{0}', '\u{0}']), - ('\u{2c37}', ['\u{2c07}', '\u{0}', '\u{0}']), ('\u{2c38}', ['\u{2c08}', '\u{0}', '\u{0}']), - ('\u{2c39}', ['\u{2c09}', '\u{0}', '\u{0}']), ('\u{2c3a}', ['\u{2c0a}', '\u{0}', '\u{0}']), - ('\u{2c3b}', ['\u{2c0b}', '\u{0}', '\u{0}']), ('\u{2c3c}', ['\u{2c0c}', '\u{0}', '\u{0}']), - ('\u{2c3d}', ['\u{2c0d}', '\u{0}', '\u{0}']), ('\u{2c3e}', ['\u{2c0e}', '\u{0}', '\u{0}']), - ('\u{2c3f}', ['\u{2c0f}', '\u{0}', '\u{0}']), ('\u{2c40}', ['\u{2c10}', '\u{0}', '\u{0}']), - ('\u{2c41}', ['\u{2c11}', '\u{0}', '\u{0}']), ('\u{2c42}', ['\u{2c12}', '\u{0}', '\u{0}']), - ('\u{2c43}', ['\u{2c13}', '\u{0}', '\u{0}']), ('\u{2c44}', ['\u{2c14}', '\u{0}', '\u{0}']), - ('\u{2c45}', ['\u{2c15}', '\u{0}', '\u{0}']), ('\u{2c46}', ['\u{2c16}', '\u{0}', '\u{0}']), - ('\u{2c47}', ['\u{2c17}', '\u{0}', '\u{0}']), ('\u{2c48}', ['\u{2c18}', '\u{0}', '\u{0}']), - ('\u{2c49}', ['\u{2c19}', '\u{0}', '\u{0}']), ('\u{2c4a}', ['\u{2c1a}', '\u{0}', '\u{0}']), - ('\u{2c4b}', ['\u{2c1b}', '\u{0}', '\u{0}']), ('\u{2c4c}', ['\u{2c1c}', '\u{0}', '\u{0}']), - ('\u{2c4d}', ['\u{2c1d}', '\u{0}', '\u{0}']), ('\u{2c4e}', ['\u{2c1e}', '\u{0}', '\u{0}']), - ('\u{2c4f}', ['\u{2c1f}', '\u{0}', '\u{0}']), ('\u{2c50}', ['\u{2c20}', '\u{0}', '\u{0}']), - ('\u{2c51}', ['\u{2c21}', '\u{0}', '\u{0}']), ('\u{2c52}', ['\u{2c22}', '\u{0}', '\u{0}']), - ('\u{2c53}', ['\u{2c23}', '\u{0}', '\u{0}']), ('\u{2c54}', ['\u{2c24}', '\u{0}', '\u{0}']), - ('\u{2c55}', ['\u{2c25}', '\u{0}', '\u{0}']), ('\u{2c56}', ['\u{2c26}', '\u{0}', '\u{0}']), - ('\u{2c57}', ['\u{2c27}', '\u{0}', '\u{0}']), ('\u{2c58}', ['\u{2c28}', '\u{0}', '\u{0}']), - ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']), - ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']), - ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']), - ('\u{2c5f}', ['\u{2c2f}', '\u{0}', '\u{0}']), ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), - ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), - ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), - ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), - ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), - ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), - ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), - ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), - ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), - ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), - ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), - ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), - ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), - ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), - ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), - ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), - ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), - ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), - ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), - ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), - ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), - ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), - ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), - ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), - ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), - ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), - ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), - ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), - ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), - ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), - ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), - ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), - ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), - ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), - ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), - ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), - ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), - ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), - ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), - ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), - ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), - ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), - ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), - ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), - ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), - ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), - ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), - ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), - ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), - ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), - ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), - ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), - ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), - ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), - ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), - ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), - ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), - ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), - ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), - ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), - ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), - ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), - ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), - ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), - ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), - ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), - ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), - ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), - ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), - ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), - ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), - ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), - ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), - ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), - ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), - ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), - ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), - ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), - ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), - ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), - ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), - ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), - ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), - ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), - ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), - ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), - ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), - ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), - ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), - ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), - ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), - ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), - ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), - ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), - ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), - ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), - ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), - ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), - ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), - ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), - ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), - ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), - ('\u{a7c1}', ['\u{a7c0}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']), - ('\u{a7c8}', ['\u{a7c7}', '\u{0}', '\u{0}']), ('\u{a7ca}', ['\u{a7c9}', '\u{0}', '\u{0}']), - ('\u{a7cd}', ['\u{a7cc}', '\u{0}', '\u{0}']), ('\u{a7cf}', ['\u{a7ce}', '\u{0}', '\u{0}']), - ('\u{a7d1}', ['\u{a7d0}', '\u{0}', '\u{0}']), ('\u{a7d3}', ['\u{a7d2}', '\u{0}', '\u{0}']), - ('\u{a7d5}', ['\u{a7d4}', '\u{0}', '\u{0}']), ('\u{a7d7}', ['\u{a7d6}', '\u{0}', '\u{0}']), - ('\u{a7d9}', ['\u{a7d8}', '\u{0}', '\u{0}']), ('\u{a7db}', ['\u{a7da}', '\u{0}', '\u{0}']), - ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']), ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), - ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), - ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), - ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), - ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), - ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), - ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), - ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), - ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), - ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), - ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), - ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), - ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), - ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), - ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), - ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), - ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), - ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), - ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), - ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), - ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), - ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), - ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), - ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), - ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), - ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), - ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), - ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), - ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), - ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), - ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), - ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), - ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), - ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), - ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), - ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), - ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), - ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), - ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), - ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), - ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), - ('\u{fb00}', ['\u{46}', '\u{46}', '\u{0}']), ('\u{fb01}', ['\u{46}', '\u{49}', '\u{0}']), - ('\u{fb02}', ['\u{46}', '\u{4c}', '\u{0}']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), - ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\u{0}']), - ('\u{fb06}', ['\u{53}', '\u{54}', '\u{0}']), ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']), - ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']), - ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']), - ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']), - ('\u{fb17}', ['\u{544}', '\u{53d}', '\u{0}']), ('\u{ff41}', ['\u{ff21}', '\u{0}', '\u{0}']), - ('\u{ff42}', ['\u{ff22}', '\u{0}', '\u{0}']), ('\u{ff43}', ['\u{ff23}', '\u{0}', '\u{0}']), - ('\u{ff44}', ['\u{ff24}', '\u{0}', '\u{0}']), ('\u{ff45}', ['\u{ff25}', '\u{0}', '\u{0}']), - ('\u{ff46}', ['\u{ff26}', '\u{0}', '\u{0}']), ('\u{ff47}', ['\u{ff27}', '\u{0}', '\u{0}']), - ('\u{ff48}', ['\u{ff28}', '\u{0}', '\u{0}']), ('\u{ff49}', ['\u{ff29}', '\u{0}', '\u{0}']), - ('\u{ff4a}', ['\u{ff2a}', '\u{0}', '\u{0}']), ('\u{ff4b}', ['\u{ff2b}', '\u{0}', '\u{0}']), - ('\u{ff4c}', ['\u{ff2c}', '\u{0}', '\u{0}']), ('\u{ff4d}', ['\u{ff2d}', '\u{0}', '\u{0}']), - ('\u{ff4e}', ['\u{ff2e}', '\u{0}', '\u{0}']), ('\u{ff4f}', ['\u{ff2f}', '\u{0}', '\u{0}']), - ('\u{ff50}', ['\u{ff30}', '\u{0}', '\u{0}']), ('\u{ff51}', ['\u{ff31}', '\u{0}', '\u{0}']), - ('\u{ff52}', ['\u{ff32}', '\u{0}', '\u{0}']), ('\u{ff53}', ['\u{ff33}', '\u{0}', '\u{0}']), - ('\u{ff54}', ['\u{ff34}', '\u{0}', '\u{0}']), ('\u{ff55}', ['\u{ff35}', '\u{0}', '\u{0}']), - ('\u{ff56}', ['\u{ff36}', '\u{0}', '\u{0}']), ('\u{ff57}', ['\u{ff37}', '\u{0}', '\u{0}']), - ('\u{ff58}', ['\u{ff38}', '\u{0}', '\u{0}']), ('\u{ff59}', ['\u{ff39}', '\u{0}', '\u{0}']), - ('\u{ff5a}', ['\u{ff3a}', '\u{0}', '\u{0}']), - ('\u{10428}', ['\u{10400}', '\u{0}', '\u{0}']), - ('\u{10429}', ['\u{10401}', '\u{0}', '\u{0}']), - ('\u{1042a}', ['\u{10402}', '\u{0}', '\u{0}']), - ('\u{1042b}', ['\u{10403}', '\u{0}', '\u{0}']), - ('\u{1042c}', ['\u{10404}', '\u{0}', '\u{0}']), - ('\u{1042d}', ['\u{10405}', '\u{0}', '\u{0}']), - ('\u{1042e}', ['\u{10406}', '\u{0}', '\u{0}']), - ('\u{1042f}', ['\u{10407}', '\u{0}', '\u{0}']), - ('\u{10430}', ['\u{10408}', '\u{0}', '\u{0}']), - ('\u{10431}', ['\u{10409}', '\u{0}', '\u{0}']), - ('\u{10432}', ['\u{1040a}', '\u{0}', '\u{0}']), - ('\u{10433}', ['\u{1040b}', '\u{0}', '\u{0}']), - ('\u{10434}', ['\u{1040c}', '\u{0}', '\u{0}']), - ('\u{10435}', ['\u{1040d}', '\u{0}', '\u{0}']), - ('\u{10436}', ['\u{1040e}', '\u{0}', '\u{0}']), - ('\u{10437}', ['\u{1040f}', '\u{0}', '\u{0}']), - ('\u{10438}', ['\u{10410}', '\u{0}', '\u{0}']), - ('\u{10439}', ['\u{10411}', '\u{0}', '\u{0}']), - ('\u{1043a}', ['\u{10412}', '\u{0}', '\u{0}']), - ('\u{1043b}', ['\u{10413}', '\u{0}', '\u{0}']), - ('\u{1043c}', ['\u{10414}', '\u{0}', '\u{0}']), - ('\u{1043d}', ['\u{10415}', '\u{0}', '\u{0}']), - ('\u{1043e}', ['\u{10416}', '\u{0}', '\u{0}']), - ('\u{1043f}', ['\u{10417}', '\u{0}', '\u{0}']), - ('\u{10440}', ['\u{10418}', '\u{0}', '\u{0}']), - ('\u{10441}', ['\u{10419}', '\u{0}', '\u{0}']), - ('\u{10442}', ['\u{1041a}', '\u{0}', '\u{0}']), - ('\u{10443}', ['\u{1041b}', '\u{0}', '\u{0}']), - ('\u{10444}', ['\u{1041c}', '\u{0}', '\u{0}']), - ('\u{10445}', ['\u{1041d}', '\u{0}', '\u{0}']), - ('\u{10446}', ['\u{1041e}', '\u{0}', '\u{0}']), - ('\u{10447}', ['\u{1041f}', '\u{0}', '\u{0}']), - ('\u{10448}', ['\u{10420}', '\u{0}', '\u{0}']), - ('\u{10449}', ['\u{10421}', '\u{0}', '\u{0}']), - ('\u{1044a}', ['\u{10422}', '\u{0}', '\u{0}']), - ('\u{1044b}', ['\u{10423}', '\u{0}', '\u{0}']), - ('\u{1044c}', ['\u{10424}', '\u{0}', '\u{0}']), - ('\u{1044d}', ['\u{10425}', '\u{0}', '\u{0}']), - ('\u{1044e}', ['\u{10426}', '\u{0}', '\u{0}']), - ('\u{1044f}', ['\u{10427}', '\u{0}', '\u{0}']), - ('\u{104d8}', ['\u{104b0}', '\u{0}', '\u{0}']), - ('\u{104d9}', ['\u{104b1}', '\u{0}', '\u{0}']), - ('\u{104da}', ['\u{104b2}', '\u{0}', '\u{0}']), - ('\u{104db}', ['\u{104b3}', '\u{0}', '\u{0}']), - ('\u{104dc}', ['\u{104b4}', '\u{0}', '\u{0}']), - ('\u{104dd}', ['\u{104b5}', '\u{0}', '\u{0}']), - ('\u{104de}', ['\u{104b6}', '\u{0}', '\u{0}']), - ('\u{104df}', ['\u{104b7}', '\u{0}', '\u{0}']), - ('\u{104e0}', ['\u{104b8}', '\u{0}', '\u{0}']), - ('\u{104e1}', ['\u{104b9}', '\u{0}', '\u{0}']), - ('\u{104e2}', ['\u{104ba}', '\u{0}', '\u{0}']), - ('\u{104e3}', ['\u{104bb}', '\u{0}', '\u{0}']), - ('\u{104e4}', ['\u{104bc}', '\u{0}', '\u{0}']), - ('\u{104e5}', ['\u{104bd}', '\u{0}', '\u{0}']), - ('\u{104e6}', ['\u{104be}', '\u{0}', '\u{0}']), - ('\u{104e7}', ['\u{104bf}', '\u{0}', '\u{0}']), - ('\u{104e8}', ['\u{104c0}', '\u{0}', '\u{0}']), - ('\u{104e9}', ['\u{104c1}', '\u{0}', '\u{0}']), - ('\u{104ea}', ['\u{104c2}', '\u{0}', '\u{0}']), - ('\u{104eb}', ['\u{104c3}', '\u{0}', '\u{0}']), - ('\u{104ec}', ['\u{104c4}', '\u{0}', '\u{0}']), - ('\u{104ed}', ['\u{104c5}', '\u{0}', '\u{0}']), - ('\u{104ee}', ['\u{104c6}', '\u{0}', '\u{0}']), - ('\u{104ef}', ['\u{104c7}', '\u{0}', '\u{0}']), - ('\u{104f0}', ['\u{104c8}', '\u{0}', '\u{0}']), - ('\u{104f1}', ['\u{104c9}', '\u{0}', '\u{0}']), - ('\u{104f2}', ['\u{104ca}', '\u{0}', '\u{0}']), - ('\u{104f3}', ['\u{104cb}', '\u{0}', '\u{0}']), - ('\u{104f4}', ['\u{104cc}', '\u{0}', '\u{0}']), - ('\u{104f5}', ['\u{104cd}', '\u{0}', '\u{0}']), - ('\u{104f6}', ['\u{104ce}', '\u{0}', '\u{0}']), - ('\u{104f7}', ['\u{104cf}', '\u{0}', '\u{0}']), - ('\u{104f8}', ['\u{104d0}', '\u{0}', '\u{0}']), - ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']), - ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']), - ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']), - ('\u{10597}', ['\u{10570}', '\u{0}', '\u{0}']), - ('\u{10598}', ['\u{10571}', '\u{0}', '\u{0}']), - ('\u{10599}', ['\u{10572}', '\u{0}', '\u{0}']), - ('\u{1059a}', ['\u{10573}', '\u{0}', '\u{0}']), - ('\u{1059b}', ['\u{10574}', '\u{0}', '\u{0}']), - ('\u{1059c}', ['\u{10575}', '\u{0}', '\u{0}']), - ('\u{1059d}', ['\u{10576}', '\u{0}', '\u{0}']), - ('\u{1059e}', ['\u{10577}', '\u{0}', '\u{0}']), - ('\u{1059f}', ['\u{10578}', '\u{0}', '\u{0}']), - ('\u{105a0}', ['\u{10579}', '\u{0}', '\u{0}']), - ('\u{105a1}', ['\u{1057a}', '\u{0}', '\u{0}']), - ('\u{105a3}', ['\u{1057c}', '\u{0}', '\u{0}']), - ('\u{105a4}', ['\u{1057d}', '\u{0}', '\u{0}']), - ('\u{105a5}', ['\u{1057e}', '\u{0}', '\u{0}']), - ('\u{105a6}', ['\u{1057f}', '\u{0}', '\u{0}']), - ('\u{105a7}', ['\u{10580}', '\u{0}', '\u{0}']), - ('\u{105a8}', ['\u{10581}', '\u{0}', '\u{0}']), - ('\u{105a9}', ['\u{10582}', '\u{0}', '\u{0}']), - ('\u{105aa}', ['\u{10583}', '\u{0}', '\u{0}']), - ('\u{105ab}', ['\u{10584}', '\u{0}', '\u{0}']), - ('\u{105ac}', ['\u{10585}', '\u{0}', '\u{0}']), - ('\u{105ad}', ['\u{10586}', '\u{0}', '\u{0}']), - ('\u{105ae}', ['\u{10587}', '\u{0}', '\u{0}']), - ('\u{105af}', ['\u{10588}', '\u{0}', '\u{0}']), - ('\u{105b0}', ['\u{10589}', '\u{0}', '\u{0}']), - ('\u{105b1}', ['\u{1058a}', '\u{0}', '\u{0}']), - ('\u{105b3}', ['\u{1058c}', '\u{0}', '\u{0}']), - ('\u{105b4}', ['\u{1058d}', '\u{0}', '\u{0}']), - ('\u{105b5}', ['\u{1058e}', '\u{0}', '\u{0}']), - ('\u{105b6}', ['\u{1058f}', '\u{0}', '\u{0}']), - ('\u{105b7}', ['\u{10590}', '\u{0}', '\u{0}']), - ('\u{105b8}', ['\u{10591}', '\u{0}', '\u{0}']), - ('\u{105b9}', ['\u{10592}', '\u{0}', '\u{0}']), - ('\u{105bb}', ['\u{10594}', '\u{0}', '\u{0}']), - ('\u{105bc}', ['\u{10595}', '\u{0}', '\u{0}']), - ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']), - ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']), - ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']), - ('\u{10cc3}', ['\u{10c83}', '\u{0}', '\u{0}']), - ('\u{10cc4}', ['\u{10c84}', '\u{0}', '\u{0}']), - ('\u{10cc5}', ['\u{10c85}', '\u{0}', '\u{0}']), - ('\u{10cc6}', ['\u{10c86}', '\u{0}', '\u{0}']), - ('\u{10cc7}', ['\u{10c87}', '\u{0}', '\u{0}']), - ('\u{10cc8}', ['\u{10c88}', '\u{0}', '\u{0}']), - ('\u{10cc9}', ['\u{10c89}', '\u{0}', '\u{0}']), - ('\u{10cca}', ['\u{10c8a}', '\u{0}', '\u{0}']), - ('\u{10ccb}', ['\u{10c8b}', '\u{0}', '\u{0}']), - ('\u{10ccc}', ['\u{10c8c}', '\u{0}', '\u{0}']), - ('\u{10ccd}', ['\u{10c8d}', '\u{0}', '\u{0}']), - ('\u{10cce}', ['\u{10c8e}', '\u{0}', '\u{0}']), - ('\u{10ccf}', ['\u{10c8f}', '\u{0}', '\u{0}']), - ('\u{10cd0}', ['\u{10c90}', '\u{0}', '\u{0}']), - ('\u{10cd1}', ['\u{10c91}', '\u{0}', '\u{0}']), - ('\u{10cd2}', ['\u{10c92}', '\u{0}', '\u{0}']), - ('\u{10cd3}', ['\u{10c93}', '\u{0}', '\u{0}']), - ('\u{10cd4}', ['\u{10c94}', '\u{0}', '\u{0}']), - ('\u{10cd5}', ['\u{10c95}', '\u{0}', '\u{0}']), - ('\u{10cd6}', ['\u{10c96}', '\u{0}', '\u{0}']), - ('\u{10cd7}', ['\u{10c97}', '\u{0}', '\u{0}']), - ('\u{10cd8}', ['\u{10c98}', '\u{0}', '\u{0}']), - ('\u{10cd9}', ['\u{10c99}', '\u{0}', '\u{0}']), - ('\u{10cda}', ['\u{10c9a}', '\u{0}', '\u{0}']), - ('\u{10cdb}', ['\u{10c9b}', '\u{0}', '\u{0}']), - ('\u{10cdc}', ['\u{10c9c}', '\u{0}', '\u{0}']), - ('\u{10cdd}', ['\u{10c9d}', '\u{0}', '\u{0}']), - ('\u{10cde}', ['\u{10c9e}', '\u{0}', '\u{0}']), - ('\u{10cdf}', ['\u{10c9f}', '\u{0}', '\u{0}']), - ('\u{10ce0}', ['\u{10ca0}', '\u{0}', '\u{0}']), - ('\u{10ce1}', ['\u{10ca1}', '\u{0}', '\u{0}']), - ('\u{10ce2}', ['\u{10ca2}', '\u{0}', '\u{0}']), - ('\u{10ce3}', ['\u{10ca3}', '\u{0}', '\u{0}']), - ('\u{10ce4}', ['\u{10ca4}', '\u{0}', '\u{0}']), - ('\u{10ce5}', ['\u{10ca5}', '\u{0}', '\u{0}']), - ('\u{10ce6}', ['\u{10ca6}', '\u{0}', '\u{0}']), - ('\u{10ce7}', ['\u{10ca7}', '\u{0}', '\u{0}']), - ('\u{10ce8}', ['\u{10ca8}', '\u{0}', '\u{0}']), - ('\u{10ce9}', ['\u{10ca9}', '\u{0}', '\u{0}']), - ('\u{10cea}', ['\u{10caa}', '\u{0}', '\u{0}']), - ('\u{10ceb}', ['\u{10cab}', '\u{0}', '\u{0}']), - ('\u{10cec}', ['\u{10cac}', '\u{0}', '\u{0}']), - ('\u{10ced}', ['\u{10cad}', '\u{0}', '\u{0}']), - ('\u{10cee}', ['\u{10cae}', '\u{0}', '\u{0}']), - ('\u{10cef}', ['\u{10caf}', '\u{0}', '\u{0}']), - ('\u{10cf0}', ['\u{10cb0}', '\u{0}', '\u{0}']), - ('\u{10cf1}', ['\u{10cb1}', '\u{0}', '\u{0}']), - ('\u{10cf2}', ['\u{10cb2}', '\u{0}', '\u{0}']), - ('\u{10d70}', ['\u{10d50}', '\u{0}', '\u{0}']), - ('\u{10d71}', ['\u{10d51}', '\u{0}', '\u{0}']), - ('\u{10d72}', ['\u{10d52}', '\u{0}', '\u{0}']), - ('\u{10d73}', ['\u{10d53}', '\u{0}', '\u{0}']), - ('\u{10d74}', ['\u{10d54}', '\u{0}', '\u{0}']), - ('\u{10d75}', ['\u{10d55}', '\u{0}', '\u{0}']), - ('\u{10d76}', ['\u{10d56}', '\u{0}', '\u{0}']), - ('\u{10d77}', ['\u{10d57}', '\u{0}', '\u{0}']), - ('\u{10d78}', ['\u{10d58}', '\u{0}', '\u{0}']), - ('\u{10d79}', ['\u{10d59}', '\u{0}', '\u{0}']), - ('\u{10d7a}', ['\u{10d5a}', '\u{0}', '\u{0}']), - ('\u{10d7b}', ['\u{10d5b}', '\u{0}', '\u{0}']), - ('\u{10d7c}', ['\u{10d5c}', '\u{0}', '\u{0}']), - ('\u{10d7d}', ['\u{10d5d}', '\u{0}', '\u{0}']), - ('\u{10d7e}', ['\u{10d5e}', '\u{0}', '\u{0}']), - ('\u{10d7f}', ['\u{10d5f}', '\u{0}', '\u{0}']), - ('\u{10d80}', ['\u{10d60}', '\u{0}', '\u{0}']), - ('\u{10d81}', ['\u{10d61}', '\u{0}', '\u{0}']), - ('\u{10d82}', ['\u{10d62}', '\u{0}', '\u{0}']), - ('\u{10d83}', ['\u{10d63}', '\u{0}', '\u{0}']), - ('\u{10d84}', ['\u{10d64}', '\u{0}', '\u{0}']), - ('\u{10d85}', ['\u{10d65}', '\u{0}', '\u{0}']), - ('\u{118c0}', ['\u{118a0}', '\u{0}', '\u{0}']), - ('\u{118c1}', ['\u{118a1}', '\u{0}', '\u{0}']), - ('\u{118c2}', ['\u{118a2}', '\u{0}', '\u{0}']), - ('\u{118c3}', ['\u{118a3}', '\u{0}', '\u{0}']), - ('\u{118c4}', ['\u{118a4}', '\u{0}', '\u{0}']), - ('\u{118c5}', ['\u{118a5}', '\u{0}', '\u{0}']), - ('\u{118c6}', ['\u{118a6}', '\u{0}', '\u{0}']), - ('\u{118c7}', ['\u{118a7}', '\u{0}', '\u{0}']), - ('\u{118c8}', ['\u{118a8}', '\u{0}', '\u{0}']), - ('\u{118c9}', ['\u{118a9}', '\u{0}', '\u{0}']), - ('\u{118ca}', ['\u{118aa}', '\u{0}', '\u{0}']), - ('\u{118cb}', ['\u{118ab}', '\u{0}', '\u{0}']), - ('\u{118cc}', ['\u{118ac}', '\u{0}', '\u{0}']), - ('\u{118cd}', ['\u{118ad}', '\u{0}', '\u{0}']), - ('\u{118ce}', ['\u{118ae}', '\u{0}', '\u{0}']), - ('\u{118cf}', ['\u{118af}', '\u{0}', '\u{0}']), - ('\u{118d0}', ['\u{118b0}', '\u{0}', '\u{0}']), - ('\u{118d1}', ['\u{118b1}', '\u{0}', '\u{0}']), - ('\u{118d2}', ['\u{118b2}', '\u{0}', '\u{0}']), - ('\u{118d3}', ['\u{118b3}', '\u{0}', '\u{0}']), - ('\u{118d4}', ['\u{118b4}', '\u{0}', '\u{0}']), - ('\u{118d5}', ['\u{118b5}', '\u{0}', '\u{0}']), - ('\u{118d6}', ['\u{118b6}', '\u{0}', '\u{0}']), - ('\u{118d7}', ['\u{118b7}', '\u{0}', '\u{0}']), - ('\u{118d8}', ['\u{118b8}', '\u{0}', '\u{0}']), - ('\u{118d9}', ['\u{118b9}', '\u{0}', '\u{0}']), - ('\u{118da}', ['\u{118ba}', '\u{0}', '\u{0}']), - ('\u{118db}', ['\u{118bb}', '\u{0}', '\u{0}']), - ('\u{118dc}', ['\u{118bc}', '\u{0}', '\u{0}']), - ('\u{118dd}', ['\u{118bd}', '\u{0}', '\u{0}']), - ('\u{118de}', ['\u{118be}', '\u{0}', '\u{0}']), - ('\u{118df}', ['\u{118bf}', '\u{0}', '\u{0}']), - ('\u{16e60}', ['\u{16e40}', '\u{0}', '\u{0}']), - ('\u{16e61}', ['\u{16e41}', '\u{0}', '\u{0}']), - ('\u{16e62}', ['\u{16e42}', '\u{0}', '\u{0}']), - ('\u{16e63}', ['\u{16e43}', '\u{0}', '\u{0}']), - ('\u{16e64}', ['\u{16e44}', '\u{0}', '\u{0}']), - ('\u{16e65}', ['\u{16e45}', '\u{0}', '\u{0}']), - ('\u{16e66}', ['\u{16e46}', '\u{0}', '\u{0}']), - ('\u{16e67}', ['\u{16e47}', '\u{0}', '\u{0}']), - ('\u{16e68}', ['\u{16e48}', '\u{0}', '\u{0}']), - ('\u{16e69}', ['\u{16e49}', '\u{0}', '\u{0}']), - ('\u{16e6a}', ['\u{16e4a}', '\u{0}', '\u{0}']), - ('\u{16e6b}', ['\u{16e4b}', '\u{0}', '\u{0}']), - ('\u{16e6c}', ['\u{16e4c}', '\u{0}', '\u{0}']), - ('\u{16e6d}', ['\u{16e4d}', '\u{0}', '\u{0}']), - ('\u{16e6e}', ['\u{16e4e}', '\u{0}', '\u{0}']), - ('\u{16e6f}', ['\u{16e4f}', '\u{0}', '\u{0}']), - ('\u{16e70}', ['\u{16e50}', '\u{0}', '\u{0}']), - ('\u{16e71}', ['\u{16e51}', '\u{0}', '\u{0}']), - ('\u{16e72}', ['\u{16e52}', '\u{0}', '\u{0}']), - ('\u{16e73}', ['\u{16e53}', '\u{0}', '\u{0}']), - ('\u{16e74}', ['\u{16e54}', '\u{0}', '\u{0}']), - ('\u{16e75}', ['\u{16e55}', '\u{0}', '\u{0}']), - ('\u{16e76}', ['\u{16e56}', '\u{0}', '\u{0}']), - ('\u{16e77}', ['\u{16e57}', '\u{0}', '\u{0}']), - ('\u{16e78}', ['\u{16e58}', '\u{0}', '\u{0}']), - ('\u{16e79}', ['\u{16e59}', '\u{0}', '\u{0}']), - ('\u{16e7a}', ['\u{16e5a}', '\u{0}', '\u{0}']), - ('\u{16e7b}', ['\u{16e5b}', '\u{0}', '\u{0}']), - ('\u{16e7c}', ['\u{16e5c}', '\u{0}', '\u{0}']), - ('\u{16e7d}', ['\u{16e5d}', '\u{0}', '\u{0}']), - ('\u{16e7e}', ['\u{16e5e}', '\u{0}', '\u{0}']), - ('\u{16e7f}', ['\u{16e5f}', '\u{0}', '\u{0}']), - ('\u{16ebb}', ['\u{16ea0}', '\u{0}', '\u{0}']), - ('\u{16ebc}', ['\u{16ea1}', '\u{0}', '\u{0}']), - ('\u{16ebd}', ['\u{16ea2}', '\u{0}', '\u{0}']), - ('\u{16ebe}', ['\u{16ea3}', '\u{0}', '\u{0}']), - ('\u{16ebf}', ['\u{16ea4}', '\u{0}', '\u{0}']), - ('\u{16ec0}', ['\u{16ea5}', '\u{0}', '\u{0}']), - ('\u{16ec1}', ['\u{16ea6}', '\u{0}', '\u{0}']), - ('\u{16ec2}', ['\u{16ea7}', '\u{0}', '\u{0}']), - ('\u{16ec3}', ['\u{16ea8}', '\u{0}', '\u{0}']), - ('\u{16ec4}', ['\u{16ea9}', '\u{0}', '\u{0}']), - ('\u{16ec5}', ['\u{16eaa}', '\u{0}', '\u{0}']), - ('\u{16ec6}', ['\u{16eab}', '\u{0}', '\u{0}']), - ('\u{16ec7}', ['\u{16eac}', '\u{0}', '\u{0}']), - ('\u{16ec8}', ['\u{16ead}', '\u{0}', '\u{0}']), - ('\u{16ec9}', ['\u{16eae}', '\u{0}', '\u{0}']), - ('\u{16eca}', ['\u{16eaf}', '\u{0}', '\u{0}']), - ('\u{16ecb}', ['\u{16eb0}', '\u{0}', '\u{0}']), - ('\u{16ecc}', ['\u{16eb1}', '\u{0}', '\u{0}']), - ('\u{16ecd}', ['\u{16eb2}', '\u{0}', '\u{0}']), - ('\u{16ece}', ['\u{16eb3}', '\u{0}', '\u{0}']), - ('\u{16ecf}', ['\u{16eb4}', '\u{0}', '\u{0}']), - ('\u{16ed0}', ['\u{16eb5}', '\u{0}', '\u{0}']), - ('\u{16ed1}', ['\u{16eb6}', '\u{0}', '\u{0}']), - ('\u{16ed2}', ['\u{16eb7}', '\u{0}', '\u{0}']), - ('\u{16ed3}', ['\u{16eb8}', '\u{0}', '\u{0}']), - ('\u{1e922}', ['\u{1e900}', '\u{0}', '\u{0}']), - ('\u{1e923}', ['\u{1e901}', '\u{0}', '\u{0}']), - ('\u{1e924}', ['\u{1e902}', '\u{0}', '\u{0}']), - ('\u{1e925}', ['\u{1e903}', '\u{0}', '\u{0}']), - ('\u{1e926}', ['\u{1e904}', '\u{0}', '\u{0}']), - ('\u{1e927}', ['\u{1e905}', '\u{0}', '\u{0}']), - ('\u{1e928}', ['\u{1e906}', '\u{0}', '\u{0}']), - ('\u{1e929}', ['\u{1e907}', '\u{0}', '\u{0}']), - ('\u{1e92a}', ['\u{1e908}', '\u{0}', '\u{0}']), - ('\u{1e92b}', ['\u{1e909}', '\u{0}', '\u{0}']), - ('\u{1e92c}', ['\u{1e90a}', '\u{0}', '\u{0}']), - ('\u{1e92d}', ['\u{1e90b}', '\u{0}', '\u{0}']), - ('\u{1e92e}', ['\u{1e90c}', '\u{0}', '\u{0}']), - ('\u{1e92f}', ['\u{1e90d}', '\u{0}', '\u{0}']), - ('\u{1e930}', ['\u{1e90e}', '\u{0}', '\u{0}']), - ('\u{1e931}', ['\u{1e90f}', '\u{0}', '\u{0}']), - ('\u{1e932}', ['\u{1e910}', '\u{0}', '\u{0}']), - ('\u{1e933}', ['\u{1e911}', '\u{0}', '\u{0}']), - ('\u{1e934}', ['\u{1e912}', '\u{0}', '\u{0}']), - ('\u{1e935}', ['\u{1e913}', '\u{0}', '\u{0}']), - ('\u{1e936}', ['\u{1e914}', '\u{0}', '\u{0}']), - ('\u{1e937}', ['\u{1e915}', '\u{0}', '\u{0}']), - ('\u{1e938}', ['\u{1e916}', '\u{0}', '\u{0}']), - ('\u{1e939}', ['\u{1e917}', '\u{0}', '\u{0}']), - ('\u{1e93a}', ['\u{1e918}', '\u{0}', '\u{0}']), - ('\u{1e93b}', ['\u{1e919}', '\u{0}', '\u{0}']), - ('\u{1e93c}', ['\u{1e91a}', '\u{0}', '\u{0}']), - ('\u{1e93d}', ['\u{1e91b}', '\u{0}', '\u{0}']), - ('\u{1e93e}', ['\u{1e91c}', '\u{0}', '\u{0}']), - ('\u{1e93f}', ['\u{1e91d}', '\u{0}', '\u{0}']), - ('\u{1e940}', ['\u{1e91e}', '\u{0}', '\u{0}']), - ('\u{1e941}', ['\u{1e91f}', '\u{0}', '\u{0}']), - ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), - ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), -]; diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index f4c51a487063..6ab99ae799d7 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -374,7 +374,6 @@ impl Step for UnicodeTableGenerator { fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::UnicodeTableGenerator); cmd.arg(builder.src.join("library/core/src/unicode/unicode_data.rs")); - cmd.arg(builder.src.join("library/coretests/tests/unicode/test_data.rs")); cmd.run(builder); } } diff --git a/src/tools/unicode-table-generator/src/cascading_map.rs b/src/tools/unicode-table-generator/src/cascading_map.rs index 41124a8e85ee..56e6401908dc 100644 --- a/src/tools/unicode-table-generator/src/cascading_map.rs +++ b/src/tools/unicode-table-generator/src/cascading_map.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; +use std::fmt::Write as _; use std::ops::Range; +use crate::fmt_list; use crate::raw_emitter::RawEmitter; -use crate::writeln; impl RawEmitter { pub fn emit_cascading_map(&mut self, ranges: &[Range]) -> bool { @@ -23,6 +24,8 @@ impl RawEmitter { .flat_map(|r| (r.start..r.end).collect::>()) .collect::>(); + println!("there are {} points", points.len()); + // how many distinct ranges need to be counted? let mut codepoints_by_high_bytes = HashMap::>::new(); for point in points { @@ -34,7 +37,7 @@ impl RawEmitter { } let mut bit_for_high_byte = 1u8; - let mut arms = String::new(); + let mut arms = Vec::::new(); let mut high_bytes: Vec = codepoints_by_high_bytes.keys().copied().collect(); high_bytes.sort(); @@ -42,33 +45,33 @@ impl RawEmitter { let codepoints = codepoints_by_high_bytes.get_mut(&high_byte).unwrap(); if codepoints.len() == 1 { let ch = codepoints.pop().unwrap(); - writeln!(arms, "{high_byte:#04x} => c as u32 == {ch:#04x},"); + arms.push(format!("{high_byte} => c as u32 == {ch:#04x}")); continue; } // more than 1 codepoint in this arm for codepoint in codepoints { map[(*codepoint & 0xff) as usize] |= bit_for_high_byte; } - writeln!( - arms, - "{high_byte:#04x} => WHITESPACE_MAP[c as usize & 0xff] & {bit_for_high_byte} != 0," - ); + arms.push(format!( + "{high_byte} => WHITESPACE_MAP[c as usize & 0xff] & {bit_for_high_byte} != 0" + )); bit_for_high_byte <<= 1; } + writeln!(&mut self.file, "static WHITESPACE_MAP: [u8; 256] = [{}];", fmt_list(map.iter())) + .unwrap(); self.bytes_used += 256; - self.file = format!( - "static WHITESPACE_MAP: [u8; 256] = {map:?}; - #[inline] - pub const fn lookup(c: char) -> bool {{ - debug_assert!(!c.is_ascii()); - match c as u32 >> 8 {{ - {arms}\ - _ => false, - }} - }}" - ); + writeln!(&mut self.file, "#[inline]").unwrap(); + writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); + writeln!(&mut self.file, " match c as u32 >> 8 {{").unwrap(); + for arm in arms { + writeln!(&mut self.file, " {arm},").unwrap(); + } + writeln!(&mut self.file, " _ => false,").unwrap(); + writeln!(&mut self.file, " }}").unwrap(); + writeln!(&mut self.file, "}}").unwrap(); true } diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 3280514692b0..49aef3ec33ec 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -1,25 +1,27 @@ use std::char; use std::collections::BTreeMap; +use std::fmt::{self, Write}; -use crate::fmt_helpers::Hex; -use crate::{CharEscape, UnicodeData, fmt_list}; +use crate::{UnicodeData, fmt_list}; const INDEX_MASK: u32 = 1 << 22; pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [usize; 2]) { + let mut file = String::new(); + + write!(file, "const INDEX_MASK: u32 = 0x{INDEX_MASK:x};").unwrap(); + file.push_str("\n\n"); + file.push_str(HEADER.trim_start()); + file.push('\n'); let (lower_tables, lower_size) = generate_tables("LOWER", &data.to_lower); + file.push_str(&lower_tables); + file.push_str("\n\n"); let (upper_tables, upper_size) = generate_tables("UPPER", &data.to_upper); - let file = format!( - "{lower_tables} - {upper_tables}" - ); + file.push_str(&upper_tables); (file, [lower_size, upper_size]) } fn generate_tables(case: &str, data: &BTreeMap) -> (String, usize) { - let case_lower = case.to_lowercase(); - let case_upper = case.to_uppercase(); - let mut mappings = Vec::with_capacity(data.len()); let mut multis = Vec::new(); @@ -42,49 +44,77 @@ fn generate_tables(case: &str, data: &BTreeMap) -> (String, usize INDEX_MASK | (u32::try_from(multis.len()).unwrap() - 1) }; - mappings.push((CharEscape(key), Hex(value))); + mappings.push((CharEscape(key), value)); } - let size = size_of_val(mappings.as_slice()) + size_of_val(multis.as_slice()); - let file = format!( - " -#[rustfmt::skip] -static {case}CASE_TABLE: &[(char, u32); {mappings_len}] = &[{mappings}]; + let mut tables = String::new(); + let mut size = 0; -#[rustfmt::skip] -static {case}CASE_TABLE_MULTI: &[[char; 3]; {multis_len}] = &[{multis}]; + size += size_of_val(mappings.as_slice()); + write!( + tables, + "static {}CASE_TABLE: &[(char, u32); {}] = &[{}];", + case, + mappings.len(), + fmt_list(mappings), + ) + .unwrap(); -#[inline] -pub fn to_{case_lower}(c: char) -> [char; 3] {{ - const {{ - let mut i = 0; - while i < {case_upper}CASE_TABLE.len() {{ - let (_, val) = {case_upper}CASE_TABLE[i]; - if val & (1 << 22) == 0 {{ - assert!(char::from_u32(val).is_some()); - }} else {{ - let index = val & ((1 << 22) - 1); - assert!((index as usize) < {case_upper}CASE_TABLE_MULTI.len()); - }} - i += 1; - }} - }} + tables.push_str("\n\n"); - // SAFETY: Just checked that the tables are valid - unsafe {{ - super::case_conversion( - c, - |c| c.to_ascii_{case_lower}case(), - {case_upper}CASE_TABLE, - {case_upper}CASE_TABLE_MULTI, - ) - }} -}}", - mappings = fmt_list(&mappings), - mappings_len = mappings.len(), - multis = fmt_list(&multis), - multis_len = multis.len(), - ); + size += size_of_val(multis.as_slice()); + write!( + tables, + "static {}CASE_TABLE_MULTI: &[[char; 3]; {}] = &[{}];", + case, + multis.len(), + fmt_list(multis), + ) + .unwrap(); - (file, size) + (tables, size) } + +struct CharEscape(char); + +impl fmt::Debug for CharEscape { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'{}'", self.0.escape_default()) + } +} + +static HEADER: &str = r" +pub fn to_lower(c: char) -> [char; 3] { + if c.is_ascii() { + [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] + } else { + LOWERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = LOWERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) + } +} + +pub fn to_upper(c: char) -> [char; 3] { + if c.is_ascii() { + [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] + } else { + UPPERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = UPPERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) + } +} +"; diff --git a/src/tools/unicode-table-generator/src/fmt_helpers.rs b/src/tools/unicode-table-generator/src/fmt_helpers.rs deleted file mode 100644 index bd7417ca1100..000000000000 --- a/src/tools/unicode-table-generator/src/fmt_helpers.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::fmt; - -// Convenience macros for writing and unwrapping. -#[macro_export] -macro_rules! writeln { - ($($args:tt)*) => {{ - use std::fmt::Write as _; - std::writeln!($($args)*).unwrap(); - }}; -} -#[macro_export] -macro_rules! write { - ($($args:tt)*) => {{ - use std::fmt::Write as _; - std::write!($($args)*).unwrap(); - }}; -} - -pub fn fmt_list(values: impl IntoIterator) -> String { - let pieces = values.into_iter().map(|b| format!("{b:?}, ")); - let mut out = String::new(); - let mut line = String::from("\n "); - for piece in pieces { - if line.len() + piece.len() < 98 { - line.push_str(&piece); - } else { - writeln!(out, "{}", line.trim_end()); - line = format!(" {piece}"); - } - } - writeln!(out, "{}", line.trim_end()); - out -} - -/// Wrapper type for formatting a `T` using its `Binary` implementation. -#[derive(Copy, Clone)] -pub struct Bin(pub T); - -impl fmt::Debug for Bin { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let bits = size_of::() * 8; - std::write!(f, "0b{:0bits$b}", self.0) - } -} - -impl fmt::Display for Bin { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self, f) - } -} - -/// Wrapper type for formatting a `T` using its `LowerHex` implementation. -#[derive(Copy, Clone)] -pub struct Hex(pub T); - -impl fmt::Debug for Hex { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - std::write!(f, "{:#x}", self.0) - } -} - -impl fmt::Display for Hex { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self, f) - } -} - -/// Wrapper type for formatting a `char` using `escape_unicode`. -#[derive(Copy, Clone)] -pub struct CharEscape(pub char); - -impl fmt::Debug for CharEscape { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - std::write!(f, "'{}'", self.0.escape_unicode()) - } -} - -impl fmt::Display for CharEscape { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self, f) - } -} diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 78f63b5673a7..ded9205ffc4b 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -72,18 +72,18 @@ //! or not. use std::collections::{BTreeMap, HashMap}; +use std::fmt; +use std::fmt::Write; use std::ops::Range; use ucd_parse::Codepoints; mod cascading_map; mod case_mapping; -mod fmt_helpers; mod raw_emitter; mod skiplist; mod unicode_download; -use fmt_helpers::*; use raw_emitter::{RawEmitter, emit_codepoints, emit_whitespace}; static PROPERTIES: &[&str] = &[ @@ -207,27 +207,29 @@ fn load_data() -> UnicodeData { } fn main() { - let args = std::env::args().collect::>(); - - if args.len() != 3 { - eprintln!("Must provide paths to write unicode tables and tests to"); + let write_location = std::env::args().nth(1).unwrap_or_else(|| { + eprintln!("Must provide path to write unicode tables to"); eprintln!( - "e.g. {} library/core/src/unicode/unicode_data.rs library/coretests/tests/unicode/test_data.rs", - args[0] + "e.g. {} library/core/src/unicode/unicode_data.rs", + std::env::args().next().unwrap_or_default() ); std::process::exit(1); - } + }); - let data_path = &args[1]; - let test_path = &args[2]; + // Optional test path, which is a Rust source file testing that the unicode + // property lookups are correct. + let test_path = std::env::args().nth(2); let unicode_data = load_data(); let ranges_by_property = &unicode_data.ranges; + if let Some(path) = test_path { + std::fs::write(&path, generate_tests(&unicode_data).unwrap()).unwrap(); + } + let mut table_file = String::new(); - writeln!( - table_file, - "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!", + table_file.push_str( + "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!\n", ); let mut total_bytes = 0; @@ -243,9 +245,8 @@ fn main() { } modules.push((property.to_lowercase().to_string(), emitter.file)); - writeln!( - table_file, - "// {:16}: {:5} bytes, {:6} codepoints in {:3} ranges (U+{:06X} - U+{:06X}) using {}", + table_file.push_str(&format!( + "// {:16}: {:5} bytes, {:6} codepoints in {:3} ranges (U+{:06X} - U+{:06X}) using {}\n", property, emitter.bytes_used, datapoints, @@ -253,42 +254,47 @@ fn main() { ranges.first().unwrap().start, ranges.last().unwrap().end, emitter.desc, - ); + )); total_bytes += emitter.bytes_used; } let (conversions, sizes) = case_mapping::generate_case_mapping(&unicode_data); for (name, size) in ["to_lower", "to_upper"].iter().zip(sizes) { - writeln!(table_file, "// {:16}: {:5} bytes", name, size); + table_file.push_str(&format!("// {:16}: {:5} bytes\n", name, size)); total_bytes += size; } - writeln!(table_file, "// {:16}: {:5} bytes\n", "Total", total_bytes); + table_file.push_str(&format!("// {:16}: {:5} bytes\n", "Total", total_bytes)); - writeln!(table_file, "use super::rt::*;\n"); - writeln!(table_file, "{}\n", version()); + // Include the range search function + table_file.push('\n'); + table_file.push_str(include_str!("range_search.rs")); + table_file.push('\n'); + + table_file.push_str(&version()); + + table_file.push('\n'); modules.push((String::from("conversions"), conversions)); for (name, contents) in modules { - writeln!(table_file, "pub mod {name} {{"); - for line in contents.trim().lines() { - writeln!(table_file, " {line}"); + table_file.push_str("#[rustfmt::skip]\n"); + table_file.push_str(&format!("pub mod {name} {{\n")); + for line in contents.lines() { + if !line.trim().is_empty() { + table_file.push_str(" "); + table_file.push_str(line); + } + table_file.push('\n'); } - writeln!(table_file, "}}\n"); + table_file.push_str("}\n\n"); } - let test_file = generate_tests(&unicode_data); - - std::fs::write(&test_path, test_file).unwrap(); - std::fs::write(&data_path, table_file).unwrap(); - rustfmt(&data_path); - rustfmt(&test_path); -} - -fn rustfmt(path: &str) { - std::process::Command::new("rustfmt").arg(path).status().expect("rustfmt failed"); + std::fs::write(&write_location, format!("{}\n", table_file.trim_end())).unwrap(); } fn version() -> String { + let mut out = String::new(); + out.push_str("pub const UNICODE_VERSION: (u8, u8, u8) = "); + let readme = std::fs::read_to_string(std::path::Path::new(UNICODE_DIRECTORY).join("ReadMe.txt")) .unwrap(); @@ -300,72 +306,109 @@ fn version() -> String { readme[start..end].split('.').map(|v| v.parse::().expect(v)).collect::>(); let [major, minor, micro] = [version[0], version[1], version[2]]; - format!("pub const UNICODE_VERSION: (u8, u8, u8) = ({major}, {minor}, {micro});") + out.push_str(&format!("({major}, {minor}, {micro});\n")); + out } -fn generate_tests(data: &UnicodeData) -> String { +fn fmt_list(values: impl IntoIterator) -> String { + let pieces = values.into_iter().map(|b| format!("{b:?}, ")).collect::>(); + let mut out = String::new(); + let mut line = String::from("\n "); + for piece in pieces { + if line.len() + piece.len() < 98 { + line.push_str(&piece); + } else { + out.push_str(line.trim_end()); + out.push('\n'); + line = format!(" {piece}"); + } + } + out.push_str(line.trim_end()); + out.push('\n'); + out +} + +fn generate_tests(data: &UnicodeData) -> Result { let mut s = String::new(); - writeln!( - s, - "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!" - ); - writeln!(s, "// ignore-tidy-filelength\n"); - writeln!(s, "use std::ops::RangeInclusive;\n"); + writeln!(s, "#![feature(core_intrinsics)]")?; + writeln!(s, "#![allow(internal_features, dead_code)]")?; + writeln!(s, "// ignore-tidy-filelength")?; + writeln!(s, "use std::intrinsics;")?; + writeln!(s, "mod unicode_data;")?; + writeln!(s, "fn main() {{")?; for (property, ranges) in &data.ranges { - let prop_upper = property.to_uppercase(); - let is_true = (char::MIN..=char::MAX) + let prop = property.to_lowercase(); + writeln!(s, r#" println!("Testing {prop}");"#)?; + writeln!(s, " {prop}_true();")?; + writeln!(s, " {prop}_false();")?; + let (is_true, is_false): (Vec<_>, Vec<_>) = (char::MIN..=char::MAX) .filter(|c| !c.is_ascii()) .map(u32::from) - .filter(|c| ranges.iter().any(|r| r.contains(c))) - .collect::>(); - let is_true = ranges_from_set(&is_true); - let is_true = is_true - .iter() - .map(|r| { - let start = char::from_u32(r.start).unwrap(); - let end = char::from_u32(r.end - 1).unwrap(); - CharEscape(start)..=CharEscape(end) - }) - .collect::>(); + .partition(|c| ranges.iter().any(|r| r.contains(c))); - writeln!( - s, - r#" -#[rustfmt::skip] -pub(super) static {prop_upper}: &[RangeInclusive; {is_true_len}] = &[{is_true}]; -"#, - is_true_len = is_true.len(), - is_true = fmt_list(is_true), - ); + writeln!(s, " fn {prop}_true() {{")?; + generate_asserts(&mut s, &prop, &is_true, true)?; + writeln!(s, " }}")?; + + writeln!(s, " fn {prop}_false() {{")?; + generate_asserts(&mut s, &prop, &is_false, false)?; + writeln!(s, " }}")?; } - for (prop_lower, conversion) in - ["to_lower", "to_upper"].iter().zip([&data.to_lower, &data.to_upper]) + for (name, conversion) in ["to_lower", "to_upper"].iter().zip([&data.to_lower, &data.to_upper]) { - let prop_upper = prop_lower.to_uppercase(); + writeln!(s, r#" println!("Testing {name}");"#)?; + for (c, mapping) in conversion { + let c = char::from_u32(*c).unwrap(); + let mapping = mapping.map(|c| char::from_u32(c).unwrap()); + writeln!( + s, + r#" assert_eq!(unicode_data::conversions::{name}({c:?}), {mapping:?});"# + )?; + } + let unmapped: Vec<_> = (char::MIN..=char::MAX) + .filter(|c| !c.is_ascii()) + .map(u32::from) + .filter(|c| !conversion.contains_key(c)) + .collect(); + let unmapped_ranges = ranges_from_set(&unmapped); + for range in unmapped_ranges { + let start = char::from_u32(range.start).unwrap(); + let end = char::from_u32(range.end - 1).unwrap(); + writeln!(s, " for c in {start:?}..={end:?} {{")?; + writeln!( + s, + r#" assert_eq!(unicode_data::conversions::{name}(c), [c, '\0', '\0']);"# + )?; - let mapped = conversion - .iter() - .map(|(c, chars)| { - ( - CharEscape(char::from_u32(*c).unwrap()), - chars.map(|c| CharEscape(char::from_u32(c).unwrap())), - ) - }) - .collect::>(); - - writeln!( - s, - r#" -#[rustfmt::skip] -pub(super) static {prop_upper}: &[(char, [char; 3]); {mapped_len}] = &[{mapped}]; -"#, - mapped_len = mapped.len(), - mapped = fmt_list(mapped), - ); + writeln!(s, " }}")?; + } } - s + writeln!(s, "}}")?; + Ok(s) +} + +fn generate_asserts( + s: &mut String, + prop: &str, + points: &[u32], + truthy: bool, +) -> Result<(), fmt::Error> { + let truthy = if truthy { "" } else { "!" }; + for range in ranges_from_set(points) { + let start = char::from_u32(range.start).unwrap(); + let end = char::from_u32(range.end - 1).unwrap(); + match range.len() { + 1 => writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup({start:?}));")?, + _ => { + writeln!(s, " for c in {start:?}..={end:?} {{")?; + writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup(c));")?; + writeln!(s, " }}")?; + } + } + } + Ok(()) } /// Group the elements of `set` into contigous ranges diff --git a/library/core/src/unicode/rt.rs b/src/tools/unicode-table-generator/src/range_search.rs similarity index 76% rename from library/core/src/unicode/rt.rs rename to src/tools/unicode-table-generator/src/range_search.rs index c438635cd794..4d1dd9b423b5 100644 --- a/library/core/src/unicode/rt.rs +++ b/src/tools/unicode-table-generator/src/range_search.rs @@ -1,7 +1,5 @@ -//! Runtime support for `unicode_data`. - #[inline(always)] -pub(super) const fn bitset_search< +const fn bitset_search< const N: usize, const CHUNK_SIZE: usize, const N1: usize, @@ -48,10 +46,10 @@ pub(super) const fn bitset_search< } #[repr(transparent)] -pub(super) struct ShortOffsetRunHeader(pub(super) u32); +struct ShortOffsetRunHeader(u32); impl ShortOffsetRunHeader { - pub(super) const fn new(start_index: usize, prefix_sum: u32) -> Self { + const fn new(start_index: usize, prefix_sum: u32) -> Self { assert!(start_index < (1 << 11)); assert!(prefix_sum < (1 << 21)); @@ -59,12 +57,12 @@ impl ShortOffsetRunHeader { } #[inline] - pub(super) const fn start_index(&self) -> usize { + const fn start_index(&self) -> usize { (self.0 >> 21) as usize } #[inline] - pub(super) const fn prefix_sum(&self) -> u32 { + const fn prefix_sum(&self) -> u32 { self.0 & ((1 << 21) - 1) } } @@ -74,7 +72,7 @@ impl ShortOffsetRunHeader { /// - The last element of `short_offset_runs` must be greater than `std::char::MAX`. /// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`. #[inline(always)] -pub(super) unsafe fn skip_search( +unsafe fn skip_search( needle: char, short_offset_runs: &[ShortOffsetRunHeader; SOR], offsets: &[u8; OFFSETS], @@ -128,35 +126,3 @@ pub(super) unsafe fn skip_search( } offset_idx % 2 == 1 } - -/// # Safety -/// The second component of each tuple in `table` must either be: -/// - A valid `char` -/// - A value with the high bit (1 << 22) set, and the lower 22 bits -/// being a valid index into `multi`. -#[inline(always)] -pub(super) unsafe fn case_conversion( - c: char, - ascii_fn: fn(char) -> char, - table: &[(char, u32)], - multi: &[[char; 3]], -) -> [char; 3] { - const INDEX_MASK: u32 = 1 << 22; - - if c.is_ascii() { - return [ascii_fn(c), '\0', '\0']; - } - - let Ok(i) = table.binary_search_by(|&(key, _)| key.cmp(&c)) else { - return [c, '\0', '\0']; - }; - - let u = table[i].1; - match char::from_u32(u) { - Option::Some(c) => [c, '\0', '\0'], - Option::None => { - // SAFETY: Index comes from statically generated table - unsafe { *multi.get_unchecked((u & (INDEX_MASK - 1)) as usize) } - } - } -} diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index 048507a06d44..297965615c1a 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -1,7 +1,8 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::fmt::{self, Write}; use std::ops::Range; -use crate::{Bin, fmt_list, writeln}; +use crate::fmt_list; #[derive(Clone)] pub struct RawEmitter { @@ -15,6 +16,13 @@ impl RawEmitter { RawEmitter { file: String::new(), bytes_used: 0, desc: String::new() } } + fn blank_line(&mut self) { + if self.file.is_empty() || self.file.ends_with("\n\n") { + return; + } + writeln!(&mut self.file).unwrap(); + } + fn emit_bitset(&mut self, ranges: &[Range]) -> Result<(), String> { let first_code_point = ranges.first().unwrap().start; let last_code_point = ranges.last().unwrap().end; @@ -60,33 +68,48 @@ impl RawEmitter { } self.emit_chunk_map(word_indices[&0], &compressed_words, best.unwrap().0); + struct Bits(u64); + impl fmt::Debug for Bits { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "0b{:064b}", self.0) + } + } + + writeln!( + &mut self.file, + "static BITSET_CANONICAL: [u64; {}] = [{}];", + canonicalized.canonical_words.len(), + fmt_list(canonicalized.canonical_words.iter().map(|v| Bits(*v))), + ) + .unwrap(); self.bytes_used += 8 * canonicalized.canonical_words.len(); + writeln!( + &mut self.file, + "static BITSET_MAPPING: [(u8, u8); {}] = [{}];", + canonicalized.canonicalized_words.len(), + fmt_list(&canonicalized.canonicalized_words), + ) + .unwrap(); // 8 bit index into shifted words, 7 bits for shift + optional flip // We only need it for the words that we removed by applying a shift and // flip to them. self.bytes_used += 2 * canonicalized.canonicalized_words.len(); - writeln!( - self.file, - "static BITSET_CANONICAL: [u64; {canonical_words_len}] = {canonical_words:?}; - static BITSET_MAPPING: [(u8, u8); {canonicalized_words_len}] = {canonicalized_words:?}; + self.blank_line(); - pub const fn lookup(c: char) -> bool {{ - debug_assert!(!c.is_ascii()); - (c as u32) >= {first_code_point:#04x} && - super::bitset_search( - c as u32, - &BITSET_CHUNKS_MAP, - &BITSET_INDEX_CHUNKS, - &BITSET_CANONICAL, - &BITSET_MAPPING, - ) - }}", - canonical_words = canonicalized.canonical_words, - canonical_words_len = canonicalized.canonical_words.len(), - canonicalized_words = canonicalized.canonicalized_words, - canonicalized_words_len = canonicalized.canonicalized_words.len(), - ); + writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); + if first_code_point > 0x7f { + writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} &&").unwrap(); + } + writeln!(&mut self.file, " super::bitset_search(").unwrap(); + writeln!(&mut self.file, " c as u32,").unwrap(); + writeln!(&mut self.file, " &BITSET_CHUNKS_MAP,").unwrap(); + writeln!(&mut self.file, " &BITSET_INDEX_CHUNKS,").unwrap(); + writeln!(&mut self.file, " &BITSET_CANONICAL,").unwrap(); + writeln!(&mut self.file, " &BITSET_MAPPING,").unwrap(); + writeln!(&mut self.file, " )").unwrap(); + writeln!(&mut self.file, "}}").unwrap(); Ok(()) } @@ -110,21 +133,29 @@ impl RawEmitter { chunk_indices.push(chunk_map[chunk]); } + writeln!( + &mut self.file, + "static BITSET_CHUNKS_MAP: [u8; {}] = [{}];", + chunk_indices.len(), + fmt_list(&chunk_indices), + ) + .unwrap(); self.bytes_used += chunk_indices.len(); writeln!( - self.file, - "static BITSET_CHUNKS_MAP: [u8; {chunk_indices_len}] = {chunk_indices:?}; - static BITSET_INDEX_CHUNKS: [[u8; {chunk_len}]; {chunks_len}] = [{chunks}];", - chunk_indices_len = chunk_indices.len(), - chunk_len = chunk_length, - chunks_len = chunks.len(), - chunks = fmt_list(chunks.iter()), - ); + &mut self.file, + "static BITSET_INDEX_CHUNKS: [[u8; {}]; {}] = [{}];", + chunk_length, + chunks.len(), + fmt_list(chunks.iter()), + ) + .unwrap(); self.bytes_used += chunk_length * chunks.len(); } } pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { + emitter.blank_line(); + let mut bitset = emitter.clone(); let bitset_ok = bitset.emit_bitset(ranges).is_ok(); @@ -141,6 +172,8 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { } pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range]) { + emitter.blank_line(); + let mut cascading = emitter.clone(); cascading.emit_cascading_map(ranges); *emitter = cascading; @@ -148,7 +181,7 @@ pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range]) { } struct Canonicalized { - canonical_words: Vec>, + canonical_words: Vec, canonicalized_words: Vec<(u8, u8)>, /// Maps an input unique word to the associated index (u8) which is into @@ -361,7 +394,6 @@ impl Canonicalized { ) }) .collect::>(); - let canonical_words = canonical_words.into_iter().map(Bin).collect::>(); Canonicalized { unique_mapping, canonical_words, canonicalized_words } } } diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs index 742d61153db3..660a8f342f7a 100644 --- a/src/tools/unicode-table-generator/src/skiplist.rs +++ b/src/tools/unicode-table-generator/src/skiplist.rs @@ -1,8 +1,8 @@ -use std::fmt::{self}; +use std::fmt::{self, Write as _}; use std::ops::Range; +use crate::fmt_list; use crate::raw_emitter::RawEmitter; -use crate::writeln; /// This will get packed into a single u32 before inserting into the data set. #[derive(PartialEq)] @@ -68,45 +68,79 @@ impl RawEmitter { assert!(inserted); } + writeln!(&mut self.file, "use super::ShortOffsetRunHeader;\n").unwrap(); + writeln!( + &mut self.file, + "static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; {}] = [{}];", + short_offset_runs.len(), + fmt_list(short_offset_runs.iter()) + ) + .unwrap(); self.bytes_used += 4 * short_offset_runs.len(); + writeln!( + &mut self.file, + "static OFFSETS: [u8; {}] = [{}];", + coded_offsets.len(), + fmt_list(&coded_offsets) + ) + .unwrap(); self.bytes_used += coded_offsets.len(); // The inlining in this code works like the following: // - // The `skip_search` function is always inlined into the parent `lookup_slow` fn, + // The `skip_search` function is always inlined into the parent `lookup` fn, // thus the compiler can generate optimal code based on the referenced `static`s. // - // The lower-bounds check is inlined into the caller, and slower-path - // `skip_search` is outlined into a separate `lookup_slow` fn. - assert!(first_code_point > 0x7f); - writeln!(self.file, - "use super::ShortOffsetRunHeader; - - static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; {short_offset_runs_len}] = {short_offset_runs:?}; - static OFFSETS: [u8; {coded_offset_len}] = {coded_offsets:?}; - - #[inline] - pub fn lookup(c: char) -> bool {{ - debug_assert!(!c.is_ascii()); - (c as u32) >= {first_code_point:#04x} && lookup_slow(c) - }} - - #[inline(never)] - fn lookup_slow(c: char) -> bool {{ - const {{ - assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); - let mut i = 0; - while i < SHORT_OFFSET_RUNS.len() {{ - assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len()); - i += 1; - }} - }} - // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX` - // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`. - unsafe {{ super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }} - }}", - short_offset_runs_len = short_offset_runs.len(), - coded_offset_len = coded_offsets.len(), - ); + // In the case of ASCII optimization, the lower-bounds check is inlined into + // the caller, and slower-path `skip_search` is outlined into a separate `lookup_slow` fn. + // + // Thus, in both cases, the `skip_search` function is specialized for the `static`s, + // and outlined into the prebuilt `std`. + if first_code_point > 0x7f { + writeln!(&mut self.file, "#[inline]").unwrap(); + writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); + writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} && lookup_slow(c)") + .unwrap(); + writeln!(&mut self.file, "}}").unwrap(); + writeln!(&mut self.file).unwrap(); + writeln!(&mut self.file, "#[inline(never)]").unwrap(); + writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap(); + } else { + writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); + } + writeln!(&mut self.file, " const {{").unwrap(); + writeln!( + &mut self.file, + " assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);", + ) + .unwrap(); + writeln!(&mut self.file, " let mut i = 0;").unwrap(); + writeln!(&mut self.file, " while i < SHORT_OFFSET_RUNS.len() {{").unwrap(); + writeln!( + &mut self.file, + " assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());", + ) + .unwrap(); + writeln!(&mut self.file, " i += 1;").unwrap(); + writeln!(&mut self.file, " }}").unwrap(); + writeln!(&mut self.file, " }}").unwrap(); + writeln!( + &mut self.file, + " // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`", + ) + .unwrap(); + writeln!( + &mut self.file, + " // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.", + ) + .unwrap(); + writeln!( + &mut self.file, + " unsafe {{ super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }}" + ) + .unwrap(); + writeln!(&mut self.file, "}}").unwrap(); } } From 236b89e4a84c8d59abec0faf6967a34942e390aa Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 3 Nov 2025 20:47:40 +0800 Subject: [PATCH 338/525] Add more expression to 'in_value' When completing some expressions, it is almost always expected to have a non unit value - ArrayExpr - ParenExpr - BreakExpr - ReturnExpr - PrefixExpr - FormatArgsArg - RecordExprField - BinExpr (rhs only) - IndexExpr (inside index only) Example --- ```rust fn main() { return $0; } ``` **Before this PR** ```rust fn main() { return if $1 { $0 }; } ``` **After this PR** ```rust fn main() { return if $1 { $2 } else { $0 }; } ``` --- .../ide-completion/src/completions/keyword.rs | 140 ++++++++++++++++++ .../ide-completion/src/context/analysis.rs | 21 ++- 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs index 6162d9837283..eab2b9063f95 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs @@ -531,6 +531,146 @@ fn main() { ); } + #[test] + fn if_completion_in_format() { + check_edit( + "if", + r#" +//- minicore: fmt +fn main() { + format_args!("{}", $0); +} +"#, + r#" +fn main() { + format_args!("{}", if $1 { + $2 +} else { + $0 +}); +} +"#, + ); + + check_edit( + "if", + r#" +//- minicore: fmt +fn main() { + format_args!("{}", if$0); +} +"#, + r#" +fn main() { + format_args!("{}", if $1 { + $2 +} else { + $0 +}); +} +"#, + ); + } + + #[test] + fn if_completion_in_value_expected_expressions() { + check_edit( + "if", + r#" +fn main() { + 2 + $0; +} +"#, + r#" +fn main() { + 2 + if $1 { + $2 +} else { + $0 +}; +} +"#, + ); + + check_edit( + "if", + r#" +fn main() { + -$0; +} +"#, + r#" +fn main() { + -if $1 { + $2 +} else { + $0 +}; +} +"#, + ); + + check_edit( + "if", + r#" +fn main() { + return $0; +} +"#, + r#" +fn main() { + return if $1 { + $2 +} else { + $0 +}; +} +"#, + ); + + check_edit( + "if", + r#" +fn main() { + loop { + break $0; + } +} +"#, + r#" +fn main() { + loop { + break if $1 { + $2 +} else { + $0 +}; + } +} +"#, + ); + + check_edit( + "if", + r#" +struct Foo { x: i32 } +fn main() { + Foo { x: $0 } +} +"#, + r#" +struct Foo { x: i32 } +fn main() { + Foo { x: if $1 { + $2 +} else { + $0 +} } +} +"#, + ); + } + #[test] fn completes_let_in_block() { check_edit( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index b3d9ff004610..d6d3978385d9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -1012,6 +1012,25 @@ fn classify_name_ref<'db>( .and_then(|next| next.first_token()) .is_some_and(|token| token.kind() == SyntaxKind::ELSE_KW) }; + let is_in_value = |it: &SyntaxNode| { + let Some(node) = it.parent() else { return false }; + let kind = node.kind(); + ast::LetStmt::can_cast(kind) + || ast::ArgList::can_cast(kind) + || ast::ArrayExpr::can_cast(kind) + || ast::ParenExpr::can_cast(kind) + || ast::BreakExpr::can_cast(kind) + || ast::ReturnExpr::can_cast(kind) + || ast::PrefixExpr::can_cast(kind) + || ast::FormatArgsArg::can_cast(kind) + || ast::RecordExprField::can_cast(kind) + || ast::BinExpr::cast(node.clone()) + .and_then(|expr| expr.rhs()) + .is_some_and(|expr| expr.syntax() == it) + || ast::IndexExpr::cast(node) + .and_then(|expr| expr.index()) + .is_some_and(|expr| expr.syntax() == it) + }; // We do not want to generate path completions when we are sandwiched between an item decl signature and its body. // ex. trait Foo $0 {} @@ -1307,7 +1326,7 @@ fn classify_name_ref<'db>( .and_then(ast::LetStmt::cast) .is_some_and(|it| it.semicolon_token().is_none()) || after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw; - let in_value = it.parent().and_then(Either::::cast).is_some(); + let in_value = is_in_value(it); let impl_ = fetch_immediate_impl_or_trait(sema, original_file, expr.syntax()) .and_then(Either::left); From 1bc898e2535a5751f2abf2f9b98331086087bdc7 Mon Sep 17 00:00:00 2001 From: Jamesbarford Date: Mon, 3 Nov 2025 11:54:43 +0000 Subject: [PATCH 339/525] test for aarch64-unknown-uefi --- .../src/directives/directive_names.rs | 1 + .../aarch64-unknown-uefi-chkstk-98254.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/stack-probes/aarch64-unknown-uefi-chkstk-98254.rs diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 3a46dbc704e8..d5a3745728e4 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -190,6 +190,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-aarch64", "only-aarch64-apple-darwin", "only-aarch64-unknown-linux-gnu", + "only-aarch64-unknown-uefi", "only-apple", "only-arm", "only-arm64ec", diff --git a/tests/ui/stack-probes/aarch64-unknown-uefi-chkstk-98254.rs b/tests/ui/stack-probes/aarch64-unknown-uefi-chkstk-98254.rs new file mode 100644 index 000000000000..36273d5a5e3f --- /dev/null +++ b/tests/ui/stack-probes/aarch64-unknown-uefi-chkstk-98254.rs @@ -0,0 +1,16 @@ +//! Regression test for #98254, missing `__chkstk` symbol on `aarch64-unknown-uefi`. +//@ build-pass +//@ only-aarch64-unknown-uefi +//@ compile-flags: -Cpanic=abort +//@ compile-flags: -Clinker=rust-lld +#![no_std] +#![no_main] +#[panic_handler] +fn panic_handler(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[export_name = "efi_main"] +fn main() { + let b = [0; 1024]; +} From 4959d18a97c8b187db6fd0010546f46c3137e3c8 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Thu, 28 Aug 2025 14:44:34 -0500 Subject: [PATCH 340/525] Rename -Zno-jump-tables to -Zjump-tables= Both gcc and llvm accept -fjump-tables as well as -fno-jump-tables. For consistency, allow rustc to accept -Zjump-tables=yes too. --- compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/options.rs | 4 ++-- .../src/compiler-flags/jump-tables.md | 19 +++++++++++++++++++ .../src/compiler-flags/no-jump-tables.md | 19 ------------------- tests/assembly-llvm/x86_64-no-jump-tables.rs | 4 ++-- tests/codegen-llvm/no-jump-tables.rs | 10 ++++++---- 7 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/jump-tables.md delete mode 100644 src/doc/unstable-book/src/compiler-flags/no-jump-tables.md diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 209b8efa2c3b..d22f40fd05a9 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -229,7 +229,7 @@ fn instrument_function_attr<'ll>( } fn nojumptables_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { - if !sess.opts.unstable_opts.no_jump_tables { + if sess.opts.unstable_opts.jump_tables { return None; } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index be33db21d1df..384c38d3c395 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -814,6 +814,7 @@ fn test_unstable_options_tracking_hash() { tracked!(inline_mir_threshold, Some(123)); tracked!(instrument_mcount, true); tracked!(instrument_xray, Some(InstrumentXRay::default())); + tracked!(jump_tables, false); tracked!(link_directives, false); tracked!(link_only, true); tracked!(lint_llvm_ir, true); @@ -831,7 +832,6 @@ fn test_unstable_options_tracking_hash() { tracked!(mutable_noalias, false); tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); tracked!(no_generate_arange_section, true); - tracked!(no_jump_tables, true); tracked!(no_link, true); tracked!(no_profiler_runtime, true); tracked!(no_trait_vptr, true); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b89aec7d22a9..d10fd17677b7 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2395,6 +2395,8 @@ options! { `=skip-entry` `=skip-exit` Multiple options can be combined with commas."), + jump_tables: bool = (true, parse_bool, [TRACKED], + "allow jump table and lookup table generation from switch case lowering (default: yes)"), layout_seed: Option = (None, parse_opt_number, [TRACKED], "seed layout randomization"), link_directives: bool = (true, parse_bool, [TRACKED], @@ -2475,8 +2477,6 @@ options! { "omit DWARF address ranges that give faster lookups"), no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED], "disable the compatibility version of the `implied_bounds_ty` query"), - no_jump_tables: bool = (false, parse_no_value, [TRACKED], - "disable the jump tables and lookup tables that can be generated from a switch case lowering"), no_leak_check: bool = (false, parse_no_value, [UNTRACKED], "disable the 'leak check' for subtyping; unsound, but useful for tests"), no_link: bool = (false, parse_no_value, [TRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/jump-tables.md b/src/doc/unstable-book/src/compiler-flags/jump-tables.md new file mode 100644 index 000000000000..3abf703cd361 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/jump-tables.md @@ -0,0 +1,19 @@ +# `jump-tables` + +The tracking issue for this feature is [#116592](https://github.com/rust-lang/rust/issues/116592) + +--- + +When set to no, this option enables the `-fno-jump-tables` flag for LLVM, which makes the +codegen backend avoid generating jump tables when lowering switches. + +When set to no, this option adds the LLVM `no-jump-tables=true` attribute to every function. + +Disabling jump tables can be used to help provide protection against +jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT]. + +```sh +RUSTFLAGS="-Zjump-tables=no" cargo +nightly build -Z build-std +``` + +[IBT]: https://www.phoronix.com/news/Linux-IBT-By-Default-Tip diff --git a/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md b/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md deleted file mode 100644 index f096c20f4bd5..000000000000 --- a/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md +++ /dev/null @@ -1,19 +0,0 @@ -# `no-jump-tables` - -The tracking issue for this feature is [#116592](https://github.com/rust-lang/rust/issues/116592) - ---- - -This option enables the `-fno-jump-tables` flag for LLVM, which makes the -codegen backend avoid generating jump tables when lowering switches. - -This option adds the LLVM `no-jump-tables=true` attribute to every function. - -The option can be used to help provide protection against -jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT]. - -```sh -RUSTFLAGS="-Zno-jump-tables" cargo +nightly build -Z build-std -``` - -[IBT]: https://www.phoronix.com/news/Linux-IBT-By-Default-Tip diff --git a/tests/assembly-llvm/x86_64-no-jump-tables.rs b/tests/assembly-llvm/x86_64-no-jump-tables.rs index bb10042d8f62..0108c8817e35 100644 --- a/tests/assembly-llvm/x86_64-no-jump-tables.rs +++ b/tests/assembly-llvm/x86_64-no-jump-tables.rs @@ -1,10 +1,10 @@ -// Test that jump tables are (not) emitted when the `-Zno-jump-tables` +// Test that jump tables are (not) emitted when the `-Zjump-tables=no` // flag is (not) set. //@ revisions: unset set //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=3 -//@ [set] compile-flags: -Zno-jump-tables +//@ [set] compile-flags: -Zjump-tables=no //@ only-x86_64 //@ ignore-sgx diff --git a/tests/codegen-llvm/no-jump-tables.rs b/tests/codegen-llvm/no-jump-tables.rs index 8f607e38350d..00609cff38d9 100644 --- a/tests/codegen-llvm/no-jump-tables.rs +++ b/tests/codegen-llvm/no-jump-tables.rs @@ -1,11 +1,12 @@ // Test that the `no-jump-tables` function attribute are (not) emitted when -// the `-Zno-jump-tables` flag is (not) set. +// the `-Zjump-tables=no` flag is (not) set. //@ add-minicore -//@ revisions: unset set +//@ revisions: unset set_no set_yes //@ needs-llvm-components: x86 //@ compile-flags: --target x86_64-unknown-linux-gnu -//@ [set] compile-flags: -Zno-jump-tables +//@ [set_no] compile-flags: -Zjump-tables=no +//@ [set_yes] compile-flags: -Zjump-tables=yes #![crate_type = "lib"] #![feature(no_core, lang_items)] @@ -19,5 +20,6 @@ pub fn foo() { // CHECK: @foo() unnamed_addr #0 // unset-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} } - // set: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} } + // set_yes-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} } + // set_no: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} } } From bb9d800b780f370578a40620cc9cc46dae8fd868 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Thu, 28 Aug 2025 15:22:35 -0500 Subject: [PATCH 341/525] Stabilize -Zjump-tables= into -Cjump-table= --- compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/options.rs | 4 ++-- src/doc/rustc/src/codegen-options/index.md | 13 +++++++++++++ .../src/compiler-flags/jump-tables.md | 19 ------------------- tests/assembly-llvm/x86_64-no-jump-tables.rs | 4 ++-- tests/codegen-llvm/no-jump-tables.rs | 6 +++--- 7 files changed, 22 insertions(+), 28 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/jump-tables.md diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index d22f40fd05a9..ac20f9c64fa1 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -229,7 +229,7 @@ fn instrument_function_attr<'ll>( } fn nojumptables_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { - if sess.opts.unstable_opts.jump_tables { + if sess.opts.cg.jump_tables { return None; } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 384c38d3c395..6c08b37dec08 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -620,6 +620,7 @@ fn test_codegen_options_tracking_hash() { tracked!(force_frame_pointers, FramePointer::Always); tracked!(force_unwind_tables, Some(true)); tracked!(instrument_coverage, InstrumentCoverage::Yes); + tracked!(jump_tables, false); tracked!(link_dead_code, Some(true)); tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto); tracked!(llvm_args, vec![String::from("1"), String::from("2")]); @@ -814,7 +815,6 @@ fn test_unstable_options_tracking_hash() { tracked!(inline_mir_threshold, Some(123)); tracked!(instrument_mcount, true); tracked!(instrument_xray, Some(InstrumentXRay::default())); - tracked!(jump_tables, false); tracked!(link_directives, false); tracked!(link_only, true); tracked!(lint_llvm_ir, true); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d10fd17677b7..c9d73adf31d4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2093,6 +2093,8 @@ options! { "instrument the generated code to support LLVM source-based code coverage reports \ (note, the compiler build config must include `profiler = true`); \ implies `-C symbol-mangling-version=v0`"), + jump_tables: bool = (true, parse_bool, [TRACKED], + "allow jump table and lookup table generation from switch case lowering (default: yes)"), link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED], "a single extra argument to append to the linker invocation (can be used several times)"), link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], @@ -2395,8 +2397,6 @@ options! { `=skip-entry` `=skip-exit` Multiple options can be combined with commas."), - jump_tables: bool = (true, parse_bool, [TRACKED], - "allow jump table and lookup table generation from switch case lowering (default: yes)"), layout_seed: Option = (None, parse_opt_number, [TRACKED], "seed layout randomization"), link_directives: bool = (true, parse_bool, [TRACKED], diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f2cf1d447aa5..04901e5dda97 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -209,6 +209,19 @@ Note that while the `-C instrument-coverage` option is stable, the profile data format produced by the resulting instrumentation may change, and may not work with coverage tools other than those built and shipped with the compiler. +## jump-tables + +This option is used to allow or prevent the LLVM codegen backend from creating +jump tables when lowering switches. + +* `y`, `yes`, `on`, `true` or no value: allow jump tables (the default). +* `n`, `no`, `off` or `false`: disable jump tables. + +Disabling jump tables can be used to help provide protection against +jump-oriented-programming (JOP) attacks. However, this option makes +no guarantee any precompiled or external dependencies are compiled +with or without jump tables. + ## link-arg This flag lets you append a single extra argument to the linker invocation. diff --git a/src/doc/unstable-book/src/compiler-flags/jump-tables.md b/src/doc/unstable-book/src/compiler-flags/jump-tables.md deleted file mode 100644 index 3abf703cd361..000000000000 --- a/src/doc/unstable-book/src/compiler-flags/jump-tables.md +++ /dev/null @@ -1,19 +0,0 @@ -# `jump-tables` - -The tracking issue for this feature is [#116592](https://github.com/rust-lang/rust/issues/116592) - ---- - -When set to no, this option enables the `-fno-jump-tables` flag for LLVM, which makes the -codegen backend avoid generating jump tables when lowering switches. - -When set to no, this option adds the LLVM `no-jump-tables=true` attribute to every function. - -Disabling jump tables can be used to help provide protection against -jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT]. - -```sh -RUSTFLAGS="-Zjump-tables=no" cargo +nightly build -Z build-std -``` - -[IBT]: https://www.phoronix.com/news/Linux-IBT-By-Default-Tip diff --git a/tests/assembly-llvm/x86_64-no-jump-tables.rs b/tests/assembly-llvm/x86_64-no-jump-tables.rs index 0108c8817e35..e469aee7ed94 100644 --- a/tests/assembly-llvm/x86_64-no-jump-tables.rs +++ b/tests/assembly-llvm/x86_64-no-jump-tables.rs @@ -1,10 +1,10 @@ -// Test that jump tables are (not) emitted when the `-Zjump-tables=no` +// Test that jump tables are (not) emitted when the `-Cjump-tables=no` // flag is (not) set. //@ revisions: unset set //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=3 -//@ [set] compile-flags: -Zjump-tables=no +//@ [set] compile-flags: -Cjump-tables=no //@ only-x86_64 //@ ignore-sgx diff --git a/tests/codegen-llvm/no-jump-tables.rs b/tests/codegen-llvm/no-jump-tables.rs index 00609cff38d9..ff79c43dfc9c 100644 --- a/tests/codegen-llvm/no-jump-tables.rs +++ b/tests/codegen-llvm/no-jump-tables.rs @@ -1,12 +1,12 @@ // Test that the `no-jump-tables` function attribute are (not) emitted when -// the `-Zjump-tables=no` flag is (not) set. +// the `-Cjump-tables=no` flag is (not) set. //@ add-minicore //@ revisions: unset set_no set_yes //@ needs-llvm-components: x86 //@ compile-flags: --target x86_64-unknown-linux-gnu -//@ [set_no] compile-flags: -Zjump-tables=no -//@ [set_yes] compile-flags: -Zjump-tables=yes +//@ [set_no] compile-flags: -Cjump-tables=no +//@ [set_yes] compile-flags: -Cjump-tables=yes #![crate_type = "lib"] #![feature(no_core, lang_items)] From a78ba93220401af94afbab46c90b811f94cd4453 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Thu, 11 Sep 2025 11:56:27 -0500 Subject: [PATCH 342/525] Improve documentation of -Cjump-tables Be more verbose about what this option can and cannot do. --- src/doc/rustc/src/codegen-options/index.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 04901e5dda97..f0f991ed0c90 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -212,15 +212,23 @@ with coverage tools other than those built and shipped with the compiler. ## jump-tables This option is used to allow or prevent the LLVM codegen backend from creating -jump tables when lowering switches. +jump tables when lowering switches from Rust code. * `y`, `yes`, `on`, `true` or no value: allow jump tables (the default). * `n`, `no`, `off` or `false`: disable jump tables. +To prevent jump tables being created from Rust code, a target must ensure +all crates are compiled with jump tables disabled. + +Note, in many cases the Rust toolchain is distributed with precompiled +crates, such as the core and std crates, which could possibly include +jump tables. Furthermore, this option does not guarantee a target will +be free of jump tables. They could arise from external dependencies, +inline asm, or other complicated interactions when using crates which +are compiled with jump table support. + Disabling jump tables can be used to help provide protection against -jump-oriented-programming (JOP) attacks. However, this option makes -no guarantee any precompiled or external dependencies are compiled -with or without jump tables. +jump-oriented-programming (JOP) attacks. ## link-arg From ba2600e98e7af4f535af49d6612d0884d2069a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 01:44:52 +0000 Subject: [PATCH 343/525] Suggest appropriate type instead of `Self` in E0401 ``` error[E0401]: can't use `Self` from outer item --> $DIR/E0401.rs:22:25 | LL | impl Iterator for A { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn helper(sel: &Self) -> u8 { | ------ ^^^^ use of `Self` from outer item | | | `Self` used in this inner function | help: refer to the type directly here instead | LL - fn helper(sel: &Self) -> u8 { LL + fn helper(sel: &A) -> u8 { | ``` --- compiler/rustc_resolve/src/diagnostics.rs | 4 +++- compiler/rustc_resolve/src/errors.rs | 16 ++++++++++++++-- compiler/rustc_resolve/src/ident.rs | 10 ++++++++++ compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 1 + tests/ui/error-codes/E0401.stderr | 12 ++++++++---- tests/ui/resolve/use-self-in-inner-fn.stderr | 12 ++++++++---- 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 3020ecb6e711..2f4a18f9cfa6 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -558,6 +558,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { has_generic_params, def_kind, inner_item, + current_self_ty, } => { use errs::GenericParamsFromOuterItemLabel as Label; let static_or_const = match def_kind { @@ -595,7 +596,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { sm, self.def_span(def_id), ))); - err.refer_to_type_directly = Some(span); + err.refer_to_type_directly = + current_self_ty.map(|snippet| errs::UseTypeDirectly { span, snippet }); return self.dcx().create_err(err); } Res::Def(DefKind::TyParam, def_id) => { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 5c5938a3260e..165a17e5c11d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -17,8 +17,8 @@ pub(crate) struct GenericParamsFromOuterItem { pub(crate) span: Span, #[subdiagnostic] pub(crate) label: Option, - #[label(resolve_refer_to_type_directly)] - pub(crate) refer_to_type_directly: Option, + #[subdiagnostic] + pub(crate) refer_to_type_directly: Option, #[subdiagnostic] pub(crate) sugg: Option, #[subdiagnostic] @@ -68,6 +68,18 @@ pub(crate) struct GenericParamsFromOuterItemSugg { pub(crate) span: Span, pub(crate) snippet: String, } +#[derive(Subdiagnostic)] +#[suggestion( + resolve_refer_to_type_directly, + code = "{snippet}", + applicability = "maybe-incorrect", + style = "verbose" +)] +pub(crate) struct UseTypeDirectly { + #[primary_span] + pub(crate) span: Span, + pub(crate) snippet: String, +} #[derive(Diagnostic)] #[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)] diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 278c0fe35b7d..864c3306929e 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1415,6 +1415,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { has_generic_params, def_kind, inner_item: item, + current_self_ty: diag_metadata + .and_then(|m| m.current_self_type.as_ref()) + .and_then(|ty| { + self.tcx.sess.source_map().span_to_snippet(ty.span).ok() + }), }, ); } @@ -1503,6 +1508,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { has_generic_params, def_kind, inner_item: item, + current_self_ty: diag_metadata + .and_then(|m| m.current_self_type.as_ref()) + .and_then(|ty| { + self.tcx.sess.source_map().span_to_snippet(ty.span).ok() + }), }, ); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0b41a7952797..41c2e908d084 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -675,7 +675,7 @@ pub(crate) struct DiagMetadata<'ast> { current_trait_assoc_items: Option<&'ast [Box]>, /// The current self type if inside an impl (used for better errors). - current_self_type: Option, + pub(crate) current_self_type: Option, /// The current self item if inside an ADT (used for better errors). current_self_item: Option, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6b671df433b3..c7f65ff03f82 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -246,6 +246,7 @@ enum ResolutionError<'ra> { has_generic_params: HasGenericParams, def_kind: DefKind, inner_item: Option<(Span, ast::ItemKind)>, + current_self_ty: Option, }, /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index 8daaf09df159..6856d390efee 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -37,11 +37,15 @@ LL | impl Iterator for A { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn helper(sel: &Self) -> u8 { - | ------ ^^^^ - | | | - | | use of `Self` from outer item - | | refer to the type directly here instead + | ------ ^^^^ use of `Self` from outer item + | | | `Self` used in this inner function + | +help: refer to the type directly here instead + | +LL - fn helper(sel: &Self) -> u8 { +LL + fn helper(sel: &A) -> u8 { + | error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 645875f6e726..7f5217825c11 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -5,11 +5,15 @@ LL | impl A { | ---- `Self` type implicitly declared here, by this `impl` ... LL | fn peach(this: &Self) { - | ----- ^^^^ - | | | - | | use of `Self` from outer item - | | refer to the type directly here instead + | ----- ^^^^ use of `Self` from outer item + | | | `Self` used in this inner function + | +help: refer to the type directly here instead + | +LL - fn peach(this: &Self) { +LL + fn peach(this: &A) { + | error: aborting due to 1 previous error From 4af32ca72f2d76d03f645e93a39da07637cca2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 01:53:17 +0000 Subject: [PATCH 344/525] Add test --- tests/ui/resolve/use-self-in-inner-fn.rs | 23 +++++++++++++++++++- tests/ui/resolve/use-self-in-inner-fn.stderr | 20 ++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs index ed64ee885271..1a11fe3a21b6 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.rs +++ b/tests/ui/resolve/use-self-in-inner-fn.rs @@ -7,9 +7,30 @@ impl A { //~^ ERROR can't use `Self` from outer item //~| NOTE use of `Self` from outer item //~| NOTE `Self` used in this inner function - //~| NOTE refer to the type directly here instead + //~| HELP refer to the type directly here instead } } } +enum MyEnum {} + +impl MyEnum { +//~^ NOTE `Self` type implicitly declared here, by this `impl` + fn do_something(result: impl FnOnce()) { + result(); + } + + fn do_something_extra() { + fn inner() { + //~^ NOTE `Self` used in this inner function + Self::do_something(move || {}); + //~^ ERROR can't use `Self` from outer item + //~| NOTE use of `Self` from outer item + //~| HELP refer to the type directly here instead + MyEnum::do_something(move || {}); + } + inner(); + } +} + fn main() {} diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 7f5217825c11..2266a31ebf04 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -15,6 +15,24 @@ LL - fn peach(this: &Self) { LL + fn peach(this: &A) { | -error: aborting due to 1 previous error +error[E0401]: can't use `Self` from outer item + --> $DIR/use-self-in-inner-fn.rs:26:13 + | +LL | impl MyEnum { + | ---- `Self` type implicitly declared here, by this `impl` +... +LL | fn inner() { + | ----- `Self` used in this inner function +LL | +LL | Self::do_something(move || {}); + | ^^^^^^^^^^^^^^^^^^ use of `Self` from outer item + | +help: refer to the type directly here instead + | +LL - Self::do_something(move || {}); +LL + MyEnum(move || {}); + | + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0401`. From 48dde00f10d7438dfb3a3c4805fbdf6fa5aec1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 02:13:34 +0000 Subject: [PATCH 345/525] Use more accurate span in `resolve_ident_in_lexical_scope` --- compiler/rustc_resolve/src/ident.rs | 2 +- .../associated-item/associated-item-duplicate-bounds.stderr | 2 +- tests/ui/delegation/target-expr.stderr | 2 +- tests/ui/generics/invalid-type-param-default.stderr | 2 +- ...eric-params-from-outer-item-in-const-item.default.stderr | 6 +++--- ...from-outer-item-in-const-item.generic_const_items.stderr | 6 +++--- tests/ui/resolve/issue-39559.stderr | 2 +- tests/ui/resolve/use-self-in-inner-fn.stderr | 4 ++-- tests/ui/type/pattern_types/assoc_const.default.stderr | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 864c3306929e..f3f0a74d03bc 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -326,7 +326,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { i, rib_ident, *res, - finalize.map(|finalize| finalize.path_span), + finalize.map(|_| general_span), *original_rib_ident_def, ribs, diag_metadata, diff --git a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr index 8898880586c9..9f8faf951940 100644 --- a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr +++ b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr @@ -2,7 +2,7 @@ error: generic parameters may not be used in const operations --> $DIR/associated-item-duplicate-bounds.rs:7:18 | LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there. - | ^^^^^^^^ cannot perform const operation using `A` + | ^ cannot perform const operation using `A` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index edd1a584eab2..15af98c35067 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -7,7 +7,7 @@ LL | reuse Trait::static_method { | ------------- generic parameter used in this inner delegated function LL | LL | let _ = T::Default(); - | ^^^^^^^^^^ use of generic parameter from outer item + | ^ use of generic parameter from outer item error[E0434]: can't capture dynamic environment in a fn item --> $DIR/target-expr.rs:26:17 diff --git a/tests/ui/generics/invalid-type-param-default.stderr b/tests/ui/generics/invalid-type-param-default.stderr index 3bec7542ad00..bbae5ba1b1e1 100644 --- a/tests/ui/generics/invalid-type-param-default.stderr +++ b/tests/ui/generics/invalid-type-param-default.stderr @@ -2,7 +2,7 @@ error[E0128]: generic parameter defaults cannot reference parameters before they --> $DIR/invalid-type-param-default.rs:12:12 | LL | fn mdn(_: T) {} - | ^^^^^^^ cannot reference `T` before it is declared + | ^ cannot reference `T` before it is declared error: defaults for generic parameters are not allowed here --> $DIR/invalid-type-param-default.rs:7:8 diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr index bc67e9dce4e3..290b7a2d1916 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -4,7 +4,7 @@ error[E0401]: can't use generic parameters from outer item LL | fn outer() { // outer function | - type parameter from outer item LL | const K: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | @@ -17,7 +17,7 @@ LL | impl Tr for T { // outer impl block | - type parameter from outer item LL | const C: u32 = { LL | const I: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | @@ -29,7 +29,7 @@ error[E0401]: can't use generic parameters from outer item LL | struct S(U32<{ // outer struct | - type parameter from outer item LL | const _: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr index 3959d117c7c9..713fe1158645 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -4,7 +4,7 @@ error[E0401]: can't use generic parameters from outer item LL | fn outer() { // outer function | - type parameter from outer item LL | const K: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | @@ -21,7 +21,7 @@ LL | impl Tr for T { // outer impl block | - type parameter from outer item LL | const C: u32 = { LL | const I: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | @@ -37,7 +37,7 @@ error[E0401]: can't use generic parameters from outer item LL | struct S(U32<{ // outer struct | - type parameter from outer item LL | const _: u32 = T::C; - | - ^^^^ use of generic parameter from outer item + | - ^ use of generic parameter from outer item | | | generic parameter used in this inner constant item | diff --git a/tests/ui/resolve/issue-39559.stderr b/tests/ui/resolve/issue-39559.stderr index 0aab54fe59d5..14c7a6a9f6ab 100644 --- a/tests/ui/resolve/issue-39559.stderr +++ b/tests/ui/resolve/issue-39559.stderr @@ -2,7 +2,7 @@ error: generic parameters may not be used in const operations --> $DIR/issue-39559.rs:14:18 | LL | entries: [T; D::dim()], - | ^^^^^^ cannot perform const operation using `D` + | ^ cannot perform const operation using `D` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 2266a31ebf04..668cd2413cea 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -25,12 +25,12 @@ LL | fn inner() { | ----- `Self` used in this inner function LL | LL | Self::do_something(move || {}); - | ^^^^^^^^^^^^^^^^^^ use of `Self` from outer item + | ^^^^ use of `Self` from outer item | help: refer to the type directly here instead | LL - Self::do_something(move || {}); -LL + MyEnum(move || {}); +LL + MyEnum::do_something(move || {}); | error: aborting due to 2 previous errors diff --git a/tests/ui/type/pattern_types/assoc_const.default.stderr b/tests/ui/type/pattern_types/assoc_const.default.stderr index 8cff0cee7b97..00d5ac6af26b 100644 --- a/tests/ui/type/pattern_types/assoc_const.default.stderr +++ b/tests/ui/type/pattern_types/assoc_const.default.stderr @@ -20,7 +20,7 @@ error: generic parameters may not be used in const operations --> $DIR/assoc_const.rs:20:40 | LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} - | ^^^^^^^^ cannot perform const operation using `T` + | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions @@ -29,7 +29,7 @@ error: generic parameters may not be used in const operations --> $DIR/assoc_const.rs:20:51 | LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} - | ^^^^^^ cannot perform const operation using `T` + | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions From 14646ec374152c3988599733baebe18e8572e0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 02:55:57 +0000 Subject: [PATCH 346/525] Add note to E0401 --- compiler/rustc_resolve/messages.ftl | 1 + compiler/rustc_resolve/src/errors.rs | 1 + .../ui/const-generics/early/const-param-from-outer-fn.stderr | 1 + tests/ui/delegation/target-expr.stderr | 2 ++ tests/ui/error-codes/E0401.stderr | 3 +++ .../enum-definition-with-outer-generic-parameter-5997.stderr | 1 + .../ui/generics/generic-params-nested-fn-scope-error.stderr | 2 ++ tests/ui/generics/issue-98432.stderr | 1 + tests/ui/resolve/bad-type-env-capture.stderr | 1 + ...neric-params-from-outer-item-in-const-item.default.stderr | 3 +++ ...-from-outer-item-in-const-item.generic_const_items.stderr | 3 +++ tests/ui/resolve/issue-12796.stderr | 2 ++ tests/ui/resolve/issue-3021-c.stderr | 2 ++ tests/ui/resolve/issue-3214.stderr | 1 + .../resolve/issue-65025-extern-static-parent-generics.stderr | 1 + .../resolve/issue-65035-static-with-parent-generics.stderr | 5 +++++ tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr | 4 ++++ tests/ui/resolve/use-self-in-inner-fn.rs | 2 ++ tests/ui/resolve/use-self-in-inner-fn.stderr | 4 +++- tests/ui/statics/static-generic-param-soundness.stderr | 1 + tests/ui/type/type-arg-out-of-scope.stderr | 2 ++ 21 files changed, 42 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index d462ff589f0d..dd06c157afc7 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -175,6 +175,7 @@ resolve_generic_params_from_outer_item = } from outer item .refer_to_type_directly = refer to the type directly here instead .suggestion = try introducing a local generic parameter here + .note = nested items are independent from their parent item for everything except for privacy and name resolution resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 165a17e5c11d..0bb9909f7cbc 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -11,6 +11,7 @@ use crate::{Res, fluent_generated as fluent}; #[derive(Diagnostic)] #[diag(resolve_generic_params_from_outer_item, code = E0401)] +#[note] pub(crate) struct GenericParamsFromOuterItem { #[primary_span] #[label] diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr index 3c25dff41aa2..7aab983b6495 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -8,6 +8,7 @@ LL | fn bar() -> u32 { LL | X | ^ use of generic parameter from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar() -> u32 { diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index 15af98c35067..e26d12ee447d 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -8,6 +8,8 @@ LL | reuse Trait::static_method { LL | LL | let _ = T::Default(); | ^ use of generic parameter from outer item + | + = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0434]: can't capture dynamic environment in a fn item --> $DIR/target-expr.rs:26:17 diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index 6856d390efee..abd80d636c67 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -8,6 +8,7 @@ LL | fn bfnr, W: Fn()>(y: T) { | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bfnr, W: Fn()>(y: T) { @@ -25,6 +26,7 @@ LL | fn baz u8 { | | | `Self` used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: refer to the type directly here instead | LL - fn helper(sel: &Self) -> u8 { diff --git a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr index fb2d2f247b65..53408d05a1c1 100644 --- a/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr +++ b/tests/ui/generics/enum-definition-with-outer-generic-parameter-5997.stderr @@ -8,6 +8,7 @@ LL | enum E { V(Z) } | | | generic parameter used in this inner enum | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | enum E { V(Z) } diff --git a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr index f809740ed381..436f9c9bada1 100644 --- a/tests/ui/generics/generic-params-nested-fn-scope-error.stderr +++ b/tests/ui/generics/generic-params-nested-fn-scope-error.stderr @@ -8,6 +8,7 @@ LL | fn bar(w: [U]) -> U { | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar(w: [U]) -> U { @@ -23,6 +24,7 @@ LL | fn bar(w: [U]) -> U { | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar(w: [U]) -> U { diff --git a/tests/ui/generics/issue-98432.stderr b/tests/ui/generics/issue-98432.stderr index a1efee78cb7d..e261416ca222 100644 --- a/tests/ui/generics/issue-98432.stderr +++ b/tests/ui/generics/issue-98432.stderr @@ -9,6 +9,7 @@ LL | struct _Obligation where T:; | | | generic parameter used in this inner struct | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | struct _Obligation where T:; diff --git a/tests/ui/resolve/bad-type-env-capture.stderr b/tests/ui/resolve/bad-type-env-capture.stderr index c565997ca2a2..ebddd7014748 100644 --- a/tests/ui/resolve/bad-type-env-capture.stderr +++ b/tests/ui/resolve/bad-type-env-capture.stderr @@ -8,6 +8,7 @@ LL | fn bar(b: T) { } | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar(b: T) { } diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr index 290b7a2d1916..8827d1bbb49d 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -8,6 +8,7 @@ LL | const K: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -21,6 +22,7 @@ LL | const I: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -33,6 +35,7 @@ LL | const _: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr index 713fe1158645..8ff9771b9ade 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -8,6 +8,7 @@ LL | const K: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here | @@ -25,6 +26,7 @@ LL | const I: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here | @@ -41,6 +43,7 @@ LL | const _: u32 = T::C; | | | generic parameter used in this inner constant item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `const` is a separate item from the item that contains it help: try introducing a local generic parameter here | diff --git a/tests/ui/resolve/issue-12796.stderr b/tests/ui/resolve/issue-12796.stderr index b5828c6f5fc8..af79508689a9 100644 --- a/tests/ui/resolve/issue-12796.stderr +++ b/tests/ui/resolve/issue-12796.stderr @@ -7,6 +7,8 @@ LL | fn inner(_: &Self) { | | use of `Self` from outer item | | can't use `Self` here | `Self` used in this inner function + | + = note: nested items are independent from their parent item for everything except for privacy and name resolution error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-3021-c.stderr b/tests/ui/resolve/issue-3021-c.stderr index 8c554fd1b97d..d521d4f4a73a 100644 --- a/tests/ui/resolve/issue-3021-c.stderr +++ b/tests/ui/resolve/issue-3021-c.stderr @@ -9,6 +9,7 @@ LL | trait U { LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | trait U { @@ -25,6 +26,7 @@ LL | trait U { LL | fn g(&self, x: T) -> T; | ^ use of generic parameter from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | trait U { diff --git a/tests/ui/resolve/issue-3214.stderr b/tests/ui/resolve/issue-3214.stderr index ab12676bdd80..573a8ba975c8 100644 --- a/tests/ui/resolve/issue-3214.stderr +++ b/tests/ui/resolve/issue-3214.stderr @@ -8,6 +8,7 @@ LL | struct Foo { LL | x: T, | ^ use of generic parameter from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | struct Foo { diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr index 2d21ed0155a7..6ff8c82ce8ee 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr @@ -10,6 +10,7 @@ LL | | LL | | } | |_____- generic parameter used in this inner extern block | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr index b22bfb719bd5..d3c8095d048a 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -10,6 +10,7 @@ LL | | LL | | } | |_____- generic parameter used in this inner extern block | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -22,6 +23,7 @@ LL | static a: *const T = Default::default(); | | | generic parameter used in this inner static item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -36,6 +38,7 @@ LL | | LL | | } | |_____- generic parameter used in this inner extern block | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -48,6 +51,7 @@ LL | static a: [u8; N] = [0; N]; | | | generic parameter used in this inner static item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error[E0401]: can't use generic parameters from outer item @@ -60,6 +64,7 @@ LL | static a: [u8; N] = [0; N]; | | | generic parameter used in this inner static item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 00aa645688e7..69f41dbb910c 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -9,6 +9,7 @@ LL | enum Foo { LL | Variance(A) | ^ use of generic parameter from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | enum Foo { @@ -25,6 +26,7 @@ LL | struct Foo(A); | | | generic parameter used in this inner struct | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | struct Foo(A); @@ -41,6 +43,7 @@ LL | struct Foo { a: A } | | | generic parameter used in this inner struct | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | struct Foo { a: A } @@ -57,6 +60,7 @@ LL | fn foo(a: A) { } | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn foo(a: A) { } diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs index 1a11fe3a21b6..c9260ba769d6 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.rs +++ b/tests/ui/resolve/use-self-in-inner-fn.rs @@ -8,6 +8,7 @@ impl A { //~| NOTE use of `Self` from outer item //~| NOTE `Self` used in this inner function //~| HELP refer to the type directly here instead + //~| NOTE nested items are independent from their } } } @@ -27,6 +28,7 @@ impl MyEnum { //~^ ERROR can't use `Self` from outer item //~| NOTE use of `Self` from outer item //~| HELP refer to the type directly here instead + //~| NOTE nested items are independent from their MyEnum::do_something(move || {}); } inner(); diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 668cd2413cea..78c609ba8cb1 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -9,6 +9,7 @@ LL | fn peach(this: &Self) { | | | `Self` used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: refer to the type directly here instead | LL - fn peach(this: &Self) { @@ -16,7 +17,7 @@ LL + fn peach(this: &A) { | error[E0401]: can't use `Self` from outer item - --> $DIR/use-self-in-inner-fn.rs:26:13 + --> $DIR/use-self-in-inner-fn.rs:27:13 | LL | impl MyEnum { | ---- `Self` type implicitly declared here, by this `impl` @@ -27,6 +28,7 @@ LL | LL | Self::do_something(move || {}); | ^^^^ use of `Self` from outer item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: refer to the type directly here instead | LL - Self::do_something(move || {}); diff --git a/tests/ui/statics/static-generic-param-soundness.stderr b/tests/ui/statics/static-generic-param-soundness.stderr index 72f65e2bac7c..32c252246e3e 100644 --- a/tests/ui/statics/static-generic-param-soundness.stderr +++ b/tests/ui/statics/static-generic-param-soundness.stderr @@ -8,6 +8,7 @@ LL | static a: Bar = Bar::What; | | | generic parameter used in this inner static item | + = note: nested items are independent from their parent item for everything except for privacy and name resolution = note: a `static` is a separate item from the item that contains it error[E0392]: type parameter `T` is never used diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr index 3d8850ebccea..56fecdb33810 100644 --- a/tests/ui/type/type-arg-out-of-scope.stderr +++ b/tests/ui/type/type-arg-out-of-scope.stderr @@ -8,6 +8,7 @@ LL | fn bar(f: Box T>) { } | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar(f: Box T>) { } @@ -23,6 +24,7 @@ LL | fn bar(f: Box T>) { } | | | generic parameter used in this inner function | + = note: nested items are independent from their parent item for everything except for privacy and name resolution help: try introducing a local generic parameter here | LL | fn bar(f: Box T>) { } From ec1b2fa38bebfe7f0150447b761046aced5b703f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Oct 2025 18:00:04 +0200 Subject: [PATCH 347/525] Gracefully handle in case we cannot run the compiler in doctests --- src/librustdoc/doctest.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c9cd9f7fd4b1..f39d5aadfb49 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -500,7 +500,10 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String { input + &exe_suffix } -fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command { +fn wrapped_rustc_command<'a>( + rustc_wrappers: &'a [PathBuf], + rustc_binary: &'a Path, +) -> (Command, &'a Path) { let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary]); let exe = args.next().expect("unable to create rustc command"); @@ -509,7 +512,7 @@ fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Com command.arg(arg); } - command + (command, rustc_wrappers.first().map(|p| &**p).unwrap_or(rustc_binary)) } /// Information needed for running a bundle of doctests. @@ -629,7 +632,8 @@ fn run_test( .test_builder .as_deref() .unwrap_or_else(|| rustc_interface::util::rustc_path(sysroot).expect("found rustc")); - let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); + let (mut compiler, binary_path) = + wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); compiler.args(&compiler_args); @@ -670,7 +674,13 @@ fn run_test( debug!("compiler invocation for doctest: {compiler:?}"); - let mut child = compiler.spawn().expect("Failed to spawn rustc process"); + let mut child = match compiler.spawn() { + Ok(child) => child, + Err(error) => { + eprintln!("Failed to spawn {binary_path:?}: {error:?}"); + return (Duration::default(), Err(TestFailure::CompileError)); + } + }; let output = if let Some(merged_test_code) = &doctest.merged_test_code { // compile-fail tests never get merged, so this should always pass let status = child.wait().expect("Failed to wait"); @@ -679,7 +689,7 @@ fn run_test( // build it now let runner_input_file = doctest.path_for_merged_doctest_runner(); - let mut runner_compiler = + let (mut runner_compiler, binary_path) = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); // the test runner does not contain any user-written code, so this doesn't allow // the user to exploit nightly-only features on stable @@ -732,7 +742,13 @@ fn run_test( let status = if !status.success() { status } else { - let mut child_runner = runner_compiler.spawn().expect("Failed to spawn rustc process"); + let mut child_runner = match runner_compiler.spawn() { + Ok(child) => child, + Err(error) => { + eprintln!("Failed to spawn {binary_path:?}: {error:?}"); + return (Duration::default(), Err(TestFailure::CompileError)); + } + }; child_runner.wait().expect("Failed to wait") }; From b24b7bd6e6f784c67ce5df03d1e8611fdb7fe20a Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 3 Nov 2025 18:01:33 +0100 Subject: [PATCH 348/525] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index af415fc6c8a6..f660f341887c 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit af415fc6c8a6823dfb4595074f27d5a3e9e2fe49 +Subproject commit f660f341887c8bbcd6c24fbfdf5d2a262f523965 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index e2ed891f0036..5c621253d8f2 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit e2ed891f00361efc26616d82590b1c85d7a8920e +Subproject commit 5c621253d8f2a5a4adb64a6365905db67dffe3a2 diff --git a/src/doc/reference b/src/doc/reference index 752eab01cebd..e122eefff3fe 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 752eab01cebdd6a2d90b53087298844c251859a1 +Subproject commit e122eefff3fef362eb7e0c08fb7ffbf5f9461905 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 2c9b490d70e5..160e6bbca70b 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 2c9b490d70e535cf166bf17feba59e594579843f +Subproject commit 160e6bbca70b0c01aa4de88d19db7fc5ff8447c3 From fdaf4fa6f68a30322152d3f3e76890de92ffc6cb Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 4 Nov 2025 00:36:27 +0900 Subject: [PATCH 349/525] fix: Expand literals with wrong suffixes into `LitKind::Err` --- .../test_data/regression_20952.html | 45 +++++++++++++++++++ .../ide/src/syntax_highlighting/tests.rs | 14 ++++++ .../crates/proc-macro-srv/src/tests/mod.rs | 4 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 9 ++++ 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/regression_20952.html diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/regression_20952.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/regression_20952.html new file mode 100644 index 000000000000..2c0250c6d4c4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/regression_20952.html @@ -0,0 +1,45 @@ + + +
fn main() {
+    format_args!("{} {}, {} (подозрение на спам: {:.2}%)"б);
+}
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 4e84127c29f8..58c613ef7c64 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -1497,3 +1497,17 @@ fn main() { false, ); } + +#[test] +fn regression_20952() { + check_highlighting( + r#" +//- minicore: fmt +fn main() { + format_args!("{} {}, {} (подозрение на спам: {:.2}%)"б); +} +"#, + expect_file!["./test_data/regression_20952.html"], + false, + ); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs index 08495f50bff4..d4f9976c92bd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs @@ -326,7 +326,7 @@ fn test_fn_like_macro_clone_literals() { PUNCH , [alone] 1 LITERAL Str hello bridge 1 PUNCH , [alone] 1 - LITERAL Str suffixedsuffix 1 + LITERAL Err(()) "suffixed"suffix 1 PUNCH , [alone] 1 LITERAL StrRaw(2) raw 1 PUNCH , [alone] 1 @@ -372,7 +372,7 @@ fn test_fn_like_macro_clone_literals() { PUNCH , [alone] 42:Root[0000, 0]@27..28#ROOT2024 LITERAL Str hello bridge 42:Root[0000, 0]@29..43#ROOT2024 PUNCH , [alone] 42:Root[0000, 0]@43..44#ROOT2024 - LITERAL Str suffixedsuffix 42:Root[0000, 0]@45..61#ROOT2024 + LITERAL Err(()) "suffixed"suffix 42:Root[0000, 0]@45..61#ROOT2024 PUNCH , [alone] 42:Root[0000, 0]@61..62#ROOT2024 LITERAL StrRaw(2) raw 42:Root[0000, 0]@63..73#ROOT2024 PUNCH , [alone] 42:Root[0000, 0]@73..74#ROOT2024 diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 243a27b83b0d..f9a547f61138 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -622,6 +622,15 @@ where let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { "" | "_" => None, + // ill-suffixed literals + _ if !matches!(kind, LitKind::Integer | LitKind::Float | LitKind::Err(_)) => { + return Literal { + span, + symbol: Symbol::intern(text), + kind: LitKind::Err(()), + suffix: None, + }; + } suffix => Some(Symbol::intern(suffix)), }; From 001be2fab4d0c733e2fe55ba8b33298645f0a29c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 21 Oct 2025 19:40:24 +0200 Subject: [PATCH 350/525] Make `parse_cfg_entry` output `ErrorGuaranteed` on failure Signed-off-by: Jonathan Brouwer --- .../rustc_attr_parsing/src/attributes/cfg.rs | 66 +++++++++---------- .../src/attributes/link_attrs.rs | 2 +- compiler/rustc_attr_parsing/src/interface.rs | 4 +- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index dab9e7666c23..7f703782a854 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -12,7 +12,7 @@ use rustc_session::config::ExpectedValues; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::parse::{ParseSess, feature_err}; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; use thin_vec::ThinVec; use crate::context::{AcceptContext, ShouldEmit, Stage}; @@ -47,20 +47,19 @@ pub fn parse_cfg<'c, S: Stage>( cx.expected_single_argument(list.span); return None; }; - parse_cfg_entry(cx, single) + parse_cfg_entry(cx, single).ok() } pub(crate) fn parse_cfg_entry( cx: &mut AcceptContext<'_, '_, S>, item: &MetaItemOrLitParser<'_>, -) -> Option { - Some(match item { +) -> Result { + Ok(match item { MetaItemOrLitParser::MetaItemParser(meta) => match meta.args() { ArgParser::List(list) => match meta.path().word_sym() { Some(sym::not) => { let Some(single) = list.single() else { - cx.expected_single_argument(list.span); - return None; + return Err(cx.expected_single_argument(list.span)); }; CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span) } @@ -75,29 +74,24 @@ pub(crate) fn parse_cfg_entry( Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?, Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?, _ => { - cx.emit_err(session_diagnostics::InvalidPredicate { + return Err(cx.emit_err(session_diagnostics::InvalidPredicate { span: meta.span(), predicate: meta.path().to_string(), - }); - return None; + })); } }, a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => { let Some(name) = meta.path().word_sym() else { - cx.expected_identifier(meta.path().span()); - return None; + return Err(cx.expected_identifier(meta.path().span())); }; parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)? } }, MetaItemOrLitParser::Lit(lit) => match lit.kind { LitKind::Bool(b) => CfgEntry::Bool(b, lit.span), - _ => { - cx.expected_identifier(lit.span); - return None; - } + _ => return Err(cx.expected_identifier(lit.span)), }, - MetaItemOrLitParser::Err(_, _) => return None, + MetaItemOrLitParser::Err(_, err) => return Err(*err), }) } @@ -105,19 +99,22 @@ fn parse_cfg_entry_version( cx: &mut AcceptContext<'_, '_, S>, list: &MetaItemListParser<'_>, meta_span: Span, -) -> Option { +) -> Result { try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option()); let Some(version) = list.single() else { - cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span }); - return None; + return Err( + cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span }) + ); }; let Some(version_lit) = version.lit() else { - cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() }); - return None; + return Err( + cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() }) + ); }; let Some(version_str) = version_lit.value_str() else { - cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span }); - return None; + return Err( + cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span }) + ); }; let min_version = parse_version(version_str).or_else(|| { @@ -127,14 +124,14 @@ fn parse_cfg_entry_version( None }); - Some(CfgEntry::Version(min_version, list.span)) + Ok(CfgEntry::Version(min_version, list.span)) } fn parse_cfg_entry_target( cx: &mut AcceptContext<'_, '_, S>, list: &MetaItemListParser<'_>, meta_span: Span, -) -> Option { +) -> Result { if let Some(features) = cx.features_option() && !features.cfg_target_compact() { @@ -161,17 +158,16 @@ fn parse_cfg_entry_target( // Then, parse it as a name-value item let Some(name) = sub_item.path().word_sym() else { - cx.expected_identifier(sub_item.path().span()); - return None; + return Err(cx.expected_identifier(sub_item.path().span())); }; let name = Symbol::intern(&format!("target_{name}")); - if let Some(cfg) = + if let Ok(cfg) = parse_name_value(name, sub_item.path().span(), Some(nv), sub_item.span(), cx) { result.push(cfg); } } - Some(CfgEntry::All(result, list.span)) + Ok(CfgEntry::All(result, list.span)) } fn parse_name_value( @@ -180,21 +176,22 @@ fn parse_name_value( value: Option<&NameValueParser>, span: Span, cx: &mut AcceptContext<'_, '_, S>, -) -> Option { +) -> Result { try_gate_cfg(name, span, cx.sess(), cx.features_option()); let value = match value { None => None, Some(value) => { let Some(value_str) = value.value_as_str() else { - cx.expected_string_literal(value.value_span, Some(value.value_as_lit())); - return None; + return Err( + cx.expected_string_literal(value.value_span, Some(value.value_as_lit())) + ); }; Some((value_str, value.value_span)) } }; - Some(CfgEntry::NameValue { name, name_span, value, span }) + Ok(CfgEntry::NameValue { name, name_span, value, span }) } pub fn eval_config_entry( @@ -406,7 +403,8 @@ fn parse_cfg_attr_internal<'a>( parse_cfg_entry, &CFG_ATTR_TEMPLATE, ) - .ok_or_else(|| { + .map_err(|_err: ErrorGuaranteed| { + // We have an `ErrorGuaranteed` so this delayed bug cannot fail, but we need a `Diag` for the `PResult` so we make one anyways let mut diag = sess.dcx().struct_err( "cfg_entry parsing failing with `ShouldEmit::ErrorsAndLints` should emit a error.", ); diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 797d04b914dd..065ed8959fc7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -396,7 +396,7 @@ impl LinkParser { ) .emit(); } - *cfg = parse_cfg_entry(cx, link_cfg); + *cfg = parse_cfg_entry(cx, link_cfg).ok(); true } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 953b0ebfaf04..a8ce19f7b3a8 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -168,9 +168,9 @@ impl<'sess> AttributeParser<'sess, Early> { features: Option<&'sess Features>, emit_errors: ShouldEmit, args: &I, - parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> Option, + parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> T, template: &AttributeTemplate, - ) -> Option { + ) -> T { let mut parser = Self { features, tools: Vec::new(), From b78800fd5d06726262b76f5921c42a9d9c76ca0c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 21 Oct 2025 20:13:41 +0200 Subject: [PATCH 351/525] Port `cfg!()` macro to the new attribute parsing system Signed-off-by: Jonathan Brouwer --- .../rustc_attr_parsing/src/attributes/cfg.rs | 2 +- compiler/rustc_attr_parsing/src/lib.rs | 2 +- compiler/rustc_builtin_macros/src/cfg.rs | 61 +++++++++++-------- .../src/error_codes/E0536.md | 12 ++-- tests/ui/macros/cfg.rs | 4 +- tests/ui/macros/cfg.stderr | 24 +++++--- tests/ui/span/E0536.rs | 3 - tests/ui/span/E0536.stderr | 9 --- tests/ui/span/E0805.rs | 3 + tests/ui/span/E0805.stderr | 14 +++++ 10 files changed, 83 insertions(+), 51 deletions(-) delete mode 100644 tests/ui/span/E0536.rs delete mode 100644 tests/ui/span/E0536.stderr create mode 100644 tests/ui/span/E0805.rs create mode 100644 tests/ui/span/E0805.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 7f703782a854..c9d4e2e83000 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -50,7 +50,7 @@ pub fn parse_cfg<'c, S: Stage>( parse_cfg_entry(cx, single).ok() } -pub(crate) fn parse_cfg_entry( +pub fn parse_cfg_entry( cx: &mut AcceptContext<'_, '_, S>, item: &MetaItemOrLitParser<'_>, ) -> Result { diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index bcd0d674c75f..9579b0eae804 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -106,7 +106,7 @@ mod target_checking; pub mod validate_attr; pub use attributes::cfg::{ - CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, + CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry, }; pub use attributes::cfg_old::*; pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version}; diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 85b8ef79c050..5ac23f992054 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -2,13 +2,16 @@ //! a literal `true` or `false` based on whether the given cfg matches the //! current compilation environment. -use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_errors::PResult; +use rustc_ast::{AttrStyle, CRATE_NODE_ID, token}; +use rustc_attr_parsing as attr; +use rustc_attr_parsing::parser::MetaItemOrLitParser; +use rustc_attr_parsing::{AttributeParser, CFG_TEMPLATE, ShouldEmit, parse_cfg_entry}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; +use rustc_hir::AttrPath; +use rustc_hir::attrs::CfgEntry; use rustc_parse::exp; -use rustc_span::Span; -use {rustc_ast as ast, rustc_attr_parsing as attr}; +use rustc_span::{ErrorGuaranteed, Ident, Span}; use crate::errors; @@ -21,38 +24,48 @@ pub(crate) fn expand_cfg( ExpandResult::Ready(match parse_cfg(cx, sp, tts) { Ok(cfg) => { - let matches_cfg = attr::cfg_matches( + let matches_cfg = attr::eval_config_entry( + cx.sess, &cfg, - &cx.sess, cx.current_expansion.lint_node_id, Some(cx.ecfg.features), - ); + ShouldEmit::ErrorsAndLints, + ) + .as_bool(); + MacEager::expr(cx.expr_bool(sp, matches_cfg)) } - Err(err) => { - let guar = err.emit(); - DummyResult::any(sp, guar) - } + Err(guar) => DummyResult::any(sp, guar), }) } -fn parse_cfg<'a>( - cx: &ExtCtxt<'a>, - span: Span, - tts: TokenStream, -) -> PResult<'a, ast::MetaItemInner> { - let mut p = cx.new_parser_from_tts(tts); - - if p.token == token::Eof { - return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span })); +fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result { + let mut parser = cx.new_parser_from_tts(tts); + if parser.token == token::Eof { + return Err(cx.dcx().emit_err(errors::RequiresCfgPattern { span })); } - let cfg = p.parse_meta_item_inner()?; + let meta = MetaItemOrLitParser::parse_single(&mut parser, ShouldEmit::ErrorsAndLints) + .map_err(|diag| diag.emit())?; + let cfg = AttributeParser::parse_single_args( + cx.sess, + span, + span, + AttrStyle::Inner, + AttrPath { segments: vec![Ident::from_str("cfg")].into_boxed_slice(), span }, + span, + CRATE_NODE_ID, + Some(cx.ecfg.features), + ShouldEmit::ErrorsAndLints, + &meta, + parse_cfg_entry, + &CFG_TEMPLATE, + )?; - let _ = p.eat(exp!(Comma)); + let _ = parser.eat(exp!(Comma)); - if !p.eat(exp!(Eof)) { - return Err(cx.dcx().create_err(errors::OneCfgPattern { span })); + if !parser.eat(exp!(Eof)) { + return Err(cx.dcx().emit_err(errors::OneCfgPattern { span })); } Ok(cfg) diff --git a/compiler/rustc_error_codes/src/error_codes/E0536.md b/compiler/rustc_error_codes/src/error_codes/E0536.md index f00d17739448..c1f43fa741cf 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0536.md +++ b/compiler/rustc_error_codes/src/error_codes/E0536.md @@ -1,18 +1,22 @@ The `not` cfg-predicate was malformed. -Erroneous code example: +Erroneous code example (using `cargo doc`): -```compile_fail,E0536 +```ignore, E0536 (only triggers on cargo doc) +#![feature(doc_cfg)] +#[doc(cfg(not()))] pub fn main() { - if cfg!(not()) { } + } ``` The `not` predicate expects one cfg-pattern. Example: ``` +#![feature(doc_cfg)] +#[doc(cfg(not(target_os = "linux")))] // ok! pub fn main() { - if cfg!(not(target_os = "linux")) { } // ok! + } ``` diff --git a/tests/ui/macros/cfg.rs b/tests/ui/macros/cfg.rs index 50998572274e..4b817f682a29 100644 --- a/tests/ui/macros/cfg.rs +++ b/tests/ui/macros/cfg.rs @@ -1,6 +1,6 @@ fn main() { cfg!(); //~ ERROR macro requires a cfg-pattern - cfg!(123); //~ ERROR literal in `cfg` predicate value must be a boolean - cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string + cfg!(123); //~ ERROR malformed `cfg` attribute input + cfg!(foo = 123); //~ ERROR malformed `cfg` attribute input cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern } diff --git a/tests/ui/macros/cfg.stderr b/tests/ui/macros/cfg.stderr index ad3f9b188ddb..cdbbea16cbe9 100644 --- a/tests/ui/macros/cfg.stderr +++ b/tests/ui/macros/cfg.stderr @@ -4,17 +4,27 @@ error: macro requires a cfg-pattern as an argument LL | cfg!(); | ^^^^^^ cfg-pattern required -error[E0565]: literal in `cfg` predicate value must be a boolean - --> $DIR/cfg.rs:3:10 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg.rs:3:5 | LL | cfg!(123); - | ^^^ + | ^^^^^---^ + | | | + | | expected a valid identifier here + | help: must be of the form: `cfg(predicate)` + | + = note: for more information, visit -error[E0565]: literal in `cfg` predicate value must be a string - --> $DIR/cfg.rs:4:16 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg.rs:4:5 | LL | cfg!(foo = 123); - | ^^^ + | ^^^^^^^^^^^---^ + | | | + | | expected a string literal here + | help: must be of the form: `cfg(predicate)` + | + = note: for more information, visit error: expected 1 cfg-pattern --> $DIR/cfg.rs:5:5 @@ -24,4 +34,4 @@ LL | cfg!(foo, bar); error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0565`. +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/span/E0536.rs b/tests/ui/span/E0536.rs deleted file mode 100644 index ae0733633541..000000000000 --- a/tests/ui/span/E0536.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn main() { - if cfg!(not()) { } //~ ERROR E0536 -} diff --git a/tests/ui/span/E0536.stderr b/tests/ui/span/E0536.stderr deleted file mode 100644 index 6c25f9140a1a..000000000000 --- a/tests/ui/span/E0536.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0536]: expected 1 cfg-pattern - --> $DIR/E0536.rs:2:13 - | -LL | if cfg!(not()) { } - | ^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0536`. diff --git a/tests/ui/span/E0805.rs b/tests/ui/span/E0805.rs new file mode 100644 index 000000000000..097f5cd8e586 --- /dev/null +++ b/tests/ui/span/E0805.rs @@ -0,0 +1,3 @@ +pub fn main() { + if cfg!(not()) { } //~ ERROR E0805 +} diff --git a/tests/ui/span/E0805.stderr b/tests/ui/span/E0805.stderr new file mode 100644 index 000000000000..544af096ccc7 --- /dev/null +++ b/tests/ui/span/E0805.stderr @@ -0,0 +1,14 @@ +error[E0805]: malformed `cfg` attribute input + --> $DIR/E0805.rs:2:8 + | +LL | if cfg!(not()) { } + | ^^^^^^^^--^ + | | | + | | expected a single argument here + | help: must be of the form: `cfg(predicate)` + | + = note: for more information, visit + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0805`. From a628e71edf7c7ce5a213ae8223fb0b1c66748346 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 29 Oct 2025 20:59:04 +0100 Subject: [PATCH 352/525] Add `ParsedDescription` to the attribute parsers Signed-off-by: Jonathan Brouwer --- .../rustc_attr_parsing/src/attributes/cfg.rs | 5 +- compiler/rustc_attr_parsing/src/context.rs | 47 +++++++++++++------ compiler/rustc_attr_parsing/src/interface.rs | 5 ++ compiler/rustc_attr_parsing/src/lib.rs | 1 + .../src/session_diagnostics.rs | 31 ++++++++---- compiler/rustc_builtin_macros/src/cfg.rs | 5 +- tests/ui/macros/cfg.rs | 4 +- tests/ui/macros/cfg.stderr | 4 +- tests/ui/span/E0805.stderr | 2 +- 9 files changed, 75 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index c9d4e2e83000..47b46cd69d84 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -19,6 +19,7 @@ use crate::context::{AcceptContext, ShouldEmit, Stage}; use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser}; use crate::session_diagnostics::{ AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, + ParsedDescription, }; use crate::{ AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, @@ -352,7 +353,8 @@ pub fn parse_cfg_attr( span, attr_span: cfg_attr.span, template: CFG_ATTR_TEMPLATE, - attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path), + path: AttrPath::from_ast(&cfg_attr.get_normal_item().path), + description: ParsedDescription::Attribute, reason, suggestions: CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr), }); @@ -395,6 +397,7 @@ fn parse_cfg_attr_internal<'a>( .into_boxed_slice(), span: attribute.span, }, + ParsedDescription::Attribute, pred_span, CRATE_NODE_ID, features, diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 15904fd7d334..773527c96a3a 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -71,7 +71,9 @@ use crate::attributes::traits::{ use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, PathParser}; -use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem}; +use crate::session_diagnostics::{ + AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem, +}; use crate::target_checking::AllowedTargets; type GroupType = LazyLock>; @@ -353,6 +355,10 @@ pub struct AcceptContext<'f, 'sess, S: Stage> { /// Whether it is an inner or outer attribute pub(crate) attr_style: AttrStyle, + /// A description of the thing we are parsing using this attribute parser + /// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro. + pub(crate) parsed_description: ParsedDescription, + /// The expected structure of the attribute. /// /// Used in reporting errors to give a hint to users what the attribute *should* look like. @@ -431,7 +437,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedStringLiteral { byte_string: actual_literal.and_then(|i| { i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span)) @@ -446,7 +453,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedIntegerLiteral, suggestions: self.suggestions(), }) @@ -457,7 +465,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedList, suggestions: self.suggestions(), }) @@ -468,7 +477,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span: args_span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedNoArgs, suggestions: self.suggestions(), }) @@ -480,7 +490,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedIdentifier, suggestions: self.suggestions(), }) @@ -493,7 +504,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedNameValue(name), suggestions: self.suggestions(), }) @@ -505,7 +517,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::DuplicateKey(key), suggestions: self.suggestions(), }) @@ -518,7 +531,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::UnexpectedLiteral, suggestions: self.suggestions(), }) @@ -529,7 +543,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedSingleArgument, suggestions: self.suggestions(), }) @@ -540,7 +555,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument, suggestions: self.suggestions(), }) @@ -556,7 +572,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: false, @@ -577,7 +594,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: false, @@ -597,7 +615,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, attr_span: self.attr_span, template: self.template.clone(), - attribute: self.attr_path.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, reason: AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: true, diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index a8ce19f7b3a8..b7a6a1ef6d66 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -12,6 +12,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; +use crate::session_diagnostics::ParsedDescription; use crate::{Early, Late, OmitDoc, ShouldEmit}; /// Context created once, for example as part of the ast lowering @@ -145,6 +146,7 @@ impl<'sess> AttributeParser<'sess, Early> { normal_attr.item.span(), attr.style, path.get_attribute_path(), + ParsedDescription::Attribute, target_span, target_node_id, features, @@ -163,6 +165,7 @@ impl<'sess> AttributeParser<'sess, Early> { inner_span: Span, attr_style: AttrStyle, attr_path: AttrPath, + parsed_description: ParsedDescription, target_span: Span, target_node_id: NodeId, features: Option<&'sess Features>, @@ -190,6 +193,7 @@ impl<'sess> AttributeParser<'sess, Early> { attr_span, inner_span, attr_style, + parsed_description, template, attr_path, }; @@ -310,6 +314,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_span: lower_span(attr.span), inner_span: lower_span(attr.get_normal_item().span()), attr_style: attr.style, + parsed_description: ParsedDescription::Attribute, template: &accept.template, attr_path: path.get_attribute_path(), }; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 9579b0eae804..2e0c5be587bb 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -113,5 +113,6 @@ pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, p pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; pub use lints::emit_attribute_lint; +pub use session_diagnostics::ParsedDescription; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 82bd29218313..8d783503f7be 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -610,20 +610,35 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedIdentifier, } +/// A description of a thing that can be parsed using an attribute parser. +#[derive(Copy, Clone)] +pub enum ParsedDescription { + /// Used when parsing attributes. + Attribute, + /// Used when parsing some macros, such as the `cfg!()` macro. + Macro, +} + pub(crate) struct AttributeParseError<'a> { pub(crate) span: Span, pub(crate) attr_span: Span, pub(crate) template: AttributeTemplate, - pub(crate) attribute: AttrPath, + pub(crate) path: AttrPath, + pub(crate) description: ParsedDescription, pub(crate) reason: AttributeParseErrorReason<'a>, pub(crate) suggestions: Vec, } impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let name = self.attribute.to_string(); + let name = self.path.to_string(); - let mut diag = Diag::new(dcx, level, format!("malformed `{name}` attribute input")); + let description = match self.description { + ParsedDescription::Attribute => "attribute", + ParsedDescription::Macro => "macro", + }; + + let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input")); diag.span(self.attr_span); diag.code(E0539); match self.reason { @@ -724,12 +739,12 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { diag.span_label( self.span, format!( - "this attribute is only valid with {quote}{x}{quote} as an argument" + "this {description} is only valid with {quote}{x}{quote} as an argument" ), ); } [first, second] => { - diag.span_label(self.span, format!("this attribute is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument")); + diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument")); } [first @ .., second_to_last, last] => { let mut res = String::new(); @@ -740,7 +755,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { "{quote}{second_to_last}{quote} or {quote}{last}{quote}" )); - diag.span_label(self.span, format!("this attribute is only valid with one of the following arguments: {res}")); + diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}")); } } } @@ -756,9 +771,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { diag.span_suggestions( self.attr_span, if self.suggestions.len() == 1 { - "must be of the form" + "must be of the form".to_string() } else { - "try changing it to one of the following valid forms of the attribute" + format!("try changing it to one of the following valid forms of the {description}") }, self.suggestions, Applicability::HasPlaceholders, diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 5ac23f992054..387399668111 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -6,7 +6,9 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AttrStyle, CRATE_NODE_ID, token}; use rustc_attr_parsing as attr; use rustc_attr_parsing::parser::MetaItemOrLitParser; -use rustc_attr_parsing::{AttributeParser, CFG_TEMPLATE, ShouldEmit, parse_cfg_entry}; +use rustc_attr_parsing::{ + AttributeParser, CFG_TEMPLATE, ParsedDescription, ShouldEmit, parse_cfg_entry, +}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_hir::AttrPath; use rustc_hir::attrs::CfgEntry; @@ -53,6 +55,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result $DIR/cfg.rs:3:5 | LL | cfg!(123); @@ -15,7 +15,7 @@ LL | cfg!(123); | = note: for more information, visit -error[E0539]: malformed `cfg` attribute input +error[E0539]: malformed `cfg` macro input --> $DIR/cfg.rs:4:5 | LL | cfg!(foo = 123); diff --git a/tests/ui/span/E0805.stderr b/tests/ui/span/E0805.stderr index 544af096ccc7..58c0e31ce084 100644 --- a/tests/ui/span/E0805.stderr +++ b/tests/ui/span/E0805.stderr @@ -1,4 +1,4 @@ -error[E0805]: malformed `cfg` attribute input +error[E0805]: malformed `cfg` macro input --> $DIR/E0805.rs:2:8 | LL | if cfg!(not()) { } From f3111966a47d167a6fd2defc356bd0c0f92ac0f1 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 4 Nov 2025 01:37:13 +0900 Subject: [PATCH 353/525] fix: Canonicalize `custom-target.json` paths when fetching sysroot metadata --- .../crates/project-model/src/workspace.rs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 3c696256854c..aa2e15930cbb 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -374,6 +374,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + workspace_dir, &targets, toolchain.clone(), )), @@ -480,6 +481,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + project_json.project_root(), &targets, toolchain.clone(), )), @@ -535,6 +537,7 @@ impl ProjectWorkspace { let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + dir, &targets, toolchain.clone(), )), @@ -1864,12 +1867,29 @@ fn add_dep_inner(graph: &mut CrateGraphBuilder, from: CrateBuilderId, dep: Depen fn sysroot_metadata_config( config: &CargoConfig, + current_dir: &AbsPath, targets: &[String], toolchain_version: Option, ) -> CargoMetadataConfig { + // We run `cargo metadata` on sysroot with sysroot dir as a working directory, but still pass + // the `targets` from the cargo config evaluated from the workspace's `current_dir`. + // So, we need to *canonicalize* those *might-be-relative-paths-to-custom-target-json-files*. + // + // See https://github.com/rust-lang/cargo/blob/f7acf448fc127df9a77c52cc2bba027790ac4931/src/cargo/core/compiler/compile_kind.rs#L171-L192 + let targets = targets + .iter() + .map(|target| { + if target.ends_with(".json") { + current_dir.join(target).to_string() + } else { + target.to_owned() + } + }) + .collect(); + CargoMetadataConfig { features: Default::default(), - targets: targets.to_vec(), + targets, extra_args: Default::default(), extra_env: config.extra_env.clone(), toolchain_version, From 97e69d13e1d261685d3df6d9cf21613bbdfb3d75 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 3 Nov 2025 19:29:36 +0100 Subject: [PATCH 354/525] tidy: Fix false positives with absolute repo paths in `pal.rs` `check()` Fixes the bug: 1. git clone https://github.com/rust-lang/rust.git rust-improve-tests 2. cd rust-improve-tests 3. ./x test tidy Expected: No tidy errors found Actual: ``` thread 'pal (library)' (837175) panicked at src/tools/tidy/src/pal.rs:100:5: assertion failed: saw_target_arch ``` Since the git checkout dir contains the word "tests", the `pal.rs` `check()` used to erroneously ignore all paths. --- src/tools/tidy/src/pal.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index dfca2cda9a0f..f03dde6257d7 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -68,14 +68,20 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/std/src/io/error.rs", // Repr unpacked needed for UEFI ]; -pub fn check(path: &Path, tidy_ctx: TidyCtx) { - let mut check = tidy_ctx.start_check(CheckId::new("pal").path(path)); +pub fn check(library_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("pal").path(library_path)); + + let root_path = library_path.parent().unwrap(); + // Let's double-check that this is the root path by making sure it has `x.py`. + assert!(root_path.join("x.py").is_file()); // Sanity check that the complex parsing here works. let mut saw_target_arch = false; let mut saw_cfg_bang = false; - walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { + walk(library_path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = entry.path(); + // We don't want the absolute path to matter, so make it relative. + let file = file.strip_prefix(root_path).unwrap(); let filestr = file.to_string_lossy().replace("\\", "/"); if !filestr.ends_with(".rs") { return; From 5d0011c1efe2ee91a6d15da31b369c3c5c187599 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Oct 2025 18:00:48 +0200 Subject: [PATCH 355/525] Add regression test when unable to run compiler in doctest --- src/librustdoc/doctest.rs | 16 +++++--------- tests/run-make/rustdoc-test-builder/foo.rs | 3 +++ tests/run-make/rustdoc-test-builder/rmake.rs | 23 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 tests/run-make/rustdoc-test-builder/foo.rs create mode 100644 tests/run-make/rustdoc-test-builder/rmake.rs diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index f39d5aadfb49..58f728082a44 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -500,10 +500,7 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String { input + &exe_suffix } -fn wrapped_rustc_command<'a>( - rustc_wrappers: &'a [PathBuf], - rustc_binary: &'a Path, -) -> (Command, &'a Path) { +fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command { let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary]); let exe = args.next().expect("unable to create rustc command"); @@ -512,7 +509,7 @@ fn wrapped_rustc_command<'a>( command.arg(arg); } - (command, rustc_wrappers.first().map(|p| &**p).unwrap_or(rustc_binary)) + command } /// Information needed for running a bundle of doctests. @@ -632,8 +629,7 @@ fn run_test( .test_builder .as_deref() .unwrap_or_else(|| rustc_interface::util::rustc_path(sysroot).expect("found rustc")); - let (mut compiler, binary_path) = - wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); + let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); compiler.args(&compiler_args); @@ -677,7 +673,7 @@ fn run_test( let mut child = match compiler.spawn() { Ok(child) => child, Err(error) => { - eprintln!("Failed to spawn {binary_path:?}: {error:?}"); + eprintln!("Failed to spawn {:?}: {error:?}", compiler.get_program()); return (Duration::default(), Err(TestFailure::CompileError)); } }; @@ -689,7 +685,7 @@ fn run_test( // build it now let runner_input_file = doctest.path_for_merged_doctest_runner(); - let (mut runner_compiler, binary_path) = + let mut runner_compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); // the test runner does not contain any user-written code, so this doesn't allow // the user to exploit nightly-only features on stable @@ -745,7 +741,7 @@ fn run_test( let mut child_runner = match runner_compiler.spawn() { Ok(child) => child, Err(error) => { - eprintln!("Failed to spawn {binary_path:?}: {error:?}"); + eprintln!("Failed to spawn {:?}: {error:?}", runner_compiler.get_program()); return (Duration::default(), Err(TestFailure::CompileError)); } }; diff --git a/tests/run-make/rustdoc-test-builder/foo.rs b/tests/run-make/rustdoc-test-builder/foo.rs new file mode 100644 index 000000000000..51d17849fd71 --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/foo.rs @@ -0,0 +1,3 @@ +//! ``` +//! let x = 12; +//! ``` diff --git a/tests/run-make/rustdoc-test-builder/rmake.rs b/tests/run-make/rustdoc-test-builder/rmake.rs new file mode 100644 index 000000000000..c243b784eb9b --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/rmake.rs @@ -0,0 +1,23 @@ +// This test ensures that if the rustdoc test binary is not executable, it will +// gracefully fail and not panic. + +//@ needs-target-std + +use run_make_support::{path, rfs, rustdoc}; + +fn main() { + let absolute_path = path("foo.rs").canonicalize().expect("failed to get absolute path"); + let output = rustdoc() + .input("foo.rs") + .arg("--test") + .arg("-Zunstable-options") + .arg("--test-builder") + .arg(&absolute_path) + .run_fail(); + + // We also double-check that we don't have the panic text in the output. + output.assert_stdout_contains("Failed to spawn "); + output.assert_stderr_not_contains("the compiler unexpectedly panicked. this is a bug."); + // Just in case... + output.assert_stdout_not_contains("the compiler unexpectedly panicked. this is a bug."); +} From fd1112557ea063727c3aa37cd95b36f741098f77 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 1 Nov 2025 08:55:44 +0100 Subject: [PATCH 356/525] CI: rfl: move to temporary commit to support `-Cjump-tables=n` Link: https://github.com/rust-lang/rust/pull/145974 Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index b7d7151b171d..e7f86e10f55a 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,7 +2,8 @@ set -euo pipefail -LINUX_VERSION=v6.17-rc5 +# https://github.com/rust-lang/rust/pull/145974 +LINUX_VERSION=842cfd8e5aff3157cb25481b2900b49c188d628a # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt From 4ab1fc5127bd66ba3f431e7aa886e4dc54340317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 17 Nov 2024 23:30:20 +0000 Subject: [PATCH 357/525] Provide more context on `Fn` closure modifying binding When modifying a binding from inside of an `Fn` closure, point at the binding definition and suggest using an `std::sync` type that would allow the code to compile. ``` error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure --> f703.rs:6:9 | 4 | let mut counter = 0; | ----------- `counter` declared here, outside the closure 5 | let x: Box = Box::new(|| { | -- in this closure 6 | counter += 1; | ^^^^^^^^^^^^ cannot assign ``` --- .../src/diagnostics/mutability_errors.rs | 58 ++++++++++++++++--- .../async-closures/wrong-fn-kind.stderr | 2 + .../borrow-immutable-upvar-mutation.stderr | 7 +++ .../borrow-raw-address-of-mutability.stderr | 2 + tests/ui/borrowck/mutability-errors.stderr | 16 +++-- ...bility-violation-with-closure-21600.stderr | 5 ++ ...wrong-closure-arg-suggestion-125325.stderr | 5 ++ tests/ui/nll/closure-captures.stderr | 6 +- ...sures-mutated-upvar-from-fn-closure.stderr | 2 + 9 files changed, 90 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e23c7eebeca1..db746242ac05 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -150,8 +150,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - PlaceRef { local: _, projection: [proj_base @ .., ProjectionElem::Deref] } => { - if the_place_err.local == ty::CAPTURE_STRUCT_LOCAL + PlaceRef { local, projection: [proj_base @ .., ProjectionElem::Deref] } => { + if local == ty::CAPTURE_STRUCT_LOCAL && proj_base.is_empty() && !self.upvars.is_empty() { @@ -165,10 +165,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ", as `Fn` closures cannot mutate their captured variables".to_string() } } else { - let source = self.borrowed_content_source(PlaceRef { - local: the_place_err.local, - projection: proj_base, - }); + let source = + self.borrowed_content_source(PlaceRef { local, projection: proj_base }); let pointer_type = source.describe_for_immutable_place(self.infcx.tcx); opt_source = Some(source); if let Some(desc) = self.describe_place(access_place.as_ref()) { @@ -532,6 +530,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { PlaceRef { local, projection: [ProjectionElem::Deref] } if local == ty::CAPTURE_STRUCT_LOCAL && !self.upvars.is_empty() => { + self.point_at_binding_outside_closure(&mut err, local, access_place); self.expected_fn_found_fn_mut_call(&mut err, span, act); } @@ -950,6 +949,50 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } + /// When modifying a binding from inside of an `Fn` closure, point at the binding definition. + fn point_at_binding_outside_closure( + &self, + err: &mut Diag<'_>, + local: Local, + access_place: Place<'tcx>, + ) { + let place = access_place.as_ref(); + for (index, elem) in place.projection.into_iter().enumerate() { + if let ProjectionElem::Deref = elem { + if index == 0 { + if self.body.local_decls[local].is_ref_for_guard() { + continue; + } + if let LocalInfo::StaticRef { .. } = *self.body.local_decls[local].local_info() + { + continue; + } + } + if let Some(field) = self.is_upvar_field_projection(PlaceRef { + local, + projection: place.projection.split_at(index + 1).0, + }) { + let var_index = field.index(); + let upvar = self.upvars[var_index]; + if let Some(hir_id) = upvar.info.capture_kind_expr_id { + let node = self.infcx.tcx.hir_node(hir_id); + if let hir::Node::Expr(expr) = node + && let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind + && let hir::def::Res::Local(hir_id) = path.res + && let hir::Node::Pat(pat) = self.infcx.tcx.hir_node(hir_id) + { + let name = upvar.to_string(self.infcx.tcx); + err.span_label( + pat.span, + format!("`{name}` declared here, outside the closure"), + ); + break; + } + } + } + } + } + } /// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected. fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str) { err.span_label(sp, format!("cannot {act}")); @@ -962,6 +1005,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let def_id = tcx.hir_enclosing_body_owner(fn_call_id); let mut look_at_return = true; + err.span_label(closure_span, "in this closure"); // If the HIR node is a function or method call, get the DefId // of the callee function or method, the span, and args of the call expr let get_call_details = || { @@ -1032,7 +1076,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Some(span) = arg { err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); err.span_label(call_span, "expects `Fn` instead of `FnMut`"); - err.span_label(closure_span, "in this closure"); look_at_return = false; } } @@ -1059,7 +1102,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { sig.decl.output.span(), "change this to return `FnMut` instead of `Fn`", ); - err.span_label(closure_span, "in this closure"); } _ => {} } diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr index 95f314214cc6..dd0f4da5dd32 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr @@ -25,6 +25,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F LL | fn needs_async_fn(_: impl AsyncFn()) {} | -------------- change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = 1; + | ----- `x` declared here, outside the closure LL | needs_async_fn(async || { | -------------- ^^^^^^^^ | | | diff --git a/tests/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/tests/ui/borrowck/borrow-immutable-upvar-mutation.stderr index a0eaf1f163b0..4e40ebf738e3 100644 --- a/tests/ui/borrowck/borrow-immutable-upvar-mutation.stderr +++ b/tests/ui/borrowck/borrow-immutable-upvar-mutation.stderr @@ -4,6 +4,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu LL | fn to_fn>(f: F) -> F { | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = 0; + | ----- `x` declared here, outside the closure LL | let _f = to_fn(|| x = 42); | ----- -- ^^^^^^ cannot assign | | | @@ -16,6 +18,8 @@ error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `F LL | fn to_fn>(f: F) -> F { | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut y = 0; + | ----- `y` declared here, outside the closure LL | let _g = to_fn(|| set(&mut y)); | ----- -- ^^^^^^ cannot borrow as mutable | | | @@ -28,6 +32,9 @@ error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closu LL | fn to_fn>(f: F) -> F { | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut z = 0; + | ----- `z` declared here, outside the closure +... LL | to_fn(|| z = 42); | ----- -- ^^^^^^ cannot assign | | | diff --git a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr index f81a8c99376f..c4b97950727a 100644 --- a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr +++ b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr @@ -40,6 +40,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F LL | fn make_fn(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = 0; + | ----- `x` declared here, outside the closure LL | let f = make_fn(|| { | ------- -- in this closure | | diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr index 3cab3ccb993c..7307e1f2a86b 100644 --- a/tests/ui/borrowck/mutability-errors.stderr +++ b/tests/ui/borrowck/mutability-errors.stderr @@ -139,7 +139,9 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu | LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` -... +LL | +LL | fn ref_closure(mut x: (i32,)) { + | ----- `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | @@ -152,7 +154,9 @@ error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captu | LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` -... +LL | +LL | fn ref_closure(mut x: (i32,)) { + | ----- `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | @@ -166,7 +170,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F | LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` -... +LL | +LL | fn ref_closure(mut x: (i32,)) { + | ----- `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | @@ -180,7 +186,9 @@ error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate the | LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` -... +LL | +LL | fn ref_closure(mut x: (i32,)) { + | ----- `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | diff --git a/tests/ui/closures/aliasability-violation-with-closure-21600.stderr b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr index 2d2397a2141d..2f4135b12fa5 100644 --- a/tests/ui/closures/aliasability-violation-with-closure-21600.stderr +++ b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr @@ -4,6 +4,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F LL | fn call_it(f: F) where F: Fn() { f(); } | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = A; + | ----- `x` declared here, outside the closure +... LL | call_it(|| x.gen_mut()); | ------- -- ^ cannot borrow as mutable | | | @@ -16,6 +19,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F LL | fn call_it(f: F) where F: Fn() { f(); } | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = A; + | ----- `x` declared here, outside the closure LL | call_it(|| { | ------- -- in this closure | | diff --git a/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr index e0cce8c4b314..f419f7c1b44d 100644 --- a/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr +++ b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr @@ -4,6 +4,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu LL | fn assoc_func(&self, _f: impl Fn()) -> usize { | --------- change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = (); + | ----- `x` declared here, outside the closure LL | s.assoc_func(|| x = ()); | --------------^^^^^^- | | | | @@ -17,6 +19,9 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu LL | fn func(_f: impl Fn()) -> usize { | --------- change this to accept `FnMut` instead of `Fn` ... +LL | let mut x = (); + | ----- `x` declared here, outside the closure +... LL | func(|| x = ()) | ---- -- ^^^^^^ cannot assign | | | diff --git a/tests/ui/nll/closure-captures.stderr b/tests/ui/nll/closure-captures.stderr index 828974c517e6..80ac033351aa 100644 --- a/tests/ui/nll/closure-captures.stderr +++ b/tests/ui/nll/closure-captures.stderr @@ -47,7 +47,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F | LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` -... +LL | +LL | fn two_closures_ref_mut(mut x: i32) { + | ----- `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | @@ -89,6 +91,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F LL | fn fn_ref(f: F) -> F { f } | - change this to accept `FnMut` instead of `Fn` ... +LL | fn two_closures_ref(x: i32) { + | - `x` declared here, outside the closure LL | fn_ref(|| { | ------ -- in this closure | | diff --git a/tests/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr b/tests/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr index cbe42861d5ee..f82faeea516f 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr @@ -4,6 +4,8 @@ error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` LL | fn call(f: F) where F : Fn() { | - change this to accept `FnMut` instead of `Fn` ... +LL | let mut counter = 0; + | ----------- `counter` declared here, outside the closure LL | call(|| { | ---- -- in this closure | | From 75de61915974c598d540adfa302b5bcecb1914d7 Mon Sep 17 00:00:00 2001 From: sayantn Date: Wed, 8 Oct 2025 08:12:09 +0530 Subject: [PATCH 358/525] Add alignment parameter to `simd_masked_{load,store}` --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 31 +++++- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 +- compiler/rustc_middle/src/ty/consts/int.rs | 24 +++++ compiler/rustc_middle/src/ty/mod.rs | 2 +- library/core/src/intrinsics/simd.rs | 25 +++-- .../crates/core_simd/src/vector.rs | 18 +++- .../tests/pass/intrinsics/portable-simd.rs | 24 ++++- .../assembly-llvm/simd-intrinsic-mask-load.rs | 40 +++++++- .../simd-intrinsic-mask-store.rs | 24 ++++- tests/auxiliary/minicore.rs | 14 +++ .../simd-intrinsic-generic-masked-load.rs | 45 ++++++++- .../simd-intrinsic-generic-masked-store.rs | 37 ++++++- tests/ui/simd/masked-load-store-build-fail.rs | 66 +++++++++---- .../simd/masked-load-store-build-fail.stderr | 96 ++++++++++++------- tests/ui/simd/masked-load-store-check-fail.rs | 19 ++-- .../simd/masked-load-store-check-fail.stderr | 46 +++++---- tests/ui/simd/masked-load-store.rs | 21 +++- 17 files changed, 421 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 14b3f3626efe..0626cb3f2f16 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::{self as hir}; use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; -use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; @@ -1840,8 +1840,21 @@ fn generic_simd_intrinsic<'ll, 'tcx>( return Ok(call); } + fn llvm_alignment<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + alignment: SimdAlign, + vector_ty: Ty<'tcx>, + element_ty: Ty<'tcx>, + ) -> u64 { + match alignment { + SimdAlign::Unaligned => 1, + SimdAlign::Element => bx.align_of(element_ty).bytes(), + SimdAlign::Vector => bx.align_of(vector_ty).bytes(), + } + } + if name == sym::simd_masked_load { - // simd_masked_load(mask: , pointer: *_ T, values: ) -> + // simd_masked_load<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *_ T, values: ) -> // * N: number of elements in the input vectors // * T: type of the element to load // * M: any integer width is supported, will be truncated to i1 @@ -1849,6 +1862,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off” lanes are not accessed. + let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; let (mask_len, mask_elem) = (in_len, in_elem); @@ -1905,7 +1922,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.align_of(values_elem).bytes(); + let alignment = llvm_alignment(bx, alignment, values_ty, values_elem); let llvm_pointer = bx.type_ptr(); @@ -1932,7 +1949,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_masked_store { - // simd_masked_store(mask: , pointer: *mut T, values: ) -> () + // simd_masked_store<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *mut T, values: ) -> () // * N: number of elements in the input vectors // * T: type of the element to load // * M: any integer width is supported, will be truncated to i1 @@ -1940,6 +1957,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off” lanes are not accessed. + let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; let (mask_len, mask_elem) = (in_len, in_elem); @@ -1990,7 +2011,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.align_of(values_elem).bytes(); + let alignment = llvm_alignment(bx, alignment, values_ty, values_elem); let llvm_pointer = bx.type_ptr(); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index a6659912e3fb..a8e8830db99d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -695,8 +695,8 @@ pub(crate) fn check_intrinsic_type( (1, 0, vec![param(0), param(0), param(0)], param(0)) } sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)), - sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)), - sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit), + sym::simd_masked_load => (3, 1, vec![param(0), param(1), param(2)], param(2)), + sym::simd_masked_store => (3, 1, vec![param(0), param(1), param(2)], tcx.types.unit), sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit), sym::simd_insert | sym::simd_insert_dyn => { (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)) diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 6ee76b945073..eaf67ae23ad2 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -39,6 +39,15 @@ pub enum AtomicOrdering { SeqCst = 4, } +/// An enum to represent the compiler-side view of `intrinsics::simd::SimdAlign`. +#[derive(Debug, Copy, Clone)] +pub enum SimdAlign { + // These values must match `intrinsics::simd::SimdAlign`! + Unaligned = 0, + Element = 1, + Vector = 2, +} + impl std::fmt::Debug for ConstInt { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { int, signed, is_ptr_sized_integral } = *self; @@ -350,6 +359,21 @@ impl ScalarInt { } } + #[inline] + pub fn to_simd_alignment(self) -> SimdAlign { + use SimdAlign::*; + let val = self.to_u32(); + if val == Unaligned as u32 { + Unaligned + } else if val == Element as u32 { + Element + } else if val == Vector as u32 { + Vector + } else { + panic!("not a valid simd alignment") + } + } + /// Converts the `ScalarInt` to `bool`. /// Panics if the `size` of the `ScalarInt` is not equal to 1 byte. /// Errors if it is not a valid `bool`. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2b9079da1830..2f331780670b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -74,7 +74,7 @@ pub use self::closure::{ }; pub use self::consts::{ AnonConstKind, AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr, - ExprKind, ScalarInt, UnevaluatedConst, ValTree, ValTreeKind, Value, + ExprKind, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKind, Value, }; pub use self::context::{ CtxtInterners, CurrentGcx, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 19488082cc33..c56e04bfc2d9 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -2,6 +2,8 @@ //! //! In this module, a "vector" is any `repr(simd)` type. +use crate::marker::ConstParamTy; + /// Inserts an element into a vector, returning the updated vector. /// /// `T` must be a vector with element type `U`, and `idx` must be `const`. @@ -377,6 +379,19 @@ pub unsafe fn simd_gather(val: T, ptr: U, mask: V) -> T; #[rustc_nounwind] pub unsafe fn simd_scatter(val: T, ptr: U, mask: V); +/// A type for alignment options for SIMD masked load/store intrinsics. +#[derive(Debug, ConstParamTy, PartialEq, Eq)] +pub enum SimdAlign { + // These values must match the compiler's `SimdAlign` defined in + // `rustc_middle/src/ty/consts/int.rs`! + /// No alignment requirements on the pointer + Unaligned = 0, + /// The pointer must be aligned to the element type of the SIMD vector + Element = 1, + /// The pointer must be aligned to the SIMD vector type + Vector = 2, +} + /// Reads a vector of pointers. /// /// `T` must be a vector. @@ -392,13 +407,12 @@ pub unsafe fn simd_scatter(val: T, ptr: U, mask: V); /// `val`. /// /// # Safety -/// Unmasked values in `T` must be readable as if by `::read` (e.g. aligned to the element -/// type). +/// `ptr` must be aligned according to the `ALIGN` parameter, see [`SimdAlign`] for details. /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_masked_load(mask: V, ptr: U, val: T) -> T; +pub unsafe fn simd_masked_load(mask: V, ptr: U, val: T) -> T; /// Writes to a vector of pointers. /// @@ -414,13 +428,12 @@ pub unsafe fn simd_masked_load(mask: V, ptr: U, val: T) -> T; /// Otherwise if the corresponding value in `mask` is `0`, do nothing. /// /// # Safety -/// Unmasked values in `T` must be writeable as if by `::write` (e.g. aligned to the element -/// type). +/// `ptr` must be aligned according to the `ALIGN` parameter, see [`SimdAlign`] for details. /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_masked_store(mask: V, ptr: U, val: T); +pub unsafe fn simd_masked_store(mask: V, ptr: U, val: T); /// Adds two simd vectors elementwise, with saturation. /// diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs index d76a6cd52bfc..f40031f8c4da 100644 --- a/library/portable-simd/crates/core_simd/src/vector.rs +++ b/library/portable-simd/crates/core_simd/src/vector.rs @@ -474,7 +474,14 @@ where or: Self, ) -> Self { // SAFETY: The safety of reading elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_load(enable.to_int(), ptr, or) } + unsafe { + core::intrinsics::simd::simd_masked_load::< + _, + _, + _, + { core::intrinsics::simd::SimdAlign::Element }, + >(enable.to_int(), ptr, or) + } } /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. @@ -723,7 +730,14 @@ where #[inline] pub unsafe fn store_select_ptr(self, ptr: *mut T, enable: Mask<::Mask, N>) { // SAFETY: The safety of writing elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_store(enable.to_int(), ptr, self) } + unsafe { + core::intrinsics::simd::simd_masked_store::< + _, + _, + _, + { core::intrinsics::simd::SimdAlign::Element }, + >(enable.to_int(), ptr, self) + } } /// Writes the values in a SIMD vector to potentially discontiguous indices in `slice`. diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index b7d2584c58fb..faf79fc1a8d1 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -936,25 +936,39 @@ fn simd_float_intrinsics() { } fn simd_masked_loadstore() { + use intrinsics::*; + // The buffer is deliberarely too short, so reading the last element would be UB. let buf = [3i32; 3]; let default = i32x4::splat(0); let mask = i32x4::from_array([!0, !0, !0, 0]); - let vals = unsafe { intrinsics::simd_masked_load(mask, buf.as_ptr(), default) }; + let vals = + unsafe { simd_masked_load::<_, _, _, { SimdAlign::Element }>(mask, buf.as_ptr(), default) }; assert_eq!(vals, i32x4::from_array([3, 3, 3, 0])); // Also read in a way that the *first* element is OOB. let mask2 = i32x4::from_array([0, !0, !0, !0]); - let vals = - unsafe { intrinsics::simd_masked_load(mask2, buf.as_ptr().wrapping_sub(1), default) }; + let vals = unsafe { + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + mask2, + buf.as_ptr().wrapping_sub(1), + default, + ) + }; assert_eq!(vals, i32x4::from_array([0, 3, 3, 3])); // The buffer is deliberarely too short, so writing the last element would be UB. let mut buf = [42i32; 3]; let vals = i32x4::from_array([1, 2, 3, 4]); - unsafe { intrinsics::simd_masked_store(mask, buf.as_mut_ptr(), vals) }; + unsafe { simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, buf.as_mut_ptr(), vals) }; assert_eq!(buf, [1, 2, 3]); // Also write in a way that the *first* element is OOB. - unsafe { intrinsics::simd_masked_store(mask2, buf.as_mut_ptr().wrapping_sub(1), vals) }; + unsafe { + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + mask2, + buf.as_mut_ptr().wrapping_sub(1), + vals, + ) + }; assert_eq!(buf, [2, 3, 4]); } diff --git a/tests/assembly-llvm/simd-intrinsic-mask-load.rs b/tests/assembly-llvm/simd-intrinsic-mask-load.rs index e9ad554ae987..f77cdb6fc676 100644 --- a/tests/assembly-llvm/simd-intrinsic-mask-load.rs +++ b/tests/assembly-llvm/simd-intrinsic-mask-load.rs @@ -9,7 +9,7 @@ //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -Copt-level=3 -C panic=abort -#![feature(no_core, lang_items, repr_simd, intrinsics)] +#![feature(no_core, lang_items, repr_simd, intrinsics, adt_const_params)] #![no_core] #![allow(non_camel_case_types)] @@ -35,7 +35,7 @@ pub struct f64x4([f64; 4]); pub struct m64x4([i64; 4]); #[rustc_intrinsic] -unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; +unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; // CHECK-LABEL: load_i8x16 #[no_mangle] @@ -56,7 +56,11 @@ pub unsafe extern "C" fn load_i8x16(mask: m8x16, pointer: *const i8) -> i8x16 { // x86-avx512-NOT: vpsllw // x86-avx512: vpmovb2m k1, xmm0 // x86-avx512-NEXT: vmovdqu8 xmm0 {k1} {z}, xmmword ptr [rdi] - simd_masked_load(mask, pointer, i8x16([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])) + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + mask, + pointer, + i8x16([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + ) } // CHECK-LABEL: load_f32x8 @@ -68,7 +72,29 @@ pub unsafe extern "C" fn load_f32x8(mask: m32x8, pointer: *const f32) -> f32x8 { // x86-avx512-NOT: vpslld // x86-avx512: vpmovd2m k1, ymm0 // x86-avx512-NEXT: vmovups ymm0 {k1} {z}, ymmword ptr [rdi] - simd_masked_load(mask, pointer, f32x8([0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32])) + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + mask, + pointer, + f32x8([0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32]), + ) +} + +// CHECK-LABEL: load_f32x8_aligned +#[no_mangle] +pub unsafe extern "C" fn load_f32x8_aligned(mask: m32x8, pointer: *const f32) -> f32x8 { + // x86-avx2-NOT: vpslld + // x86-avx2: vmaskmovps ymm0, ymm0, ymmword ptr [rdi] + // + // x86-avx512-NOT: vpslld + // x86-avx512: vpmovd2m k1, ymm0 + // x86-avx512-NEXT: vmovaps ymm0 {k1} {z}, ymmword ptr [rdi] + // + // this aligned version should generate `movaps` instead of `movups` + simd_masked_load::<_, _, _, { SimdAlign::Vector }>( + mask, + pointer, + f32x8([0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32]), + ) } // CHECK-LABEL: load_f64x4 @@ -79,5 +105,9 @@ pub unsafe extern "C" fn load_f64x4(mask: m64x4, pointer: *const f64) -> f64x4 { // // x86-avx512-NOT: vpsllq // x86-avx512: vpmovq2m k1, ymm0 - simd_masked_load(mask, pointer, f64x4([0_f64, 0_f64, 0_f64, 0_f64])) + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + mask, + pointer, + f64x4([0_f64, 0_f64, 0_f64, 0_f64]), + ) } diff --git a/tests/assembly-llvm/simd-intrinsic-mask-store.rs b/tests/assembly-llvm/simd-intrinsic-mask-store.rs index b8b76b618231..20154076836d 100644 --- a/tests/assembly-llvm/simd-intrinsic-mask-store.rs +++ b/tests/assembly-llvm/simd-intrinsic-mask-store.rs @@ -9,7 +9,7 @@ //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -Copt-level=3 -C panic=abort -#![feature(no_core, lang_items, repr_simd, intrinsics)] +#![feature(no_core, lang_items, repr_simd, intrinsics, adt_const_params)] #![no_core] #![allow(non_camel_case_types)] @@ -35,7 +35,7 @@ pub struct f64x4([f64; 4]); pub struct m64x4([i64; 4]); #[rustc_intrinsic] -unsafe fn simd_masked_store(mask: M, pointer: P, values: T); +unsafe fn simd_masked_store(mask: M, pointer: P, values: T); // CHECK-LABEL: store_i8x16 #[no_mangle] @@ -54,7 +54,7 @@ pub unsafe extern "C" fn store_i8x16(mask: m8x16, pointer: *mut i8, value: i8x16 // x86-avx512-NOT: vpsllw // x86-avx512: vpmovb2m k1, xmm0 // x86-avx512-NEXT: vmovdqu8 xmmword ptr [rdi] {k1}, xmm1 - simd_masked_store(mask, pointer, value) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, value) } // CHECK-LABEL: store_f32x8 @@ -66,7 +66,21 @@ pub unsafe extern "C" fn store_f32x8(mask: m32x8, pointer: *mut f32, value: f32x // x86-avx512-NOT: vpslld // x86-avx512: vpmovd2m k1, ymm0 // x86-avx512-NEXT: vmovups ymmword ptr [rdi] {k1}, ymm1 - simd_masked_store(mask, pointer, value) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, value) +} + +// CHECK-LABEL: store_f32x8_aligned +#[no_mangle] +pub unsafe extern "C" fn store_f32x8_aligned(mask: m32x8, pointer: *mut f32, value: f32x8) { + // x86-avx2-NOT: vpslld + // x86-avx2: vmaskmovps ymmword ptr [rdi], ymm0, ymm1 + // + // x86-avx512-NOT: vpslld + // x86-avx512: vpmovd2m k1, ymm0 + // x86-avx512-NEXT: vmovaps ymmword ptr [rdi] {k1}, ymm1 + // + // this aligned version should generate `movaps` instead of `movups` + simd_masked_store::<_, _, _, { SimdAlign::Vector }>(mask, pointer, value) } // CHECK-LABEL: store_f64x4 @@ -78,5 +92,5 @@ pub unsafe extern "C" fn store_f64x4(mask: m64x4, pointer: *mut f64, value: f64x // x86-avx512-NOT: vpsllq // x86-avx512: vpmovq2m k1, ymm0 // x86-avx512-NEXT: vmovupd ymmword ptr [rdi] {k1}, ymm1 - simd_masked_store(mask, pointer, value) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, value) } diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 4f4c653cb46e..1ff70bdb9531 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -239,3 +239,17 @@ pub enum c_void { __variant1, __variant2, } + +#[lang = "const_param_ty"] +#[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] +pub trait ConstParamTy_ {} + +pub enum SimdAlign { + // These values must match the compiler's `SimdAlign` defined in + // `rustc_middle/src/ty/consts/int.rs`! + Unaligned = 0, + Element = 1, + Vector = 2, +} + +impl ConstParamTy_ for SimdAlign {} diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index 7df73cb9b4d7..ffe3851c5ad7 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -12,7 +12,7 @@ mod minisimd; use minisimd::*; -use std::intrinsics::simd::simd_masked_load; +use std::intrinsics::simd::{SimdAlign, simd_masked_load}; pub type Vec2 = Simd; pub type Vec4 = Simd; @@ -23,8 +23,45 @@ pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, values: Vec2 // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // ^^^^^ // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) - simd_masked_load(mask, pointer, values) + // ^^^^^^^ + // the align parameter should be equal to the alignment of the element type (assumed to be 4) + simd_masked_load::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) +} + +// CHECK-LABEL: @load_f32x2_aligned +#[no_mangle] +pub unsafe fn load_f32x2_aligned( + mask: Vec2, + pointer: *const f32, + values: Vec2, +) -> Vec2 { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 8, <2 x i1> [[B]], <2 x float> {{.*}}) + // ^^^^^ + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 8 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // ^^^^^^^ + // the align parameter should be equal to the size of the vector + simd_masked_load::<_, _, _, { SimdAlign::Vector }>(mask, pointer, values) +} + +// CHECK-LABEL: @load_f32x2_unaligned +#[no_mangle] +pub unsafe fn load_f32x2_unaligned( + mask: Vec2, + pointer: *const f32, + values: Vec2, +) -> Vec2 { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 1, <2 x i1> [[B]], <2 x float> {{.*}}) + // ^^^^^ + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 1 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // ^^^^^^^ + // the align parameter should be 1 + simd_masked_load::<_, _, _, { SimdAlign::Unaligned }>(mask, pointer, values) } // CHECK-LABEL: @load_f32x2_unsigned @@ -38,7 +75,7 @@ pub unsafe fn load_f32x2_unsigned( // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) - simd_masked_load(mask, pointer, values) + simd_masked_load::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) } // CHECK-LABEL: @load_pf32x4 @@ -52,5 +89,5 @@ pub unsafe fn load_pf32x4( // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> // LLVM21: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) // LLVM22: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr align {{.*}} {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) - simd_masked_load(mask, pointer, values) + simd_masked_load::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 03119d89bacd..efeeceec09d1 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -12,7 +12,7 @@ mod minisimd; use minisimd::*; -use std::intrinsics::simd::simd_masked_store; +use std::intrinsics::simd::{SimdAlign, simd_masked_store}; pub type Vec2 = Simd; pub type Vec4 = Simd; @@ -23,8 +23,37 @@ pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // ^^^^^ // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) - simd_masked_store(mask, pointer, values) + // ^^^^^^^ + // the align parameter should be equal to the alignment of the element type (assumed to be 4) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) +} + +// CHECK-LABEL: @store_f32x2_aligned +#[no_mangle] +pub unsafe fn store_f32x2_aligned(mask: Vec2, pointer: *mut f32, values: Vec2) { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 8, <2 x i1> [[B]]) + // ^^^^^ + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 8 {{.*}}, <2 x i1> [[B]]) + // ^^^^^^^ + // the align parameter should be equal to the size of the vector + simd_masked_store::<_, _, _, { SimdAlign::Vector }>(mask, pointer, values) +} + +// CHECK-LABEL: @store_f32x2_unaligned +#[no_mangle] +pub unsafe fn store_f32x2_unaligned(mask: Vec2, pointer: *mut f32, values: Vec2) { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 1, <2 x i1> [[B]]) + // ^^^^^ + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 1 {{.*}}, <2 x i1> [[B]]) + // ^^^^^^^ + // the align parameter should be 1 + simd_masked_store::<_, _, _, { SimdAlign::Unaligned }>(mask, pointer, values) } // CHECK-LABEL: @store_f32x2_unsigned @@ -34,7 +63,7 @@ pub unsafe fn store_f32x2_unsigned(mask: Vec2, pointer: *mut f32, values: V // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) - simd_masked_store(mask, pointer, values) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) } // CHECK-LABEL: @store_pf32x4 @@ -44,5 +73,5 @@ pub unsafe fn store_pf32x4(mask: Vec4, pointer: *mut *const f32, values: Ve // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> // LLVM21: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) // LLVM22: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr align {{.*}} {{.*}}, <4 x i1> [[B]]) - simd_masked_store(mask, pointer, values) + simd_masked_store::<_, _, _, { SimdAlign::Element }>(mask, pointer, values) } diff --git a/tests/ui/simd/masked-load-store-build-fail.rs b/tests/ui/simd/masked-load-store-build-fail.rs index c711b6dfd977..82866af2c221 100644 --- a/tests/ui/simd/masked-load-store-build-fail.rs +++ b/tests/ui/simd/masked-load-store-build-fail.rs @@ -2,7 +2,7 @@ //@ ignore-backends: gcc #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; +use std::intrinsics::simd::{SimdAlign, simd_masked_load, simd_masked_store}; #[derive(Copy, Clone)] #[repr(simd)] @@ -13,28 +13,60 @@ fn main() { let mut arr = [4u8, 5, 6, 7]; let default = Simd::([9; 4]); - simd_masked_load(Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), arr.as_ptr(), default); - //~^ ERROR expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 + //~v ERROR expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), + arr.as_ptr(), + default, + ); - simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr() as *const i8, default); - //~^ ERROR expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` + //~v ERROR expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, 0, -1, -1]), + arr.as_ptr() as *const i8, + default, + ); - simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); - //~^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` + //~v ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, 0, -1, -1]), + arr.as_ptr(), + Simd::([9; 4]), + ); - simd_masked_load(Simd::([1.0, 0.0, 1.0, 1.0]), arr.as_ptr(), default); - //~^ ERROR expected mask element type to be an integer, found `f32` + //~v ERROR expected mask element type to be an integer, found `f32` + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([1.0, 0.0, 1.0, 1.0]), + arr.as_ptr(), + default, + ); - simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u32; 4])); - //~^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` + //~v ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd([-1i8; 4]), + arr.as_ptr(), + Simd([5u32; 4]), + ); - simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u8; 4])); - //~^ ERROR expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` + //~v ERROR expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd([-1i8; 4]), + arr.as_ptr(), + Simd([5u8; 4]), + ); - simd_masked_store(Simd([-1i8; 4]), arr.as_mut_ptr(), Simd([5u8; 2])); - //~^ ERROR expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 + //~v ERROR expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd([-1i8; 4]), + arr.as_mut_ptr(), + Simd([5u8; 2]), + ); - simd_masked_store(Simd([1f32; 4]), arr.as_mut_ptr(), Simd([5u8; 4])); - //~^ ERROR expected mask element type to be an integer, found `f32` + //~v ERROR expected mask element type to be an integer, found `f32` + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd([1f32; 4]), + arr.as_mut_ptr(), + Simd([5u8; 4]), + ); } } diff --git a/tests/ui/simd/masked-load-store-build-fail.stderr b/tests/ui/simd/masked-load-store-build-fail.stderr index b9158f46ea9a..f2a9ecfb731f 100644 --- a/tests/ui/simd/masked-load-store-build-fail.stderr +++ b/tests/ui/simd/masked-load-store-build-fail.stderr @@ -1,50 +1,82 @@ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 - --> $DIR/masked-load-store-build-fail.rs:16:9 + --> $DIR/masked-load-store-build-fail.rs:17:9 | -LL | simd_masked_load(Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), arr.as_ptr(), default); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / simd_masked_load::<_, _, _, { SimdAlign::Element }>( +LL | | Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), +LL | | arr.as_ptr(), +LL | | default, +LL | | ); + | |_________^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` - --> $DIR/masked-load-store-build-fail.rs:19:9 + --> $DIR/masked-load-store-build-fail.rs:24:9 | -LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr() as *const i8, default); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / simd_masked_load::<_, _, _, { SimdAlign::Element }>( +LL | | Simd::([-1, 0, -1, -1]), +LL | | arr.as_ptr() as *const i8, +LL | | default, +LL | | ); + | |_________^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` - --> $DIR/masked-load-store-build-fail.rs:22:9 - | -LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected mask element type to be an integer, found `f32` - --> $DIR/masked-load-store-build-fail.rs:25:9 - | -LL | simd_masked_load(Simd::([1.0, 0.0, 1.0, 1.0]), arr.as_ptr(), default); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` - --> $DIR/masked-load-store-build-fail.rs:28:9 - | -LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u32; 4])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` --> $DIR/masked-load-store-build-fail.rs:31:9 | -LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u8; 4])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / simd_masked_load::<_, _, _, { SimdAlign::Element }>( +LL | | Simd::([-1, 0, -1, -1]), +LL | | arr.as_ptr(), +LL | | Simd::([9; 4]), +LL | | ); + | |_________^ + +error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected mask element type to be an integer, found `f32` + --> $DIR/masked-load-store-build-fail.rs:38:9 + | +LL | / simd_masked_load::<_, _, _, { SimdAlign::Element }>( +LL | | Simd::([1.0, 0.0, 1.0, 1.0]), +LL | | arr.as_ptr(), +LL | | default, +LL | | ); + | |_________^ + +error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` + --> $DIR/masked-load-store-build-fail.rs:45:9 + | +LL | / simd_masked_store::<_, _, _, { SimdAlign::Element }>( +LL | | Simd([-1i8; 4]), +LL | | arr.as_ptr(), +LL | | Simd([5u32; 4]), +LL | | ); + | |_________^ + +error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` + --> $DIR/masked-load-store-build-fail.rs:52:9 + | +LL | / simd_masked_store::<_, _, _, { SimdAlign::Element }>( +LL | | Simd([-1i8; 4]), +LL | | arr.as_ptr(), +LL | | Simd([5u8; 4]), +LL | | ); + | |_________^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 - --> $DIR/masked-load-store-build-fail.rs:34:9 + --> $DIR/masked-load-store-build-fail.rs:59:9 | -LL | simd_masked_store(Simd([-1i8; 4]), arr.as_mut_ptr(), Simd([5u8; 2])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / simd_masked_store::<_, _, _, { SimdAlign::Element }>( +LL | | Simd([-1i8; 4]), +LL | | arr.as_mut_ptr(), +LL | | Simd([5u8; 2]), +LL | | ); + | |_________^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected mask element type to be an integer, found `f32` - --> $DIR/masked-load-store-build-fail.rs:37:9 + --> $DIR/masked-load-store-build-fail.rs:66:9 | -LL | simd_masked_store(Simd([1f32; 4]), arr.as_mut_ptr(), Simd([5u8; 4])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / simd_masked_store::<_, _, _, { SimdAlign::Element }>( +LL | | Simd([1f32; 4]), +LL | | arr.as_mut_ptr(), +LL | | Simd([5u8; 4]), +LL | | ); + | |_________^ error: aborting due to 8 previous errors diff --git a/tests/ui/simd/masked-load-store-check-fail.rs b/tests/ui/simd/masked-load-store-check-fail.rs index 3ed47cd9ed40..bd6448a589a4 100644 --- a/tests/ui/simd/masked-load-store-check-fail.rs +++ b/tests/ui/simd/masked-load-store-check-fail.rs @@ -1,7 +1,7 @@ //@ check-fail #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; +use std::intrinsics::simd::{SimdAlign, simd_masked_load, simd_masked_store}; #[derive(Copy, Clone)] #[repr(simd)] @@ -12,11 +12,18 @@ fn main() { let mut arr = [4u8, 5, 6, 7]; let default = Simd::([9; 4]); - let _x: Simd = - simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); - //~^ ERROR mismatched types + let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, 0, -1, -1]), + arr.as_ptr(), + Simd::([9; 4]), + ); + //~^^ ERROR mismatched types - let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); - //~^ ERROR mismatched types + let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([1, 0, 1, 1]), + arr.as_ptr(), + default, + ); + //~^^ ERROR mismatched types } } diff --git a/tests/ui/simd/masked-load-store-check-fail.stderr b/tests/ui/simd/masked-load-store-check-fail.stderr index 1c9f9d246df5..4e63d04a3b15 100644 --- a/tests/ui/simd/masked-load-store-check-fail.stderr +++ b/tests/ui/simd/masked-load-store-check-fail.stderr @@ -1,36 +1,50 @@ error[E0308]: mismatched types - --> $DIR/masked-load-store-check-fail.rs:16:76 + --> $DIR/masked-load-store-check-fail.rs:18:13 | -LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); - | ---------------- arguments to this function are incorrect ^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` +LL | let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + | --------------------------------------------------- arguments to this function are incorrect +... +LL | Simd::([9; 4]), + | ^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | = note: expected struct `Simd<_, 2>` found struct `Simd<_, 4>` help: the return type of this call is `Simd` due to the type of the argument passed - --> $DIR/masked-load-store-check-fail.rs:16:13 + --> $DIR/masked-load-store-check-fail.rs:15:31 | -LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------^ - | | - | this argument influences the return type of `simd_masked_load` +LL | let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + | _______________________________^ +LL | | Simd::([-1, 0, -1, -1]), +LL | | arr.as_ptr(), +LL | | Simd::([9; 4]), + | | --------------------- this argument influences the return type of `simd_masked_load` +LL | | ); + | |_________^ note: function defined here --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL error[E0308]: mismatched types - --> $DIR/masked-load-store-check-fail.rs:19:92 + --> $DIR/masked-load-store-check-fail.rs:25:13 | -LL | let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); - | ---------------- arguments to this function are incorrect ^^^^^^^ expected `Simd`, found `Simd` +LL | let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + | --------------------------------------------------- arguments to this function are incorrect +... +LL | default, + | ^^^^^^^ expected `Simd`, found `Simd` | = note: expected struct `Simd` found struct `Simd` help: the return type of this call is `Simd` due to the type of the argument passed - --> $DIR/masked-load-store-check-fail.rs:19:32 + --> $DIR/masked-load-store-check-fail.rs:22:32 | -LL | let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^ - | | - | this argument influences the return type of `simd_masked_load` +LL | let _x: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + | ________________________________^ +LL | | Simd::([1, 0, 1, 1]), +LL | | arr.as_ptr(), +LL | | default, + | | ------- this argument influences the return type of `simd_masked_load` +LL | | ); + | |_________^ note: function defined here --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL diff --git a/tests/ui/simd/masked-load-store.rs b/tests/ui/simd/masked-load-store.rs index bc4307fb26d6..f6682ad16725 100644 --- a/tests/ui/simd/masked-load-store.rs +++ b/tests/ui/simd/masked-load-store.rs @@ -6,23 +6,34 @@ mod minisimd; use minisimd::*; -use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; +use std::intrinsics::simd::{SimdAlign, simd_masked_load, simd_masked_store}; fn main() { unsafe { let a = Simd::([0, 1, 2, 3]); let b_src = [4u8, 5, 6, 7]; let b_default = Simd::([9; 4]); - let b: Simd = - simd_masked_load(Simd::([-1, 0, -1, -1]), b_src.as_ptr(), b_default); + let b: Simd = simd_masked_load::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, 0, -1, -1]), + b_src.as_ptr(), + b_default, + ); assert_eq!(b.as_array(), &[4, 9, 6, 7]); let mut output = [u8::MAX; 5]; - simd_masked_store(Simd::([-1, -1, -1, 0]), output.as_mut_ptr(), a); + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd::([-1, -1, -1, 0]), + output.as_mut_ptr(), + a, + ); assert_eq!(&output, &[0, 1, 2, u8::MAX, u8::MAX]); - simd_masked_store(Simd::([0, -1, -1, 0]), output[1..].as_mut_ptr(), b); + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + Simd::([0, -1, -1, 0]), + output[1..].as_mut_ptr(), + b, + ); assert_eq!(&output, &[0, 1, 9, 6, u8::MAX]); } } From ffe6cf6e166cf1512576d4a17df6c51aa0063c24 Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 9 Oct 2025 22:39:48 +0530 Subject: [PATCH 359/525] Add implementation of the alignment parameter in Miri --- .../src/interpret/intrinsics/simd.rs | 56 +++++++++++++++++-- .../simd_masked_load_element_misaligned.rs | 17 ++++++ ...simd_masked_load_element_misaligned.stderr | 18 ++++++ .../simd_masked_load_vector_misaligned.rs | 17 ++++++ .../simd_masked_load_vector_misaligned.stderr | 18 ++++++ .../simd_masked_store_element_misaligned.rs | 17 ++++++ ...imd_masked_store_element_misaligned.stderr | 18 ++++++ .../simd_masked_store_vector_misaligned.rs | 17 ++++++ ...simd_masked_store_vector_misaligned.stderr | 18 ++++++ .../tests/pass/intrinsics/portable-simd.rs | 53 ++++++++++++++++++ 10 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.stderr create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.stderr create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.stderr create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.stderr diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index f97bdf627ed9..751674f3f068 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -1,16 +1,16 @@ use either::Either; -use rustc_abi::Endian; +use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; -use rustc_middle::mir::interpret::{InterpErrorKind, UndefinedBehaviorInfo}; -use rustc_middle::ty::FloatTy; +use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; +use rustc_middle::ty::{FloatTy, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; use rustc_span::{Symbol, sym}; use tracing::trace; use super::{ ImmTy, InterpCx, InterpResult, Machine, MinMax, MulAddType, OpTy, PlaceTy, Provenance, Scalar, - Size, interp_ok, throw_ub_format, + Size, TyAndLayout, assert_matches, interp_ok, throw_ub_format, }; use crate::interpret::Writeable; @@ -644,6 +644,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } sym::simd_masked_load => { + let dest_layout = dest.layout; + let (mask, mask_len) = self.project_to_simd(&args[0])?; let ptr = self.read_pointer(&args[1])?; let (default, default_len) = self.project_to_simd(&args[2])?; @@ -652,6 +654,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { assert_eq!(dest_len, mask_len); assert_eq!(dest_len, default_len); + self.check_simd_ptr_alignment( + ptr, + dest_layout, + generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(), + )?; + for i in 0..dest_len { let mask = self.read_immediate(&self.project_index(&mask, i)?)?; let default = self.read_immediate(&self.project_index(&default, i)?)?; @@ -660,7 +670,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let val = if simd_element_to_bool(mask)? { // Size * u64 is implemented as always checked let ptr = ptr.wrapping_offset(dest.layout.size * i, self); - let place = self.ptr_to_mplace(ptr, dest.layout); + // we have already checked the alignment requirements + let place = self.ptr_to_mplace_unaligned(ptr, dest.layout); self.read_immediate(&place)? } else { default @@ -675,6 +686,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { assert_eq!(mask_len, vals_len); + self.check_simd_ptr_alignment( + ptr, + args[2].layout, + generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(), + )?; + for i in 0..vals_len { let mask = self.read_immediate(&self.project_index(&mask, i)?)?; let val = self.read_immediate(&self.project_index(&vals, i)?)?; @@ -682,7 +701,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if simd_element_to_bool(mask)? { // Size * u64 is implemented as always checked let ptr = ptr.wrapping_offset(val.layout.size * i, self); - let place = self.ptr_to_mplace(ptr, val.layout); + // we have already checked the alignment requirements + let place = self.ptr_to_mplace_unaligned(ptr, val.layout); self.write_immediate(*val, &place)? }; } @@ -753,6 +773,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { FloatTy::F128 => self.float_minmax::(left, right, op)?, }) } + + fn check_simd_ptr_alignment( + &self, + ptr: Pointer>, + vector_layout: TyAndLayout<'tcx>, + alignment: SimdAlign, + ) -> InterpResult<'tcx> { + assert_matches!(vector_layout.backend_repr, BackendRepr::SimdVector { .. }); + + let align = match alignment { + ty::SimdAlign::Unaligned => { + // The pointer is supposed to be unaligned, so no check is required. + return interp_ok(()); + } + ty::SimdAlign::Element => { + // Take the alignment of the only field, which is an array and therefore has the same + // alignment as the element type. + vector_layout.field(self, 0).align.abi + } + ty::SimdAlign::Vector => vector_layout.align.abi, + }; + + self.check_ptr_align(ptr, align) + } } fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs new file mode 100644 index 000000000000..3b5e389cf27e --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs @@ -0,0 +1,17 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::*; +use std::simd::*; + +fn main() { + unsafe { + let buf = [0u32; 5]; + //~v ERROR: accessing memory with alignment + simd_masked_load::<_, _, _, { SimdAlign::Element }>( + i32x4::splat(-1), + // This is not i32-aligned + buf.as_ptr().byte_offset(1), + i32x4::splat(0), + ); + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.stderr b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.stderr new file mode 100644 index 000000000000..155097cbc0e8 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required + --> tests/fail/intrinsics/simd_masked_load_element_misaligned.rs:LL:CC + | +LL | / simd_masked_load::<_, _, _, { SimdAlign::Element }>( +LL | | i32x4::splat(-1), +LL | | // This is not i32-aligned +LL | | buf.as_ptr().byte_offset(1), +LL | | i32x4::splat(0), +LL | | ); + | |_________^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.rs b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.rs new file mode 100644 index 000000000000..9b1eeaab8d2f --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.rs @@ -0,0 +1,17 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::*; +use std::simd::*; + +fn main() { + unsafe { + let buf = Simd::::splat(0); + //~v ERROR: accessing memory with alignment + simd_masked_load::<_, _, _, { SimdAlign::Vector }>( + i32x4::splat(-1), + // This is i32-aligned but not i32x4-aligned. + buf.as_array()[1..].as_ptr(), + i32x4::splat(0), + ); + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.stderr b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.stderr new file mode 100644 index 000000000000..8dfd1c1b95da --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_vector_misaligned.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required + --> tests/fail/intrinsics/simd_masked_load_vector_misaligned.rs:LL:CC + | +LL | / simd_masked_load::<_, _, _, { SimdAlign::Vector }>( +LL | | i32x4::splat(-1), +LL | | // This is i32-aligned but not i32x4-aligned. +LL | | buf.as_array()[1..].as_ptr(), +LL | | i32x4::splat(0), +LL | | ); + | |_________^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.rs b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.rs new file mode 100644 index 000000000000..b7e23dd1d3b3 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.rs @@ -0,0 +1,17 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::*; +use std::simd::*; + +fn main() { + unsafe { + let mut buf = [0u32; 5]; + //~v ERROR: accessing memory with alignment + simd_masked_store::<_, _, _, { SimdAlign::Element }>( + i32x4::splat(-1), + // This is not i32-aligned + buf.as_mut_ptr().byte_offset(1), + i32x4::splat(0), + ); + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.stderr b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.stderr new file mode 100644 index 000000000000..7b2ebaaf495c --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_element_misaligned.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required + --> tests/fail/intrinsics/simd_masked_store_element_misaligned.rs:LL:CC + | +LL | / simd_masked_store::<_, _, _, { SimdAlign::Element }>( +LL | | i32x4::splat(-1), +LL | | // This is not i32-aligned +LL | | buf.as_mut_ptr().byte_offset(1), +LL | | i32x4::splat(0), +LL | | ); + | |_________^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.rs b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.rs new file mode 100644 index 000000000000..8982413e57ee --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.rs @@ -0,0 +1,17 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::*; +use std::simd::*; + +fn main() { + unsafe { + let mut buf = Simd::::splat(0); + //~v ERROR: accessing memory with alignment + simd_masked_store::<_, _, _, { SimdAlign::Vector }>( + i32x4::splat(-1), + // This is i32-aligned but not i32x4-aligned. + buf.as_mut_array()[1..].as_mut_ptr(), + i32x4::splat(0), + ); + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.stderr b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.stderr new file mode 100644 index 000000000000..7f34e0dcc0db --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_store_vector_misaligned.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required + --> tests/fail/intrinsics/simd_masked_store_vector_misaligned.rs:LL:CC + | +LL | / simd_masked_store::<_, _, _, { SimdAlign::Vector }>( +LL | | i32x4::splat(-1), +LL | | // This is i32-aligned but not i32x4-aligned. +LL | | buf.as_mut_array()[1..].as_mut_ptr(), +LL | | i32x4::splat(0), +LL | | ); + | |_________^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index faf79fc1a8d1..4ecbe167b525 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -970,6 +970,59 @@ fn simd_masked_loadstore() { ) }; assert_eq!(buf, [2, 3, 4]); + + // we use a purposely misaliged buffer to make sure Miri doesn't error in this case + let buf = [0x03030303_i32; 5]; + let default = i32x4::splat(0); + let mask = i32x4::splat(!0); + let vals = unsafe { + simd_masked_load::<_, _, _, { SimdAlign::Unaligned }>( + mask, + buf.as_ptr().byte_offset(1), // this is guaranteed to be unaligned + default, + ) + }; + assert_eq!(vals, i32x4::splat(0x03030303)); + + let mut buf = [0i32; 5]; + let mask = i32x4::splat(!0); + unsafe { + simd_masked_store::<_, _, _, { SimdAlign::Unaligned }>( + mask, + buf.as_mut_ptr().byte_offset(1), // this is guaranteed to be unaligned + vals, + ) + }; + assert_eq!( + buf, + [ + i32::from_ne_bytes([0, 3, 3, 3]), + 0x03030303, + 0x03030303, + 0x03030303, + i32::from_ne_bytes([3, 0, 0, 0]) + ] + ); + + // `repr(simd)` types like `Simd` have the correct alignment for vectors + let buf = i32x4::splat(3); + let default = i32x4::splat(0); + let mask = i32x4::splat(!0); + let vals = unsafe { + simd_masked_load::<_, _, _, { SimdAlign::Vector }>( + mask, + &raw const buf as *const i32, + default, + ) + }; + assert_eq!(vals, buf); + + let mut buf = i32x4::splat(0); + let mask = i32x4::splat(!0); + unsafe { + simd_masked_store::<_, _, _, { SimdAlign::Vector }>(mask, &raw mut buf as *mut i32, vals) + }; + assert_eq!(buf, vals); } fn simd_ops_non_pow2() { From 21fb8015e60e40b48284a2ccb135d2ce6b27860c Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 10 Oct 2025 20:49:13 +0530 Subject: [PATCH 360/525] Implement the alignment parameter in cg_clif --- .../src/intrinsics/simd.rs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 6281089ee244..ca41381f0abc 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -2,6 +2,7 @@ use cranelift_codegen::ir::immediates::Offset32; use rustc_abi::Endian; +use rustc_middle::ty::SimdAlign; use super::*; use crate::prelude::*; @@ -960,6 +961,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ptr_val = ptr.load_scalar(fx); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..val_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); @@ -972,7 +982,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.switch_to_block(if_enabled); let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; - fx.bcx.ins().store(MemFlags::trusted(), val_lane, ptr_val, Offset32::new(offset)); + fx.bcx.ins().store(memflags, val_lane, ptr_val, Offset32::new(offset)); fx.bcx.ins().jump(next, &[]); fx.bcx.seal_block(next); @@ -996,6 +1006,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..ptr_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx); @@ -1011,7 +1030,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.seal_block(if_disabled); fx.bcx.switch_to_block(if_enabled); - let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0); + let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); From d28c5a51c4350514242291d8a09413c585596481 Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 10 Oct 2025 20:49:13 +0530 Subject: [PATCH 361/525] Implement the alignment parameter in cg_clif --- src/intrinsics/simd.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 6281089ee244..ca41381f0abc 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -2,6 +2,7 @@ use cranelift_codegen::ir::immediates::Offset32; use rustc_abi::Endian; +use rustc_middle::ty::SimdAlign; use super::*; use crate::prelude::*; @@ -960,6 +961,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ptr_val = ptr.load_scalar(fx); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..val_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); @@ -972,7 +982,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.switch_to_block(if_enabled); let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; - fx.bcx.ins().store(MemFlags::trusted(), val_lane, ptr_val, Offset32::new(offset)); + fx.bcx.ins().store(memflags, val_lane, ptr_val, Offset32::new(offset)); fx.bcx.ins().jump(next, &[]); fx.bcx.seal_block(next); @@ -996,6 +1006,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..ptr_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx); @@ -1011,7 +1030,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.seal_block(if_disabled); fx.bcx.switch_to_block(if_enabled); - let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0); + let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); From ec7c884a03df160ff1ad4bc8bf2d3448b0e2d13e Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Mon, 3 Nov 2025 22:43:31 +0100 Subject: [PATCH 362/525] Use Github URL to fetch GenMC This commit also modifies MiriInterface.hpp so that it is compatible with GenMC's API. --- src/tools/miri/genmc-sys/build.rs | 4 ++-- src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/genmc-sys/build.rs b/src/tools/miri/genmc-sys/build.rs index f10e151a3d0b..1b4e064d1ba2 100644 --- a/src/tools/miri/genmc-sys/build.rs +++ b/src/tools/miri/genmc-sys/build.rs @@ -26,9 +26,9 @@ mod downloading { use super::GENMC_DOWNLOAD_PATH; /// The GenMC repository the we get our commit from. - pub(crate) const GENMC_GITHUB_URL: &str = "https://gitlab.inf.ethz.ch/public-plf/genmc.git"; + pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git"; /// The GenMC commit we depend on. It must be available on the specified GenMC repository. - pub(crate) const GENMC_COMMIT: &str = "ce775ccd7866db820fa12ffca66463087a11dd96"; + pub(crate) const GENMC_COMMIT: &str = "d9527280bb99f1cef64326b1803ffd952e3880df"; /// Ensure that a local GenMC repo is present and set to the correct commit. /// Return the path of the GenMC repo and whether the checked out commit was changed. diff --git a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp index b0bd397ab34b..81644edddbfd 100644 --- a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp @@ -269,7 +269,7 @@ inline GenmcScalar uninit() { inline GenmcScalar from_sval(SVal sval) { return GenmcScalar { .value = sval.get(), - .extra = sval.getExtra(), + .extra = sval.getProvenance(), .is_init = true, }; } From e207006ad37d85b16929b16b843a81874eef7e4a Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Thu, 25 Sep 2025 12:47:36 -0700 Subject: [PATCH 363/525] Add default sanitizers to TargetOptions Some sanitizers are part of a system's ABI, like the shadow call stack on Aarch64 and RISC-V Fuchsia. Typically ABI options have other spellings, but LLVM has, for historical reasons, marked this as a sanitizer instead of an alternate ABI option. As a result, Fuchsia targets may not be compiled against the correct ABI unless this option is set. This hasn't caused correctness problems, since the backend reserves the SCS register, and thus preserves its value. But this is an issue for unwinding, as the SCS will not be an array of PCs describing the call complete call chain, and will have gaps from callers that don't use the correct ABI. In the long term, I'd like to see all the sanitizer configs that all frontends copy from clang moved into llvm's libFrontend, and exposed so that frontend consumers can use a small set of simple APIs to use sanitizers in a consistent way across the LLVM ecosystem, but that work is not yet ready today. --- compiler/rustc_codegen_llvm/src/abi.rs | 2 +- compiler/rustc_codegen_llvm/src/attributes.rs | 10 ++-------- compiler/rustc_codegen_ssa/src/back/link.rs | 8 ++------ compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_metadata/src/creader.rs | 10 +++++----- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_session/src/config/cfg.rs | 2 +- compiler/rustc_session/src/options.rs | 11 ++++++----- compiler/rustc_session/src/session.rs | 10 +++++++--- compiler/rustc_target/src/spec/json.rs | 7 +++++++ compiler/rustc_target/src/spec/mod.rs | 8 ++++++++ .../src/spec/targets/aarch64_unknown_fuchsia.rs | 1 + .../src/spec/targets/riscv64gc_unknown_fuchsia.rs | 1 + 13 files changed, 43 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 3793a1470aad..6b296c3046ef 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -96,7 +96,7 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&' } } } - } else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) { + } else if cx.tcx.sess.sanitizers().contains(SanitizerSet::MEMORY) { // If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects // memory sanitizer's behavior. diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 209b8efa2c3b..8092e9b9512d 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -101,7 +101,7 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>( no_sanitize: SanitizerSet, ) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); - let enabled = tcx.sess.opts.unstable_opts.sanitizer - no_sanitize; + let enabled = tcx.sess.sanitizers() - no_sanitize; if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) { attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx)); } @@ -240,13 +240,7 @@ fn probestack_attr<'ll, 'tcx>(cx: &SimpleCx<'ll>, tcx: TyCtxt<'tcx>) -> Option<& // Currently stack probes seem somewhat incompatible with the address // sanitizer and thread sanitizer. With asan we're already protected from // stack overflow anyway so we don't really need stack probes regardless. - if tcx - .sess - .opts - .unstable_opts - .sanitizer - .intersects(SanitizerSet::ADDRESS | SanitizerSet::THREAD) - { + if tcx.sess.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::THREAD) { return None; } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ea538d3d4698..5219ee1abe88 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1226,7 +1226,7 @@ fn add_sanitizer_libraries( return; } - let sanitizer = sess.opts.unstable_opts.sanitizer; + let sanitizer = sess.sanitizers(); if sanitizer.contains(SanitizerSet::ADDRESS) { link_sanitizer_runtime(sess, flavor, linker, "asan"); } @@ -2496,11 +2496,7 @@ fn add_order_independent_options( && crate_type == CrateType::Executable && !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _)) { - let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) { - "asan/" - } else { - "" - }; + let prefix = if sess.sanitizers().contains(SanitizerSet::ADDRESS) { "asan/" } else { "" }; cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1")); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 368a2e307bb2..c1e80e08a0eb 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -176,7 +176,7 @@ impl ModuleConfig { debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling, instrument_coverage: if_regular!(sess.instrument_coverage(), false), - sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()), + sanitizer: if_regular!(sess.sanitizers(), SanitizerSet::empty()), sanitizer_dataflow_abilist: if_regular!( sess.opts.unstable_opts.sanitizer_dataflow_abilist.clone(), Vec::new() diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 62de18072902..4e2e1e21ec6d 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -412,7 +412,7 @@ impl CStore { match (&left_name_val, &right_name_val) { (Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) { cmp::Ordering::Equal => { - if !l.1.consistent(&tcx.sess.opts, Some(&r.1)) { + if !l.1.consistent(&tcx.sess, Some(&r.1)) { report_diff( &l.0.prefix, &l.0.name, @@ -424,26 +424,26 @@ impl CStore { right_name_val = None; } cmp::Ordering::Greater => { - if !r.1.consistent(&tcx.sess.opts, None) { + if !r.1.consistent(&tcx.sess, None) { report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name)); } right_name_val = None; } cmp::Ordering::Less => { - if !l.1.consistent(&tcx.sess.opts, None) { + if !l.1.consistent(&tcx.sess, None) { report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None); } left_name_val = None; } }, (Some(l), None) => { - if !l.1.consistent(&tcx.sess.opts, None) { + if !l.1.consistent(&tcx.sess, None) { report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None); } left_name_val = None; } (None, Some(r)) => { - if !r.1.consistent(&tcx.sess.opts, None) { + if !r.1.consistent(&tcx.sess, None) { report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name)); } right_name_val = None; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 15572063d45a..9044cc2737fd 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -71,7 +71,7 @@ pub fn walk_native_lib_search_dirs( || sess.target.os == "linux" || sess.target.os == "fuchsia" || sess.target.is_like_aix - || sess.target.is_like_darwin && !sess.opts.unstable_opts.sanitizer.is_empty() + || sess.target.is_like_darwin && !sess.sanitizers().is_empty() { f(&sess.target_tlib_path.dir, false)?; } diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index a72f6201dcea..ddf0dba730cb 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -224,7 +224,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol()); } - for mut s in sess.opts.unstable_opts.sanitizer { + for mut s in sess.sanitizers() { // KASAN is still ASAN under the hood, so it uses the same attribute. if s == SanitizerSet::KERNELADDRESS { s = SanitizerSet::ADDRESS; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b89aec7d22a9..9c2fa2576c8e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -22,7 +22,7 @@ use rustc_target::spec::{ use crate::config::*; use crate::search_paths::SearchPath; use crate::utils::NativeLib; -use crate::{EarlyDiagCtxt, lint}; +use crate::{EarlyDiagCtxt, Session, lint}; macro_rules! insert { ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr) => { @@ -111,12 +111,12 @@ mod target_modifier_consistency_check { lparsed & tmod_sanitizers == rparsed & tmod_sanitizers } pub(super) fn sanitizer_cfi_normalize_integers( - opts: &Options, + sess: &Session, l: &TargetModifier, r: Option<&TargetModifier>, ) -> bool { // For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier - if opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) { + if sess.sanitizers().contains(SanitizerSet::KCFI) { if let Some(r) = r { return l.extend().tech_value == r.extend().tech_value; } else { @@ -133,7 +133,7 @@ impl TargetModifier { } // Custom consistency check for target modifiers (or default `l.tech_value == r.tech_value`) // When other is None, consistency with default value is checked - pub fn consistent(&self, opts: &Options, other: Option<&TargetModifier>) -> bool { + pub fn consistent(&self, sess: &Session, other: Option<&TargetModifier>) -> bool { assert!(other.is_none() || self.opt == other.unwrap().opt); match self.opt { OptionsTargetModifiers::UnstableOptions(unstable) => match unstable { @@ -142,7 +142,7 @@ impl TargetModifier { } UnstableOptionsTargetModifiers::sanitizer_cfi_normalize_integers => { return target_modifier_consistency_check::sanitizer_cfi_normalize_integers( - opts, self, other, + sess, self, other, ); } _ => {} @@ -2575,6 +2575,7 @@ written to standard error output)"), retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], "enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \ target features (default: no)"), + #[rustc_lint_opt_deny_field_access("use `Session::sanitizers()` instead of this field")] sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER], "use a sanitizer"), sanitizer_cfi_canonical_jump_tables: Option = (Some(true), parse_opt_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 522faf1db9ff..e1e20959f902 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -323,7 +323,7 @@ impl Session { } pub fn is_sanitizer_cfi_enabled(&self) -> bool { - self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI) + self.sanitizers().contains(SanitizerSet::CFI) } pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool { @@ -347,7 +347,7 @@ impl Session { } pub fn is_sanitizer_kcfi_enabled(&self) -> bool { - self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) + self.sanitizers().contains(SanitizerSet::KCFI) } pub fn is_split_lto_unit_enabled(&self) -> bool { @@ -527,7 +527,7 @@ impl Session { // AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs. // MemorySanitizer uses lifetimes to detect use of uninitialized stack variables. // HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future. - || self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS) + || self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS) } pub fn diagnostic_width(&self) -> usize { @@ -922,6 +922,10 @@ impl Session { min } } + + pub fn sanitizers(&self) -> SanitizerSet { + return self.opts.unstable_opts.sanitizer | self.target.options.default_sanitizers; + } } // JUSTIFICATION: part of session construction diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index f236be92b3b6..1bcf3ce409d2 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -214,6 +214,11 @@ impl Target { supported_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b); } + if let Some(default_sanitizers) = json.default_sanitizers { + base.default_sanitizers = + default_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b); + } + forward!(generate_arange_section); forward!(supports_stack_protector); forward!(small_data_threshold_support); @@ -392,6 +397,7 @@ impl ToJson for Target { target_option_val!(split_debuginfo); target_option_val!(supported_split_debuginfo); target_option_val!(supported_sanitizers); + target_option_val!(default_sanitizers); target_option_val!(c_enum_min_bits); target_option_val!(generate_arange_section); target_option_val!(supports_stack_protector); @@ -612,6 +618,7 @@ struct TargetSpecJson { split_debuginfo: Option, supported_split_debuginfo: Option>, supported_sanitizers: Option>, + default_sanitizers: Option>, generate_arange_section: Option, supports_stack_protector: Option, small_data_threshold_support: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b49e7fc9cff6..c753089b1d3d 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2327,6 +2327,13 @@ pub struct TargetOptions { /// distributed with the target, the sanitizer should still appear in this list for the target. pub supported_sanitizers: SanitizerSet, + /// The sanitizers that are enabled by default on this target. + /// + /// Note that the support here is at a codegen level. If the machine code with sanitizer + /// enabled can generated on this target, but the necessary supporting libraries are not + /// distributed with the target, the sanitizer should still appear in this list for the target. + pub default_sanitizers: SanitizerSet, + /// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int pub c_enum_min_bits: Option, @@ -2575,6 +2582,7 @@ impl Default for TargetOptions { // `Off` is supported by default, but targets can remove this manually, e.g. Windows. supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), supported_sanitizers: SanitizerSet::empty(), + default_sanitizers: SanitizerSet::empty(), c_enum_min_bits: None, generate_arange_section: true, supports_stack_protector: true, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 8366b6d9bd82..6dbe376d02f8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -12,6 +12,7 @@ pub(crate) fn target() -> Target { | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::SHADOWCALLSTACK; + base.default_sanitizers = SanitizerSet::SHADOWCALLSTACK; base.supports_xray = true; base.add_pre_link_args( diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs index c4466e13d143..28d2b4c54ef9 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs @@ -9,6 +9,7 @@ pub(crate) fn target() -> Target { base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::SHADOWCALLSTACK; + base.default_sanitizers = SanitizerSet::SHADOWCALLSTACK; base.supports_xray = true; Target { From 75835fb8255df8ccfab39ed1d2dec6f28d23d97e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 3 Nov 2025 17:17:14 -0800 Subject: [PATCH 364/525] Repoint Waker::from_fn_ptr from feature request issue to tracking issue --- library/core/src/task/wake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 178717fe42ea..480b3c4577eb 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -588,7 +588,7 @@ impl Waker { /// Constructs a `Waker` from a function pointer. #[inline] #[must_use] - #[unstable(feature = "waker_from_fn_ptr", issue = "146055")] + #[unstable(feature = "waker_from_fn_ptr", issue = "148457")] pub const fn from_fn_ptr(f: fn()) -> Self { // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it // is sound to transmute it back to `fn()`. @@ -905,7 +905,7 @@ impl LocalWaker { /// Constructs a `LocalWaker` from a function pointer. #[inline] #[must_use] - #[unstable(feature = "waker_from_fn_ptr", issue = "146055")] + #[unstable(feature = "waker_from_fn_ptr", issue = "148457")] pub const fn from_fn_ptr(f: fn()) -> Self { // SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it // is sound to transmute it back to `fn()`. From 948bed2f0ca9e3a0ae718303149d8082ed513654 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 3 Nov 2025 21:00:40 +1100 Subject: [PATCH 365/525] Split out a separate `./x test bootstrap-py` step When working on the Rust parts of bootstrap, it's unhelpful for `./x test bootstrap` to also run Python unit tests. --- src/bootstrap/src/core/build_steps/test.rs | 48 ++++++++++++++++------ src/bootstrap/src/core/builder/mod.rs | 1 + 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 57dedcccf98c..b66f965cd555 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3337,6 +3337,42 @@ fn distcheck_rustc_dev(builder: &Builder<'_>, dir: &Path) { builder.remove_dir(dir); } +/// Runs unit tests in `bootstrap_test.py`, which test the Python parts of bootstrap. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) struct BootstrapPy; + +impl Step for BootstrapPy { + type Output = (); + const DEFAULT: bool = true; + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + // Bootstrap tests might not be perfectly self-contained and can depend + // on the environment, so only run them by default in CI, not locally. + // See `test::Bootstrap::should_run`. + let is_ci = run.builder.config.is_running_on_ci; + run.alias("bootstrap-py").default_condition(is_ci) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(BootstrapPy) + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let mut check_bootstrap = command(builder.python()); + check_bootstrap + .args(["-m", "unittest", "bootstrap_test.py"]) + // Forward command-line args after `--` to unittest, for filtering etc. + .args(builder.config.test_args()) + .env("BUILD_DIR", &builder.out) + .env("BUILD_PLATFORM", builder.build.host_target.triple) + .env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc) + .env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo) + .current_dir(builder.src.join("src/bootstrap/")); + check_bootstrap.delay_failure().run(builder); + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Bootstrap; @@ -3353,18 +3389,6 @@ impl Step for Bootstrap { // Some tests require cargo submodule to be present. builder.build.require_submodule("src/tools/cargo", None); - let mut check_bootstrap = command(builder.python()); - check_bootstrap - .args(["-m", "unittest", "bootstrap_test.py"]) - .env("BUILD_DIR", &builder.out) - .env("BUILD_PLATFORM", builder.build.host_target.triple) - .env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc) - .env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo) - .current_dir(builder.src.join("src/bootstrap/")); - // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. - // Use `python -m unittest` manually if you want to pass arguments. - check_bootstrap.delay_failure().run(builder); - let mut cargo = tool::prepare_tool_cargo( builder, build_compiler, diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index c7490c7072bd..43faf92fe6d9 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -869,6 +869,7 @@ impl<'a> Builder<'a> { Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, test::Tidy, + test::BootstrapPy, test::Bootstrap, test::Ui, test::Crashes, From 3e0ea10fa0aaec5a61206f7949656aac5f5af61c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 4 Nov 2025 04:53:50 +0000 Subject: [PATCH 366/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 5f9dd05862d2e4bceb3be1031b6c936e35671501. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0e89b4ab6ac7..036282b12f5d 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c5dabe8cf798123087d094f06417f5a767ca73e8 +5f9dd05862d2e4bceb3be1031b6c936e35671501 From 9e9ea26d64ecf69b1149976b833cd66043fdb535 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 29 Aug 2025 12:44:26 +0800 Subject: [PATCH 367/525] Add ide-assist: convert_range_for_to_while Convert for each range into while loop. ```rust fn foo() { $0for i in 3..7 { foo(i); } } ``` -> ```rust fn foo() { let mut i = 3; while i < 7 { foo(i); i += 1; } } ``` --- .../handlers/convert_range_for_to_while.rs | 254 ++++++++++++++++++ .../crates/ide-assists/src/lib.rs | 2 + .../crates/ide-assists/src/tests/generated.rs | 23 ++ .../crates/syntax/src/ast/make.rs | 2 +- .../src/ast/syntax_factory/constructors.rs | 14 + 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs new file mode 100644 index 000000000000..16f9b4c41120 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs @@ -0,0 +1,254 @@ +use ide_db::assists::AssistId; +use itertools::Itertools; +use syntax::{ + AstNode, T, + algo::previous_non_trivia_token, + ast::{ + self, HasArgList, HasLoopBody, HasName, RangeItem, edit::AstNodeEdit, make, + syntax_factory::SyntaxFactory, + }, + syntax_editor::{Element, Position}, +}; + +use crate::assist_context::{AssistContext, Assists}; + +// Assist: convert_range_for_to_while +// +// Convert for each range into while loop. +// +// ``` +// fn foo() { +// $0for i in 3..7 { +// foo(i); +// } +// } +// ``` +// -> +// ``` +// fn foo() { +// let mut i = 3; +// while i < 7 { +// foo(i); +// i += 1; +// } +// } +// ``` +pub(crate) fn convert_range_for_to_while(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let for_kw = ctx.find_token_syntax_at_offset(T![for])?; + let for_ = ast::ForExpr::cast(for_kw.parent()?)?; + let ast::Pat::IdentPat(pat) = for_.pat()? else { return None }; + let iterable = for_.iterable()?; + let (start, end, step, inclusive) = extract_range(&iterable)?; + let name = pat.name()?; + let body = for_.loop_body()?; + let last = previous_non_trivia_token(body.stmt_list()?.r_curly_token()?)?; + + acc.add( + AssistId::refactor("convert_range_for_to_while"), + "Replace to while or loop", + for_.syntax().text_range(), + |builder| { + let mut edit = builder.make_editor(for_.syntax()); + let make = SyntaxFactory::with_mappings(); + + let indent = for_.indent_level(); + let pat = make.ident_pat(pat.ref_token().is_some(), true, name.clone()); + let let_stmt = make.let_stmt(pat.into(), None, Some(start)); + edit.insert_all( + Position::before(for_.syntax()), + vec![ + let_stmt.syntax().syntax_element(), + make.whitespace(&format!("\n{}", indent)).syntax_element(), + ], + ); + + let mut elements = vec![]; + + let var_expr = make.expr_path(make.ident_path(&name.text())); + let op = ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Less, + strict: !inclusive, + }); + if let Some(end) = end { + elements.extend([ + make.token(T![while]).syntax_element(), + make.whitespace(" ").syntax_element(), + make.expr_bin(var_expr.clone(), op, end).syntax().syntax_element(), + ]); + } else { + elements.push(make.token(T![loop]).syntax_element()); + } + + edit.replace_all( + for_kw.syntax_element()..=iterable.syntax().syntax_element(), + elements, + ); + + let op = ast::BinaryOp::Assignment { op: Some(ast::ArithOp::Add) }; + edit.insert_all( + Position::after(last), + vec![ + make.whitespace(&format!("\n{}", indent + 1)).syntax_element(), + make.expr_bin(var_expr, op, step).syntax().syntax_element(), + make.token(T![;]).syntax_element(), + ], + ); + + edit.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), edit); + }, + ) +} + +fn extract_range(iterable: &ast::Expr) -> Option<(ast::Expr, Option, ast::Expr, bool)> { + Some(match iterable { + ast::Expr::ParenExpr(expr) => extract_range(&expr.expr()?)?, + ast::Expr::RangeExpr(range) => { + let inclusive = range.op_kind()? == ast::RangeOp::Inclusive; + (range.start()?, range.end(), make::expr_literal("1").into(), inclusive) + } + ast::Expr::MethodCallExpr(call) if call.name_ref()?.text() == "step_by" => { + let [step] = call.arg_list()?.args().collect_array()?; + let (start, end, _, inclusive) = extract_range(&call.receiver()?)?; + (start, end, step, inclusive) + } + _ => return None, + }) +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::*; + + #[test] + fn test_convert_range_for_to_while() { + check_assist( + convert_range_for_to_while, + " +fn foo() { + $0for i in 3..7 { + foo(i); + } +} + ", + " +fn foo() { + let mut i = 3; + while i < 7 { + foo(i); + i += 1; + } +} + ", + ); + } + + #[test] + fn test_convert_range_for_to_while_no_end_bound() { + check_assist( + convert_range_for_to_while, + " +fn foo() { + $0for i in 3.. { + foo(i); + } +} + ", + " +fn foo() { + let mut i = 3; + loop { + foo(i); + i += 1; + } +} + ", + ); + } + + #[test] + fn test_convert_range_for_to_while_with_mut_binding() { + check_assist( + convert_range_for_to_while, + " +fn foo() { + $0for mut i in 3..7 { + foo(i); + } +} + ", + " +fn foo() { + let mut i = 3; + while i < 7 { + foo(i); + i += 1; + } +} + ", + ); + } + + #[test] + fn test_convert_range_for_to_while_with_label() { + check_assist( + convert_range_for_to_while, + " +fn foo() { + 'a: $0for mut i in 3..7 { + foo(i); + } +} + ", + " +fn foo() { + let mut i = 3; + 'a: while i < 7 { + foo(i); + i += 1; + } +} + ", + ); + } + + #[test] + fn test_convert_range_for_to_while_step_by() { + check_assist( + convert_range_for_to_while, + " +fn foo() { + $0for mut i in (3..7).step_by(2) { + foo(i); + } +} + ", + " +fn foo() { + let mut i = 3; + while i < 7 { + foo(i); + i += 2; + } +} + ", + ); + } + + #[test] + fn test_convert_range_for_to_while_not_applicable_non_range() { + check_assist_not_applicable( + convert_range_for_to_while, + " +fn foo() { + let ident = 3..7; + $0for mut i in ident { + foo(i); + } +} + ", + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index e9f2d686465e..4b4aa9427955 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -131,6 +131,7 @@ mod handlers { mod convert_match_to_let_else; mod convert_named_struct_to_tuple_struct; mod convert_nested_function_to_closure; + mod convert_range_for_to_while; mod convert_to_guarded_return; mod convert_tuple_return_type_to_struct; mod convert_tuple_struct_to_named_struct; @@ -268,6 +269,7 @@ mod handlers { convert_match_to_let_else::convert_match_to_let_else, convert_named_struct_to_tuple_struct::convert_named_struct_to_tuple_struct, convert_nested_function_to_closure::convert_nested_function_to_closure, + convert_range_for_to_while::convert_range_for_to_while, convert_to_guarded_return::convert_to_guarded_return, convert_tuple_return_type_to_struct::convert_tuple_return_type_to_struct, convert_tuple_struct_to_named_struct::convert_tuple_struct_to_named_struct, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index a99fe8de333d..7f0836abdf3c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -731,6 +731,29 @@ fn main() { ) } +#[test] +fn doctest_convert_range_for_to_while() { + check_doc_test( + "convert_range_for_to_while", + r#####" +fn foo() { + $0for i in 3..7 { + foo(i); + } +} +"#####, + r#####" +fn foo() { + let mut i = 3; + while i < 7 { + foo(i); + i += 1; + } +} +"#####, + ) +} + #[test] fn doctest_convert_to_guarded_return() { check_doc_test( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 051c5835571b..dba39204e32e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -1355,7 +1355,7 @@ pub mod tokens { pub(super) static SOURCE_FILE: LazyLock> = LazyLock::new(|| { SourceFile::parse( - "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] })\n;\n\nunsafe impl A for B where: {}", + "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] }, while loop {} {})\n;\n\nunsafe impl A for B where: {}", Edition::CURRENT, ) }); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 8bf27f967482..969552392180 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -644,6 +644,20 @@ impl SyntaxFactory { ast } + pub fn expr_loop(&self, body: ast::BlockExpr) -> ast::LoopExpr { + let ast::Expr::LoopExpr(ast) = make::expr_loop(body.clone()).clone_for_update() else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(body.syntax().clone(), ast.loop_body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_while_loop(&self, condition: ast::Expr, body: ast::BlockExpr) -> ast::WhileExpr { let ast = make::expr_while_loop(condition.clone(), body.clone()).clone_for_update(); From a925768250c80e4859610978bc138195bad23d99 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 4 Nov 2025 13:26:55 +0800 Subject: [PATCH 368/525] Add dynamic assistant description --- .../ide-assists/src/handlers/convert_range_for_to_while.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs index 16f9b4c41120..68cb76403095 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs @@ -43,9 +43,14 @@ pub(crate) fn convert_range_for_to_while(acc: &mut Assists, ctx: &AssistContext< let body = for_.loop_body()?; let last = previous_non_trivia_token(body.stmt_list()?.r_curly_token()?)?; + let description = if end.is_some() { + "Replace with while expression" + } else { + "Replace with loop expression" + }; acc.add( AssistId::refactor("convert_range_for_to_while"), - "Replace to while or loop", + description, for_.syntax().text_range(), |builder| { let mut edit = builder.make_editor(for_.syntax()); From 459dae5df1f82cbbd51d32357ecc344f9cd06910 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 08:34:42 +0100 Subject: [PATCH 369/525] wasi is too strange of a target, remove it for now --- src/tools/miri/README.md | 1 - src/tools/miri/ci/ci.sh | 1 - src/tools/miri/src/shims/env.rs | 2 +- src/tools/miri/src/shims/foreign_items.rs | 5 - src/tools/miri/src/shims/mod.rs | 1 - src/tools/miri/src/shims/tls.rs | 1 - .../miri/src/shims/wasi/foreign_items.rs | 110 ------------------ src/tools/miri/src/shims/wasi/mod.rs | 1 - 8 files changed, 1 insertion(+), 121 deletions(-) delete mode 100644 src/tools/miri/src/shims/wasi/foreign_items.rs delete mode 100644 src/tools/miri/src/shims/wasi/mod.rs diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 0cbfe0e96a3f..f6c675839e01 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -220,7 +220,6 @@ degree documented below): - `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite. - `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite. - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. - - `wasi`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. - For targets on other operating systems, Miri might fail before even reaching the `main` function. However, even for targets that we do support, the degree of support for accessing platform APIs diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index bcc110f648b9..2d27f0274999 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -153,7 +153,6 @@ case $HOST_TARGET in BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd - TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC hello wasm TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std ;; diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 689cd3a7269c..b9fb9192df4a 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -51,7 +51,7 @@ impl<'tcx> EnvVars<'tcx> { } else if ecx.tcx.sess.target.os == "windows" { EnvVars::Windows(WindowsEnvVars::new(ecx, env_vars)?) } else { - // Used e.g. for wasi + // For "none" targets (i.e., without an OS). EnvVars::Uninit }; ecx.machine.env_vars = env_vars; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 74a1ac729e88..54fe27382efd 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -102,7 +102,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); match this.tcx.sess.target.os.as_ref() { os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os), - "wasi" => shims::wasi::foreign_items::is_dyn_sym(name), "windows" => shims::windows::foreign_items::is_dyn_sym(name), _ => false, } @@ -846,10 +845,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "wasi" => - shims::wasi::foreign_items::EvalContextExt::emulate_foreign_item_inner( - this, link_name, abi, args, dest, - ), "windows" => shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 7f7bc3b1cf72..e51ace2fd907 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -8,7 +8,6 @@ mod math; #[cfg(all(unix, feature = "native-lib"))] mod native_lib; mod unix; -mod wasi; mod windows; mod x86; diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 1200029692dc..9dc829d7a1ee 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -253,7 +253,6 @@ impl<'tcx> TlsDtorsState<'tcx> { } _ => { // No TLS dtor support. - // FIXME: should we do something on wasi? break 'new_state Done; } } diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs deleted file mode 100644 index ffc02dc986f9..000000000000 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ /dev/null @@ -1,110 +0,0 @@ -use rustc_abi::CanonAbi; -use rustc_middle::ty::Ty; -use rustc_span::Symbol; -use rustc_target::callconv::FnAbi; - -use crate::shims::alloc::EvalContextExt as _; -use crate::*; - -pub fn is_dyn_sym(_name: &str) -> bool { - false -} - -impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} -pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn emulate_foreign_item_inner( - &mut self, - link_name: Symbol, - abi: &FnAbi<'tcx, Ty<'tcx>>, - args: &[OpTy<'tcx>], - dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { - let this = self.eval_context_mut(); - match link_name.as_str() { - // Allocation - "posix_memalign" => { - let [memptr, align, size] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.posix_memalign(memptr, align, size)?; - this.write_scalar(result, dest)?; - } - "aligned_alloc" => { - let [align, size] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let res = this.aligned_alloc(align, size)?; - this.write_pointer(res, dest)?; - } - - // Standard input/output - // FIXME: These shims are hacks that just get basic stdout/stderr working. We can't - // constrain them to "std" since std itself uses the wasi crate for this. - "get-stdout" => { - let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?; - this.write_scalar(Scalar::from_i32(1), dest)?; // POSIX FD number for stdout - } - "get-stderr" => { - let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?; - this.write_scalar(Scalar::from_i32(2), dest)?; // POSIX FD number for stderr - } - "[resource-drop]output-stream" => { - let [handle] = - this.check_shim_sig(shim_sig!(extern "C" fn(i32) -> ()), link_name, abi, args)?; - let handle = this.read_scalar(handle)?.to_i32()?; - - if !(handle == 1 || handle == 2) { - throw_unsup_format!("wasm output-stream: unsupported handle"); - } - // We don't actually close these FDs, so this is a NOP. - } - "[method]output-stream.blocking-write-and-flush" => { - let [handle, buf, len, ret_area] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32, *mut _, usize, *mut _) -> ()), - link_name, - abi, - args, - )?; - let handle = this.read_scalar(handle)?.to_i32()?; - let buf = this.read_pointer(buf)?; - let len = this.read_target_usize(len)?; - let ret_area = this.read_pointer(ret_area)?; - - if len > 4096 { - throw_unsup_format!( - "wasm output-stream.blocking-write-and-flush: buffer too big" - ); - } - let len = usize::try_from(len).unwrap(); - let Some(fd) = this.machine.fds.get(handle) else { - throw_unsup_format!( - "wasm output-stream.blocking-write-and-flush: unsupported handle" - ); - }; - fd.write( - this.machine.communicate(), - buf, - len, - this, - callback!( - @capture<'tcx> { - len: usize, - ret_area: Pointer, - } - |this, result: Result| { - if !matches!(result, Ok(l) if l == len) { - throw_unsup_format!("wasm output-stream.blocking-write-and-flush: returning errors is not supported"); - } - // 0 in the first byte of the ret_area indicates success. - let ret = this.ptr_to_mplace(ret_area, this.machine.layouts.u8); - this.write_null(&ret)?; - interp_ok(()) - }), - )?; - } - - _ => return interp_ok(EmulateItemResult::NotSupported), - } - interp_ok(EmulateItemResult::NeedsReturn) - } -} diff --git a/src/tools/miri/src/shims/wasi/mod.rs b/src/tools/miri/src/shims/wasi/mod.rs deleted file mode 100644 index 09c6507b24f8..000000000000 --- a/src/tools/miri/src/shims/wasi/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod foreign_items; From fe6abc79d29f17bcafbecef7c225fd1875f13d30 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 4 Nov 2025 09:58:29 +0200 Subject: [PATCH 370/525] Fix test name --- src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 32ecf1480737..75d32035d099 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2508,7 +2508,7 @@ fn main() { } #[test] -fn foo() { +fn module_inside_block() { check_types( r#" fn foo() { From a47726f10cdd8407c4c0da86f36367955788b6f0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 09:02:27 +0100 Subject: [PATCH 371/525] GenmcScalar: rename extra to provenance --- .../miri/genmc-sys/cpp/include/MiriInterface.hpp | 8 ++++---- src/tools/miri/genmc-sys/src/lib.rs | 11 ++++++----- src/tools/miri/src/concurrency/genmc/helper.rs | 15 ++++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp index 81644edddbfd..3a04edc01368 100644 --- a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp @@ -261,7 +261,7 @@ namespace GenmcScalarExt { inline GenmcScalar uninit() { return GenmcScalar { .value = 0, - .extra = 0, + .provenance = 0, .is_init = false, }; } @@ -269,19 +269,19 @@ inline GenmcScalar uninit() { inline GenmcScalar from_sval(SVal sval) { return GenmcScalar { .value = sval.get(), - .extra = sval.getProvenance(), + .provenance = sval.getProvenance(), .is_init = true, }; } inline SVal to_sval(GenmcScalar scalar) { ERROR_ON(!scalar.is_init, "Cannot convert an uninitialized `GenmcScalar` into an `SVal`\n"); - return SVal(scalar.value, scalar.extra); + return SVal(scalar.value, scalar.provenance); } inline std::optional try_to_sval(GenmcScalar scalar) { if (scalar.is_init) - return { SVal(scalar.value, scalar.extra) }; + return { SVal(scalar.value, scalar.provenance) }; return std::nullopt; } } // namespace GenmcScalarExt diff --git a/src/tools/miri/genmc-sys/src/lib.rs b/src/tools/miri/genmc-sys/src/lib.rs index a34c7f2b3a66..69aeca3ebc72 100644 --- a/src/tools/miri/genmc-sys/src/lib.rs +++ b/src/tools/miri/genmc-sys/src/lib.rs @@ -45,14 +45,14 @@ pub fn create_genmc_driver_handle( } impl GenmcScalar { - pub const UNINIT: Self = Self { value: 0, extra: 0, is_init: false }; + pub const UNINIT: Self = Self { value: 0, provenance: 0, is_init: false }; pub const fn from_u64(value: u64) -> Self { - Self { value, extra: 0, is_init: true } + Self { value, provenance: 0, is_init: true } } pub const fn has_provenance(&self) -> bool { - self.extra != 0 + self.provenance != 0 } } @@ -172,8 +172,9 @@ mod ffi { value: u64, /// This is zero for integer values. For pointers, this encodes the provenance by /// storing the base address of the allocation that this pointer belongs to. - /// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `extra` of the left argument (`left.fetch_add(right, ...)`). - extra: u64, + /// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `provenance` of the left + /// argument (`left.fetch_add(right, ...)`). + provenance: u64, /// Indicates whether this value is initialized. If this is `false`, the other fields do not matter. /// (Ideally we'd use `std::optional` but CXX does not support that.) is_init: bool, diff --git a/src/tools/miri/src/concurrency/genmc/helper.rs b/src/tools/miri/src/concurrency/genmc/helper.rs index b2e4b5aea534..ae16898106d8 100644 --- a/src/tools/miri/src/concurrency/genmc/helper.rs +++ b/src/tools/miri/src/concurrency/genmc/helper.rs @@ -55,7 +55,7 @@ pub fn scalar_to_genmc_scalar<'tcx>( rustc_const_eval::interpret::Scalar::Int(scalar_int) => { // FIXME(genmc): Add u128 support once GenMC supports it. let value: u64 = scalar_int.to_uint(scalar_int.size()).try_into().unwrap(); - GenmcScalar { value, extra: 0, is_init: true } + GenmcScalar { value, provenance: 0, is_init: true } } rustc_const_eval::interpret::Scalar::Ptr(pointer, size) => { // FIXME(genmc,borrow tracking): Borrow tracking information is lost. @@ -69,7 +69,7 @@ pub fn scalar_to_genmc_scalar<'tcx>( let base_addr = ecx.addr_from_alloc_id(alloc_id, None)?; // Add the base_addr alloc_id pair to the map. genmc_ctx.exec_state.genmc_shared_allocs_map.borrow_mut().insert(base_addr, alloc_id); - GenmcScalar { value: addr.bytes(), extra: base_addr, is_init: true } + GenmcScalar { value: addr.bytes(), provenance: base_addr, is_init: true } } }) } @@ -84,16 +84,17 @@ pub fn genmc_scalar_to_scalar<'tcx>( scalar: GenmcScalar, size: Size, ) -> InterpResult<'tcx, Scalar> { - // If `extra` is zero, we have a regular integer. - if scalar.extra == 0 { + // If `provenance` is zero, we have a regular integer. + if scalar.provenance == 0 { // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated. // FIXME(genmc): GenMC should be doing the truncation, not Miri. let (value_scalar_int, _got_truncated) = ScalarInt::truncate_from_uint(scalar.value, size); return interp_ok(Scalar::from(value_scalar_int)); } - // `extra` is non-zero, we have a pointer. - // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same execution (since the reads-from relation is always respected). - let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.extra]; + // `provenance` is non-zero, we have a pointer. + // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same + // execution (since the reads-from relation is always respected). + let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.provenance]; // FIXME(genmc,borrow tracking): Borrow tracking not yet supported. let provenance = machine::Provenance::Concrete { alloc_id, tag: BorTag::default() }; let ptr = interpret::Pointer::new(provenance, Size::from_bytes(scalar.value)); From d81d5f0b7084cc7b131daeff2a33fbe6c6efe0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 4 Nov 2025 10:09:45 +0200 Subject: [PATCH 372/525] Fix test URL --- .../crates/hir-def/src/macro_expansion_tests/mbe/meta_syntax.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/meta_syntax.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/meta_syntax.rs index 9997455432f7..311fdc34260e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/meta_syntax.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/meta_syntax.rs @@ -98,7 +98,7 @@ macro_rules! m2 { () => ( ${invalid()} ) } #[test] fn test_rustc_issue_57597() { - // + // check( r#" macro_rules! m0 { ($($($i:ident)?)+) => {}; } From 7354d3d9c2ce2c1660e24f5257f9d6ace4a08387 Mon Sep 17 00:00:00 2001 From: beetrees Date: Fri, 4 Jul 2025 17:43:45 +0100 Subject: [PATCH 373/525] Add `#[rustc_pass_indirectly_in_non_rustic_abis]` --- compiler/rustc_abi/src/layout/ty.rs | 25 ++++++ compiler/rustc_abi/src/lib.rs | 15 ++-- .../src/attributes/codegen_attrs.rs | 9 ++ compiler/rustc_attr_parsing/src/context.rs | 6 +- compiler/rustc_feature/src/builtin_attrs.rs | 6 ++ .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_middle/src/ty/layout.rs | 7 +- compiler/rustc_middle/src/ty/mod.rs | 8 ++ compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/callconv/aarch64.rs | 4 + compiler/rustc_target/src/callconv/amdgpu.rs | 6 +- compiler/rustc_target/src/callconv/arm.rs | 4 + compiler/rustc_target/src/callconv/avr.rs | 18 +++- compiler/rustc_target/src/callconv/bpf.rs | 18 +++- compiler/rustc_target/src/callconv/csky.rs | 18 +++- compiler/rustc_target/src/callconv/hexagon.rs | 18 +++- .../rustc_target/src/callconv/loongarch.rs | 5 ++ compiler/rustc_target/src/callconv/m68k.rs | 18 +++- compiler/rustc_target/src/callconv/mips.rs | 17 +++- compiler/rustc_target/src/callconv/mips64.rs | 4 + compiler/rustc_target/src/callconv/mod.rs | 21 +++-- compiler/rustc_target/src/callconv/msp430.rs | 18 +++- compiler/rustc_target/src/callconv/nvptx64.rs | 16 +++- compiler/rustc_target/src/callconv/powerpc.rs | 14 +++- .../rustc_target/src/callconv/powerpc64.rs | 4 + compiler/rustc_target/src/callconv/riscv.rs | 6 ++ compiler/rustc_target/src/callconv/s390x.rs | 4 + compiler/rustc_target/src/callconv/sparc.rs | 14 +++- compiler/rustc_target/src/callconv/sparc64.rs | 4 + compiler/rustc_target/src/callconv/wasm.rs | 4 + compiler/rustc_target/src/callconv/x86.rs | 5 ++ compiler/rustc_target/src/callconv/x86_64.rs | 6 ++ .../rustc_target/src/callconv/x86_win32.rs | 5 ++ .../rustc_target/src/callconv/x86_win64.rs | 11 ++- compiler/rustc_target/src/callconv/xtensa.rs | 26 ++++-- tests/ui/abi/pass-indirectly-attr.rs | 16 ++++ tests/ui/abi/pass-indirectly-attr.stderr | 84 +++++++++++++++++++ tests/ui/attributes/pass-indirectly.rs | 15 ++++ tests/ui/attributes/pass-indirectly.stderr | 10 +++ 41 files changed, 438 insertions(+), 57 deletions(-) create mode 100644 tests/ui/abi/pass-indirectly-attr.rs create mode 100644 tests/ui/abi/pass-indirectly-attr.stderr create mode 100644 tests/ui/attributes/pass-indirectly.rs create mode 100644 tests/ui/attributes/pass-indirectly.stderr diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 8d3c10fd770a..3f80e5d3e9d5 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -172,6 +172,8 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; fn is_unit(this: TyAndLayout<'a, Self>) -> bool; fn is_transparent(this: TyAndLayout<'a, Self>) -> bool; + /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. + fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'a, Self>) -> bool; } impl<'a, Ty> TyAndLayout<'a, Ty> { @@ -269,6 +271,29 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } + /// If this method returns `true`, then this type should always have a `PassMode` of + /// `Indirect { on_stack: false, .. }` when being used as the argument type of a function with a + /// non-Rustic ABI (this is true for structs annotated with the + /// `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute). + /// + /// This is used to replicate some of the behaviour of C array-to-pointer decay; however unlike + /// C any changes the caller makes to the passed value will not be reflected in the callee, so + /// the attribute is only useful for types where observing the value in the caller after the + /// function call isn't allowed (a.k.a. `va_list`). + /// + /// This function handles transparent types automatically. + pub fn pass_indirectly_in_non_rustic_abis(mut self, cx: &C) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + while self.is_transparent() + && let Some((_, field)) = self.non_1zst_field(cx) + { + self = field; + } + Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self) + } + /// Finds the one field that is not a 1-ZST. /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. pub fn non_1zst_field(&self, cx: &C) -> Option<(FieldIdx, Self)> diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index de44c8755a07..05b25da8043a 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -88,14 +88,17 @@ bitflags! { const IS_C = 1 << 0; const IS_SIMD = 1 << 1; const IS_TRANSPARENT = 1 << 2; - // Internal only for now. If true, don't reorder fields. - // On its own it does not prevent ABI optimizations. + /// Internal only for now. If true, don't reorder fields. + /// On its own it does not prevent ABI optimizations. const IS_LINEAR = 1 << 3; - // If true, the type's crate has opted into layout randomization. - // Other flags can still inhibit reordering and thus randomization. - // The seed stored in `ReprOptions.field_shuffle_seed`. + /// If true, the type's crate has opted into layout randomization. + /// Other flags can still inhibit reordering and thus randomization. + /// The seed stored in `ReprOptions.field_shuffle_seed`. const RANDOMIZE_LAYOUT = 1 << 4; - // Any of these flags being set prevent field reordering optimisation. + /// If true, the type is always passed indirectly by non-Rustic ABIs. + /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. + const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS = 1 << 5; + /// Any of these flags being set prevent field reordering optimisation. const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits() | ReprFlags::IS_LINEAR.bits(); diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index f09b02251e4d..1270f8759d1b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -676,3 +676,12 @@ impl SingleAttributeParser for SanitizeParser { Some(AttributeKind::Sanitize { on_set, off_set, span: cx.attr_span }) } } + +pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser; + +impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser { + const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 773527c96a3a..a3473c675dd5 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -20,8 +20,9 @@ use crate::attributes::allow_unstable::{ use crate::attributes::body::CoroutineParser; use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, - NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, SanitizeParser, - TargetFeatureParser, TrackCallerParser, UsedParser, + NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, + RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser, + TrackCallerParser, UsedParser, }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ @@ -243,6 +244,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 2c472801aa04..5dcb5df55720 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -657,6 +657,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-naked-attribute"), WarnFollowing, EncodeCrossCrate::No ), + // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. + rustc_attr!( + rustc_pass_indirectly_in_non_rustic_abis, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::No, + "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic abis." + ), // Limits: ungated!( diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 1bb87673d52d..a5f7debe1787 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -679,6 +679,9 @@ pub enum AttributeKind { /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, + /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` + RustcPassIndirectlyInNonRusticAbis(Span), + /// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`. RustcSimdMonomorphizeLaneLimit(Limit), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 11c54b0ac1da..d59fccb3f1a0 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -91,6 +91,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcMain => No, RustcObjectLifetimeDefault => No, + RustcPassIndirectlyInNonRusticAbis(..) => No, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate Sanitize { .. } => No, ShouldPanic { .. } => No, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index eefb913a33fa..7763507143f4 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -3,7 +3,7 @@ use std::{cmp, fmt}; use rustc_abi::{ AddressSpace, Align, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData, PointeeInfo, - PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, + PointerKind, Primitive, ReprFlags, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, TyAbiInterface, VariantIdx, Variants, }; use rustc_error_messages::DiagMessage; @@ -1173,6 +1173,11 @@ where fn is_transparent(this: TyAndLayout<'tcx>) -> bool { matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent()) } + + /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. + fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'tcx>) -> bool { + matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().flags.contains(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS)) + } } /// Calculates whether a function's ABI can unwind or not. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2b9079da1830..77c5e46e5e4c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1573,6 +1573,14 @@ impl<'tcx> TyCtxt<'tcx> { flags.insert(ReprFlags::IS_LINEAR); } + // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. + if find_attr!( + self.get_all_attrs(did), + AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) + ) { + flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS); + } + ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c214104d6067..0a266f3eb8b9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -284,6 +284,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::DebuggerVisualizer(..) | AttributeKind::RustcMain + | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::PinV2(..), ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 02bae6fec785..86b6bb16835b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1944,6 +1944,7 @@ symbols! { rustc_partition_codegened, rustc_partition_reused, rustc_pass_by_value, + rustc_pass_indirectly_in_non_rustic_abis, rustc_peek, rustc_peek_liveness, rustc_peek_maybe_init, diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs index 5c23e7036b04..b86d0baeb942 100644 --- a/compiler/rustc_target/src/callconv/aarch64.rs +++ b/compiler/rustc_target/src/callconv/aarch64.rs @@ -114,6 +114,10 @@ where // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if !arg.layout.is_aggregate() { if kind == AbiKind::DarwinPCS { // On Darwin, when passing an i8/i16, it must be sign-extended to 32 bits, diff --git a/compiler/rustc_target/src/callconv/amdgpu.rs b/compiler/rustc_target/src/callconv/amdgpu.rs index 3ec6d0b3da20..98ab3ce8eb74 100644 --- a/compiler/rustc_target/src/callconv/amdgpu.rs +++ b/compiler/rustc_target/src/callconv/amdgpu.rs @@ -10,11 +10,15 @@ where ret.extend_integer_width_to(32); } -fn classify_arg<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>) +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } arg.extend_integer_width_to(32); } diff --git a/compiler/rustc_target/src/callconv/arm.rs b/compiler/rustc_target/src/callconv/arm.rs index abc9a404e2ea..4c1ff27aac50 100644 --- a/compiler/rustc_target/src/callconv/arm.rs +++ b/compiler/rustc_target/src/callconv/arm.rs @@ -65,6 +65,10 @@ where // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; diff --git a/compiler/rustc_target/src/callconv/avr.rs b/compiler/rustc_target/src/callconv/avr.rs index 0d690eff68dc..0646d3c8ea1a 100644 --- a/compiler/rustc_target/src/callconv/avr.rs +++ b/compiler/rustc_target/src/callconv/avr.rs @@ -30,6 +30,8 @@ //! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount //! of compiler frontend specific calling convention logic implemented here. +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; fn classify_ret_ty(ret: &mut ArgAbi<'_, Ty>) { @@ -38,13 +40,23 @@ fn classify_ret_ty(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg_ty(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() { arg.make_indirect(); } } -pub(crate) fn compute_abi_info(fty: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } @@ -54,6 +66,6 @@ pub(crate) fn compute_abi_info(fty: &mut FnAbi<'_, Ty>) { continue; } - classify_arg_ty(arg); + classify_arg_ty(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/bpf.rs b/compiler/rustc_target/src/callconv/bpf.rs index ec5c1c2cf686..3624f406704e 100644 --- a/compiler/rustc_target/src/callconv/bpf.rs +++ b/compiler/rustc_target/src/callconv/bpf.rs @@ -1,4 +1,6 @@ // see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFCallingConv.td +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { @@ -9,7 +11,14 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -17,7 +26,10 @@ fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -26,7 +38,7 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/csky.rs b/compiler/rustc_target/src/callconv/csky.rs index cf289e639eac..95741f137fea 100644 --- a/compiler/rustc_target/src/callconv/csky.rs +++ b/compiler/rustc_target/src/callconv/csky.rs @@ -4,6 +4,8 @@ // Reference: Clang CSKY lowering code // https://github.com/llvm/llvm-project/blob/4a074f32a6914f2a8d7215d78758c24942dddc3d/clang/lib/CodeGen/Targets/CSKY.cpp#L76-L162 +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform}; fn classify_ret(arg: &mut ArgAbi<'_, Ty>) { @@ -27,11 +29,18 @@ fn classify_ret(arg: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !arg.layout.is_sized() { // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } // For argument type, the first 4*XLen parts of aggregate will be passed // in registers, and the rest will be passed in stack. // So we can coerce to integers directly and let backend handle it correctly. @@ -47,7 +56,10 @@ fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -56,6 +68,6 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/hexagon.rs b/compiler/rustc_target/src/callconv/hexagon.rs index d4f6dd0a5b4d..e08e6daa7405 100644 --- a/compiler/rustc_target/src/callconv/hexagon.rs +++ b/compiler/rustc_target/src/callconv/hexagon.rs @@ -1,3 +1,5 @@ +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { @@ -8,7 +10,14 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -16,7 +25,10 @@ fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -25,6 +37,6 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index bc3c9601fa3d..bbea841b4106 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -287,6 +287,11 @@ fn classify_arg<'a, Ty, C>( // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + *avail_gprs = (*avail_gprs).saturating_sub(1); + return; + } if !is_vararg { match should_use_fp_conv(cx, &arg.layout, xlen, flen) { Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { diff --git a/compiler/rustc_target/src/callconv/m68k.rs b/compiler/rustc_target/src/callconv/m68k.rs index 0b637e1e27a5..f4668b4afbd2 100644 --- a/compiler/rustc_target/src/callconv/m68k.rs +++ b/compiler/rustc_target/src/callconv/m68k.rs @@ -1,3 +1,5 @@ +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { @@ -8,11 +10,18 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !arg.layout.is_sized() { // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() { arg.pass_by_stack_offset(None); } else { @@ -20,7 +29,10 @@ fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -29,6 +41,6 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/mips.rs b/compiler/rustc_target/src/callconv/mips.rs index 8ffd7bd17784..d2572cc035c1 100644 --- a/compiler/rustc_target/src/callconv/mips.rs +++ b/compiler/rustc_target/src/callconv/mips.rs @@ -1,4 +1,4 @@ -use rustc_abi::{HasDataLayout, Size}; +use rustc_abi::{HasDataLayout, Size, TyAbiInterface}; use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform}; @@ -14,18 +14,26 @@ where } } -fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, offset: &mut Size) where + Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { if !arg.layout.is_sized() { + // FIXME: Update offset? // Not touching this... return; } let dl = cx.data_layout(); - let size = arg.layout.size; let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align); + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + *offset = offset.align_to(align) + dl.pointer_size().align_to(align); + return; + } + + let size = arg.layout.size; if arg.layout.is_aggregate() { let pad_i32 = !offset.is_aligned(align); arg.cast_to_and_pad_i32(Uniform::new(Reg::i32(), size), pad_i32); @@ -36,8 +44,9 @@ where *offset = offset.align_to(align) + size.align_to(align); } -pub(crate) fn compute_abi_info(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where + Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { let mut offset = Size::ZERO; diff --git a/compiler/rustc_target/src/callconv/mips64.rs b/compiler/rustc_target/src/callconv/mips64.rs index 8386a15933c9..313ad6ddce80 100644 --- a/compiler/rustc_target/src/callconv/mips64.rs +++ b/compiler/rustc_target/src/callconv/mips64.rs @@ -82,6 +82,10 @@ where extend_integer_width_mips(arg, 64); return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } let dl = cx.data_layout(); let size = arg.layout.size; diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index a33c246c88c6..a51517338e55 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -677,32 +677,39 @@ impl<'a, Ty> FnAbi<'a, Ty> { } "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), - "avr" => avr::compute_abi_info(self), + "avr" => avr::compute_abi_info(cx, self), "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self), - "m68k" => m68k::compute_abi_info(self), - "csky" => csky::compute_abi_info(self), + "m68k" => m68k::compute_abi_info(cx, self), + "csky" => csky::compute_abi_info(cx, self), "mips" | "mips32r6" => mips::compute_abi_info(cx, self), "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self), "powerpc" => powerpc::compute_abi_info(cx, self), "powerpc64" => powerpc64::compute_abi_info(cx, self), "s390x" => s390x::compute_abi_info(cx, self), - "msp430" => msp430::compute_abi_info(self), + "msp430" => msp430::compute_abi_info(cx, self), "sparc" => sparc::compute_abi_info(cx, self), "sparc64" => sparc64::compute_abi_info(cx, self), "nvptx64" => { if abi == ExternAbi::PtxKernel || abi == ExternAbi::GpuKernel { nvptx64::compute_ptx_kernel_abi_info(cx, self) } else { - nvptx64::compute_abi_info(self) + nvptx64::compute_abi_info(cx, self) } } - "hexagon" => hexagon::compute_abi_info(self), + "hexagon" => hexagon::compute_abi_info(cx, self), "xtensa" => xtensa::compute_abi_info(cx, self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" | "wasm64" => wasm::compute_abi_info(cx, self), - "bpf" => bpf::compute_abi_info(self), + "bpf" => bpf::compute_abi_info(cx, self), arch => panic!("no lowering implemented for {arch}"), } + // Double check that any argument types annotated with the + // `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute are passed indirectly. + for arg in &self.args { + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + assert!(matches!(arg.mode, PassMode::Indirect { on_stack: false, .. })); + } + } } pub fn adjust_for_rust_abi(&mut self, cx: &C) diff --git a/compiler/rustc_target/src/callconv/msp430.rs b/compiler/rustc_target/src/callconv/msp430.rs index 3b53d183ddcd..7d2336346beb 100644 --- a/compiler/rustc_target/src/callconv/msp430.rs +++ b/compiler/rustc_target/src/callconv/msp430.rs @@ -1,6 +1,8 @@ // Reference: MSP430 Embedded Application Binary Interface // https://www.ti.com/lit/an/slaa534a/slaa534a.pdf +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; // 3.5 Structures or Unions Passed and Returned by Reference @@ -17,7 +19,14 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 { arg.make_indirect(); } else { @@ -25,7 +34,10 @@ fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -34,6 +46,6 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/nvptx64.rs b/compiler/rustc_target/src/callconv/nvptx64.rs index dc32dd87a7e7..a19b89c0132f 100644 --- a/compiler/rustc_target/src/callconv/nvptx64.rs +++ b/compiler/rustc_target/src/callconv/nvptx64.rs @@ -11,7 +11,14 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if arg.layout.is_aggregate() && arg.layout.is_sized() { classify_aggregate(arg) } else if arg.layout.size.bits() < 32 && arg.layout.is_sized() { @@ -81,7 +88,10 @@ where } } -pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } @@ -90,7 +100,7 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } diff --git a/compiler/rustc_target/src/callconv/powerpc.rs b/compiler/rustc_target/src/callconv/powerpc.rs index 2f6129626b81..67066672eca3 100644 --- a/compiler/rustc_target/src/callconv/powerpc.rs +++ b/compiler/rustc_target/src/callconv/powerpc.rs @@ -1,3 +1,5 @@ +use rustc_abi::TyAbiInterface; + use crate::callconv::{ArgAbi, FnAbi}; use crate::spec::HasTargetSpec; @@ -9,7 +11,10 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } } -fn classify_arg(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C: HasTargetSpec>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if arg.is_ignore() { // powerpc-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. if cx.target_spec().os == "linux" @@ -20,14 +25,17 @@ fn classify_arg(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) { } return; } - if arg.layout.is_aggregate() { + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) || arg.layout.is_aggregate() { arg.make_indirect(); } else { arg.extend_integer_width_to(32); } } -pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C: HasTargetSpec>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); } diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index be1d13816eff..380b280fbc64 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs @@ -52,6 +52,10 @@ where // Not touching this... return; } + if !is_ret && arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 16de3fe070dd..c4310bf6ccfb 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -290,9 +290,15 @@ fn classify_arg<'a, Ty, C>( Ty: TyAbiInterface<'a, C> + Copy, { if !arg.layout.is_sized() { + // FIXME: Update avail_gprs? // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + *avail_gprs = (*avail_gprs).saturating_sub(1); + return; + } if !is_vararg { match should_use_fp_conv(cx, &arg.layout, xlen, flen) { Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index d2ae404b23b8..c2f2b47690ca 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -37,6 +37,10 @@ where } return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } let size = arg.layout.size; if size.bits() <= 128 { diff --git a/compiler/rustc_target/src/callconv/sparc.rs b/compiler/rustc_target/src/callconv/sparc.rs index 8ffd7bd17784..d424214aa497 100644 --- a/compiler/rustc_target/src/callconv/sparc.rs +++ b/compiler/rustc_target/src/callconv/sparc.rs @@ -1,4 +1,4 @@ -use rustc_abi::{HasDataLayout, Size}; +use rustc_abi::{HasDataLayout, Size, TyAbiInterface}; use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform}; @@ -14,15 +14,22 @@ where } } -fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, offset: &mut Size) where + Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { if !arg.layout.is_sized() { + // FIXME: Update offset? // Not touching this... return; } let dl = cx.data_layout(); + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + *offset += dl.pointer_size(); + return; + } let size = arg.layout.size; let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align); @@ -36,8 +43,9 @@ where *offset = offset.align_to(align) + size.align_to(align); } -pub(crate) fn compute_abi_info(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where + Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { let mut offset = Size::ZERO; diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs index 62c8ed1dc21b..911eaaf08f82 100644 --- a/compiler/rustc_target/src/callconv/sparc64.rs +++ b/compiler/rustc_target/src/callconv/sparc64.rs @@ -140,6 +140,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; diff --git a/compiler/rustc_target/src/callconv/wasm.rs b/compiler/rustc_target/src/callconv/wasm.rs index a308f378ee87..5be8cd5d88f2 100644 --- a/compiler/rustc_target/src/callconv/wasm.rs +++ b/compiler/rustc_target/src/callconv/wasm.rs @@ -52,6 +52,10 @@ where // Not touching this... return; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + return; + } arg.extend_integer_width_to(32); if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { arg.make_indirect(); diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 918b71c80c4f..93dc60dc1593 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -64,6 +64,11 @@ where continue; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + continue; + } + let t = cx.target_spec(); let align_4 = Align::from_bytes(4).unwrap(); let align_16 = Align::from_bytes(16).unwrap(); diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index d8db7ed6e4c0..04eecbfbc8dd 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -183,9 +183,15 @@ where let mut x86_64_arg_or_ret = |arg: &mut ArgAbi<'a, Ty>, is_arg: bool| { if !arg.layout.is_sized() { + // FIXME: Update int_regs? // Not touching this... return; } + if is_arg && arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + int_regs = int_regs.saturating_sub(1); + arg.make_indirect(); + return; + } let mut cls_or_mem = classify_arg(cx, arg); if is_arg { diff --git a/compiler/rustc_target/src/callconv/x86_win32.rs b/compiler/rustc_target/src/callconv/x86_win32.rs index 554a7368848b..824e7cc098a4 100644 --- a/compiler/rustc_target/src/callconv/x86_win32.rs +++ b/compiler/rustc_target/src/callconv/x86_win32.rs @@ -46,6 +46,11 @@ pub(crate) fn compute_abi_info<'a, Ty, C>( continue; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + continue; + } + // FIXME: MSVC 2015+ will pass the first 3 vector arguments in [XYZ]MM0-2 // See https://reviews.llvm.org/D72114 for Clang behavior diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 8f8597ea662a..85ee59eabc7c 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -1,11 +1,14 @@ -use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size}; +use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size, TyAbiInterface}; use crate::callconv::{ArgAbi, FnAbi, Reg}; use crate::spec::{HasTargetSpec, RustcAbi}; // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing -pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info<'a, Ty, C: HasTargetSpec>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| { match a.layout.backend_repr { BackendRepr::Memory { sized: false } => {} @@ -59,6 +62,10 @@ pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<' arg.make_indirect_from_ignore(); continue; } + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + continue; + } fixup(arg, false); } // FIXME: We should likely also do something about ZST return types, similar to above. diff --git a/compiler/rustc_target/src/callconv/xtensa.rs b/compiler/rustc_target/src/callconv/xtensa.rs index 561ee98787de..4dc9fad65063 100644 --- a/compiler/rustc_target/src/callconv/xtensa.rs +++ b/compiler/rustc_target/src/callconv/xtensa.rs @@ -15,7 +15,7 @@ const NUM_RET_GPRS: u64 = 4; const MAX_ARG_IN_REGS_SIZE: u64 = NUM_ARG_GPRS * 32; const MAX_RET_IN_REGS_SIZE: u64 = NUM_RET_GPRS * 32; -fn classify_ret_ty<'a, Ty, C>(arg: &mut ArgAbi<'_, Ty>) +fn classify_ret_ty<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, { @@ -26,7 +26,7 @@ where // The rules for return and argument types are the same, // so defer to `classify_arg_ty`. let mut arg_gprs_left = NUM_RET_GPRS; - classify_arg_ty(arg, &mut arg_gprs_left, MAX_RET_IN_REGS_SIZE); + classify_arg_ty(cx, arg, &mut arg_gprs_left, true); // Ret args cannot be passed via stack, we lower to indirect and let the backend handle the invisible reference match arg.mode { super::PassMode::Indirect { attrs: _, meta_attrs: _, ref mut on_stack } => { @@ -36,12 +36,24 @@ where } } -fn classify_arg_ty<'a, Ty, C>(arg: &mut ArgAbi<'_, Ty>, arg_gprs_left: &mut u64, max_size: u64) -where +fn classify_arg_ty<'a, Ty, C>( + cx: &C, + arg: &mut ArgAbi<'a, Ty>, + arg_gprs_left: &mut u64, + is_ret: bool, +) where Ty: TyAbiInterface<'a, C> + Copy, { assert!(*arg_gprs_left <= NUM_ARG_GPRS, "Arg GPR tracking underflow"); + let max_size = if is_ret { MAX_RET_IN_REGS_SIZE } else { MAX_ARG_IN_REGS_SIZE }; + + if !is_ret && arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + *arg_gprs_left = arg_gprs_left.saturating_sub(1); + arg.make_indirect(); + return; + } + // Ignore empty structs/unions. if arg.layout.is_zst() { return; @@ -95,13 +107,13 @@ where } } -pub(crate) fn compute_abi_info<'a, Ty, C>(_cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { if !fn_abi.ret.is_ignore() { - classify_ret_ty(&mut fn_abi.ret); + classify_ret_ty(cx, &mut fn_abi.ret); } let mut arg_gprs_left = NUM_ARG_GPRS; @@ -110,7 +122,7 @@ where if arg.is_ignore() { continue; } - classify_arg_ty(arg, &mut arg_gprs_left, MAX_ARG_IN_REGS_SIZE); + classify_arg_ty(cx, arg, &mut arg_gprs_left, false); } } diff --git a/tests/ui/abi/pass-indirectly-attr.rs b/tests/ui/abi/pass-indirectly-attr.rs new file mode 100644 index 000000000000..3460abfe1eda --- /dev/null +++ b/tests/ui/abi/pass-indirectly-attr.rs @@ -0,0 +1,16 @@ +//@ check-fail +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" +//@ compile-flags: -O + +#![feature(rustc_attrs)] +#![crate_type = "lib"] + +#[repr(C)] +#[rustc_pass_indirectly_in_non_rustic_abis] +pub struct Type(u8); + +#[rustc_abi(debug)] +pub extern "C" fn func(_: Type) {} +//~^ ERROR fn_abi_of(func) = FnAbi { +//~^^ ERROR mode: Indirect { +//~^^^ ERROR on_stack: false, diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr new file mode 100644 index 000000000000..0f979db5d5ac --- /dev/null +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -0,0 +1,84 @@ +error: fn_abi_of(func) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: Type, + layout: Layout { + size: Size(1 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(1 bytes), + pointee_align: Some( + Align(1 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-indirectly-attr.rs:13:1 + | +LL | pub extern "C" fn func(_: Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/pass-indirectly.rs b/tests/ui/attributes/pass-indirectly.rs new file mode 100644 index 000000000000..0eacffbf01fb --- /dev/null +++ b/tests/ui/attributes/pass-indirectly.rs @@ -0,0 +1,15 @@ +//@ check-fail + +#![feature(rustc_attrs)] +#![crate_type = "lib"] + +#[rustc_pass_indirectly_in_non_rustic_abis] +//~^ ERROR: `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute cannot be used on functions +fn not_a_struct() {} + +#[repr(C)] +#[rustc_pass_indirectly_in_non_rustic_abis] +struct YesAStruct { + foo: u8, + bar: u16, +} diff --git a/tests/ui/attributes/pass-indirectly.stderr b/tests/ui/attributes/pass-indirectly.stderr new file mode 100644 index 000000000000..2011f3d928f6 --- /dev/null +++ b/tests/ui/attributes/pass-indirectly.stderr @@ -0,0 +1,10 @@ +error: `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute cannot be used on functions + --> $DIR/pass-indirectly.rs:6:1 + | +LL | #[rustc_pass_indirectly_in_non_rustic_abis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_pass_indirectly_in_non_rustic_abis]` can only be applied to structs + +error: aborting due to 1 previous error + From 1866b3a8cf0917aa1f08eee7b6d5123823b2a5bc Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 24 Sep 2025 14:09:56 +0200 Subject: [PATCH 374/525] assert that `#[rustc_pass_indirectly_in_non_rustic_abis]` is respected --- compiler/rustc_target/src/callconv/mod.rs | 7 ------- compiler/rustc_ty_utils/src/abi.rs | 7 +++++++ library/core/src/ffi/va_list.rs | 12 ++++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index a51517338e55..5411e8f8176b 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -703,13 +703,6 @@ impl<'a, Ty> FnAbi<'a, Ty> { "bpf" => bpf::compute_abi_info(cx, self), arch => panic!("no lowering implemented for {arch}"), } - // Double check that any argument types annotated with the - // `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute are passed indirectly. - for arg in &self.args { - if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { - assert!(matches!(arg.mode, PassMode::Indirect { on_stack: false, .. })); - } - } } pub fn adjust_for_rust_abi(&mut self, cx: &C) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0f09e548f0e2..f98f161e8093 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,3 +1,4 @@ +use std::assert_matches::assert_matches; use std::iter; use rustc_abi::Primitive::Pointer; @@ -388,6 +389,12 @@ fn fn_abi_sanity_check<'tcx>( if let PassMode::Indirect { on_stack, .. } = arg.mode { assert!(!on_stack, "rust abi shouldn't use on_stack"); } + } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + assert_matches!( + arg.mode, + PassMode::Indirect { on_stack: false, .. }, + "the {spec_abi} ABI does not implement `#[rustc_pass_indirectly_in_non_rustic_abis]`" + ); } match &arg.mode { diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 46ccf330d1c2..3c9587d383e3 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -299,3 +299,15 @@ impl<'f> Drop for VaListImpl<'f> { // This works for now, since `va_end` is a no-op on all current LLVM targets. } } + +// Checks (via an assert in `compiler/rustc_ty_utils/src/abi.rs`) that the C ABI for the current +// target correctly implements `rustc_pass_indirectly_in_non_rustic_abis`. +const _: () = { + #[repr(C)] + #[rustc_pass_indirectly_in_non_rustic_abis] + struct Type(usize); + + const extern "C" fn c(_: Type) {} + + c(Type(0)) +}; From 7be6d6f2e8742cd55a2ce8b6004eb76687c46bee Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 24 Sep 2025 16:29:59 +0200 Subject: [PATCH 375/525] additional tests for `pass_indirectly_in_non_rustic_abis` Also emit an error when `rustc_pass_indirectly_in_non_rustic_abis` is used in combination with `repr(transparent)`. --- compiler/rustc_abi/src/layout/ty.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 11 +++ tests/ui/abi/pass-indirectly-attr.rs | 32 +++++- tests/ui/abi/pass-indirectly-attr.stderr | 120 ++++++++++++++++++++++- 4 files changed, 154 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 3f80e5d3e9d5..ca2753ea2fd9 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -291,6 +291,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { { self = field; } + Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0a266f3eb8b9..5944a1e8da5d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1771,6 +1771,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target: target.to_string(), }); } + // Error on `#[repr(transparent)]` in combination with + // `#[rustc_pass_indirectly_in_non_rustic_abis]` + if is_transparent + && let Some(&pass_indirectly_span) = + find_attr!(attrs, AttributeKind::RustcPassIndirectlyInNonRusticAbis(span) => span) + { + self.dcx().emit_err(errors::TransparentIncompatible { + hint_spans: vec![span, pass_indirectly_span], + target: target.to_string(), + }); + } if is_explicit_rust && (int_reprs > 0 || is_c || is_simd) { let hint_spans = hint_spans.clone().collect(); self.dcx().emit_err(errors::ReprConflicting { hint_spans }); diff --git a/tests/ui/abi/pass-indirectly-attr.rs b/tests/ui/abi/pass-indirectly-attr.rs index 3460abfe1eda..54aafc716587 100644 --- a/tests/ui/abi/pass-indirectly-attr.rs +++ b/tests/ui/abi/pass-indirectly-attr.rs @@ -1,16 +1,38 @@ +//@ add-minicore //@ check-fail //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" -//@ compile-flags: -O +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "lib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; #[repr(C)] #[rustc_pass_indirectly_in_non_rustic_abis] pub struct Type(u8); #[rustc_abi(debug)] -pub extern "C" fn func(_: Type) {} -//~^ ERROR fn_abi_of(func) = FnAbi { -//~^^ ERROR mode: Indirect { -//~^^^ ERROR on_stack: false, +pub extern "C" fn extern_c(_: Type) {} +//~^ ERROR fn_abi_of(extern_c) = FnAbi { +//~| ERROR mode: Indirect +//~| ERROR on_stack: false, +//~| ERROR conv: C, + +#[rustc_abi(debug)] +pub extern "Rust" fn extern_rust(_: Type) {} +//~^ ERROR fn_abi_of(extern_rust) = FnAbi { +//~| ERROR mode: Cast +//~| ERROR conv: Rust + +#[repr(transparent)] +struct Inner(u64); + +#[rustc_pass_indirectly_in_non_rustic_abis] +//~^ ERROR transparent struct cannot have other repr hints +#[repr(transparent)] +struct Wrapper(Inner); diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr index 0f979db5d5ac..a93982dacfa1 100644 --- a/tests/ui/abi/pass-indirectly-attr.stderr +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -1,4 +1,13 @@ -error: fn_abi_of(func) = FnAbi { +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/pass-indirectly-attr.rs:35:1 + | +LL | #[rustc_pass_indirectly_in_non_rustic_abis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | struct Wrapper(Inner); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: fn_abi_of(extern_c) = FnAbi { args: [ ArgAbi { layout: TyAndLayout { @@ -75,10 +84,111 @@ error: fn_abi_of(func) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/pass-indirectly-attr.rs:13:1 + --> $DIR/pass-indirectly-attr.rs:20:1 | -LL | pub extern "C" fn func(_: Type) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub extern "C" fn extern_c(_: Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: fn_abi_of(extern_rust) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: Type, + layout: Layout { + size: Size(1 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Cast { + pad_i32: false, + cast: CastTarget { + prefix: [ + None, + None, + None, + None, + None, + None, + None, + None, + ], + rest_offset: None, + rest: Uniform { + unit: Reg { + kind: Integer, + size: Size(1 bytes), + }, + total: Size(1 bytes), + is_consecutive: false, + }, + attrs: ArgAttributes { + regular: , + arg_ext: None, + pointee_size: Size(0 bytes), + pointee_align: None, + }, + }, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: Rust, + can_unwind: false, + } + --> $DIR/pass-indirectly-attr.rs:27:1 + | +LL | pub extern "Rust" fn extern_rust(_: Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0692`. From add37c0c25f271771c6760720885f8520bc69bc8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Sep 2025 23:08:00 +0200 Subject: [PATCH 376/525] extend some comments and clarify some names around enum tag type computation --- compiler/rustc_abi/src/layout.rs | 2 +- compiler/rustc_abi/src/lib.rs | 5 +++++ compiler/rustc_middle/src/ty/layout.rs | 5 ++++- compiler/rustc_ty_utils/src/layout.rs | 8 ++++---- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 14356813b7bb..b078fc92482f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -812,7 +812,7 @@ impl LayoutCalculator { let (max, min) = largest_niche // We might have no inhabited variants, so pretend there's at least one. .unwrap_or((0, 0)); - let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max); + let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::discr_range_of_repr(tcx, ty, &repr, min, max); let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index de44c8755a07..45c114acf25d 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -183,6 +183,11 @@ impl ReprOptions { /// Returns the discriminant type, given these `repr` options. /// This must only be called on enums! + /// + /// This is the "typeck type" of the discriminant, which is effectively the maximum size: + /// discriminant values will be wrapped to fit (with a lint). Layout can later decide to use a + /// smaller type for the tag that stores the discriminant at runtime and that will work just + /// fine, it just induces casts when getting/setting the discriminant. pub fn discr_type(&self) -> IntegerType { self.int.unwrap_or(IntegerType::Pointer(true)) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index eefb913a33fa..3c73e9daa06e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -72,7 +72,10 @@ impl abi::Integer { /// signed discriminant range and `#[repr]` attribute. /// N.B.: `u128` values above `i128::MAX` will be treated as signed, but /// that shouldn't affect anything, other than maybe debuginfo. - fn repr_discr<'tcx>( + /// + /// This is the basis for computing the type of the *tag* of an enum (which can be smaller than + /// the type of the *discriminant*, which is determined by [`ReprOptions::discr_type`]). + fn discr_range_of_repr<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, repr: &ReprOptions, diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index b3c0953b8e14..3a935b917ea2 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -639,8 +639,8 @@ fn layout_of_uncached<'tcx>( // UnsafeCell and UnsafePinned both disable niche optimizations let is_special_no_niche = def.is_unsafe_cell() || def.is_unsafe_pinned(); - let get_discriminant_type = - |min, max| abi::Integer::repr_discr(tcx, ty, &def.repr(), min, max); + let discr_range_of_repr = + |min, max| abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min, max); let discriminants_iter = || { def.is_enum() @@ -663,7 +663,7 @@ fn layout_of_uncached<'tcx>( def.is_enum(), is_special_no_niche, tcx.layout_scalar_valid_range(def.did()), - get_discriminant_type, + discr_range_of_repr, discriminants_iter(), !maybe_unsized, ) @@ -688,7 +688,7 @@ fn layout_of_uncached<'tcx>( def.is_enum(), is_special_no_niche, tcx.layout_scalar_valid_range(def.did()), - get_discriminant_type, + discr_range_of_repr, discriminants_iter(), !maybe_unsized, ) else { From 8b96fbecb6af782c3ef683eb26c330cc452380f8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Sep 2025 11:08:08 +0200 Subject: [PATCH 377/525] FCW for repr(C) enums whose discriminant values do not fit into a c_int --- .../rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 53 +++++++++++++------ compiler/rustc_lint/src/types.rs | 3 +- compiler/rustc_lint_defs/src/builtin.rs | 48 +++++++++++++++++ compiler/rustc_middle/src/ty/layout.rs | 3 +- .../rustc_ty_utils/src/layout/invariant.rs | 2 + tests/auxiliary/minicore.rs | 22 ++++++++ .../repr-c-big-discriminant1.ptr32.stderr | 19 +++++++ .../repr-c-big-discriminant1.ptr64.stderr | 40 ++++++++++++++ .../repr-c-big-discriminant1.rs | 40 ++++++++++++++ .../repr-c-big-discriminant2.ptr32.stderr | 11 ++++ .../repr-c-big-discriminant2.ptr64.stderr | 18 +++++++ .../repr-c-big-discriminant2.rs | 25 +++++++++ 13 files changed, 266 insertions(+), 20 deletions(-) create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant1.rs create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr create mode 100644 tests/ui/enum-discriminant/repr-c-big-discriminant2.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index cc6598916eec..1e12adbbfc6e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -782,7 +782,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); - crate::collect::lower_enum_variant_types(tcx, def_id.to_def_id()); + crate::collect::lower_enum_variant_types(tcx, def_id); check_enum(tcx, def_id); check_variances_for_type_defn(tcx, def_id); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1386070e3d9b..9409fca0a757 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -19,7 +19,7 @@ use std::cell::Cell; use std::iter; use std::ops::Bound; -use rustc_abi::ExternAbi; +use rustc_abi::{ExternAbi, Size}; use rustc_ast::Recovered; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; @@ -605,7 +605,7 @@ pub(super) fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx.ensure_ok().predicates_of(def_id); } -pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { +pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) { let def = tcx.adt_def(def_id); let repr_type = def.repr().discr_type(); let initial = repr_type.initial_discriminant(tcx); @@ -614,23 +614,44 @@ pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { // fill the discriminant values and field types for variant in def.variants() { let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); - prev_discr = Some( - if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr { - def.eval_explicit_discr(tcx, const_def_id).ok() - } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) { - Some(discr) - } else { + let cur_discr = if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr { + def.eval_explicit_discr(tcx, const_def_id).ok() + } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) { + Some(discr) + } else { + let span = tcx.def_span(variant.def_id); + tcx.dcx().emit_err(errors::EnumDiscriminantOverflowed { + span, + discr: prev_discr.unwrap().to_string(), + item_name: tcx.item_ident(variant.def_id), + wrapped_discr: wrapped_discr.to_string(), + }); + None + } + .unwrap_or(wrapped_discr); + + if def.repr().c() { + // c_int is a signed type, so get a proper signed version of the discriminant + let discr_size = cur_discr.ty.int_size_and_signed(tcx).0; + let discr_val = discr_size.sign_extend(cur_discr.val); + + let c_int = Size::from_bits(tcx.sess.target.c_int_width); + if discr_val < c_int.signed_int_min() || discr_val > c_int.signed_int_max() { let span = tcx.def_span(variant.def_id); - tcx.dcx().emit_err(errors::EnumDiscriminantOverflowed { + tcx.node_span_lint( + rustc_session::lint::builtin::REPR_C_ENUMS_LARGER_THAN_INT, + tcx.local_def_id_to_hir_id(def_id), span, - discr: prev_discr.unwrap().to_string(), - item_name: tcx.item_ident(variant.def_id), - wrapped_discr: wrapped_discr.to_string(), - }); - None + |d| { + d.primary_message("`repr(C)` enum discriminant does not fit into C `int`") + .note("`repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C") + .help("use `repr($int_ty)` instead to explicitly set the size of this enum"); + } + ); } - .unwrap_or(wrapped_discr), - ); + } + + prev_discr = Some(cur_discr); for f in &variant.fields { tcx.ensure_ok().generics_of(f.did); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 8ce74ff76eff..4895e61069e5 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -10,7 +10,7 @@ use rustc_span::{Span, Symbol, sym}; use tracing::debug; use {rustc_ast as ast, rustc_hir as hir}; -mod improper_ctypes; // these filed do the implementation for ImproperCTypesDefinitions,ImproperCTypesDeclarations +mod improper_ctypes; // these files do the implementation for ImproperCTypesDefinitions,ImproperCTypesDeclarations pub(crate) use improper_ctypes::ImproperCTypesLint; use crate::lints::{ @@ -25,7 +25,6 @@ use crate::lints::{ use crate::{LateContext, LateLintPass, LintContext}; mod literal; - use literal::{int_ty_range, lint_literal, uint_ty_range}; declare_lint! { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 8c474ed28240..0cc4502bb73b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -86,6 +86,7 @@ declare_lint_pass! { REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE, RENAMED_AND_REMOVED_LINTS, + REPR_C_ENUMS_LARGER_THAN_INT, REPR_TRANSPARENT_NON_ZST_FIELDS, RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, RUST_2021_INCOMPATIBLE_OR_PATTERNS, @@ -5213,3 +5214,50 @@ declare_lint! { Warn, r#"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"#, } + +declare_lint! { + /// The `repr_c_enums_larger_than_int` lint detects `repr(C)` enums with discriminant + /// values that do not fit into a C `int`. + /// + /// ### Example + /// + /// ```rust,ignore (only errors on 64bit) + /// #[repr(C)] + /// enum E { + /// V = 9223372036854775807, // i64::MAX + /// } + /// ``` + /// + /// This will produce: + /// + /// ```text + /// error: `repr(C)` enum discriminant does not fit into C `int` + /// --> $DIR/repr-c-big-discriminant1.rs:16:5 + /// | + /// LL | A = 9223372036854775807, // i64::MAX + /// | ^ + /// | + /// = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + /// = help: use `repr($int_ty)` instead to explicitly set the size of this enum + /// ``` + /// + /// ### Explanation + /// + /// In C, enums with discriminants that do not fit into an `int` are a portability hazard: such + /// enums are only permitted since C23, and not supported e.g. by MSVC. Furthermore, Rust + /// interprets the discriminant values of `repr(C)` enums as expressions of type `isize`, which + /// cannot be changed in a backwards-compatible way. If the discriminant is given as a literal + /// that does not fit into `isize`, it is wrapped (with a warning). This makes it impossible to + /// implement the C23 behavior of enums where the enum discriminants have no predefined type and + /// instead the enum uses a type large enough to hold all discriminants. + /// + /// Therefore, `repr(C)` enums require all discriminants to fit into a C `int`. + pub REPR_C_ENUMS_LARGER_THAN_INT, + Warn, + "repr(C) enums with discriminant values that do not fit into a C int", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseError, + reference: "issue #124403 ", + report_in_deps: false, + }; +} diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3c73e9daa06e..b0eabb3c122b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -111,7 +111,8 @@ impl abi::Integer { abi::Integer::I8 }; - // Pick the smallest fit. + // Pick the smallest fit. Prefer unsigned; that matches clang in cases where this makes a + // difference (https://godbolt.org/z/h4xEasW1d) so it is crucial for repr(C). if unsigned_fit <= signed_fit { (cmp::max(unsigned_fit, at_least), false) } else { diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index b768269215fa..d1484aed1671 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -14,6 +14,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou if layout.size.bytes() >= tcx.data_layout.obj_size_bound() { bug!("size is too large, in the following layout:\n{layout:#?}"); } + // FIXME(#124403): Once `repr_c_enums_larger_than_int` is a hard error, we could assert + // here that a repr(c) enum discriminant is never larger than a c_int. if !cfg!(debug_assertions) { // Stop here, the rest is kind of expensive. diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 4f4c653cb46e..076474caf558 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -177,6 +177,21 @@ impl Add for isize { } } +#[lang = "neg"] +pub trait Neg { + type Output; + + fn neg(self) -> Self::Output; +} + +impl Neg for isize { + type Output = isize; + + fn neg(self) -> isize { + loop {} // Dummy impl, not actually used + } +} + #[lang = "sync"] trait Sync {} impl_marker_trait!( @@ -231,6 +246,13 @@ pub mod mem { #[rustc_nounwind] #[rustc_intrinsic] pub unsafe fn transmute(src: Src) -> Dst; + + #[rustc_nounwind] + #[rustc_intrinsic] + pub const fn size_of() -> usize; + #[rustc_nounwind] + #[rustc_intrinsic] + pub const fn align_of() -> usize; } #[lang = "c_void"] diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr new file mode 100644 index 000000000000..297380379385 --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr @@ -0,0 +1,19 @@ +error: literal out of range for `isize` + --> $DIR/repr-c-big-discriminant1.rs:16:9 + | +LL | A = 9223372036854775807, // i64::MAX + | ^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `9223372036854775807` does not fit into the type `isize` whose range is `-2147483648..=2147483647` + = note: `#[deny(overflowing_literals)]` on by default + +error: literal out of range for `isize` + --> $DIR/repr-c-big-discriminant1.rs:24:9 + | +LL | A = -2147483649, // i32::MIN-1 + | ^^^^^^^^^^^ + | + = note: the literal `-2147483649` does not fit into the type `isize` whose range is `-2147483648..=2147483647` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr new file mode 100644 index 000000000000..332f3023cfbe --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr @@ -0,0 +1,40 @@ +error: `repr(C)` enum discriminant does not fit into C `int` + --> $DIR/repr-c-big-discriminant1.rs:16:5 + | +LL | A = 9223372036854775807, // i64::MAX + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum +note: the lint level is defined here + --> $DIR/repr-c-big-discriminant1.rs:6:9 + | +LL | #![deny(repr_c_enums_larger_than_int)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `repr(C)` enum discriminant does not fit into C `int` + --> $DIR/repr-c-big-discriminant1.rs:24:5 + | +LL | A = -2147483649, // i32::MIN-1 + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum + +error: `repr(C)` enum discriminant does not fit into C `int` + --> $DIR/repr-c-big-discriminant1.rs:34:5 + | +LL | A = I64_MAX as isize, + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum + +error: aborting due to 3 previous errors + diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs b/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs new file mode 100644 index 000000000000..16d007432a02 --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs @@ -0,0 +1,40 @@ +//@ revisions: ptr32 ptr64 +//@[ptr32] compile-flags: --target i686-unknown-linux-gnu +//@[ptr32] needs-llvm-components: x86 +//@[ptr64] compile-flags: --target x86_64-unknown-linux-gnu +//@[ptr64] needs-llvm-components: x86 +#![deny(repr_c_enums_larger_than_int)] + +//@ add-minicore +#![feature(no_core)] +#![no_core] +extern crate minicore; +use minicore::*; + +#[repr(C)] +enum OverflowingEnum1 { + A = 9223372036854775807, // i64::MAX + //[ptr32]~^ ERROR: literal out of range + //[ptr64]~^^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^^ WARN: previously accepted +} + +#[repr(C)] +enum OverflowingEnum2 { + A = -2147483649, // i32::MIN-1 + //[ptr32]~^ ERROR: literal out of range + //[ptr64]~^^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^^ WARN: previously accepted +} + +const I64_MAX: i64 = 9223372036854775807; + +#[repr(C)] +enum OverflowingEnum3 { + A = I64_MAX as isize, + //[ptr64]~^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^ WARN: previously accepted + // No warning/error on 32bit targets, but the `as isize` hints that wrapping is occurring. +} + +fn main() {} diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr new file mode 100644 index 000000000000..9fbadf3bc39e --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr @@ -0,0 +1,11 @@ +error[E0370]: enum discriminant overflowed + --> $DIR/repr-c-big-discriminant2.rs:19:5 + | +LL | B, // +1 + | ^ overflowed on value after 2147483647 + | + = note: explicitly set `B = -2147483648` if that is desired outcome + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0370`. diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr new file mode 100644 index 000000000000..39c4f39b5707 --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr @@ -0,0 +1,18 @@ +error: `repr(C)` enum discriminant does not fit into C `int` + --> $DIR/repr-c-big-discriminant2.rs:19:5 + | +LL | B, // +1 + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum +note: the lint level is defined here + --> $DIR/repr-c-big-discriminant2.rs:6:9 + | +LL | #![deny(repr_c_enums_larger_than_int)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs b/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs new file mode 100644 index 000000000000..87c9f0bea736 --- /dev/null +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs @@ -0,0 +1,25 @@ +//@ revisions: ptr32 ptr64 +//@[ptr32] compile-flags: --target i686-unknown-linux-gnu +//@[ptr32] needs-llvm-components: x86 +//@[ptr64] compile-flags: --target x86_64-unknown-linux-gnu +//@[ptr64] needs-llvm-components: x86 +#![deny(repr_c_enums_larger_than_int)] + +//@ add-minicore +#![feature(no_core)] +#![no_core] +extern crate minicore; +use minicore::*; + +// Separate test since it suppresses other errors on ptr32 + +#[repr(C)] +enum OverflowingEnum { + A = 2147483647, // i32::MAX + B, // +1 + //[ptr32]~^ ERROR: enum discriminant overflowed + //[ptr64]~^^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^^ WARN: previously accepted +} + +fn main() {} From a92bae0b1ca3beb7862639a1ce4e9dea49a5c4d7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 Oct 2025 09:58:34 +0200 Subject: [PATCH 378/525] do not complain about enums where all discriminants fit into a c_uint --- compiler/rustc_hir_analysis/src/collect.rs | 23 +++++++++-- compiler/rustc_lint_defs/src/builtin.rs | 22 ++++++----- .../ui/enum-discriminant/discriminant_size.rs | 23 +++++++++++ .../repr-c-big-discriminant1.ptr32.stderr | 22 +++++++++-- .../repr-c-big-discriminant1.ptr64.stderr | 38 +++++++++++++++---- .../repr-c-big-discriminant1.rs | 35 +++++++++++++++-- .../repr-c-big-discriminant2.ptr32.stderr | 2 +- .../repr-c-big-discriminant2.ptr64.stderr | 6 +-- .../repr-c-big-discriminant2.rs | 7 +++- 9 files changed, 145 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9409fca0a757..6e62e50d3af8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -610,6 +610,10 @@ pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) { let repr_type = def.repr().discr_type(); let initial = repr_type.initial_discriminant(tcx); let mut prev_discr = None::>; + // Some of the logic below relies on `i128` being able to hold all c_int and c_uint values. + assert!(tcx.sess.target.c_int_width < 128); + let mut min_discr = i128::MAX; + let mut max_discr = i128::MIN; // fill the discriminant values and field types for variant in def.variants() { @@ -631,19 +635,32 @@ pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) { .unwrap_or(wrapped_discr); if def.repr().c() { + let c_int = Size::from_bits(tcx.sess.target.c_int_width); + let c_uint_max = i128::try_from(c_int.unsigned_int_max()).unwrap(); // c_int is a signed type, so get a proper signed version of the discriminant let discr_size = cur_discr.ty.int_size_and_signed(tcx).0; let discr_val = discr_size.sign_extend(cur_discr.val); + min_discr = min_discr.min(discr_val); + max_discr = max_discr.max(discr_val); - let c_int = Size::from_bits(tcx.sess.target.c_int_width); - if discr_val < c_int.signed_int_min() || discr_val > c_int.signed_int_max() { + // The discriminant range must either fit into c_int or c_uint. + if !(min_discr >= c_int.signed_int_min() && max_discr <= c_int.signed_int_max()) + && !(min_discr >= 0 && max_discr <= c_uint_max) + { let span = tcx.def_span(variant.def_id); + let msg = if discr_val < c_int.signed_int_min() || discr_val > c_uint_max { + "`repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int`" + } else if discr_val < 0 { + "`repr(C)` enum discriminant does not fit into C `unsigned int`, and a previous discriminant does not fit into C `int`" + } else { + "`repr(C)` enum discriminant does not fit into C `int`, and a previous discriminant does not fit into C `unsigned int`" + }; tcx.node_span_lint( rustc_session::lint::builtin::REPR_C_ENUMS_LARGER_THAN_INT, tcx.local_def_id_to_hir_id(def_id), span, |d| { - d.primary_message("`repr(C)` enum discriminant does not fit into C `int`") + d.primary_message(msg) .note("`repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C") .help("use `repr($int_ty)` instead to explicitly set the size of this enum"); } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 0cc4502bb73b..86aa6341aff8 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -5217,7 +5217,7 @@ declare_lint! { declare_lint! { /// The `repr_c_enums_larger_than_int` lint detects `repr(C)` enums with discriminant - /// values that do not fit into a C `int`. + /// values that do not fit into a C `int` or `unsigned int`. /// /// ### Example /// @@ -5231,7 +5231,7 @@ declare_lint! { /// This will produce: /// /// ```text - /// error: `repr(C)` enum discriminant does not fit into C `int` + /// error: `repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int` /// --> $DIR/repr-c-big-discriminant1.rs:16:5 /// | /// LL | A = 9223372036854775807, // i64::MAX @@ -5243,15 +5243,17 @@ declare_lint! { /// /// ### Explanation /// - /// In C, enums with discriminants that do not fit into an `int` are a portability hazard: such - /// enums are only permitted since C23, and not supported e.g. by MSVC. Furthermore, Rust - /// interprets the discriminant values of `repr(C)` enums as expressions of type `isize`, which - /// cannot be changed in a backwards-compatible way. If the discriminant is given as a literal - /// that does not fit into `isize`, it is wrapped (with a warning). This makes it impossible to - /// implement the C23 behavior of enums where the enum discriminants have no predefined type and - /// instead the enum uses a type large enough to hold all discriminants. + /// In C, enums with discriminants that do not all fit into an `int` or all fit into an + /// `unsigned int` are a portability hazard: such enums are only permitted since C23, and not + /// supported e.g. by MSVC. /// - /// Therefore, `repr(C)` enums require all discriminants to fit into a C `int`. + /// Furthermore, Rust interprets the discriminant values of `repr(C)` enums as expressions of + /// type `isize`. This makes it impossible to implement the C23 behavior of enums where the enum + /// discriminants have no predefined type and instead the enum uses a type large enough to hold + /// all discriminants. + /// + /// Therefore, `repr(C)` enums in Rust require that either all discriminants to fit into a C + /// `int` or they all fit into an `unsigned int`. pub REPR_C_ENUMS_LARGER_THAN_INT, Warn, "repr(C) enums with discriminant values that do not fit into a C int", diff --git a/tests/ui/enum-discriminant/discriminant_size.rs b/tests/ui/enum-discriminant/discriminant_size.rs index b1feff3c59e1..537940cfb7ee 100644 --- a/tests/ui/enum-discriminant/discriminant_size.rs +++ b/tests/ui/enum-discriminant/discriminant_size.rs @@ -2,6 +2,7 @@ #![feature(core_intrinsics)] use std::intrinsics::discriminant_value; +use std::mem::size_of; enum E1 { A, @@ -20,6 +21,14 @@ enum E3 { B = 100, } +// Enums like this are found in the ecosystem, let's make sure they get the right size. +#[repr(C)] +#[allow(overflowing_literals)] +enum UnsignedIntEnum { + A = 0, + O = 0xffffffff, // doesn't fit into `int`, but fits into `unsigned int` +} + #[repr(i128)] enum E4 { A = 0x1223_3445_5667_7889, @@ -27,24 +36,38 @@ enum E4 { } fn main() { + assert_eq!(size_of::(), 1); let mut target: [isize; 3] = [0, 0, 0]; target[1] = discriminant_value(&E1::A); assert_eq!(target, [0, 0, 0]); target[1] = discriminant_value(&E1::B); assert_eq!(target, [0, 1, 0]); + assert_eq!(size_of::(), 1); let mut target: [i8; 3] = [0, 0, 0]; target[1] = discriminant_value(&E2::A); assert_eq!(target, [0, 7, 0]); target[1] = discriminant_value(&E2::B); assert_eq!(target, [0, -2, 0]); + // E3's size is target-dependent let mut target: [isize; 3] = [0, 0, 0]; target[1] = discriminant_value(&E3::A); assert_eq!(target, [0, 42, 0]); target[1] = discriminant_value(&E3::B); assert_eq!(target, [0, 100, 0]); + #[allow(overflowing_literals)] + { + assert_eq!(size_of::(), 4); + let mut target: [isize; 3] = [0, -1, 0]; + target[1] = discriminant_value(&UnsignedIntEnum::A); + assert_eq!(target, [0, 0, 0]); + target[1] = discriminant_value(&UnsignedIntEnum::O); + assert_eq!(target, [0, 0xffffffff as isize, 0]); + } + + assert_eq!(size_of::(), 16); let mut target: [i128; 3] = [0, 0, 0]; target[1] = discriminant_value(&E4::A); assert_eq!(target, [0, 0x1223_3445_5667_7889, 0]); diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr index 297380379385..db60fd1f7a3c 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr32.stderr @@ -1,5 +1,5 @@ error: literal out of range for `isize` - --> $DIR/repr-c-big-discriminant1.rs:16:9 + --> $DIR/repr-c-big-discriminant1.rs:18:9 | LL | A = 9223372036854775807, // i64::MAX | ^^^^^^^^^^^^^^^^^^^ @@ -8,12 +8,28 @@ LL | A = 9223372036854775807, // i64::MAX = note: `#[deny(overflowing_literals)]` on by default error: literal out of range for `isize` - --> $DIR/repr-c-big-discriminant1.rs:24:9 + --> $DIR/repr-c-big-discriminant1.rs:26:9 | LL | A = -2147483649, // i32::MIN-1 | ^^^^^^^^^^^ | = note: the literal `-2147483649` does not fit into the type `isize` whose range is `-2147483648..=2147483647` -error: aborting due to 2 previous errors +error: literal out of range for `isize` + --> $DIR/repr-c-big-discriminant1.rs:34:9 + | +LL | A = 2147483648, // i32::MAX+1 + | ^^^^^^^^^^ + | + = note: the literal `2147483648` does not fit into the type `isize` whose range is `-2147483648..=2147483647` + +error: literal out of range for `isize` + --> $DIR/repr-c-big-discriminant1.rs:43:9 + | +LL | A = 2147483648, // i32::MAX+1 + | ^^^^^^^^^^ + | + = note: the literal `2147483648` does not fit into the type `isize` whose range is `-2147483648..=2147483647` + +error: aborting due to 4 previous errors diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr index 332f3023cfbe..e2517ab342f4 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.ptr64.stderr @@ -1,5 +1,5 @@ -error: `repr(C)` enum discriminant does not fit into C `int` - --> $DIR/repr-c-big-discriminant1.rs:16:5 +error: `repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int` + --> $DIR/repr-c-big-discriminant1.rs:18:5 | LL | A = 9223372036854775807, // i64::MAX | ^ @@ -9,13 +9,13 @@ LL | A = 9223372036854775807, // i64::MAX = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C = help: use `repr($int_ty)` instead to explicitly set the size of this enum note: the lint level is defined here - --> $DIR/repr-c-big-discriminant1.rs:6:9 + --> $DIR/repr-c-big-discriminant1.rs:8:9 | LL | #![deny(repr_c_enums_larger_than_int)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `repr(C)` enum discriminant does not fit into C `int` - --> $DIR/repr-c-big-discriminant1.rs:24:5 +error: `repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int` + --> $DIR/repr-c-big-discriminant1.rs:26:5 | LL | A = -2147483649, // i32::MIN-1 | ^ @@ -25,8 +25,30 @@ LL | A = -2147483649, // i32::MIN-1 = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C = help: use `repr($int_ty)` instead to explicitly set the size of this enum -error: `repr(C)` enum discriminant does not fit into C `int` - --> $DIR/repr-c-big-discriminant1.rs:34:5 +error: `repr(C)` enum discriminant does not fit into C `unsigned int`, and a previous discriminant does not fit into C `int` + --> $DIR/repr-c-big-discriminant1.rs:36:5 + | +LL | B = -1, + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum + +error: `repr(C)` enum discriminant does not fit into C `int`, and a previous discriminant does not fit into C `unsigned int` + --> $DIR/repr-c-big-discriminant1.rs:43:5 + | +LL | A = 2147483648, // i32::MAX+1 + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124403 + = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C + = help: use `repr($int_ty)` instead to explicitly set the size of this enum + +error: `repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int` + --> $DIR/repr-c-big-discriminant1.rs:53:5 | LL | A = I64_MAX as isize, | ^ @@ -36,5 +58,5 @@ LL | A = I64_MAX as isize, = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C = help: use `repr($int_ty)` instead to explicitly set the size of this enum -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs b/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs index 16d007432a02..739f7cbed14b 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant1.rs @@ -3,6 +3,8 @@ //@[ptr32] needs-llvm-components: x86 //@[ptr64] compile-flags: --target x86_64-unknown-linux-gnu //@[ptr64] needs-llvm-components: x86 +// GCC doesn't like cross-compilation +//@ ignore-backends: gcc #![deny(repr_c_enums_larger_than_int)] //@ add-minicore @@ -15,7 +17,7 @@ use minicore::*; enum OverflowingEnum1 { A = 9223372036854775807, // i64::MAX //[ptr32]~^ ERROR: literal out of range - //[ptr64]~^^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^ ERROR: discriminant does not fit into C `int` nor into C `unsigned int` //[ptr64]~^^^ WARN: previously accepted } @@ -23,18 +25,43 @@ enum OverflowingEnum1 { enum OverflowingEnum2 { A = -2147483649, // i32::MIN-1 //[ptr32]~^ ERROR: literal out of range - //[ptr64]~^^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^^ ERROR: discriminant does not fit into C `int` nor into C `unsigned int` + //[ptr64]~^^^ WARN: previously accepted +} + +#[repr(C)] +enum OverflowingEnum3a { + A = 2147483648, // i32::MAX+1 + //[ptr32]~^ ERROR: literal out of range + B = -1, + //[ptr64]~^ ERROR: discriminant does not fit into C `unsigned int`, and a previous + //[ptr64]~^^ WARN: previously accepted +} +#[repr(C)] +enum OverflowingEnum3b { + B = -1, + A = 2147483648, // i32::MAX+1 + //[ptr32]~^ ERROR: literal out of range + //[ptr64]~^^ ERROR: discriminant does not fit into C `int`, and a previous //[ptr64]~^^^ WARN: previously accepted } const I64_MAX: i64 = 9223372036854775807; #[repr(C)] -enum OverflowingEnum3 { +enum OverflowingEnum4 { A = I64_MAX as isize, - //[ptr64]~^ ERROR: discriminant does not fit into C `int` + //[ptr64]~^ ERROR: discriminant does not fit into C `int` nor into C `unsigned int` //[ptr64]~^^ WARN: previously accepted // No warning/error on 32bit targets, but the `as isize` hints that wrapping is occurring. } +// Enums like this are found in the ecosystem, let's make sure they get accepted. +#[repr(C)] +#[allow(overflowing_literals)] +enum OkayEnum { + A = 0, + O = 0xffffffff, +} + fn main() {} diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr index 9fbadf3bc39e..85aaff46a689 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr32.stderr @@ -1,5 +1,5 @@ error[E0370]: enum discriminant overflowed - --> $DIR/repr-c-big-discriminant2.rs:19:5 + --> $DIR/repr-c-big-discriminant2.rs:24:5 | LL | B, // +1 | ^ overflowed on value after 2147483647 diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr index 39c4f39b5707..8cd978ccb2fb 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.ptr64.stderr @@ -1,5 +1,5 @@ -error: `repr(C)` enum discriminant does not fit into C `int` - --> $DIR/repr-c-big-discriminant2.rs:19:5 +error: `repr(C)` enum discriminant does not fit into C `int`, and a previous discriminant does not fit into C `unsigned int` + --> $DIR/repr-c-big-discriminant2.rs:24:5 | LL | B, // +1 | ^ @@ -9,7 +9,7 @@ LL | B, // +1 = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C = help: use `repr($int_ty)` instead to explicitly set the size of this enum note: the lint level is defined here - --> $DIR/repr-c-big-discriminant2.rs:6:9 + --> $DIR/repr-c-big-discriminant2.rs:8:9 | LL | #![deny(repr_c_enums_larger_than_int)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs b/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs index 87c9f0bea736..8e333b759892 100644 --- a/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs +++ b/tests/ui/enum-discriminant/repr-c-big-discriminant2.rs @@ -3,6 +3,8 @@ //@[ptr32] needs-llvm-components: x86 //@[ptr64] compile-flags: --target x86_64-unknown-linux-gnu //@[ptr64] needs-llvm-components: x86 +// GCC doesn't like cross-compilation +//@ ignore-backends: gcc #![deny(repr_c_enums_larger_than_int)] //@ add-minicore @@ -11,10 +13,13 @@ extern crate minicore; use minicore::*; -// Separate test since it suppresses other errors on ptr32 +// Separate test since it suppresses other errors on ptr32: +// ensure we find the bad discriminant when it is implicitly computed by incrementing +// the previous discriminant. #[repr(C)] enum OverflowingEnum { + NEG = -1, A = 2147483647, // i32::MAX B, // +1 //[ptr32]~^ ERROR: enum discriminant overflowed From 5f312079f2782999e07ff25869e1353082bbe240 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 4 Nov 2025 12:02:58 +0100 Subject: [PATCH 379/525] add logging to `fudge_inference_if_ok` --- compiler/rustc_infer/src/infer/snapshot/fudge.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index e210479581ba..3730d215a901 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::ops::Range; use rustc_data_structures::{snapshot_vec as sv, unify as ut}; @@ -84,11 +85,12 @@ impl<'tcx> InferCtxt<'tcx> { /// the actual types (`?T`, `Option`) -- and remember that /// after the snapshot is popped, the variable `?T` is no longer /// unified. - #[instrument(skip(self, f), level = "debug")] + #[instrument(skip(self, f), level = "debug", ret)] pub fn fudge_inference_if_ok(&self, f: F) -> Result where F: FnOnce() -> Result, T: TypeFoldable>, + E: Debug, { let variable_lengths = self.variable_lengths(); let (snapshot_vars, value) = self.probe(|_| { From acd029484577c064949d537894d9b2265a28cba0 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 17 Oct 2025 12:10:51 +0000 Subject: [PATCH 380/525] btree: cleanup difference, intersection, is_subset --- library/alloc/src/collections/btree/set.rs | 179 +++++++++--------- library/alloctests/Cargo.toml | 2 +- tests/run-make/alloc-no-oom-handling/rmake.rs | 2 +- tests/run-make/alloc-no-rc/rmake.rs | 2 +- tests/run-make/alloc-no-sync/rmake.rs | 2 +- 5 files changed, 90 insertions(+), 97 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 6e6996bcbd69..cb3e14252f8a 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -427,39 +427,35 @@ impl BTreeSet { where T: Ord, { - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return Difference { inner: DifferenceInner::Iterate(self.iter()) }; - }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return Difference { inner: DifferenceInner::Iterate(self.iter()) }; - }; - Difference { - inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { - (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()), - (Equal, _) => { - let mut self_iter = self.iter(); - self_iter.next(); - DifferenceInner::Iterate(self_iter) - } - (_, Equal) => { - let mut self_iter = self.iter(); - self_iter.next_back(); - DifferenceInner::Iterate(self_iter) - } - _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - DifferenceInner::Search { self_iter: self.iter(), other_set: other } - } - _ => DifferenceInner::Stitch { - self_iter: self.iter(), - other_iter: other.iter().peekable(), + if let Some(self_min) = self.first() + && let Some(self_max) = self.last() + && let Some(other_min) = other.first() + && let Some(other_max) = other.last() + { + Difference { + inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { + (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()), + (Equal, _) => { + let mut self_iter = self.iter(); + self_iter.next(); + DifferenceInner::Iterate(self_iter) + } + (_, Equal) => { + let mut self_iter = self.iter(); + self_iter.next_back(); + DifferenceInner::Iterate(self_iter) + } + _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + DifferenceInner::Search { self_iter: self.iter(), other_set: other } + } + _ => DifferenceInner::Stitch { + self_iter: self.iter(), + other_iter: other.iter().peekable(), + }, }, - }, + } + } else { + Difference { inner: DifferenceInner::Iterate(self.iter()) } } } @@ -519,31 +515,27 @@ impl BTreeSet { where T: Ord, { - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return Intersection { inner: IntersectionInner::Answer(None) }; - }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return Intersection { inner: IntersectionInner::Answer(None) }; - }; - Intersection { - inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { - (Greater, _) | (_, Less) => IntersectionInner::Answer(None), - (Equal, _) => IntersectionInner::Answer(Some(self_min)), - (_, Equal) => IntersectionInner::Answer(Some(self_max)), - _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { small_iter: self.iter(), large_set: other } - } - _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { small_iter: other.iter(), large_set: self } - } - _ => IntersectionInner::Stitch { a: self.iter(), b: other.iter() }, - }, + if let Some(self_min) = self.first() + && let Some(self_max) = self.last() + && let Some(other_min) = other.first() + && let Some(other_max) = other.last() + { + Intersection { + inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { + (Greater, _) | (_, Less) => IntersectionInner::Answer(None), + (Equal, _) => IntersectionInner::Answer(Some(self_min)), + (_, Equal) => IntersectionInner::Answer(Some(self_max)), + _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + IntersectionInner::Search { small_iter: self.iter(), large_set: other } + } + _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + IntersectionInner::Search { small_iter: other.iter(), large_set: self } + } + _ => IntersectionInner::Stitch { a: self.iter(), b: other.iter() }, + }, + } + } else { + Intersection { inner: IntersectionInner::Answer(None) } } } @@ -694,55 +686,56 @@ impl BTreeSet { // Same result as self.difference(other).next().is_none() // but the code below is faster (hugely in some cases). if self.len() > other.len() { - return false; + return false; // self has more elements than other } - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return true; // self is empty - }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return false; // other is empty - }; + let (Some(self_min), Some(self_max)) = (self.first(), self.last()) else { + return true; // self is empty + }; + let (Some(other_min), Some(other_max)) = (other.first(), other.last()) else { + return false; // other is empty + }; let mut self_iter = self.iter(); match self_min.cmp(other_min) { - Less => return false, + Less => return false, // other does not contain self_min Equal => { - self_iter.next(); + self_iter.next(); // self_min is contained in other, so remove it from consideration + // other_min is now not in self_iter (used below) } - Greater => (), - } + Greater => {} // other_min is not in self_iter (used below) + }; + match self_max.cmp(other_max) { - Greater => return false, + Greater => return false, // other does not contain self_max Equal => { - self_iter.next_back(); + self_iter.next_back(); // self_max is contained in other, so remove it from consideration + // other_max is now not in self_iter (used below) } - Less => (), - } + Less => {} // other_max is not in self_iter (used below) + }; if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { - for next in self_iter { - if !other.contains(next) { - return false; - } - } + self_iter.all(|e| other.contains(e)) } else { let mut other_iter = other.iter(); - other_iter.next(); - other_iter.next_back(); - let mut self_next = self_iter.next(); - while let Some(self1) = self_next { - match other_iter.next().map_or(Less, |other1| self1.cmp(other1)) { - Less => return false, - Equal => self_next = self_iter.next(), - Greater => (), - } + { + // remove other_min and other_max as they are not in self_iter (see above) + other_iter.next(); + other_iter.next_back(); } + // custom `self_iter.all(|e| other.contains(e))` + self_iter.all(|self1| { + while let Some(other1) = other_iter.next() { + match other1.cmp(self1) { + // happens up to `ITER_PERFORMANCE_TIPPING_SIZE_DIFF * self.len() - 1` times + Less => continue, // skip over elements that are smaller + // happens `self.len()` times + Equal => return true, // self1 is in other + // happens only once + Greater => return false, // self1 is not in other + } + } + false + }) } - true } /// Returns `true` if the set is a superset of another, diff --git a/library/alloctests/Cargo.toml b/library/alloctests/Cargo.toml index 07c45d1b8248..3b522bf80a21 100644 --- a/library/alloctests/Cargo.toml +++ b/library/alloctests/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/rust-lang/rust.git" description = "Tests for the Rust Allocation Library" autotests = false autobenches = false -edition = "2021" +edition = "2024" [lib] path = "lib.rs" diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 89a6636d9a0c..94002eca5736 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index 12171c2148f1..8d8cd4990bc6 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 29f204f30673..a096d3941d46 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) From 0588be09973fc8b6545c8799932d9f5ec8f11eb7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 18:47:40 +0200 Subject: [PATCH 381/525] sembr src/tests/minicore.md --- src/doc/rustc-dev-guide/src/tests/minicore.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/minicore.md b/src/doc/rustc-dev-guide/src/tests/minicore.md index 28570376f7c6..3789b04e7c24 100644 --- a/src/doc/rustc-dev-guide/src/tests/minicore.md +++ b/src/doc/rustc-dev-guide/src/tests/minicore.md @@ -2,15 +2,14 @@ -[`tests/auxiliary/minicore.rs`][`minicore`] is a test auxiliary for -ui/codegen/assembly test suites. It provides `core` stubs for tests that need to +[`tests/auxiliary/minicore.rs`][`minicore`] is a test auxiliary for ui/codegen/assembly test suites. +It provides `core` stubs for tests that need to build for cross-compiled targets but do not need/want to run.
Please note that [`minicore`] is only intended for `core` items, and explicitly -**not** `std` or `alloc` items because `core` items are applicable to a wider -range of tests. +**not** `std` or `alloc` items because `core` items are applicable to a wider range of tests.
@@ -41,8 +40,8 @@ by more than one test. ## Staying in sync with `core` -The `minicore` items must be kept up to date with `core`. For consistent -diagnostic output between using `core` and `minicore`, any `diagnostic` +The `minicore` items must be kept up to date with `core`. +For consistent diagnostic output between using `core` and `minicore`, any `diagnostic` attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`. ## Example codegen test that uses `minicore` From df4d8830bb1c7f63f2afc5a428560c148f718b5e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 18:56:17 +0200 Subject: [PATCH 382/525] date-check src/tests/minicore.md This was updated recently. Also, the annotation was broken, so would not appear in date-check issue. --- src/doc/rustc-dev-guide/src/tests/minicore.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/minicore.md b/src/doc/rustc-dev-guide/src/tests/minicore.md index 3789b04e7c24..5d05c2c1e0a9 100644 --- a/src/doc/rustc-dev-guide/src/tests/minicore.md +++ b/src/doc/rustc-dev-guide/src/tests/minicore.md @@ -1,6 +1,6 @@ # `minicore` test auxiliary: using `core` stubs - + [`tests/auxiliary/minicore.rs`][`minicore`] is a test auxiliary for ui/codegen/assembly test suites. It provides `core` stubs for tests that need to From b150b0eddbc35027d9a2a24bb790473ad5ca6797 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 19:27:48 +0200 Subject: [PATCH 383/525] sembr src/contributing.md --- src/doc/rustc-dev-guide/src/contributing.md | 199 +++++++++++--------- 1 file changed, 109 insertions(+), 90 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 512c6790165c..f74b34438564 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -2,9 +2,9 @@ ## Bug reports -While bugs are unfortunate, they're a reality in software. We can't fix what we -don't know about, so please report liberally. If you're not sure if something -is a bug or not, feel free to file a bug anyway. +While bugs are unfortunate, they're a reality in software. +We can't fix what we don't know about, so please report liberally. +If you're not sure if something is a bug or not, feel free to file a bug anyway. **If you believe reporting your bug publicly represents a security risk to Rust users, please follow our [instructions for reporting security vulnerabilities][vuln]**. @@ -12,16 +12,18 @@ please follow our [instructions for reporting security vulnerabilities][vuln]**. [vuln]: https://www.rust-lang.org/policies/security If you're using the nightly channel, please check if the bug exists in the -latest toolchain before filing your bug. It might be fixed already. +latest toolchain before filing your bug. +It might be fixed already. If you have the chance, before reporting a bug, please [search existing issues], -as it's possible that someone else has already reported your error. This doesn't -always work, and sometimes it's hard to know what to search for, so consider this -extra credit. We won't mind if you accidentally file a duplicate report. +as it's possible that someone else has already reported your error. +This doesn't always work, and sometimes it's hard to know what to search for, so consider this +extra credit. +We won't mind if you accidentally file a duplicate report. Similarly, to help others who encountered the bug find your issue, consider -filing an issue with a descriptive title, which contains information that might -be unique to it. This can be the language or compiler feature used, the +filing an issue with a descriptive title, which contains information that might be unique to it. +This can be the language or compiler feature used, the conditions that trigger the bug, or part of the error message if there is any. An example could be: **"impossible case reached" on lifetime inference for impl Trait in return position**. @@ -31,14 +33,15 @@ in the appropriate provided template. ## Bug fixes or "normal" code changes -For most PRs, no special procedures are needed. You can just [open a PR], and it -will be reviewed, approved, and merged. This includes most bug fixes, -refactorings, and other user-invisible changes. The next few sections talk -about exceptions to this rule. +For most PRs, no special procedures are needed. +You can just [open a PR], and it will be reviewed, approved, and merged. +This includes most bug fixes, refactorings, and other user-invisible changes. +The next few sections talk about exceptions to this rule. Also, note that it is perfectly acceptable to open WIP PRs or GitHub [Draft PRs]. Some people prefer to do this so they can get feedback along the -way or share their code with a collaborator. Others do this so they can utilize +way or share their code with a collaborator. +Others do this so they can utilize the CI to build and test their PR (e.g. when developing on a slow machine). [open a PR]: #pull-requests @@ -46,9 +49,9 @@ the CI to build and test their PR (e.g. when developing on a slow machine). ## New features -Rust has strong backwards-compatibility guarantees. Thus, new features can't -just be implemented directly in stable Rust. Instead, we have 3 release -channels: stable, beta, and nightly. +Rust has strong backwards-compatibility guarantees. +Thus, new features can't just be implemented directly in stable Rust. +Instead, we have 3 release channels: stable, beta, and nightly. - **Stable**: this is the latest stable release for general usage. - **Beta**: this is the next release (will be stable within 6 weeks). @@ -65,35 +68,36 @@ Breaking changes have a [dedicated section][Breaking Changes] in the dev-guide. ### Major changes -The compiler team has a special process for large changes, whether or not they -cause breakage. This process is called a Major Change Proposal (MCP). MCP is a -relatively lightweight mechanism for getting feedback on large changes to the +The compiler team has a special process for large changes, whether or not they cause breakage. +This process is called a Major Change Proposal (MCP). +MCP is a relatively lightweight mechanism for getting feedback on large changes to the compiler (as opposed to a full RFC or a design meeting with the team). Example of things that might require MCPs include major refactorings, changes to important types, or important changes to how the compiler does something, or smaller user-facing changes. -**When in doubt, ask on [Zulip]. It would be a shame to put a lot of work -into a PR that ends up not getting merged!** [See this document][mcpinfo] for -more info on MCPs. +**When in doubt, ask on [Zulip]. +It would be a shame to put a lot of work +into a PR that ends up not getting merged!** [See this document][mcpinfo] for more info on MCPs. [mcpinfo]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler ### Performance -Compiler performance is important. We have put a lot of effort over the last -few years into [gradually improving it][perfdash]. +Compiler performance is important. +We have put a lot of effort over the last few years into [gradually improving it][perfdash]. [perfdash]: https://perf.rust-lang.org/dashboard.html If you suspect that your change may cause a performance regression (or improvement), you can request a "perf run" (and your reviewer may also request one -before approving). This is yet another bot that will compile a collection of -benchmarks on a compiler with your changes. The numbers are reported -[here][perf], and you can see a comparison of your changes against the latest -master. +before approving). +This is yet another bot that will compile a collection of +benchmarks on a compiler with your changes. +The numbers are reported +[here][perf], and you can see a comparison of your changes against the latest master. > For an introduction to the performance of Rust code in general > which would also be useful in rustc development, see [The Rust Performance Book]. @@ -104,11 +108,11 @@ master. ## Pull requests Pull requests (or PRs for short) are the primary mechanism we use to change Rust. -GitHub itself has some [great documentation][about-pull-requests] on using the -Pull Request feature. We use the "fork and pull" model [described here][development-models], +GitHub itself has some [great documentation][about-pull-requests] on using the Pull Request feature. +We use the "fork and pull" model [described here][development-models], where contributors push changes to their personal fork and create pull requests to -bring those changes into the source repository. We have more info about how to use git -when contributing to Rust under [the git section](./git.md). +bring those changes into the source repository. +We have more info about how to use git when contributing to Rust under [the git section](./git.md). > **Advice for potentially large, complex, cross-cutting and/or very domain-specific changes** > @@ -150,7 +154,8 @@ when contributing to Rust under [the git section](./git.md). ### Keeping your branch up-to-date The CI in rust-lang/rust applies your patches directly against the current master, -not against the commit your branch is based on. This can lead to unexpected failures +not against the commit your branch is based on. +This can lead to unexpected failures if your branch is outdated, even when there are no explicit merge conflicts. Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. @@ -159,32 +164,36 @@ During review, make incremental commits to address feedback. Prefer to squash or rebase only at the end, or when a reviewer requests it. When updating, use `git push --force-with-lease` and leave a brief comment explaining what changed. -Some repos prefer merging from `upstream/master` instead of rebasing; follow the project's conventions. +Some repos prefer merging from `upstream/master` instead of rebasing; +follow the project's conventions. See [keeping things up to date](git.md#keeping-things-up-to-date) for detailed instructions. After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. ### r? -All pull requests are reviewed by another person. We have a bot, -[@rustbot], that will automatically assign a random person +All pull requests are reviewed by another person. +We have a bot, [@rustbot], that will automatically assign a random person to review your request based on which files you changed. If you want to request that a specific person reviews your pull request, you -can add an `r?` to the pull request description or in a comment. For example, -if you want to ask a review to @awesome-reviewer, add +can add an `r?` to the pull request description or in a comment. +For example, if you want to ask a review to @awesome-reviewer, add - r? @awesome-reviewer + r? + @awesome-reviewer to the end of the pull request description, and [@rustbot] will assign -them instead of a random person. This is entirely optional. +them instead of a random person. +This is entirely optional. -You can also assign a random reviewer from a specific team by writing `r? rust-lang/groupname`. -As an example, -if you were making a diagnostics change, +You can also assign a random reviewer from a specific team by writing `r? +rust-lang/groupname`. +As an example, if you were making a diagnostics change, then you could get a reviewer from the diagnostics team by adding: - r? rust-lang/diagnostics + r? + rust-lang/diagnostics For a full list of possible `groupname`s, check the `adhoc_groups` section at the [triagebot.toml config file], @@ -209,15 +218,15 @@ or the list of teams in the [rust-lang teams database]. > the author is ready for a review, > and this PR will be queued again in the reviewer's queue. -Please note that the reviewers are humans, who for the most part work on `rustc` -in their free time. This means that they can take some time to respond and review -your PR. It also means that reviewers can miss some PRs that are assigned to them. +Please note that the reviewers are humans, who for the most part work on `rustc` in their free time. +This means that they can take some time to respond and review your PR. +It also means that reviewers can miss some PRs that are assigned to them. To try to move PRs forward, the Triage WG regularly goes through all PRs that -are waiting for review and haven't been discussed for at least 2 weeks. If you -don't get a review within 2 weeks, feel free to ask the Triage WG on -Zulip ([#t-release/triage]). They have knowledge of when to ping, who might be -on vacation, etc. +are waiting for review and haven't been discussed for at least 2 weeks. +If you don't get a review within 2 weeks, feel free to ask the Triage WG on +Zulip ([#t-release/triage]). +They have knowledge of when to ping, who might be on vacation, etc. The reviewer may request some changes using the GitHub code review interface. They may also request special procedures for some PRs. @@ -230,7 +239,8 @@ See [Crater] and [Breaking Changes] chapters for some examples of such procedure ### CI In addition to being reviewed by a human, pull requests are automatically tested, -thanks to continuous integration (CI). Basically, every time you open and update +thanks to continuous integration (CI). +Basically, every time you open and update a pull request, CI builds the compiler and tests it against the [compiler test suite], and also performs other tests such as checking that your pull request is in compliance with Rust's style guidelines. @@ -240,33 +250,37 @@ without going through a first review cycle, and also helps reviewers stay aware of the status of a particular pull request. Rust has plenty of CI capacity, and you should never have to worry about wasting -computational resources each time you push a change. It is also perfectly fine -(and even encouraged!) to use the CI to test your changes if it can help your -productivity. In particular, we don't recommend running the full `./x test` suite locally, +computational resources each time you push a change. +It is also perfectly fine +(and even encouraged!) to use the CI to test your changes if it can help your productivity. +In particular, we don't recommend running the full `./x test` suite locally, since it takes a very long time to execute. ### r+ After someone has reviewed your pull request, they will leave an annotation -on the pull request with an `r+`. It will look something like this: +on the pull request with an `r+`. +It will look something like this: @bors r+ -This tells [@bors], our lovable integration bot, that your pull request has -been approved. The PR then enters the [merge queue], where [@bors] -will run *all* the tests on *every* platform we support. If it all works out, -[@bors] will merge your code into `master` and close the pull request. +This tells [@bors], our lovable integration bot, that your pull request has been approved. +The PR then enters the [merge queue], where [@bors] +will run *all* the tests on *every* platform we support. +If it all works out, [@bors] will merge your code into `master` and close the pull request. Depending on the scale of the change, you may see a slightly different form of `r+`: @bors r+ rollup The additional `rollup` tells [@bors] that this change should always be "rolled up". -Changes that are rolled up are tested and merged alongside other PRs, to -speed the process up. Typically only small changes that are expected not to conflict +Changes that are rolled up are tested and merged alongside other PRs, to speed the process up. +Typically only small changes that are expected not to conflict with one another are marked as "always roll up". -Be patient; this can take a while and the queue can sometimes be long. PRs are never merged by hand. +Be patient; +this can take a while and the queue can sometimes be long. +PRs are never merged by hand. [@rustbot]: https://github.com/rustbot [@bors]: https://github.com/bors @@ -274,7 +288,8 @@ Be patient; this can take a while and the queue can sometimes be long. PRs are n ### Opening a PR You are now ready to file a pull request (PR)? -Great! Here are a few points you should be aware of. +Great! +Here are a few points you should be aware of. All pull requests should be filed against the `master` branch, unless you know for sure that you should target a different branch. @@ -283,15 +298,16 @@ Run some style checks before you submit the PR: ./x test tidy --bless -We recommend to make this check before every pull request (and every new commit -in a pull request); you can add [git hooks] -before every push to make sure you never forget to make this check. +We recommend to make this check before every pull request (and every new commit in a pull request); +you can add [git hooks] before every push to make sure you never forget to make this check. The CI will also run tidy and will fail if tidy fails. Rust follows a _no merge-commit policy_, meaning, when you encounter merge -conflicts you are expected to always rebase instead of merging. E.g. always use -rebase when bringing the latest changes from the master branch to your feature -branch. If your PR contains merge commits, it will get marked as `has-merge-commits`. +conflicts you are expected to always rebase instead of merging. +E.g. +always use rebase when bringing the latest changes from the master branch to your feature +branch. +If your PR contains merge commits, it will get marked as `has-merge-commits`. Once you have removed the merge commits, e.g., through an interactive rebase, you should remove the label again: @@ -300,13 +316,14 @@ should remove the label again: See [this chapter][labeling] for more details. If you encounter merge conflicts or when a reviewer asks you to perform some -changes, your PR will get marked as `S-waiting-on-author`. When you resolve -them, you should use `@rustbot` to mark it as `S-waiting-on-review`: +changes, your PR will get marked as `S-waiting-on-author`. +When you resolve them, you should use `@rustbot` to mark it as `S-waiting-on-review`: @rustbot ready -GitHub allows [closing issues using keywords][closing-keywords]. This feature -should be used to keep the issue tracker tidy. However, it is generally preferred +GitHub allows [closing issues using keywords][closing-keywords]. +This feature should be used to keep the issue tracker tidy. +However, it is generally preferred to put the "closes #123" text in the PR description rather than the issue commit; particularly during rebasing, citing the issue number in the commit can "spam" the issue in question. @@ -319,9 +336,10 @@ Please update the PR description while still mentioning the issue somewhere. For example, you could write `Fixes (after beta backport) #NNN.`. As for further actions, please keep a sharp look-out for a PR whose title begins with -`[beta]` or `[stable]` and which backports the PR in question. When that one gets -merged, the relevant issue can be closed. The closing comment should mention all -PRs that were involved. If you don't have the permissions to close the issue, please +`[beta]` or `[stable]` and which backports the PR in question. +When that one gets merged, the relevant issue can be closed. +The closing comment should mention all PRs that were involved. +If you don't have the permissions to close the issue, please leave a comment on the original PR asking the reviewer to close it for you. [labeling]: ./rustbot.md#issue-relabeling @@ -330,11 +348,13 @@ leave a comment on the original PR asking the reviewer to close it for you. ### Reverting a PR When a PR leads to miscompile, significant performance regressions, or other critical issues, we may -want to revert that PR with a regression test case. You can also check out the [revert policy] on +want to revert that PR with a regression test case. +You can also check out the [revert policy] on Forge docs (which is mainly targeted for reviewers, but contains useful info for PR authors too). If the PR contains huge changes, it can be challenging to revert, making it harder to review -incremental fixes in subsequent updates. Or if certain code in that PR is heavily depended upon by +incremental fixes in subsequent updates. +Or if certain code in that PR is heavily depended upon by subsequent PRs, reverting it can become difficult. In such cases, we can identify the problematic code and disable it for some input, as shown in [#128271][#128271]. @@ -352,7 +372,8 @@ This section has moved to ["Using External Repositories"](./external-repos.md). ## Writing documentation -Documentation improvements are very welcome. The source of `doc.rust-lang.org` +Documentation improvements are very welcome. +The source of `doc.rust-lang.org` is located in [`src/doc`] in the tree, and standard API documentation is generated from the source code itself (e.g. [`library/std/src/lib.rs`][std-root]). Documentation pull requests function in the same way as other pull requests. @@ -370,8 +391,8 @@ Results should appear in `build/host/doc`, as well as automatically open in your See [Building Documentation](./building/compiler-documenting.md#building-documentation) for more information. -You can also use `rustdoc` directly to check small fixes. For example, -`rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. +You can also use `rustdoc` directly to check small fixes. +For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. The CSS might be messed up, but you can verify that the HTML is right. Please notice that we don't accept typography/spellcheck fixes to **internal documentation** @@ -389,7 +410,8 @@ There are issues for beginners and advanced compiler devs alike! Just a few things to keep in mind: - Please try to avoid overly long lines and use semantic line breaks (where you break the line after each sentence). - There is no strict limit on line lengths; let the sentence or part of the sentence flow to its proper end on the same line. + There is no strict limit on line lengths; + let the sentence or part of the sentence flow to its proper end on the same line. You can use a tool in ci/sembr to help with this. Its help output can be seen with this command: @@ -406,8 +428,7 @@ Just a few things to keep in mind: as change is a constant across the project. - The date the comment was added, e.g. instead of writing _"Currently, ..."_ - or _"As of now, ..."_, - consider adding the date, in one of the following formats: + or _"As of now, ..."_, consider adding the date, in one of the following formats: - Jan 2021 - January 2021 - jan 2021 @@ -417,8 +438,7 @@ Just a few things to keep in mind: that generates a monthly report showing those that are over 6 months old ([example](https://github.com/rust-lang/rustc-dev-guide/issues/2052)). - For the action to pick the date, - add a special annotation before specifying the date: + For the action to pick the date, add a special annotation before specifying the date: ```md Apr 2025 @@ -442,8 +462,7 @@ Just a few things to keep in mind: outdated. - If a text grows rather long (more than a few page scrolls) or complicated (more than four - subsections), - it might benefit from having a Table of Contents at the beginning, + subsections), it might benefit from having a Table of Contents at the beginning, which you can auto-generate by including the `` marker at the top. #### ⚠️ Note: Where to contribute `rustc-dev-guide` changes From 5f6fa960c254dfda8ba1d5dc2fb281b6908d8005 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Tue, 4 Nov 2025 10:58:10 -0600 Subject: [PATCH 384/525] Relax r29 inline asm restriction on PowerPC64 targets LLVM uses r29 to hold a base pointer for some PowerPC target configurations. It is usable on all 64 bit targets as a callee save register. --- compiler/rustc_target/src/asm/powerpc.rs | 19 ++++++++++++++++--- .../asm-experimental-arch.md | 8 +++++--- tests/ui/asm/powerpc/bad-reg.aix64.stderr | 8 +------- tests/ui/asm/powerpc/bad-reg.powerpc.stderr | 12 ++++++------ tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 8 +------- .../ui/asm/powerpc/bad-reg.powerpc64le.stderr | 8 +------- tests/ui/asm/powerpc/bad-reg.rs | 2 +- 7 files changed, 31 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index 2824d5dde9d8..09682ee9d4e6 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -82,6 +82,20 @@ fn reserved_r13( } } +fn reserved_r29( + arch: InlineAsmArch, + _reloc_model: RelocModel, + _target_features: &FxIndexSet, + _target: &Target, + _is_clobber: bool, +) -> Result<(), &'static str> { + if arch != InlineAsmArch::PowerPC { + Ok(()) + } else { + Err("r29 is used internally by LLVM and cannot be used as an operand for inline asm") + } +} + fn reserved_v20to31( _arch: InlineAsmArch, _reloc_model: RelocModel, @@ -129,6 +143,7 @@ def_regs! { r26: reg, reg_nonzero = ["r26", "26"], r27: reg, reg_nonzero = ["r27", "27"], r28: reg, reg_nonzero = ["r28", "28"], + r29: reg, reg_nonzero = ["r29", "29"] % reserved_r29, f0: freg = ["f0", "fr0"], f1: freg = ["f1", "fr1"], f2: freg = ["f2", "fr2"], @@ -274,8 +289,6 @@ def_regs! { "the stack pointer cannot be used as an operand for inline asm", #error = ["r2", "2"] => "r2 is a system reserved register and cannot be used as an operand for inline asm", - #error = ["r29", "29"] => - "r29 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r30", "30"] => "r30 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r31", "31", "fp"] => @@ -306,7 +319,7 @@ impl PowerPCInlineAsmReg { (r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7"); (r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r13, "13"), (r14, "14"), (r15, "15"); (r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23"); - (r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28"); + (r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28"), (r29, "29"); (f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7"); (f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15"); (f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23"); diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 94de948a480e..c96605fb7944 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -31,8 +31,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | | Hexagon | `preg` | `p[0-3]` | Only clobbers | -| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | -| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | +| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-29]`\* | `r` | +| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-29]`\* | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | | PowerPC | `vreg` | `v[0-31]` | `v` | | PowerPC | `vsreg | `vs[0-63]` | `wa` | @@ -61,6 +61,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect > - NVPTX doesn't have a fixed register set, so named registers are not supported. > > - WebAssembly doesn't have registers, so named registers are not supported. +> +> - r29 is reserved only on 32 bit PowerPC targets. # Register class supported types @@ -148,7 +150,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. | | All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | -| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | +| All | `r19` (Hexagon), `r29` (PowerPC 32 bit only), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 67ad0a5d2c45..4490053215b5 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use LL | asm!("", out("r2") _); | ^^^^^^^^^^^ -error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 - | -LL | asm!("", out("r29") _); - | ^^^^^^^^^^^^ - error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm --> $DIR/bad-reg.rs:44:18 | @@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x); | = note: register class `xer` supports these types: -error: aborting due to 113 previous errors +error: aborting due to 112 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index 64a8f6a3d5b9..651e8cdfd3d5 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use LL | asm!("", out("r2") _); | ^^^^^^^^^^^ -error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 - | -LL | asm!("", out("r29") _); - | ^^^^^^^^^^^^ - error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm --> $DIR/bad-reg.rs:44:18 | @@ -712,6 +706,12 @@ error: cannot use register `r13`: r13 is a reserved register on this target LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ +error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:42:18 + | +LL | asm!("", out("r29") _); + | ^^^^^^^^^^^^ + error: register class `vreg` requires at least one of the following target features: altivec, vsx --> $DIR/bad-reg.rs:53:18 | diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 3315a00cc1ab..552fb0504b8d 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use LL | asm!("", out("r2") _); | ^^^^^^^^^^^ -error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 - | -LL | asm!("", out("r29") _); - | ^^^^^^^^^^^^ - error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm --> $DIR/bad-reg.rs:44:18 | @@ -916,5 +910,5 @@ LL | asm!("/* {} */", in(xer) x); | = note: register class `xer` supports these types: -error: aborting due to 123 previous errors +error: aborting due to 122 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 67ad0a5d2c45..4490053215b5 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use LL | asm!("", out("r2") _); | ^^^^^^^^^^^ -error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 - | -LL | asm!("", out("r29") _); - | ^^^^^^^^^^^^ - error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm --> $DIR/bad-reg.rs:44:18 | @@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x); | = note: register class `xer` supports these types: -error: aborting due to 113 previous errors +error: aborting due to 112 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 6ded9b97eb88..7ceae5c6d8d3 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -40,7 +40,7 @@ fn f() { asm!("", out("r13") _); //~^ ERROR cannot use register `r13`: r13 is a reserved register on this target asm!("", out("r29") _); - //~^ ERROR invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + //[powerpc]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("r30") _); //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("fp") _); From 100a870844c7038a8cc130b676c620fa3400cad9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Oct 2025 16:24:30 +0100 Subject: [PATCH 385/525] user-relevant span: if no frame is in a local crate, use topmost non-track_caller frame --- src/tools/miri/src/concurrency/thread.rs | 30 +++++++++---- src/tools/miri/src/diagnostics.rs | 20 ++++----- src/tools/miri/src/helpers.rs | 17 ++++--- src/tools/miri/src/machine.rs | 45 +++++++++---------- .../fail/panic/tls_macro_drop_panic.stderr | 1 + .../genmc/pass/std/arc.check_count.stderr | 35 ++++++++++----- .../genmc/pass/std/arc.try_upgrade.stderr | 35 ++++++++++----- .../tests/genmc/pass/std/empty_main.stderr | 35 ++++++++++----- .../genmc/pass/std/spawn_std_threads.stderr | 35 ++++++++++----- .../tests/genmc/pass/std/thread_locals.stderr | 35 ++++++++++----- 10 files changed, 191 insertions(+), 97 deletions(-) diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index dd2b0edcb896..6178f87d7849 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -181,7 +181,6 @@ pub struct Thread<'tcx> { /// The index of the topmost user-relevant frame in `stack`. This field must contain /// the value produced by `get_top_user_relevant_frame`. - /// The `None` state here represents /// This field is a cache to reduce how often we call that method. The cache is manually /// maintained inside `MiriMachine::after_stack_push` and `MiriMachine::after_stack_pop`. top_user_relevant_frame: Option, @@ -232,12 +231,21 @@ impl<'tcx> Thread<'tcx> { /// justifying the optimization that only pushes of user-relevant frames require updating the /// `top_user_relevant_frame` field. fn compute_top_user_relevant_frame(&self, skip: usize) -> Option { - self.stack - .iter() - .enumerate() - .rev() - .skip(skip) - .find_map(|(idx, frame)| if frame.extra.is_user_relevant { Some(idx) } else { None }) + // We are search for the frame with maximum relevance. + let mut best = None; + for (idx, frame) in self.stack.iter().enumerate().rev().skip(skip) { + let relevance = frame.extra.user_relevance; + if relevance == u8::MAX { + // We can short-circuit this search. + return Some(idx); + } + if best.is_none_or(|(_best_idx, best_relevance)| best_relevance < relevance) { + // The previous best frame has strictly worse relevance, so despite us being lower + // in the stack, we win. + best = Some((idx, relevance)); + } + } + best.map(|(idx, _relevance)| idx) } /// Re-compute the top user-relevant frame from scratch. `skip` indicates how many top frames @@ -256,14 +264,20 @@ impl<'tcx> Thread<'tcx> { /// Returns the topmost frame that is considered user-relevant, or the /// top of the stack if there is no such frame, or `None` if the stack is empty. pub fn top_user_relevant_frame(&self) -> Option { - debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0)); // This can be called upon creation of an allocation. We create allocations while setting up // parts of the Rust runtime when we do not have any stack frames yet, so we need to handle // empty stacks. self.top_user_relevant_frame.or_else(|| self.stack.len().checked_sub(1)) } + pub fn current_user_relevance(&self) -> u8 { + self.top_user_relevant_frame() + .map(|frame_idx| self.stack[frame_idx].extra.user_relevance) + .unwrap_or(0) + } + pub fn current_user_relevant_span(&self) -> Span { + debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0)); self.top_user_relevant_frame() .map(|frame_idx| self.stack[frame_idx].current_span()) .unwrap_or(rustc_span::DUMMY_SP) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 0acdfdd3ffe5..d0cfb9c805e1 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -187,16 +187,14 @@ pub fn prune_stacktrace<'tcx>( } BacktraceStyle::Short => { let original_len = stacktrace.len(); - // Only prune frames if there is at least one local frame. This check ensures that if - // we get a backtrace that never makes it to the user code because it has detected a - // bug in the Rust runtime, we don't prune away every frame. - let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame)); + // Remove all frames marked with `caller_location` -- that attribute indicates we + // usually want to point at the caller, not them. + stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx)); + // Only prune further frames if there is at least one local frame. This check ensures + // that if we get a backtrace that never makes it to the user code because it has + // detected a bug in the Rust runtime, we don't prune away every frame. + let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame.instance)); if has_local_frame { - // Remove all frames marked with `caller_location` -- that attribute indicates we - // usually want to point at the caller, not them. - stacktrace - .retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx)); - // This is part of the logic that `std` uses to select the relevant part of a // backtrace. But here, we only look for __rust_begin_short_backtrace, not // __rust_end_short_backtrace because the end symbol comes from a call to the default @@ -216,7 +214,7 @@ pub fn prune_stacktrace<'tcx>( // This len check ensures that we don't somehow remove every frame, as doing so breaks // the primary error message. while stacktrace.len() > 1 - && stacktrace.last().is_some_and(|frame| !machine.is_local(frame)) + && stacktrace.last().is_some_and(|frame| !machine.is_local(frame.instance)) { stacktrace.pop(); } @@ -619,7 +617,7 @@ pub fn report_msg<'tcx>( write!(backtrace_title, ":").unwrap(); err.note(backtrace_title); for (idx, frame_info) in stacktrace.iter().enumerate() { - let is_local = machine.is_local(frame_info); + let is_local = machine.is_local(frame_info.instance); // No span for non-local frames and the first frame (which is the error site). if is_local && idx > 0 { err.subdiagnostic(frame_info.as_note(machine.tcx)); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 769e501c4533..7e1fdfa8cdf2 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1088,11 +1088,18 @@ impl<'tcx> MiriMachine<'tcx> { self.threads.active_thread_ref().top_user_relevant_frame() } - /// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`. - pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool { - let def_id = frame.instance().def_id(); - (def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)) - && !frame.instance().def.requires_caller_location(self.tcx) + /// This is the source of truth for the `user_relevance` flag in our `FrameExtra`. + pub fn user_relevance(&self, frame: &Frame<'tcx, Provenance>) -> u8 { + if frame.instance().def.requires_caller_location(self.tcx) { + return 0; + } + if self.is_local(frame.instance()) { + u8::MAX + } else { + // A non-relevant frame, but at least it doesn't require a caller location, so + // better than nothing. + 1 + } } } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 33f854bee23d..7ec00d82492e 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -139,11 +139,10 @@ pub struct FrameExtra<'tcx> { /// we use this to register a completed event with `measureme`. pub timing: Option, - /// Indicates whether a `Frame` is part of a workspace-local crate and is also not - /// `#[track_caller]`. We compute this once on creation and store the result, as an - /// optimization. - /// This is used by `MiriMachine::current_span` and `MiriMachine::caller_span` - pub is_user_relevant: bool, + /// Indicates how user-relevant this frame is. `#[track_caller]` frames are never relevant. + /// Frames from user-relevant crates are maximally relevant; frames from other crates are less + /// relevant. + pub user_relevance: u8, /// Data race detector per-frame data. pub data_race: Option, @@ -152,12 +151,12 @@ pub struct FrameExtra<'tcx> { impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Omitting `timing`, it does not support `Debug`. - let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant, data_race } = + let FrameExtra { borrow_tracker, catch_unwind, timing: _, user_relevance, data_race } = self; f.debug_struct("FrameData") .field("borrow_tracker", borrow_tracker) .field("catch_unwind", catch_unwind) - .field("is_user_relevant", is_user_relevant) + .field("user_relevance", user_relevance) .field("data_race", data_race) .finish() } @@ -165,13 +164,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> { impl VisitProvenance for FrameExtra<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { - let FrameExtra { - catch_unwind, - borrow_tracker, - timing: _, - is_user_relevant: _, - data_race: _, - } = self; + let FrameExtra { catch_unwind, borrow_tracker, timing: _, user_relevance: _, data_race: _ } = + self; catch_unwind.visit_provenance(visit); borrow_tracker.visit_provenance(visit); @@ -910,8 +904,8 @@ impl<'tcx> MiriMachine<'tcx> { } /// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate. - pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool { - let def_id = frame.instance.def_id(); + pub(crate) fn is_local(&self, instance: ty::Instance<'tcx>) -> bool { + let def_id = instance.def_id(); def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate) } @@ -1702,7 +1696,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { borrow_tracker: borrow_tracker.map(|bt| bt.borrow_mut().new_frame()), catch_unwind: None, timing, - is_user_relevant: ecx.machine.is_user_relevant(&frame), + user_relevance: ecx.machine.user_relevance(&frame), data_race: ecx .machine .data_race @@ -1758,9 +1752,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { #[inline(always)] fn after_stack_push(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { - if ecx.frame().extra.is_user_relevant { - // We just pushed a local frame, so we know that the topmost local frame is the topmost - // frame. If we push a non-local frame, there's no need to do anything. + if ecx.frame().extra.user_relevance >= ecx.active_thread_ref().current_user_relevance() { + // We just pushed a frame that's at least as relevant as the so-far most relevant frame. + // That means we are now the most relevant frame. let stack_len = ecx.active_thread_stack().len(); ecx.active_thread_mut().set_top_user_relevant_frame(stack_len - 1); } @@ -1774,9 +1768,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if ecx.machine.borrow_tracker.is_some() { ecx.on_stack_pop(frame)?; } - if frame.extra.is_user_relevant { - // All that we store is whether or not the frame we just removed is local, so now we - // have no idea where the next topmost local frame is. So we recompute it. + if ecx + .active_thread_ref() + .top_user_relevant_frame() + .expect("there should always be a most relevant frame for a non-empty stack") + == ecx.frame_idx() + { + // We are popping the most relevant frame. We have no clue what the next relevant frame + // below that is, so we recompute that. // (If this ever becomes a bottleneck, we could have `push` store the previous // user-relevant frame and restore that here.) // We have to skip the frame that is just being popped. diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr index 4fdaa97e1d0a..39263a8d61cc 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr @@ -4,5 +4,6 @@ ow fatal runtime error: thread local panicked on drop, aborting error: abnormal termination: the program aborted execution + error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr index 878077edb818..695aa3f5aeaf 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -91,19 +91,34 @@ LL | handle.join().unwrap(); | ^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr index fc43c6313590..8609c2c5c864 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -91,19 +91,34 @@ LL | handle.join().unwrap(); | ^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr index 1b8712167d8a..b1413ee6d574 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr @@ -1,28 +1,43 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr index b148c11e39b1..87d3c60ef02e 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -95,19 +95,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr index 208de4e37ffb..91d2f5daa146 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -78,19 +78,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC From 7e66d6c3b945768b02348419139ff8446af44369 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 4 Nov 2025 19:14:47 +0000 Subject: [PATCH 386/525] Implement Path::is_empty --- library/std/src/path.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 6e3b1e6e47d0..1ae36a71270a 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2756,6 +2756,28 @@ impl Path { iter_after(self.components().rev(), child.components().rev()).is_some() } + /// Checks whether the `Path` is empty. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_is_empty)] + /// use std::path::Path; + /// + /// let path = Path::new(""); + /// assert!(path.is_empty()); + /// + /// let path = Path::new("foo"); + /// assert!(!path.is_empty()); + /// + /// let path = Path::new("."); + /// assert!(!path.is_empty()); + /// ``` + #[unstable(feature = "path_is_empty", issue = "148494")] + pub fn is_empty(&self) -> bool { + self.as_os_str().is_empty() + } + /// Extracts the stem (non-extension) portion of [`self.file_name`]. /// /// [`self.file_name`]: Path::file_name From bddac3c3d4ce2793d10b84a8639c59c022e4bbed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 20:54:42 +0100 Subject: [PATCH 387/525] x86/rounding-error test: avoid rounding during error calculation --- .../tests/pass/shims/x86/rounding-error.rs | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/tools/miri/tests/pass/shims/x86/rounding-error.rs b/src/tools/miri/tests/pass/shims/x86/rounding-error.rs index bf56111b2e49..aa9fd9686181 100644 --- a/src/tools/miri/tests/pass/shims/x86/rounding-error.rs +++ b/src/tools/miri/tests/pass/shims/x86/rounding-error.rs @@ -11,25 +11,27 @@ use std::arch::x86_64::*; use std::collections::HashSet; fn main() { + let a = unsafe { _mm_setr_ps(4.0, 4.0, 4.0, 4.0) }; + let exact = 0.5; + // max error: 2^-12. + let rel_error_bound = 1.0 / (1 << 12) as f32; + let mut vals = HashSet::new(); for _ in 0..50 { - unsafe { - // Compute the inverse square root of 4.0, four times. - let a = _mm_setr_ps(4.0, 4.0, 4.0, 4.0); - let exact = 0.5; - let r = _mm_rsqrt_ps(a); - let r: [f32; 4] = std::mem::transmute(r); - // Check the results. - for r in r { - vals.insert(r.to_bits()); - // Ensure the relative error is less than 2^-12. - let rel_error = (r - exact) / exact; - let log_error = rel_error.abs().log2(); - assert!( - rel_error == 0.0 || log_error < -12.0, - "got an error of {rel_error} = 2^{log_error}" - ); - } + // Compute the inverse square root of 4.0, four times. + let r = unsafe { _mm_rsqrt_ps(a) }; + let r: [f32; 4] = unsafe { std::mem::transmute(r) }; + // Check the results. + for r in r { + vals.insert(r.to_bits()); + // Ensure the relative error is no more than 2^-12. + let rel_error = (r - exact) / exact; + assert!( + rel_error.abs() <= rel_error_bound, + "correct result: {exact}, got: {r}\n\ + that's a relative error of {rel_error} (= 2^{log_error})", + log_error = rel_error.abs().log2() + ); } } // Ensure we saw a bunch of different results. From 389c3ce0f762bf4d6713ce6eb2b0f66945115065 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:04:49 +0000 Subject: [PATCH 388/525] Remove no longer necessary lint allow --- library/panic_unwind/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 83311f323801..1be19913f260 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -24,8 +24,6 @@ #![feature(rustc_attrs)] #![panic_runtime] #![feature(panic_runtime)] -// `real_imp` is unused with Miri, so silence warnings. -#![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] #![warn(unreachable_pub)] #![deny(unsafe_op_in_unsafe_fn)] From 2dee8525ac070eb1136d6df149ede247515416c7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 21:15:49 +0200 Subject: [PATCH 389/525] misc improvents to src/contributing.md --- src/doc/rustc-dev-guide/src/contributing.md | 43 ++++++++++----------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index f74b34438564..cd6ebc90b7cb 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -4,7 +4,7 @@ While bugs are unfortunate, they're a reality in software. We can't fix what we don't know about, so please report liberally. -If you're not sure if something is a bug or not, feel free to file a bug anyway. +If you're not sure if something is a bug, feel free to open an issue anyway. **If you believe reporting your bug publicly represents a security risk to Rust users, please follow our [instructions for reporting security vulnerabilities][vuln]**. @@ -77,12 +77,12 @@ Example of things that might require MCPs include major refactorings, changes to important types, or important changes to how the compiler does something, or smaller user-facing changes. -**When in doubt, ask on [Zulip]. +**When in doubt, ask [on Zulip]. It would be a shame to put a lot of work into a PR that ends up not getting merged!** [See this document][mcpinfo] for more info on MCPs. [mcpinfo]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp -[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler +[on Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler ### Performance @@ -109,10 +109,10 @@ The numbers are reported Pull requests (or PRs for short) are the primary mechanism we use to change Rust. GitHub itself has some [great documentation][about-pull-requests] on using the Pull Request feature. -We use the "fork and pull" model [described here][development-models], +We use the ["fork and pull" model][development-models], where contributors push changes to their personal fork and create pull requests to bring those changes into the source repository. -We have more info about how to use git when contributing to Rust under [the git section](./git.md). +We have [a chapter](git.md) on how to use Git when contributing to Rust. > **Advice for potentially large, complex, cross-cutting and/or very domain-specific changes** > @@ -178,22 +178,19 @@ to review your request based on which files you changed. If you want to request that a specific person reviews your pull request, you can add an `r?` to the pull request description or in a comment. -For example, if you want to ask a review to @awesome-reviewer, add +For example, if you want to ask a review by @awesome-reviewer, +add the following to the end of the pull request description: - r? - @awesome-reviewer + r? @awesome-reviewer -to the end of the pull request description, and [@rustbot] will assign -them instead of a random person. +[@rustbot] will then assign the PR to that reviewer instead of a random person. This is entirely optional. -You can also assign a random reviewer from a specific team by writing `r? -rust-lang/groupname`. +You can also assign a random reviewer from a specific team by writing `r? rust-lang/groupname`. As an example, if you were making a diagnostics change, -then you could get a reviewer from the diagnostics team by adding: +you could get a reviewer from the diagnostics team by adding: - r? - rust-lang/diagnostics + r? rust-lang/diagnostics For a full list of possible `groupname`s, check the `adhoc_groups` section at the [triagebot.toml config file], @@ -275,12 +272,12 @@ Depending on the scale of the change, you may see a slightly different form of ` The additional `rollup` tells [@bors] that this change should always be "rolled up". Changes that are rolled up are tested and merged alongside other PRs, to speed the process up. -Typically only small changes that are expected not to conflict +Typically, only small changes that are expected not to conflict with one another are marked as "always roll up". Be patient; this can take a while and the queue can sometimes be long. -PRs are never merged by hand. +Also, note that PRs are never merged by hand. [@rustbot]: https://github.com/rustbot [@bors]: https://github.com/bors @@ -302,11 +299,11 @@ We recommend to make this check before every pull request (and every new commit you can add [git hooks] before every push to make sure you never forget to make this check. The CI will also run tidy and will fail if tidy fails. -Rust follows a _no merge-commit policy_, meaning, when you encounter merge -conflicts you are expected to always rebase instead of merging. -E.g. -always use rebase when bringing the latest changes from the master branch to your feature -branch. +Rust follows a _no merge-commit policy_, +meaning that when you encounter merge conflicts, +you are expected to always rebase instead of merging. +For example, +always use rebase when bringing the latest changes from the master branch to your feature branch. If your PR contains merge commits, it will get marked as `has-merge-commits`. Once you have removed the merge commits, e.g., through an interactive rebase, you should remove the label again: @@ -424,7 +421,7 @@ Just a few things to keep in mind: and/or a reason so that the reader knows how much to trust the information. Aim to provide a reasonable amount of context, possibly including but not limited to: - - A reason for why the data may be out of date other than "change", + - A reason for why the text may be out of date other than "change", as change is a constant across the project. - The date the comment was added, e.g. instead of writing _"Currently, ..."_ From 56757ab89768801c6d7de559b8886f7b9b357613 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 23:27:09 +0200 Subject: [PATCH 390/525] sembr: adjust after using src/contributing.md --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 28 +++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index edf5b6401cd9..c056f68c31d7 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -27,7 +27,7 @@ static REGEX_IGNORE: LazyLock = static REGEX_IGNORE_END: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)$").unwrap()); static REGEX_IGNORE_LINK_TARGETS: LazyLock = LazyLock::new(|| Regex::new(r"^\[.+\]: ").unwrap()); -static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)\s+").unwrap()); +static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|[^r]\?|;|!)\s+").unwrap()); fn main() -> Result<()> { let cli = Cli::parse(); @@ -92,7 +92,7 @@ fn display(header: &str, paths: &[PathBuf]) { fn ignore(line: &str, in_code_block: bool) -> bool { in_code_block - || line.contains("e.g.") + || line.to_lowercase().contains("e.g.") || line.contains("i.e.") || line.contains('|') || line.trim_start().starts_with('>') @@ -174,7 +174,9 @@ fn test_sembr() { must! be; split? and. normalizes space 1. ignore numbered ignore | tables -ignore e.g. and i.e. +ignore e.g. and +ignore i.e. and +ignore E.g. too - ignore. list * ignore. list ``` @@ -191,7 +193,9 @@ and. normalizes space 1. ignore numbered ignore | tables -ignore e.g. and i.e. +ignore e.g. and +ignore i.e. and +ignore E.g. too - ignore. list * ignore. list ``` @@ -269,3 +273,19 @@ hi again. let processed = lengthen_lines(&processed, 50); assert_eq!(expected, processed); } + +#[test] +fn test_sembr_question_mark() { + let original = "\ +o? whatever +r? @reviewer + r? @reviewer +"; + let expected = "\ +o? +whatever +r? @reviewer + r? @reviewer +"; + assert_eq!(expected, comply(original)); +} From 743b803fae62fbc7399d0e91a035758f4ee1dd92 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 4 Nov 2025 23:30:58 +0200 Subject: [PATCH 391/525] date-check src/contributing.md Had a look due to reviewing sembr changes --- src/doc/rustc-dev-guide/src/contributing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index cd6ebc90b7cb..b8614e5a90f0 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -438,20 +438,20 @@ Just a few things to keep in mind: For the action to pick the date, add a special annotation before specifying the date: ```md - Apr 2025 + Nov 2025 ``` Example: ```md - As of Apr 2025, the foo did the bar. + As of Nov 2025, the foo did the bar. ``` For cases where the date should not be part of the visible rendered output, use the following instead: ```md - + ``` - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide From f7f0ca4b76c5a3beaed7b4f4823200cb20ea54b7 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 4 Nov 2025 15:26:01 -0600 Subject: [PATCH 392/525] triagebot: Create Zulip topics for libs backports Take the configuration used by other teams to create Zulip topics for T-libs backports. --- triagebot.toml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 5a96d96b346d..325a62235c71 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -794,6 +794,55 @@ zulip_stream = 474880 # #t-compiler/backports topic = "#{number}: stable-nominated" message_on_add = "PR #{number} has been **accepted** for **stable** backport." +[notify-zulip."beta-nominated".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +topic = "#{number}: beta-nominated" +message_on_add = [ + """\ +@*T-libs* PR #{number} "{title}" has been nominated for beta backport. +""", + """\ +/poll Should #{number} be beta backported? +approve +decline +don't know +""", +] +message_on_remove = "PR #{number}'s beta-nomination has been removed." + +[notify-zulip."beta-accepted".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +# Put it in the same Zulip topic as beta-nominated. +topic = "#{number}: beta-nominated" +message_on_add = "PR #{number} has been **accepted** for **beta** backport." + +[notify-zulip."stable-nominated".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +topic = "#{number}: stable-nominated" +message_on_add = [ + """\ +@**channel** PR #{number} "{title}" has been nominated for stable backport. +""", + """\ +/poll Approve stable backport of #{number}? +approve +approve (but does not justify new dot release on its own) +decline +don't know +""", +] +message_on_remove = "PR #{number}'s stable-nomination has been removed." + +[notify-zulip."stable-accepted".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +# Put it in the same thread as stable-nominated. +topic = "#{number}: stable-nominated" +message_on_add = "PR #{number} has been **accepted** for **stable** backport." + [notify-zulip."beta-nominated".bootstrap] required_labels = ["T-bootstrap"] From 5d83132bf32df597606691b9d5b12bc570c31f3c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 25 Oct 2025 22:49:59 +1100 Subject: [PATCH 393/525] Store the list of known directive names in a set This allows every check to be a single hashtable lookup instead of a linear scan. --- src/tools/compiletest/src/directives.rs | 6 +++--- src/tools/compiletest/src/directives/directive_names.rs | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index f25294d8d198..d8fc66c3ba04 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -11,7 +11,7 @@ use crate::debuggers::{extract_cdb_version, extract_gdb_version}; pub(crate) use crate::directives::auxiliary::AuxProps; use crate::directives::auxiliary::parse_and_update_aux; use crate::directives::directive_names::{ - KNOWN_DIRECTIVE_NAMES, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, + KNOWN_DIRECTIVE_NAMES_SET, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, }; pub(crate) use crate::directives::file::FileDirectives; use crate::directives::line::{DirectiveLine, line_directive}; @@ -786,7 +786,7 @@ fn check_directive<'a>( ) -> CheckDirectiveResult<'a> { let &DirectiveLine { name: directive_name, .. } = directive_ln; - let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name) + let is_known_directive = KNOWN_DIRECTIVE_NAMES_SET.contains(&directive_name) || match mode { TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES.contains(&directive_name), TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES.contains(&directive_name), @@ -799,7 +799,7 @@ fn check_directive<'a>( let trailing_directive = directive_ln .remark_after_space() .map(|remark| remark.trim_start().split(' ').next().unwrap()) - .filter(|token| KNOWN_DIRECTIVE_NAMES.contains(token)); + .filter(|token| KNOWN_DIRECTIVE_NAMES_SET.contains(token)); // FIXME(Zalathar): Consider emitting specialized error/help messages for // bogus directive names that are similar to real ones, e.g.: diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 1474df146f9c..b8cb53fca20d 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -1,3 +1,9 @@ +use std::collections::HashSet; +use std::sync::LazyLock; + +pub(crate) static KNOWN_DIRECTIVE_NAMES_SET: LazyLock> = + LazyLock::new(|| KNOWN_DIRECTIVE_NAMES.iter().copied().collect()); + /// This was originally generated by collecting directives from ui tests and then extracting their /// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is /// a best-effort approximation for diagnostics. Add new directives to this list when needed. From 795e9068d051e0a6e357bb5281d7e8edc37cc24f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 25 Oct 2025 23:09:31 +1100 Subject: [PATCH 394/525] Pull the known-directive-names check out of `iter_directives` This also incorporates some requested improvements to the error message for unknown directives. --- src/tools/compiletest/src/directives.rs | 85 +++++++------------ src/tools/compiletest/src/directives/tests.rs | 9 +- src/tools/compiletest/src/lib.rs | 6 ++ 3 files changed, 42 insertions(+), 58 deletions(-) diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index d8fc66c3ba04..7c1bbe940321 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -53,13 +53,10 @@ impl EarlyProps { config: &Config, file_directives: &FileDirectives<'_>, ) -> Self { - let testfile = file_directives.path; let mut props = EarlyProps::default(); - let mut poisoned = false; iter_directives( config.mode, - &mut poisoned, file_directives, // (dummy comment to force args into vertical layout) &mut |ln: &DirectiveLine<'_>| { @@ -67,11 +64,6 @@ impl EarlyProps { }, ); - if poisoned { - eprintln!("errors encountered during EarlyProps parsing: {}", testfile); - panic!("errors encountered during EarlyProps parsing"); - } - props } } @@ -358,12 +350,10 @@ impl TestProps { let file_contents = fs::read_to_string(testfile).unwrap(); let file_directives = FileDirectives::from_file_contents(testfile, &file_contents); - let mut poisoned = false; - iter_directives( config.mode, - &mut poisoned, &file_directives, + // (dummy comment to force args into vertical layout) &mut |ln: &DirectiveLine<'_>| { if !ln.applies_to_test_revision(test_revision) { return; @@ -634,11 +624,6 @@ impl TestProps { ); }, ); - - if poisoned { - eprintln!("errors encountered during TestProps parsing: {}", testfile); - panic!("errors encountered during TestProps parsing"); - } } if self.should_ice { @@ -775,6 +760,34 @@ impl TestProps { } } +pub(crate) fn do_early_directives_check( + mode: TestMode, + file_directives: &FileDirectives<'_>, +) -> Result<(), String> { + let testfile = file_directives.path; + + for directive_line @ DirectiveLine { line_number, .. } in &file_directives.lines { + let CheckDirectiveResult { is_known_directive, trailing_directive } = + check_directive(directive_line, mode); + + if !is_known_directive { + return Err(format!( + "ERROR: unknown compiletest directive `{directive}` at {testfile}:{line_number}", + directive = directive_line.display(), + )); + } + + if let Some(trailing_directive) = &trailing_directive { + return Err(format!( + "ERROR: detected trailing compiletest directive `{trailing_directive}` at {testfile}:{line_number}\n\ + HELP: put the directive on its own line: `//@ {trailing_directive}`" + )); + } + } + + Ok(()) +} + pub(crate) struct CheckDirectiveResult<'ln> { is_known_directive: bool, trailing_directive: Option<&'ln str>, @@ -811,7 +824,6 @@ fn check_directive<'a>( fn iter_directives( mode: TestMode, - poisoned: &mut bool, file_directives: &FileDirectives<'_>, it: &mut dyn FnMut(&DirectiveLine<'_>), ) { @@ -837,36 +849,7 @@ fn iter_directives( } } - for directive_line @ &DirectiveLine { line_number, .. } in &file_directives.lines { - // Perform unknown directive check on Rust files. - if testfile.extension() == Some("rs") { - let CheckDirectiveResult { is_known_directive, trailing_directive } = - check_directive(directive_line, mode); - - if !is_known_directive { - *poisoned = true; - - error!( - "{testfile}:{line_number}: detected unknown compiletest test directive `{}`", - directive_line.display(), - ); - - return; - } - - if let Some(trailing_directive) = &trailing_directive { - *poisoned = true; - - error!( - "{testfile}:{line_number}: detected trailing compiletest test directive `{}`", - trailing_directive, - ); - help!("put the trailing directive in its own line: `//@ {}`", trailing_directive); - - return; - } - } - + for directive_line in &file_directives.lines { it(directive_line); } } @@ -1304,12 +1287,9 @@ pub(crate) fn make_test_description( let mut ignore_message = None; let mut should_fail = false; - let mut local_poisoned = false; - // Scan through the test file to handle `ignore-*`, `only-*`, and `needs-*` directives. iter_directives( config.mode, - &mut local_poisoned, file_directives, &mut |ln @ &DirectiveLine { line_number, .. }| { if !ln.applies_to_test_revision(test_revision) { @@ -1358,11 +1338,6 @@ pub(crate) fn make_test_description( }, ); - if local_poisoned { - eprintln!("errors encountered when trying to make test description: {}", path); - panic!("errors encountered when trying to make test description"); - } - // The `should-fail` annotation doesn't apply to pretty tests, // since we run the pretty printer across all tests by default. // If desired, we could add a `should-fail-pretty` annotation. diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 0bf2bcd3af43..e221c3a2daf2 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -3,8 +3,8 @@ use semver::Version; use crate::common::{Config, Debugger, TestMode}; use crate::directives::{ - AuxProps, DirectivesCache, EarlyProps, Edition, EditionRange, FileDirectives, - extract_llvm_version, extract_version_range, iter_directives, line_directive, parse_edition, + self, AuxProps, DirectivesCache, EarlyProps, Edition, EditionRange, FileDirectives, + extract_llvm_version, extract_version_range, line_directive, parse_edition, parse_normalize_rule, }; use crate::executor::{CollectedTestDesc, ShouldFail}; @@ -767,7 +767,10 @@ fn threads_support() { fn run_path(poisoned: &mut bool, path: &Utf8Path, file_contents: &str) { let file_directives = FileDirectives::from_file_contents(path, file_contents); - iter_directives(TestMode::Ui, poisoned, &file_directives, &mut |_| {}); + let result = directives::do_early_directives_check(TestMode::Ui, &file_directives); + if result.is_err() { + *poisoned = true; + } } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 89f5623c1fc9..a3a40a1a7ee8 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -869,6 +869,12 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te let file_contents = fs::read_to_string(&test_path).expect("reading test file for directives should succeed"); let file_directives = FileDirectives::from_file_contents(&test_path, &file_contents); + + if let Err(message) = directives::do_early_directives_check(cx.config.mode, &file_directives) { + // FIXME(Zalathar): Overhaul compiletest error handling so that we + // don't have to resort to ad-hoc panics everywhere. + panic!("directives check failed:\n{message}"); + } let early_props = EarlyProps::from_file_directives(&cx.config, &file_directives); // Normally we create one structure per revision, with two exceptions: From 5e73e6593f0d079ceb2b2400df7f50586cca3b70 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 25 Oct 2025 16:09:00 -0400 Subject: [PATCH 395/525] rename `rustc_target::spec::abi_map::Arch{,Kind}` This makes way for `rustc_target::spec::Arch`. --- compiler/rustc_target/src/spec/abi_map.rs | 74 ++++++++++++----------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index 23e74539ddc0..5370903d0d6a 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -8,7 +8,7 @@ use crate::spec::Target; /// encapsulating arch-specific ABI lowering details to make them more testable. #[derive(Clone, Debug)] pub struct AbiMap { - arch: Arch, + arch: ArchKind, os: OsKind, } @@ -48,17 +48,17 @@ impl AbiMap { pub fn from_target(target: &Target) -> Self { // the purpose of this little exercise is to force listing what affects these mappings let arch = match &*target.arch { - "aarch64" => Arch::Aarch64, - "amdgpu" => Arch::Amdgpu, - "arm" if target.llvm_target.starts_with("thumbv8m") => Arch::Arm(ArmVer::ThumbV8M), - "arm" => Arch::Arm(ArmVer::Other), - "avr" => Arch::Avr, - "msp430" => Arch::Msp430, - "nvptx64" => Arch::Nvptx, - "riscv32" | "riscv64" => Arch::Riscv, - "x86" => Arch::X86, - "x86_64" => Arch::X86_64, - _ => Arch::Other, + "aarch64" => ArchKind::Aarch64, + "amdgpu" => ArchKind::Amdgpu, + "arm" if target.llvm_target.starts_with("thumbv8m") => ArchKind::Arm(ArmVer::ThumbV8M), + "arm" => ArchKind::Arm(ArmVer::Other), + "avr" => ArchKind::Avr, + "msp430" => ArchKind::Msp430, + "nvptx64" => ArchKind::Nvptx, + "riscv32" | "riscv64" => ArchKind::Riscv, + "x86" => ArchKind::X86, + "x86_64" => ArchKind::X86_64, + _ => ArchKind::Other, }; let os = if target.is_like_windows { @@ -87,10 +87,12 @@ impl AbiMap { (ExternAbi::Custom, _) => CanonAbi::Custom, - (ExternAbi::System { .. }, Arch::X86) if os == OsKind::Windows && !has_c_varargs => { + (ExternAbi::System { .. }, ArchKind::X86) + if os == OsKind::Windows && !has_c_varargs => + { CanonAbi::X86(X86Call::Stdcall) } - (ExternAbi::System { .. }, Arch::Arm(..)) if self.os == OsKind::VEXos => { + (ExternAbi::System { .. }, ArchKind::Arm(..)) if self.os == OsKind::VEXos => { // Calls to VEXos APIs do not use VFP registers. CanonAbi::Arm(ArmCall::Aapcs) } @@ -101,19 +103,19 @@ impl AbiMap { // always and forever (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid, - (ExternAbi::EfiApi, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), - (ExternAbi::EfiApi, Arch::X86_64) => CanonAbi::X86(X86Call::Win64), - (ExternAbi::EfiApi, Arch::Aarch64 | Arch::Riscv | Arch::X86) => CanonAbi::C, + (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), + (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64), + (ExternAbi::EfiApi, ArchKind::Aarch64 | ArchKind::Riscv | ArchKind::X86) => CanonAbi::C, (ExternAbi::EfiApi, _) => return AbiMapping::Invalid, /* arm */ - (ExternAbi::Aapcs { .. }, Arch::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), + (ExternAbi::Aapcs { .. }, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), (ExternAbi::Aapcs { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::CmseNonSecureCall, Arch::Arm(ArmVer::ThumbV8M)) => { + (ExternAbi::CmseNonSecureCall, ArchKind::Arm(ArmVer::ThumbV8M)) => { CanonAbi::Arm(ArmCall::CCmseNonSecureCall) } - (ExternAbi::CmseNonSecureEntry, Arch::Arm(ArmVer::ThumbV8M)) => { + (ExternAbi::CmseNonSecureEntry, ArchKind::Arm(ArmVer::ThumbV8M)) => { CanonAbi::Arm(ArmCall::CCmseNonSecureEntry) } (ExternAbi::CmseNonSecureCall | ExternAbi::CmseNonSecureEntry, ..) => { @@ -121,53 +123,53 @@ impl AbiMap { } /* gpu */ - (ExternAbi::PtxKernel, Arch::Nvptx) => CanonAbi::GpuKernel, - (ExternAbi::GpuKernel, Arch::Amdgpu | Arch::Nvptx) => CanonAbi::GpuKernel, + (ExternAbi::PtxKernel, ArchKind::Nvptx) => CanonAbi::GpuKernel, + (ExternAbi::GpuKernel, ArchKind::Amdgpu | ArchKind::Nvptx) => CanonAbi::GpuKernel, (ExternAbi::PtxKernel | ExternAbi::GpuKernel, _) => return AbiMapping::Invalid, /* x86 */ - (ExternAbi::Cdecl { .. }, Arch::X86) => CanonAbi::C, + (ExternAbi::Cdecl { .. }, ArchKind::X86) => CanonAbi::C, (ExternAbi::Cdecl { .. }, _) => return AbiMapping::Deprecated(CanonAbi::C), - (ExternAbi::Fastcall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Fastcall), + (ExternAbi::Fastcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Fastcall), (ExternAbi::Fastcall { .. }, _) if os == OsKind::Windows => { return AbiMapping::Deprecated(CanonAbi::C); } (ExternAbi::Fastcall { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::Stdcall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Stdcall), + (ExternAbi::Stdcall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Stdcall), (ExternAbi::Stdcall { .. }, _) if os == OsKind::Windows => { return AbiMapping::Deprecated(CanonAbi::C); } (ExternAbi::Stdcall { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::Thiscall { .. }, Arch::X86) => CanonAbi::X86(X86Call::Thiscall), + (ExternAbi::Thiscall { .. }, ArchKind::X86) => CanonAbi::X86(X86Call::Thiscall), (ExternAbi::Thiscall { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::Vectorcall { .. }, Arch::X86 | Arch::X86_64) => { + (ExternAbi::Vectorcall { .. }, ArchKind::X86 | ArchKind::X86_64) => { CanonAbi::X86(X86Call::Vectorcall) } (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid, - (ExternAbi::SysV64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::SysV64), - (ExternAbi::Win64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::Win64), + (ExternAbi::SysV64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::SysV64), + (ExternAbi::Win64 { .. }, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64), (ExternAbi::SysV64 { .. } | ExternAbi::Win64 { .. }, _) => return AbiMapping::Invalid, /* interrupts */ - (ExternAbi::AvrInterrupt, Arch::Avr) => CanonAbi::Interrupt(InterruptKind::Avr), - (ExternAbi::AvrNonBlockingInterrupt, Arch::Avr) => { + (ExternAbi::AvrInterrupt, ArchKind::Avr) => CanonAbi::Interrupt(InterruptKind::Avr), + (ExternAbi::AvrNonBlockingInterrupt, ArchKind::Avr) => { CanonAbi::Interrupt(InterruptKind::AvrNonBlocking) } - (ExternAbi::Msp430Interrupt, Arch::Msp430) => { + (ExternAbi::Msp430Interrupt, ArchKind::Msp430) => { CanonAbi::Interrupt(InterruptKind::Msp430) } - (ExternAbi::RiscvInterruptM, Arch::Riscv) => { + (ExternAbi::RiscvInterruptM, ArchKind::Riscv) => { CanonAbi::Interrupt(InterruptKind::RiscvMachine) } - (ExternAbi::RiscvInterruptS, Arch::Riscv) => { + (ExternAbi::RiscvInterruptS, ArchKind::Riscv) => { CanonAbi::Interrupt(InterruptKind::RiscvSupervisor) } - (ExternAbi::X86Interrupt, Arch::X86 | Arch::X86_64) => { + (ExternAbi::X86Interrupt, ArchKind::X86 | ArchKind::X86_64) => { CanonAbi::Interrupt(InterruptKind::X86) } ( @@ -186,7 +188,7 @@ impl AbiMap { } #[derive(Debug, PartialEq, Copy, Clone)] -enum Arch { +enum ArchKind { Aarch64, Amdgpu, Arm(ArmVer), From cf053b37749a98e8e5ebcc63952aa9a232689316 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 25 Oct 2025 16:20:58 -0400 Subject: [PATCH 396/525] rustc_target::spec::base::apple: nix `use Arch::*` This will reduce ambiguity with `rustc_target::spec::Arch`. --- .../rustc_target/src/spec/base/apple/mod.rs | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index c32e333eb8b0..8f0b9a4517f9 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -11,7 +11,6 @@ use crate::spec::{ #[cfg(test)] mod tests; -use Arch::*; #[allow(non_camel_case_types)] #[derive(Copy, Clone, PartialEq)] pub(crate) enum Arch { @@ -29,54 +28,60 @@ pub(crate) enum Arch { impl Arch { fn target_name(self) -> &'static str { match self { - Armv7k => "armv7k", - Armv7s => "armv7s", - Arm64 => "arm64", - Arm64e => "arm64e", - Arm64_32 => "arm64_32", - I386 => "i386", - I686 => "i686", - X86_64 => "x86_64", - X86_64h => "x86_64h", + Self::Armv7k => "armv7k", + Self::Armv7s => "armv7s", + Self::Arm64 => "arm64", + Self::Arm64e => "arm64e", + Self::Arm64_32 => "arm64_32", + Self::I386 => "i386", + Self::I686 => "i686", + Self::X86_64 => "x86_64", + Self::X86_64h => "x86_64h", } } pub(crate) fn target_arch(self) -> Cow<'static, str> { Cow::Borrowed(match self { - Armv7k | Armv7s => "arm", - Arm64 | Arm64e | Arm64_32 => "aarch64", - I386 | I686 => "x86", - X86_64 | X86_64h => "x86_64", + Self::Armv7k | Self::Armv7s => "arm", + Self::Arm64 | Self::Arm64e | Self::Arm64_32 => "aarch64", + Self::I386 | Self::I686 => "x86", + Self::X86_64 | Self::X86_64h => "x86_64", }) } fn target_cpu(self, env: TargetEnv) -> &'static str { match self { - Armv7k => "cortex-a8", - Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher. - Arm64 => match env { + Self::Armv7k => "cortex-a8", + Self::Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher. + Self::Arm64 => match env { TargetEnv::Normal => "apple-a7", TargetEnv::Simulator => "apple-a12", TargetEnv::MacCatalyst => "apple-a12", }, - Arm64e => "apple-a12", - Arm64_32 => "apple-s4", + Self::Arm64e => "apple-a12", + Self::Arm64_32 => "apple-s4", // Only macOS 10.12+ is supported, which means // all x86_64/x86 CPUs must be running at least penryn // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82 - I386 | I686 => "penryn", - X86_64 => "penryn", + Self::I386 | Self::I686 => "penryn", + Self::X86_64 => "penryn", // Note: `core-avx2` is slightly more advanced than `x86_64h`, see // comments (and disabled features) in `x86_64h_apple_darwin` for // details. It is a higher baseline then `penryn` however. - X86_64h => "core-avx2", + Self::X86_64h => "core-avx2", } } fn stack_probes(self) -> StackProbeType { match self { - Armv7k | Armv7s => StackProbeType::None, - Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => StackProbeType::Inline, + Self::Armv7k | Self::Armv7s => StackProbeType::None, + Self::Arm64 + | Self::Arm64e + | Self::Arm64_32 + | Self::I386 + | Self::I686 + | Self::X86_64 + | Self::X86_64h => StackProbeType::Inline, } } } @@ -132,10 +137,10 @@ pub(crate) fn base( default_dwarf_version: 4, frame_pointer: match arch { // clang ignores `-fomit-frame-pointer` for Armv7, it only accepts `-momit-leaf-frame-pointer` - Armv7k | Armv7s => FramePointer::Always, + Arch::Armv7k | Arch::Armv7s => FramePointer::Always, // clang supports omitting frame pointers for the rest, but... don't? - Arm64 | Arm64e | Arm64_32 => FramePointer::NonLeaf, - I386 | I686 | X86_64 | X86_64h => FramePointer::Always, + Arch::Arm64 | Arch::Arm64e | Arch::Arm64_32 => FramePointer::NonLeaf, + Arch::I386 | Arch::I686 | Arch::X86_64 | Arch::X86_64h => FramePointer::Always, }, has_rpath: true, dll_suffix: ".dylib".into(), From 270e49b3072fe03ea388ebbb76e0eee80ee27565 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 13 Oct 2025 12:41:24 -0400 Subject: [PATCH 397/525] rustc_target: introduce Arch Improve type safety by using an enum rather than strings. --- .../src/attributes/link_attrs.rs | 4 +- .../rustc_codegen_cranelift/src/abi/mod.rs | 17 +- .../src/codegen_f16_f128.rs | 10 +- .../rustc_codegen_cranelift/src/common.rs | 4 +- compiler/rustc_codegen_cranelift/src/lib.rs | 23 +-- compiler/rustc_codegen_gcc/src/abi.rs | 20 +- compiler/rustc_codegen_gcc/src/attributes.rs | 8 +- compiler/rustc_codegen_gcc/src/base.rs | 4 +- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_codegen_gcc/src/gcc_util.rs | 68 ++++--- compiler/rustc_codegen_gcc/src/lib.rs | 4 +- compiler/rustc_codegen_llvm/src/abi.rs | 17 +- compiler/rustc_codegen_llvm/src/attributes.rs | 8 +- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +- compiler/rustc_codegen_llvm/src/builder.rs | 11 +- compiler/rustc_codegen_llvm/src/callee.rs | 3 +- compiler/rustc_codegen_llvm/src/consts.rs | 3 +- compiler/rustc_codegen_llvm/src/context.rs | 18 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 183 ++++++++++-------- compiler/rustc_codegen_llvm/src/mono_item.rs | 4 +- compiler/rustc_codegen_llvm/src/va_arg.rs | 37 ++-- compiler/rustc_codegen_ssa/src/back/apple.rs | 6 +- .../rustc_codegen_ssa/src/back/archive.rs | 43 ++-- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- .../src/back/link/raw_dylib.rs | 3 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 16 +- .../src/back/symbol_export.rs | 10 +- compiler/rustc_codegen_ssa/src/base.rs | 7 +- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 3 +- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 4 +- .../rustc_codegen_ssa/src/target_features.rs | 3 +- compiler/rustc_metadata/src/native_libs.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_session/src/config/cfg.rs | 4 +- compiler/rustc_session/src/session.rs | 18 +- compiler/rustc_target/src/asm/mod.rs | 65 +++---- compiler/rustc_target/src/callconv/mod.rs | 66 ++++--- compiler/rustc_target/src/spec/abi_map.rs | 27 +-- .../rustc_target/src/spec/base/apple/mod.rs | 34 ++-- .../rustc_target/src/spec/base/nto_qnx.rs | 4 +- compiler/rustc_target/src/spec/json.rs | 4 +- compiler/rustc_target/src/spec/mod.rs | 137 ++++++++----- .../spec/targets/aarch64_be_unknown_hermit.rs | 4 +- .../targets/aarch64_be_unknown_linux_gnu.rs | 6 +- .../aarch64_be_unknown_linux_gnu_ilp32.rs | 6 +- .../targets/aarch64_be_unknown_linux_musl.rs | 4 +- .../spec/targets/aarch64_be_unknown_netbsd.rs | 4 +- .../aarch64_be_unknown_none_softfloat.rs | 4 +- .../spec/targets/aarch64_kmc_solid_asp3.rs | 4 +- .../src/spec/targets/aarch64_linux_android.rs | 4 +- .../aarch64_nintendo_switch_freestanding.rs | 4 +- .../targets/aarch64_pc_windows_gnullvm.rs | 4 +- .../spec/targets/aarch64_pc_windows_msvc.rs | 4 +- .../spec/targets/aarch64_unknown_freebsd.rs | 6 +- .../spec/targets/aarch64_unknown_fuchsia.rs | 4 +- .../spec/targets/aarch64_unknown_helenos.rs | 4 +- .../spec/targets/aarch64_unknown_hermit.rs | 4 +- .../spec/targets/aarch64_unknown_illumos.rs | 4 +- .../spec/targets/aarch64_unknown_linux_gnu.rs | 4 +- .../aarch64_unknown_linux_gnu_ilp32.rs | 6 +- .../targets/aarch64_unknown_linux_musl.rs | 4 +- .../targets/aarch64_unknown_linux_ohos.rs | 4 +- .../targets/aarch64_unknown_managarm_mlibc.rs | 4 +- .../spec/targets/aarch64_unknown_netbsd.rs | 4 +- .../src/spec/targets/aarch64_unknown_none.rs | 4 +- .../targets/aarch64_unknown_none_softfloat.rs | 4 +- .../src/spec/targets/aarch64_unknown_nuttx.rs | 4 +- .../spec/targets/aarch64_unknown_openbsd.rs | 4 +- .../src/spec/targets/aarch64_unknown_redox.rs | 4 +- .../src/spec/targets/aarch64_unknown_teeos.rs | 4 +- .../spec/targets/aarch64_unknown_trusty.rs | 5 +- .../src/spec/targets/aarch64_unknown_uefi.rs | 4 +- .../spec/targets/aarch64_uwp_windows_msvc.rs | 4 +- .../src/spec/targets/aarch64_wrs_vxworks.rs | 4 +- .../src/spec/targets/amdgcn_amd_amdhsa.rs | 6 +- .../spec/targets/arm64ec_pc_windows_msvc.rs | 6 +- .../src/spec/targets/arm_linux_androideabi.rs | 4 +- .../spec/targets/arm_unknown_linux_gnueabi.rs | 4 +- .../targets/arm_unknown_linux_gnueabihf.rs | 4 +- .../targets/arm_unknown_linux_musleabi.rs | 4 +- .../targets/arm_unknown_linux_musleabihf.rs | 4 +- .../targets/armeb_unknown_linux_gnueabi.rs | 4 +- .../src/spec/targets/armebv7r_none_eabi.rs | 4 +- .../src/spec/targets/armebv7r_none_eabihf.rs | 4 +- .../src/spec/targets/armv4t_none_eabi.rs | 4 +- .../targets/armv4t_unknown_linux_gnueabi.rs | 4 +- .../src/spec/targets/armv5te_none_eabi.rs | 4 +- .../targets/armv5te_unknown_linux_gnueabi.rs | 4 +- .../targets/armv5te_unknown_linux_musleabi.rs | 4 +- .../armv5te_unknown_linux_uclibceabi.rs | 4 +- .../src/spec/targets/armv6_unknown_freebsd.rs | 4 +- .../targets/armv6_unknown_netbsd_eabihf.rs | 4 +- .../src/spec/targets/armv6k_nintendo_3ds.rs | 4 +- .../spec/targets/armv7_linux_androideabi.rs | 5 +- .../src/spec/targets/armv7_rtems_eabihf.rs | 4 +- .../targets/armv7_sony_vita_newlibeabihf.rs | 4 +- .../src/spec/targets/armv7_unknown_freebsd.rs | 4 +- .../targets/armv7_unknown_linux_gnueabi.rs | 4 +- .../targets/armv7_unknown_linux_gnueabihf.rs | 4 +- .../targets/armv7_unknown_linux_musleabi.rs | 4 +- .../targets/armv7_unknown_linux_musleabihf.rs | 4 +- .../spec/targets/armv7_unknown_linux_ohos.rs | 4 +- .../targets/armv7_unknown_linux_uclibceabi.rs | 4 +- .../armv7_unknown_linux_uclibceabihf.rs | 4 +- .../targets/armv7_unknown_netbsd_eabihf.rs | 4 +- .../src/spec/targets/armv7_unknown_trusty.rs | 4 +- .../spec/targets/armv7_wrs_vxworks_eabihf.rs | 4 +- .../targets/armv7a_kmc_solid_asp3_eabi.rs | 4 +- .../targets/armv7a_kmc_solid_asp3_eabihf.rs | 4 +- .../src/spec/targets/armv7a_none_eabi.rs | 4 +- .../src/spec/targets/armv7a_none_eabihf.rs | 4 +- .../src/spec/targets/armv7a_nuttx_eabi.rs | 4 +- .../src/spec/targets/armv7a_nuttx_eabihf.rs | 4 +- .../src/spec/targets/armv7a_vex_v5.rs | 4 +- .../src/spec/targets/armv7r_none_eabi.rs | 4 +- .../src/spec/targets/armv7r_none_eabihf.rs | 4 +- .../src/spec/targets/armv8r_none_eabihf.rs | 4 +- .../rustc_target/src/spec/targets/avr_none.rs | 4 +- .../src/spec/targets/bpfeb_unknown_none.rs | 4 +- .../src/spec/targets/bpfel_unknown_none.rs | 4 +- .../targets/csky_unknown_linux_gnuabiv2.rs | 4 +- .../targets/csky_unknown_linux_gnuabiv2hf.rs | 4 +- .../targets/hexagon_unknown_linux_musl.rs | 4 +- .../spec/targets/hexagon_unknown_none_elf.rs | 4 +- .../src/spec/targets/i586_unknown_netbsd.rs | 4 +- .../src/spec/targets/i586_unknown_redox.rs | 4 +- .../src/spec/targets/i686_linux_android.rs | 4 +- .../src/spec/targets/i686_pc_nto_qnx700.rs | 4 +- .../src/spec/targets/i686_pc_windows_gnu.rs | 4 +- .../spec/targets/i686_pc_windows_gnullvm.rs | 6 +- .../src/spec/targets/i686_pc_windows_msvc.rs | 4 +- .../src/spec/targets/i686_unknown_freebsd.rs | 6 +- .../src/spec/targets/i686_unknown_haiku.rs | 6 +- .../src/spec/targets/i686_unknown_helenos.rs | 4 +- .../src/spec/targets/i686_unknown_hurd_gnu.rs | 4 +- .../spec/targets/i686_unknown_linux_gnu.rs | 5 +- .../spec/targets/i686_unknown_linux_musl.rs | 5 +- .../src/spec/targets/i686_unknown_netbsd.rs | 5 +- .../src/spec/targets/i686_unknown_openbsd.rs | 6 +- .../src/spec/targets/i686_unknown_uefi.rs | 4 +- .../src/spec/targets/i686_uwp_windows_gnu.rs | 6 +- .../src/spec/targets/i686_uwp_windows_msvc.rs | 4 +- .../src/spec/targets/i686_win7_windows_gnu.rs | 6 +- .../spec/targets/i686_win7_windows_msvc.rs | 4 +- .../src/spec/targets/i686_wrs_vxworks.rs | 6 +- .../spec/targets/loongarch32_unknown_none.rs | 4 +- .../loongarch32_unknown_none_softfloat.rs | 4 +- .../targets/loongarch64_unknown_linux_gnu.rs | 4 +- .../targets/loongarch64_unknown_linux_musl.rs | 4 +- .../targets/loongarch64_unknown_linux_ohos.rs | 4 +- .../spec/targets/loongarch64_unknown_none.rs | 4 +- .../loongarch64_unknown_none_softfloat.rs | 4 +- .../spec/targets/m68k_unknown_linux_gnu.rs | 4 +- .../src/spec/targets/m68k_unknown_none_elf.rs | 6 +- .../spec/targets/mips64_openwrt_linux_musl.rs | 4 +- .../targets/mips64_unknown_linux_gnuabi64.rs | 4 +- .../targets/mips64_unknown_linux_muslabi64.rs | 4 +- .../mips64el_unknown_linux_gnuabi64.rs | 4 +- .../mips64el_unknown_linux_muslabi64.rs | 4 +- .../src/spec/targets/mips_mti_none_elf.rs | 4 +- .../spec/targets/mips_unknown_linux_gnu.rs | 4 +- .../spec/targets/mips_unknown_linux_musl.rs | 4 +- .../spec/targets/mips_unknown_linux_uclibc.rs | 4 +- .../src/spec/targets/mipsel_mti_none_elf.rs | 4 +- .../src/spec/targets/mipsel_sony_psp.rs | 6 +- .../src/spec/targets/mipsel_sony_psx.rs | 5 +- .../spec/targets/mipsel_unknown_linux_gnu.rs | 4 +- .../spec/targets/mipsel_unknown_linux_musl.rs | 4 +- .../targets/mipsel_unknown_linux_uclibc.rs | 4 +- .../src/spec/targets/mipsel_unknown_netbsd.rs | 4 +- .../src/spec/targets/mipsel_unknown_none.rs | 4 +- .../targets/mipsisa32r6_unknown_linux_gnu.rs | 4 +- .../mipsisa32r6el_unknown_linux_gnu.rs | 4 +- .../mipsisa64r6_unknown_linux_gnuabi64.rs | 4 +- .../mipsisa64r6el_unknown_linux_gnuabi64.rs | 4 +- .../src/spec/targets/msp430_none_elf.rs | 4 +- .../src/spec/targets/nvptx64_nvidia_cuda.rs | 6 +- .../src/spec/targets/powerpc64_ibm_aix.rs | 4 +- .../spec/targets/powerpc64_unknown_freebsd.rs | 4 +- .../targets/powerpc64_unknown_linux_gnu.rs | 4 +- .../targets/powerpc64_unknown_linux_musl.rs | 4 +- .../spec/targets/powerpc64_unknown_openbsd.rs | 4 +- .../src/spec/targets/powerpc64_wrs_vxworks.rs | 4 +- .../targets/powerpc64le_unknown_freebsd.rs | 4 +- .../targets/powerpc64le_unknown_linux_gnu.rs | 4 +- .../targets/powerpc64le_unknown_linux_musl.rs | 4 +- .../spec/targets/powerpc_unknown_freebsd.rs | 4 +- .../spec/targets/powerpc_unknown_helenos.rs | 4 +- .../spec/targets/powerpc_unknown_linux_gnu.rs | 4 +- .../targets/powerpc_unknown_linux_gnuspe.rs | 4 +- .../targets/powerpc_unknown_linux_musl.rs | 4 +- .../targets/powerpc_unknown_linux_muslspe.rs | 4 +- .../spec/targets/powerpc_unknown_netbsd.rs | 4 +- .../spec/targets/powerpc_unknown_openbsd.rs | 4 +- .../src/spec/targets/powerpc_wrs_vxworks.rs | 4 +- .../spec/targets/powerpc_wrs_vxworks_spe.rs | 4 +- .../src/spec/targets/riscv32_wrs_vxworks.rs | 4 +- .../spec/targets/riscv32e_unknown_none_elf.rs | 4 +- .../targets/riscv32em_unknown_none_elf.rs | 4 +- .../targets/riscv32emc_unknown_none_elf.rs | 4 +- .../targets/riscv32gc_unknown_linux_gnu.rs | 4 +- .../targets/riscv32gc_unknown_linux_musl.rs | 4 +- .../spec/targets/riscv32i_unknown_none_elf.rs | 4 +- .../spec/targets/riscv32im_risc0_zkvm_elf.rs | 4 +- .../targets/riscv32im_unknown_none_elf.rs | 4 +- .../targets/riscv32ima_unknown_none_elf.rs | 4 +- .../spec/targets/riscv32imac_esp_espidf.rs | 4 +- .../targets/riscv32imac_unknown_none_elf.rs | 4 +- .../targets/riscv32imac_unknown_nuttx_elf.rs | 5 +- .../targets/riscv32imac_unknown_xous_elf.rs | 4 +- .../spec/targets/riscv32imafc_esp_espidf.rs | 4 +- .../targets/riscv32imafc_unknown_none_elf.rs | 4 +- .../targets/riscv32imafc_unknown_nuttx_elf.rs | 5 +- .../src/spec/targets/riscv32imc_esp_espidf.rs | 4 +- .../targets/riscv32imc_unknown_none_elf.rs | 4 +- .../targets/riscv32imc_unknown_nuttx_elf.rs | 5 +- .../src/spec/targets/riscv64_linux_android.rs | 4 +- .../src/spec/targets/riscv64_wrs_vxworks.rs | 4 +- .../targets/riscv64a23_unknown_linux_gnu.rs | 4 +- .../spec/targets/riscv64gc_unknown_freebsd.rs | 4 +- .../spec/targets/riscv64gc_unknown_fuchsia.rs | 4 +- .../spec/targets/riscv64gc_unknown_hermit.rs | 6 +- .../targets/riscv64gc_unknown_linux_gnu.rs | 4 +- .../targets/riscv64gc_unknown_linux_musl.rs | 4 +- .../riscv64gc_unknown_managarm_mlibc.rs | 4 +- .../spec/targets/riscv64gc_unknown_netbsd.rs | 4 +- .../targets/riscv64gc_unknown_none_elf.rs | 4 +- .../targets/riscv64gc_unknown_nuttx_elf.rs | 4 +- .../spec/targets/riscv64gc_unknown_openbsd.rs | 4 +- .../spec/targets/riscv64gc_unknown_redox.rs | 4 +- .../targets/riscv64imac_unknown_none_elf.rs | 4 +- .../targets/riscv64imac_unknown_nuttx_elf.rs | 4 +- .../spec/targets/s390x_unknown_linux_gnu.rs | 4 +- .../spec/targets/s390x_unknown_linux_musl.rs | 4 +- .../spec/targets/sparc64_unknown_helenos.rs | 4 +- .../spec/targets/sparc64_unknown_linux_gnu.rs | 4 +- .../spec/targets/sparc64_unknown_netbsd.rs | 4 +- .../spec/targets/sparc64_unknown_openbsd.rs | 4 +- .../spec/targets/sparc_unknown_linux_gnu.rs | 4 +- .../spec/targets/sparc_unknown_none_elf.rs | 4 +- .../src/spec/targets/sparcv9_sun_solaris.rs | 4 +- .../src/spec/targets/thumbv4t_none_eabi.rs | 6 +- .../src/spec/targets/thumbv5te_none_eabi.rs | 4 +- .../src/spec/targets/thumbv6m_none_eabi.rs | 4 +- .../src/spec/targets/thumbv6m_nuttx_eabi.rs | 4 +- .../src/spec/targets/thumbv7a_nuttx_eabi.rs | 4 +- .../src/spec/targets/thumbv7a_nuttx_eabihf.rs | 4 +- .../spec/targets/thumbv7a_pc_windows_msvc.rs | 4 +- .../spec/targets/thumbv7a_uwp_windows_msvc.rs | 4 +- .../src/spec/targets/thumbv7em_none_eabi.rs | 4 +- .../src/spec/targets/thumbv7em_none_eabihf.rs | 4 +- .../src/spec/targets/thumbv7em_nuttx_eabi.rs | 4 +- .../spec/targets/thumbv7em_nuttx_eabihf.rs | 4 +- .../src/spec/targets/thumbv7m_none_eabi.rs | 4 +- .../src/spec/targets/thumbv7m_nuttx_eabi.rs | 4 +- .../targets/thumbv7neon_linux_androideabi.rs | 6 +- .../thumbv7neon_unknown_linux_gnueabihf.rs | 4 +- .../thumbv7neon_unknown_linux_musleabihf.rs | 4 +- .../spec/targets/thumbv8m_base_none_eabi.rs | 4 +- .../spec/targets/thumbv8m_base_nuttx_eabi.rs | 4 +- .../spec/targets/thumbv8m_main_none_eabi.rs | 4 +- .../spec/targets/thumbv8m_main_none_eabihf.rs | 4 +- .../spec/targets/thumbv8m_main_nuttx_eabi.rs | 4 +- .../targets/thumbv8m_main_nuttx_eabihf.rs | 4 +- .../spec/targets/wasm32_unknown_emscripten.rs | 6 +- .../spec/targets/wasm32_unknown_unknown.rs | 4 +- .../spec/targets/wasm32_wali_linux_musl.rs | 4 +- .../src/spec/targets/wasm32_wasip1.rs | 4 +- .../src/spec/targets/wasm32_wasip1_threads.rs | 4 +- .../src/spec/targets/wasm32_wasip2.rs | 4 +- .../src/spec/targets/wasm32v1_none.rs | 4 +- .../spec/targets/wasm64_unknown_unknown.rs | 4 +- .../targets/x86_64_fortanix_unknown_sgx.rs | 4 +- .../src/spec/targets/x86_64_linux_android.rs | 6 +- .../src/spec/targets/x86_64_lynx_lynxos178.rs | 4 +- .../src/spec/targets/x86_64_pc_cygwin.rs | 4 +- .../src/spec/targets/x86_64_pc_solaris.rs | 6 +- .../src/spec/targets/x86_64_pc_windows_gnu.rs | 4 +- .../spec/targets/x86_64_pc_windows_gnullvm.rs | 4 +- .../spec/targets/x86_64_pc_windows_msvc.rs | 4 +- .../targets/x86_64_unikraft_linux_musl.rs | 4 +- .../spec/targets/x86_64_unknown_dragonfly.rs | 4 +- .../spec/targets/x86_64_unknown_freebsd.rs | 4 +- .../spec/targets/x86_64_unknown_fuchsia.rs | 4 +- .../src/spec/targets/x86_64_unknown_haiku.rs | 4 +- .../spec/targets/x86_64_unknown_helenos.rs | 4 +- .../src/spec/targets/x86_64_unknown_hermit.rs | 4 +- .../spec/targets/x86_64_unknown_hurd_gnu.rs | 4 +- .../spec/targets/x86_64_unknown_illumos.rs | 4 +- .../targets/x86_64_unknown_l4re_uclibc.rs | 4 +- .../spec/targets/x86_64_unknown_linux_gnu.rs | 4 +- .../targets/x86_64_unknown_linux_gnux32.rs | 4 +- .../spec/targets/x86_64_unknown_linux_musl.rs | 4 +- .../spec/targets/x86_64_unknown_linux_none.rs | 4 +- .../spec/targets/x86_64_unknown_linux_ohos.rs | 4 +- .../targets/x86_64_unknown_managarm_mlibc.rs | 4 +- .../src/spec/targets/x86_64_unknown_motor.rs | 4 +- .../src/spec/targets/x86_64_unknown_netbsd.rs | 6 +- .../src/spec/targets/x86_64_unknown_none.rs | 4 +- .../spec/targets/x86_64_unknown_openbsd.rs | 4 +- .../src/spec/targets/x86_64_unknown_redox.rs | 4 +- .../src/spec/targets/x86_64_unknown_trusty.rs | 6 +- .../src/spec/targets/x86_64_unknown_uefi.rs | 4 +- .../spec/targets/x86_64_uwp_windows_gnu.rs | 4 +- .../spec/targets/x86_64_uwp_windows_msvc.rs | 4 +- .../spec/targets/x86_64_win7_windows_gnu.rs | 4 +- .../spec/targets/x86_64_win7_windows_msvc.rs | 4 +- .../src/spec/targets/x86_64_wrs_vxworks.rs | 4 +- .../src/spec/targets/xtensa_esp32_espidf.rs | 4 +- .../src/spec/targets/xtensa_esp32_none_elf.rs | 4 +- .../src/spec/targets/xtensa_esp32s2_espidf.rs | 4 +- .../spec/targets/xtensa_esp32s2_none_elf.rs | 4 +- .../src/spec/targets/xtensa_esp32s3_espidf.rs | 4 +- .../spec/targets/xtensa_esp32s3_none_elf.rs | 4 +- compiler/rustc_target/src/target_features.rs | 98 ++++++---- src/tools/miri/src/machine.rs | 7 +- src/tools/miri/src/shims/alloc.rs | 43 +++- src/tools/miri/src/shims/foreign_items.rs | 13 +- .../miri/src/shims/windows/foreign_items.rs | 3 +- src/tools/miri/src/shims/x86/bmi.rs | 3 +- src/tools/miri/src/shims/x86/mod.rs | 7 +- src/tools/miri/src/shims/x86/sse42.rs | 3 +- 322 files changed, 1209 insertions(+), 1030 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 065ed8959fc7..5a4a4e759910 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -4,7 +4,7 @@ use rustc_hir::attrs::*; use rustc_session::Session; use rustc_session::parse::feature_err; use rustc_span::kw; -use rustc_target::spec::BinaryFormat; +use rustc_target::spec::{Arch, BinaryFormat}; use super::prelude::*; use super::util::parse_single_integer; @@ -438,7 +438,7 @@ impl LinkParser { cx.expected_name_value(item.span(), Some(sym::import_name_type)); return true; }; - if cx.sess().target.arch != "x86" { + if cx.sess().target.arch != Arch::X86 { cx.emit_err(ImportNameTypeX86 { span: item.span() }); return true; } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 9a9a1f4a2c0f..6ea26b02c261 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; +use rustc_target::spec::Arch; use smallvec::SmallVec; use self::pass_mode::*; @@ -155,7 +156,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let ret = self.lib_call_unadjusted(name, params, returns, &args)[0]; Cow::Owned(vec![codegen_bitcast(self, types::I128, ret)]) - } else if ret_single_i128 && self.tcx.sess.target.arch == "s390x" { + } else if ret_single_i128 && self.tcx.sess.target.arch == Arch::S390x { // Return i128 using a return area pointer on s390x. let mut params = params; let mut args = args.to_vec(); @@ -641,7 +642,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), ); - if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == "aarch64" { + if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == 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. @@ -787,25 +788,25 @@ pub(crate) fn codegen_drop<'tcx>( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (&*tcx.sess.target.arch, &*tcx.sess.target.vendor) { - ("x86_64", _) | ("aarch64", "apple") => match (ty, is_signed) { + match (tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { + (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), _ => param, }, - ("aarch64", _) => param, - ("riscv64", _) => match (ty, is_signed) { + (Arch::AArch64, _) => param, + (Arch::RiscV64, _) => match (ty, is_signed) { (types::I32, _) | (_, true) => param.sext(), _ => param.uext(), }, - ("s390x", _) => { + (Arch::S390x, _) => { if is_signed { param.sext() } else { param.uext() } } - _ => unimplemented!("{:?}", tcx.sess.target.arch), + (arch, _) => unimplemented!("{arch:?}"), } } else { param diff --git a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs index 1e202be1f185..c0f6d9d853db 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs @@ -1,8 +1,10 @@ +use rustc_target::spec::Arch; + use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { let (value, arg_ty) = - if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 { ( fx.bcx.ins().bitcast(types::I16, MemFlags::new(), value), lib_call_arg_param(fx.tcx, types::I16, false), @@ -19,7 +21,8 @@ fn f16_to_f64(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { } pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 + { types::I16 } else { types::F16 @@ -34,7 +37,8 @@ pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value } fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 + { types::I16 } else { types::F16 diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 81b1814605a1..de3d2f31af10 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{ }; use rustc_span::source_map::Spanned; use rustc_target::callconv::FnAbi; -use rustc_target::spec::{HasTargetSpec, Target}; +use rustc_target::spec::{Arch, HasTargetSpec, Target}; use crate::constant::ConstantCx; use crate::debuginfo::FunctionDebugContext; @@ -373,7 +373,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { "size must be a multiple of alignment (size={size}, align={align})" ); - let abi_align = if self.tcx.sess.target.arch == "s390x" { 8 } else { 16 }; + let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 }; if align <= abi_align { let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 5d48d0c94c58..5c23cd02e0d3 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -50,6 +50,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; +use rustc_target::spec::Arch; pub use crate::config::*; use crate::prelude::*; @@ -186,20 +187,20 @@ impl CodegenBackend for CraneliftCodegenBackend { fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] - let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" { - // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled - vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] - } else if sess.target.arch == "aarch64" { - match &*sess.target.os { + let target_features = match sess.target.arch { + Arch::X86_64 if sess.target.os != "none" => { + // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled + vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] + } + Arch::AArch64 => match &*sess.target.os { "none" => vec![], // On macOS the aes, sha2 and sha3 features are enabled by default and ring // fails to compile on macOS when they are not present. "macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], // AArch64 mandates Neon support _ => vec![sym::neon], - } - } else { - vec![] + }, + _ => vec![], }; // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); @@ -208,14 +209,14 @@ impl CodegenBackend for CraneliftCodegenBackend { // Windows, whereas LLVM 21+ and Cranelift pass it indirectly. This means that `f128` won't // work when linking against a LLVM-built sysroot. let has_reliable_f128 = !sess.target.is_like_windows; - let has_reliable_f16 = match &*sess.target.arch { + let has_reliable_f16 = match sess.target.arch { // FIXME(f16_f128): LLVM 20 does not support `f16` on s390x, meaning the required // builtins are not available in `compiler-builtins`. - "s390x" => false, + Arch::S390x => false, // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU // targets due to GCC using a different ABI than LLVM. Therefore `f16` won't be // available when using a LLVM-built sysroot. - "x86_64" + Arch::X86_64 if sess.target.os == "windows" && sess.target.env == "gnu" && sess.target.abi != "llvm" => diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 0b359f1c5c81..b7d0e19ee272 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -12,6 +12,8 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; +#[cfg(feature = "master")] +use rustc_target::spec::Arch; use crate::builder::Builder; use crate::context::CodegenCx; @@ -233,12 +235,12 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { #[cfg(feature = "master")] fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { - conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) + conv_to_fn_attribute(self.conv, cx.tcx.sess.target.arch) } } #[cfg(feature = "master")] -pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &str) -> Option> { +pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, CanonAbi::RustCold => FnAttribute::Cold, @@ -251,15 +253,11 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &str) -> Option FnAttribute::ArmCmseNonsecureEntry, ArmCall::Aapcs => FnAttribute::ArmPcs("aapcs"), }, - CanonAbi::GpuKernel => { - if arch == "amdgpu" { - FnAttribute::GcnAmdGpuHsaKernel - } else if arch == "nvptx64" { - FnAttribute::NvptxKernel - } else { - panic!("Architecture {} does not support GpuKernel calling convention", arch); - } - } + CanonAbi::GpuKernel => match arch { + Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, + Arch::Nvptx64 => FnAttribute::NvptxKernel, + arch => panic!("Arch {arch} does not support GpuKernel calling convention"), + }, // TODO(antoyo): check if those AVR attributes are mapped correctly. CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { InterruptKind::Avr => FnAttribute::AvrSignal, diff --git a/compiler/rustc_codegen_gcc/src/attributes.rs b/compiler/rustc_codegen_gcc/src/attributes.rs index 04b43bb8bb7c..5df1dc41b01d 100644 --- a/compiler/rustc_codegen_gcc/src/attributes.rs +++ b/compiler/rustc_codegen_gcc/src/attributes.rs @@ -9,6 +9,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; #[cfg(feature = "master")] use rustc_middle::mir::TerminatorKind; use rustc_middle::ty; +#[cfg(feature = "master")] +use rustc_target::spec::Arch; use crate::context::CodegenCx; use crate::gcc_util::to_gcc_features; @@ -70,7 +72,7 @@ fn inline_attr<'gcc, 'tcx>( InlineAttr::Hint => Some(FnAttribute::Inline), InlineAttr::Force { .. } => Some(FnAttribute::AlwaysInline), InlineAttr::Never => { - if cx.sess().target.arch != "amdgpu" { + if cx.sess().target.arch != Arch::AmdGpu { Some(FnAttribute::NoInline) } else { None @@ -153,8 +155,8 @@ pub fn from_fn_attrs<'gcc, 'tcx>( .join(","); if !target_features.is_empty() { #[cfg(feature = "master")] - match cx.sess().target.arch.as_ref() { - "x86" | "x86_64" | "powerpc" => { + match cx.sess().target.arch { + Arch::X86 | Arch::X86_64 | Arch::PowerPC => { func.add_attribute(FnAttribute::Target(&target_features)) } // The target attribute is not supported on other targets in GCC. diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index e8672f49580b..0a0f0ed37f0b 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; use rustc_span::Symbol; -use rustc_target::spec::RelocModel; #[cfg(feature = "master")] use rustc_target::spec::SymbolVisibility; +use rustc_target::spec::{Arch, RelocModel}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -116,7 +116,7 @@ pub fn compile_codegen_unit( .map(|string| &string[1..]) .collect(); - if !disabled_features.contains("avx") && tcx.sess.target.arch == "x86_64" { + if !disabled_features.contains("avx") && tcx.sess.target.arch == Arch::X86_64 { // NOTE: we always enable AVX because the equivalent of llvm.x86.sse2.cmp.pd in GCC for // SSE2 is multiple builtins, so we use the AVX __builtin_ia32_cmppd instead. // FIXME(antoyo): use the proper builtins for llvm.x86.sse2.cmp.pd and similar. diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index c9ae96777de4..6084b4fc07fa 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -487,7 +487,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { #[cfg(feature = "master")] - let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch); + let conv = conv_to_fn_attribute(self.sess().target.entry_abi, self.sess().target.arch); #[cfg(not(feature = "master"))] let conv = None; Some(self.declare_entry_fn(entry_name, fn_type, conv)) diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 702704ddf136..83d54472e5de 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -3,6 +3,7 @@ use gccjit::Context; use rustc_codegen_ssa::target_features; use rustc_data_structures::smallvec::{SmallVec, smallvec}; use rustc_session::Session; +use rustc_target::spec::Arch; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { target_features::retpoline_features_by_flags(sess, features); @@ -65,44 +66,47 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> { - let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch }; // cSpell:disable - match (arch, s) { + match (sess.target.arch, s) { // FIXME: seems like x87 does not exist? - ("x86", "x87") => smallvec![], - ("x86", "sse4.2") => smallvec!["sse4.2", "crc32"], - ("x86", "pclmulqdq") => smallvec!["pclmul"], - ("x86", "rdrand") => smallvec!["rdrnd"], - ("x86", "bmi1") => smallvec!["bmi"], - ("x86", "cmpxchg16b") => smallvec!["cx16"], - ("x86", "avx512vaes") => smallvec!["vaes"], - ("x86", "avx512gfni") => smallvec!["gfni"], - ("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], + (Arch::X86 | Arch::X86_64, "x87") => smallvec![], + (Arch::X86 | Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], + (Arch::X86 | Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], + (Arch::X86 | Arch::X86_64, "rdrand") => smallvec!["rdrnd"], + (Arch::X86 | Arch::X86_64, "bmi1") => smallvec!["bmi"], + (Arch::X86 | Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], + (Arch::X86 | Arch::X86_64, "avx512vaes") => smallvec!["vaes"], + (Arch::X86 | Arch::X86_64, "avx512gfni") => smallvec!["gfni"], + (Arch::X86 | Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], // NOTE: seems like GCC requires 'avx512bw' for 'avx512vbmi2'. - ("x86", "avx512vbmi2") => smallvec!["avx512vbmi2", "avx512bw"], + (Arch::X86 | Arch::X86_64, "avx512vbmi2") => { + smallvec!["avx512vbmi2", "avx512bw"] + } // NOTE: seems like GCC requires 'avx512bw' for 'avx512bitalg'. - ("x86", "avx512bitalg") => smallvec!["avx512bitalg", "avx512bw"], - ("aarch64", "rcpc2") => smallvec!["rcpc-immo"], - ("aarch64", "dpb") => smallvec!["ccpp"], - ("aarch64", "dpb2") => smallvec!["ccdp"], - ("aarch64", "frintts") => smallvec!["fptoint"], - ("aarch64", "fcma") => smallvec!["complxnum"], - ("aarch64", "pmuv3") => smallvec!["perfmon"], - ("aarch64", "paca") => smallvec!["pauth"], - ("aarch64", "pacg") => smallvec!["pauth"], + (Arch::X86 | Arch::X86_64, "avx512bitalg") => { + smallvec!["avx512bitalg", "avx512bw"] + } + (Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], + (Arch::AArch64, "dpb") => smallvec!["ccpp"], + (Arch::AArch64, "dpb2") => smallvec!["ccdp"], + (Arch::AArch64, "frintts") => smallvec!["fptoint"], + (Arch::AArch64, "fcma") => smallvec!["complxnum"], + (Arch::AArch64, "pmuv3") => smallvec!["perfmon"], + (Arch::AArch64, "paca") => smallvec!["pauth"], + (Arch::AArch64, "pacg") => smallvec!["pauth"], // Rust ties fp and neon together. In GCC neon implicitly enables fp, // but we manually enable neon when a feature only implicitly enables fp - ("aarch64", "f32mm") => smallvec!["f32mm", "neon"], - ("aarch64", "f64mm") => smallvec!["f64mm", "neon"], - ("aarch64", "fhm") => smallvec!["fp16fml", "neon"], - ("aarch64", "fp16") => smallvec!["fullfp16", "neon"], - ("aarch64", "jsconv") => smallvec!["jsconv", "neon"], - ("aarch64", "sve") => smallvec!["sve", "neon"], - ("aarch64", "sve2") => smallvec!["sve2", "neon"], - ("aarch64", "sve2-aes") => smallvec!["sve2-aes", "neon"], - ("aarch64", "sve2-sm4") => smallvec!["sve2-sm4", "neon"], - ("aarch64", "sve2-sha3") => smallvec!["sve2-sha3", "neon"], - ("aarch64", "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], + (Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], + (Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], + (Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], + (Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], + (Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], + (Arch::AArch64, "sve") => smallvec!["sve", "neon"], + (Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], + (Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], + (Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], + (Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], + (Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], (_, s) => smallvec![s], } // cSpell:enable diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 71500ded0203..9f5b03c02a09 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -103,7 +103,7 @@ use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; use rustc_span::Symbol; -use rustc_target::spec::RelocModel; +use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; use crate::back::lto::ModuleBuffer; @@ -249,7 +249,7 @@ impl CodegenBackend for GccCodegenBackend { fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { let context = Context::default(); - if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { + if matches!(tcx.sess.target.arch, Arch::X86 | Arch::X86_64) { context.add_command_line_option("-masm=intel"); } #[cfg(feature = "master")] diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 3793a1470aad..b045af3161dc 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -16,7 +16,7 @@ use rustc_session::{Session, config}; use rustc_target::callconv::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, }; -use rustc_target::spec::SanitizerSet; +use rustc_target::spec::{Arch, SanitizerSet}; use smallvec::SmallVec; use crate::attributes::{self, llfn_attrs_from_instance}; @@ -698,16 +698,11 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm: // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. CanonAbi::Custom => llvm::CCallConv, - CanonAbi::GpuKernel => { - let arch = sess.target.arch.as_ref(); - if arch == "amdgpu" { - llvm::AmdgpuKernel - } else if arch == "nvptx64" { - llvm::PtxKernel - } else { - panic!("Architecture {arch} does not support GpuKernel calling convention"); - } - } + CanonAbi::GpuKernel => match sess.target.arch { + Arch::AmdGpu => llvm::AmdgpuKernel, + Arch::Nvptx64 => llvm::PtxKernel, + arch => panic!("Architecture {arch} does not support GpuKernel calling convention"), + }, CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { InterruptKind::Avr => llvm::AvrInterrupt, InterruptKind::AvrNonBlocking => llvm::AvrNonBlockingInterrupt, diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index ac20f9c64fa1..ff9607e715ec 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -7,7 +7,7 @@ use rustc_middle::middle::codegen_fn_attrs::{ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; +use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; use crate::context::SimpleCx; @@ -54,7 +54,7 @@ pub(crate) fn inline_attr<'ll, 'tcx>( Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)) } InlineAttr::Never => { - if tcx.sess.target.arch != "amdgpu" { + if tcx.sess.target.arch != Arch::AmdGpu { Some(AttributeKind::NoInline.create_attr(cx.llcx)) } else { None @@ -287,7 +287,7 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A } fn backchain_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { - if sess.target.arch != "s390x" { + if sess.target.arch != Arch::S390x { return None; } @@ -423,7 +423,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection { - assert!(sess.target.arch == "aarch64"); + assert!(sess.target.arch == Arch::AArch64); if bti { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index cfbb9541ecd2..46f9b0020db3 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -25,7 +25,9 @@ use rustc_session::config::{ self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath, }; use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym}; -use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel}; +use rustc_target::spec::{ + Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel, +}; use tracing::{debug, trace}; use crate::back::lto::ThinBuffer; @@ -206,7 +208,7 @@ pub(crate) fn target_machine_factory( let reloc_model = to_llvm_relocation_model(sess.relocation_model()); let (opt_level, _) = to_llvm_opt_settings(optlvl); - let float_abi = if sess.target.arch == "arm" && sess.opts.cg.soft_float { + let float_abi = if sess.target.arch == Arch::Arm && sess.opts.cg.soft_float { llvm::FloatAbi::Soft } else { // `validate_commandline_args_with_session_available` has already warned about this being diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 49d38e05c8b0..d441cd119a74 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -26,7 +26,7 @@ use rustc_sanitizers::{cfi, kcfi}; use rustc_session::config::OptLevel; use rustc_span::Span; use rustc_target::callconv::{FnAbi, PassMode}; -use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; +use rustc_target::spec::{Arch, HasTargetSpec, SanitizerSet, Target}; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -839,11 +839,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // operation. But it's not clear how to do that with LLVM.) // For more context, see and // . - const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] = - &["aarch64", "arm", "riscv32", "riscv64"]; - - let use_nontemporal = - WELL_BEHAVED_NONTEMPORAL_ARCHS.contains(&&*self.cx.tcx.sess.target.arch); + let use_nontemporal = matches!( + self.cx.tcx.sess.target.arch, + Arch::AArch64 | Arch::Arm | Arch::RiscV32 | Arch::RiscV64 + ); if use_nontemporal { // According to LLVM [1] building a nontemporal store must // *always* point to a metadata value of the integer 1. diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index b86b32b92df0..f0d4c546e986 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -7,6 +7,7 @@ use rustc_codegen_ssa::common; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; +use rustc_target::spec::Arch; use tracing::debug; use crate::context::CodegenCx; @@ -35,7 +36,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t llfn } else { let instance_def_id = instance.def_id(); - let llfn = if tcx.sess.target.arch == "x86" + let llfn = if tcx.sess.target.arch == Arch::X86 && let Some(dllimport) = crate::common::get_dllimport(tcx, instance_def_id, sym) { // When calling functions in generated import libraries, MSVC needs diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 9844c9444b3d..08c53179bc14 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance}; use rustc_middle::{bug, span_bug}; use rustc_span::Symbol; +use rustc_target::spec::Arch; use tracing::{debug, instrument, trace}; use crate::common::CodegenCx; @@ -203,7 +204,7 @@ fn check_and_apply_linkage<'ll, 'tcx>( llvm::set_linkage(g2, llvm::Linkage::InternalLinkage); llvm::set_initializer(g2, g1); g2 - } else if cx.tcx.sess.target.arch == "x86" + } else if cx.tcx.sess.target.arch == Arch::X86 && common::is_mingw_gnu_toolchain(&cx.tcx.sess.target) && let Some(dllimport) = crate::common::get_dllimport(cx.tcx, def_id, sym) { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 808aaceab4d2..c01f163f2ee1 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -28,7 +28,9 @@ use rustc_session::config::{ use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel}; +use rustc_target::spec::{ + Arch, HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel, +}; use smallvec::SmallVec; use crate::abi::to_llvm_calling_convention; @@ -181,22 +183,22 @@ pub(crate) unsafe fn create_module<'ll>( let llvm_version = llvm_util::get_version(); if llvm_version < (21, 0, 0) { - if sess.target.arch == "nvptx64" { + if sess.target.arch == Arch::Nvptx64 { // LLVM 21 updated the default layout on nvptx: https://github.com/llvm/llvm-project/pull/124961 target_data_layout = target_data_layout.replace("e-p6:32:32-i64", "e-i64"); } - if sess.target.arch == "amdgpu" { + if sess.target.arch == Arch::AmdGpu { // LLVM 21 adds the address width for address space 8. // See https://github.com/llvm/llvm-project/pull/139419 target_data_layout = target_data_layout.replace("p8:128:128:128:48", "p8:128:128") } } if llvm_version < (22, 0, 0) { - if sess.target.arch == "avr" { + if sess.target.arch == Arch::Avr { // LLVM 22.0 updated the default layout on avr: https://github.com/llvm/llvm-project/pull/153010 target_data_layout = target_data_layout.replace("n8:16", "n8") } - if sess.target.arch == "nvptx64" { + if sess.target.arch == Arch::Nvptx64 { // LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198 target_data_layout = target_data_layout.replace("-i256:256", ""); } @@ -371,7 +373,7 @@ pub(crate) unsafe fn create_module<'ll>( if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection { - if sess.target.arch == "aarch64" { + if sess.target.arch == Arch::AArch64 { llvm::add_module_flag_u32( llmod, llvm::ModuleFlagMergeBehavior::Min, @@ -502,7 +504,7 @@ pub(crate) unsafe fn create_module<'ll>( // FIXME: https://github.com/llvm/llvm-project/issues/50591 // If llvm_abiname is empty, emit nothing. let llvm_abiname = &sess.target.options.llvm_abiname; - if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() { + if matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) && !llvm_abiname.is_empty() { llvm::add_module_flag_str( llmod, llvm::ModuleFlagMergeBehavior::Error, @@ -667,7 +669,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// This corresponds to the `-fobjc-abi-version=` flag in Clang / GCC. pub(crate) fn objc_abi_version(&self) -> u32 { assert!(self.tcx.sess.target.is_like_darwin); - if self.tcx.sess.target.arch == "x86" && self.tcx.sess.target.os == "macos" { + if self.tcx.sess.target.arch == Arch::X86 && self.tcx.sess.target.os == "macos" { // 32-bit x86 macOS uses ABI version 1 (a.k.a. the "fragile ABI"). 1 } else { diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 0fcad0376b11..8f8a3a3aef2f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -15,7 +15,7 @@ use rustc_fs_util::path_to_c_string; use rustc_middle::bug; use rustc_session::Session; use rustc_session::config::{PrintKind, PrintRequest}; -use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport}; +use rustc_target::spec::{Arch, MergeFunctions, PanicStrategy, SmallDataThresholdSupport}; use smallvec::{SmallVec, smallvec}; use crate::back::write::create_informational_target_machine; @@ -217,70 +217,85 @@ impl<'a> IntoIterator for LLVMFeature<'a> { /// Rust can also be build with an external precompiled version of LLVM which might lead to failures /// if the oldest tested / supported LLVM version doesn't yet support the relevant intrinsics. pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option> { - let raw_arch = &*sess.target.arch; - let arch = match raw_arch { - "x86_64" => "x86", - "arm64ec" => "aarch64", - "sparc64" => "sparc", - "powerpc64" => "powerpc", - _ => raw_arch, - }; let (major, _, _) = get_version(); - match (arch, s) { - ("aarch64", "rcpc2") => Some(LLVMFeature::new("rcpc-immo")), - ("aarch64", "dpb") => Some(LLVMFeature::new("ccpp")), - ("aarch64", "dpb2") => Some(LLVMFeature::new("ccdp")), - ("aarch64", "frintts") => Some(LLVMFeature::new("fptoint")), - ("aarch64", "fcma") => Some(LLVMFeature::new("complxnum")), - ("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")), - ("aarch64", "paca") => Some(LLVMFeature::new("pauth")), - ("aarch64", "pacg") => Some(LLVMFeature::new("pauth")), - ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")), - // Rust ties fp and neon together. - ("aarch64", "neon") => Some(LLVMFeature::with_dependencies( - "neon", - smallvec![TargetFeatureFoldStrength::Both("fp-armv8")], - )), - // In LLVM neon implicitly enables fp, but we manually enable - // neon when a feature only implicitly enables fp - ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")), - ("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")), + match sess.target.arch { + Arch::AArch64 | Arch::Arm64EC => { + match s { + "rcpc2" => Some(LLVMFeature::new("rcpc-immo")), + "dpb" => Some(LLVMFeature::new("ccpp")), + "dpb2" => Some(LLVMFeature::new("ccdp")), + "frintts" => Some(LLVMFeature::new("fptoint")), + "fcma" => Some(LLVMFeature::new("complxnum")), + "pmuv3" => Some(LLVMFeature::new("perfmon")), + "paca" => Some(LLVMFeature::new("pauth")), + "pacg" => Some(LLVMFeature::new("pauth")), + "flagm2" => Some(LLVMFeature::new("altnzcv")), + // Rust ties fp and neon together. + "neon" => Some(LLVMFeature::with_dependencies( + "neon", + smallvec![TargetFeatureFoldStrength::Both("fp-armv8")], + )), + // In LLVM neon implicitly enables fp, but we manually enable + // neon when a feature only implicitly enables fp + "fhm" => Some(LLVMFeature::new("fp16fml")), + "fp16" => Some(LLVMFeature::new("fullfp16")), + // Filter out features that are not supported by the current LLVM version + "fpmr" => None, // only existed in 18 + s => Some(LLVMFeature::new(s)), + } + } + Arch::Arm => match s { + "fp16" => Some(LLVMFeature::new("fullfp16")), + s => Some(LLVMFeature::new(s)), + }, + // Filter out features that are not supported by the current LLVM version - ("aarch64", "fpmr") => None, // only existed in 18 - ("arm", "fp16") => Some(LLVMFeature::new("fullfp16")), - // Filter out features that are not supported by the current LLVM version - ("loongarch32" | "loongarch64", "32s") if major < 21 => None, - ("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")), - ("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")), - ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies( - "sse4.2", - smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")], - )), - ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")), - ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")), - ("x86", "bmi1") => Some(LLVMFeature::new("bmi")), - ("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")), - ("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")), - // Enable the evex512 target feature if an avx512 target feature is enabled. - ("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies( - s, - smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")], - )), - ("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")), - ("x86", "avx10.2") => Some(LLVMFeature::new("avx10.2-512")), - ("x86", "apxf") => Some(LLVMFeature::with_dependencies( - "egpr", - smallvec![ - TargetFeatureFoldStrength::Both("push2pop2"), - TargetFeatureFoldStrength::Both("ppx"), - TargetFeatureFoldStrength::Both("ndd"), - TargetFeatureFoldStrength::Both("ccmp"), - TargetFeatureFoldStrength::Both("cf"), - TargetFeatureFoldStrength::Both("nf"), - TargetFeatureFoldStrength::Both("zu"), - ], - )), - (_, s) => Some(LLVMFeature::new(s)), + Arch::LoongArch32 | Arch::LoongArch64 => match s { + "32s" if major < 21 => None, + s => Some(LLVMFeature::new(s)), + }, + Arch::PowerPC | Arch::PowerPC64 => match s { + "power8-crypto" => Some(LLVMFeature::new("crypto")), + s => Some(LLVMFeature::new(s)), + }, + Arch::Sparc | Arch::Sparc64 => match s { + "leoncasa" => Some(LLVMFeature::new("hasleoncasa")), + s => Some(LLVMFeature::new(s)), + }, + Arch::X86 | Arch::X86_64 => { + match s { + "sse4.2" => Some(LLVMFeature::with_dependencies( + "sse4.2", + smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")], + )), + "pclmulqdq" => Some(LLVMFeature::new("pclmul")), + "rdrand" => Some(LLVMFeature::new("rdrnd")), + "bmi1" => Some(LLVMFeature::new("bmi")), + "cmpxchg16b" => Some(LLVMFeature::new("cx16")), + "lahfsahf" => Some(LLVMFeature::new("sahf")), + // Enable the evex512 target feature if an avx512 target feature is enabled. + s if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies( + s, + smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")], + )), + "avx10.1" => Some(LLVMFeature::new("avx10.1-512")), + "avx10.2" => Some(LLVMFeature::new("avx10.2-512")), + "apxf" => Some(LLVMFeature::with_dependencies( + "egpr", + smallvec![ + TargetFeatureFoldStrength::Both("push2pop2"), + TargetFeatureFoldStrength::Both("ppx"), + TargetFeatureFoldStrength::Both("ndd"), + TargetFeatureFoldStrength::Both("ccmp"), + TargetFeatureFoldStrength::Both("cf"), + TargetFeatureFoldStrength::Both("nf"), + TargetFeatureFoldStrength::Both("zu"), + ], + )), + s => Some(LLVMFeature::new(s)), + } + } + _ => Some(LLVMFeature::new(s)), } } @@ -327,7 +342,7 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig { /// Determine whether or not experimental float types are reliable based on known bugs. fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { - let target_arch = sess.target.arch.as_ref(); + let target_arch = sess.target.arch; let target_os = sess.target.options.os.as_ref(); let target_env = sess.target.options.env.as_ref(); let target_abi = sess.target.options.abi.as_ref(); @@ -338,23 +353,23 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { cfg.has_reliable_f16 = match (target_arch, target_os) { // LLVM crash without neon (fixed in llvm20) - ("aarch64", _) + (Arch::AArch64, _) if !cfg.target_features.iter().any(|f| f.as_str() == "neon") && lt_20_1_1 => { false } // Unsupported - ("arm64ec", _) => false, + (Arch::Arm64EC, _) => false, // Selection failure (fixed in llvm21) - ("s390x", _) if lt_21_0_0 => false, + (Arch::S390x, _) if lt_21_0_0 => false, // MinGW ABI bugs - ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, + (Arch::X86_64, "windows") if target_env == "gnu" && target_abi != "llvm" => false, // Infinite recursion - ("csky", _) => false, - ("hexagon", _) if lt_21_0_0 => false, // (fixed in llvm21) - ("powerpc" | "powerpc64", _) => false, - ("sparc" | "sparc64", _) => false, - ("wasm32" | "wasm64", _) => false, + (Arch::CSky, _) => false, + (Arch::Hexagon, _) if lt_21_0_0 => false, // (fixed in llvm21) + (Arch::PowerPC | Arch::PowerPC64, _) => false, + (Arch::Sparc | Arch::Sparc64, _) => false, + (Arch::Wasm32 | Arch::Wasm64, _) => false, // `f16` support only requires that symbols converting to and from `f32` are available. We // provide these in `compiler-builtins`, so `f16` should be available on all platforms that // do not have other ABI issues or LLVM crashes. @@ -363,24 +378,24 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { cfg.has_reliable_f128 = match (target_arch, target_os) { // Unsupported - ("arm64ec", _) => false, + (Arch::Arm64EC, _) => false, // Selection bug (fixed in llvm20) - ("mips64" | "mips64r6", _) if lt_20_1_1 => false, + (Arch::Mips64 | Arch::Mips64r6, _) if lt_20_1_1 => false, // Selection bug . This issue is closed // but basic math still does not work. - ("nvptx64", _) => false, + (Arch::Nvptx64, _) => false, // Unsupported https://github.com/llvm/llvm-project/issues/121122 - ("amdgpu", _) => false, + (Arch::AmdGpu, _) => false, // ABI bugs et al. (full // list at ) - ("powerpc" | "powerpc64", _) => false, + (Arch::PowerPC | Arch::PowerPC64, _) => false, // ABI unsupported - ("sparc", _) => false, + (Arch::Sparc, _) => false, // Stack alignment bug . NB: tests may // not fail if our compiler-builtins is linked. (fixed in llvm21) - ("x86", _) if lt_21_0_0 => false, + (Arch::X86, _) if lt_21_0_0 => false, // MinGW ABI bugs - ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, + (Arch::X86_64, "windows") if target_env == "gnu" && target_abi != "llvm" => false, // There are no known problems on other platforms, so the only requirement is that symbols // are available. `compiler-builtins` provides all symbols required for core `f128` // support, so this should work for everything else. @@ -402,7 +417,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // // musl does not implement the symbols required for f128 math at all. _ if target_env == "musl" => false, - ("x86_64", _) => false, + (Arch::X86_64, _) => false, (_, "linux") if target_pointer_width == 64 => true, _ => false, } && cfg.has_reliable_f128; @@ -605,8 +620,8 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec) { // -Zfixed-x18 if sess.opts.unstable_opts.fixed_x18 { - if sess.target.arch != "aarch64" { - sess.dcx().emit_fatal(errors::FixedX18InvalidArch { arch: &sess.target.arch }); + if sess.target.arch != Arch::AArch64 { + sess.dcx().emit_fatal(errors::FixedX18InvalidArch { arch: sess.target.arch.desc() }); } else { features.push("+reserve-x18".into()); } diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 52eefe2d4d24..4184ced74962 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_session::config::CrateType; -use rustc_target::spec::RelocModel; +use rustc_target::spec::{Arch, RelocModel}; use tracing::debug; use crate::context::CodegenCx; @@ -116,7 +116,7 @@ impl CodegenCx<'_, '_> { } // PowerPC64 prefers TOC indirection to avoid copy relocations. - if matches!(&*self.tcx.sess.target.arch, "powerpc64" | "powerpc64le") { + if matches!(self.tcx.sess.target.arch, Arch::PowerPC64 | Arch::PowerPC64LE) { return false; } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 2d9abb412d4f..115d96d9baf6 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{ }; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_target::spec::Arch; use crate::builder::Builder; use crate::llvm::{Type, Value}; @@ -886,8 +887,8 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // is lacking in some instances, so we should only use it as a fallback. let target = &bx.cx.tcx.sess.target; - match &*target.arch { - "x86" => emit_ptr_va_arg( + match target.arch { + Arch::X86 => emit_ptr_va_arg( bx, addr, target_ty, @@ -896,7 +897,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, ForceRightAdjust::No, ), - "aarch64" | "arm64ec" if target.is_like_windows || target.is_like_darwin => { + Arch::AArch64 | Arch::Arm64EC if target.is_like_windows || target.is_like_darwin => { emit_ptr_va_arg( bx, addr, @@ -907,8 +908,8 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( ForceRightAdjust::No, ) } - "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty), - "arm" => { + Arch::AArch64 => emit_aapcs_va_arg(bx, addr, target_ty), + Arch::Arm => { // Types wider than 16 bytes are not currently supported. Clang has special logic for // such types, but `VaArgSafe` is not implemented for any type that is this large. assert!(bx.cx.size_of(target_ty).bytes() <= 16); @@ -923,22 +924,28 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( ForceRightAdjust::No, ) } - "s390x" => emit_s390x_va_arg(bx, addr, target_ty), - "powerpc" => emit_powerpc_va_arg(bx, addr, target_ty), - "powerpc64" | "powerpc64le" => emit_ptr_va_arg( + Arch::S390x => emit_s390x_va_arg(bx, addr, target_ty), + Arch::PowerPC => emit_powerpc_va_arg(bx, addr, target_ty), + Arch::PowerPC64 => emit_ptr_va_arg( bx, addr, target_ty, PassMode::Direct, SlotSize::Bytes8, AllowHigherAlign::Yes, - match &*target.arch { - "powerpc64" => ForceRightAdjust::Yes, - _ => ForceRightAdjust::No, - }, + ForceRightAdjust::Yes, + ), + Arch::PowerPC64LE => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes8, + AllowHigherAlign::Yes, + ForceRightAdjust::No, ), // Windows x86_64 - "x86_64" if target.is_like_windows => { + Arch::X86_64 if target.is_like_windows => { let target_ty_size = bx.cx.size_of(target_ty).bytes(); emit_ptr_va_arg( bx, @@ -955,8 +962,8 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( ) } // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. - "x86_64" => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), - "xtensa" => emit_xtensa_va_arg(bx, addr, target_ty), + Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), + Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index b1d646d9265f..3b29ddeadc7f 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -5,8 +5,8 @@ use std::process::Command; use itertools::Itertools; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::Session; -use rustc_target::spec::Target; pub(super) use rustc_target::spec::apple::OSVersion; +use rustc_target::spec::{Arch, Target}; use tracing::debug; use crate::errors::{XcrunError, XcrunSdkPathWarning}; @@ -95,7 +95,7 @@ pub(super) fn add_data_and_relocation( pointer_width => unimplemented!("unsupported Apple pointer width {pointer_width:?}"), }; - if target.arch == "x86_64" { + if target.arch == Arch::X86_64 { // Force alignment for the entire section to be 16 on x86_64. file.section_mut(section).append_data(&[], 16); } else { @@ -111,7 +111,7 @@ pub(super) fn add_data_and_relocation( r_pcrel: false, r_length: 3, } - } else if target.arch == "arm" { + } else if target.arch == Arch::Arm { // FIXME(madsmtm): Remove once `object` supports 32-bit ARM relocations: // https://github.com/gimli-rs/object/pull/757 object::write::RelocationFlags::MachO { diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index cfd8ceac3a60..cef7df44abe3 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -17,6 +17,7 @@ use rustc_fs_util::TempDirBuilder; use rustc_metadata::EncodedMetadata; use rustc_session::Session; use rustc_span::Symbol; +use rustc_target::spec::Arch; use tracing::trace; use super::metadata::{create_compressed_metadata_file, search_for_section}; @@ -42,7 +43,7 @@ pub struct ImportLibraryItem { impl ImportLibraryItem { fn into_coff_short_export(self, sess: &Session) -> COFFShortExport { - let import_name = (sess.target.arch == "arm64ec").then(|| self.name.clone()); + let import_name = (sess.target.arch == Arch::Arm64EC).then(|| self.name.clone()); COFFShortExport { name: self.name, ext_name: None, @@ -117,12 +118,12 @@ pub trait ArchiveBuilderBuilder { let exports = items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::>(); - let machine = match &*sess.target.arch { - "x86_64" => MachineTypes::AMD64, - "x86" => MachineTypes::I386, - "aarch64" => MachineTypes::ARM64, - "arm64ec" => MachineTypes::ARM64EC, - "arm" => MachineTypes::ARMNT, + let machine = match sess.target.arch { + Arch::X86_64 => MachineTypes::AMD64, + Arch::X86 => MachineTypes::I386, + Arch::AArch64 => MachineTypes::ARM64, + Arch::Arm64EC => MachineTypes::ARM64EC, + Arch::Arm => MachineTypes::ARMNT, cpu => panic!("unsupported cpu type {cpu}"), }; @@ -223,12 +224,12 @@ fn create_mingw_dll_import_lib( }; // dlltool target architecture args from: // https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69 - let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch.as_ref() { - "x86_64" => ("i386:x86-64", "--64"), - "x86" => ("i386", "--32"), - "aarch64" => ("arm64", "--64"), - "arm" => ("arm", "--32"), - _ => panic!("unsupported arch {}", sess.target.arch), + let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch { + Arch::X86_64 => ("i386:x86-64", "--64"), + Arch::X86 => ("i386", "--32"), + Arch::AArch64 => ("arm64", "--64"), + Arch::Arm => ("arm", "--32"), + arch => panic!("unsupported arch {arch}"), }; let mut dlltool_cmd = std::process::Command::new(&dlltool); dlltool_cmd @@ -281,10 +282,10 @@ fn find_binutils_dlltool(sess: &Session) -> OsString { "dlltool.exe" } else { // On other platforms, use the architecture-specific name. - match sess.target.arch.as_ref() { - "x86_64" => "x86_64-w64-mingw32-dlltool", - "x86" => "i686-w64-mingw32-dlltool", - "aarch64" => "aarch64-w64-mingw32-dlltool", + match sess.target.arch { + Arch::X86_64 => "x86_64-w64-mingw32-dlltool", + Arch::X86 => "i686-w64-mingw32-dlltool", + Arch::AArch64 => "aarch64-w64-mingw32-dlltool", // For non-standard architectures (e.g., aarch32) fallback to "dlltool". _ => "dlltool", @@ -378,9 +379,9 @@ pub fn try_extract_macho_fat_archive( archive_path: &Path, ) -> io::Result> { let archive_map = unsafe { Mmap::map(File::open(&archive_path)?)? }; - let target_arch = match sess.target.arch.as_ref() { - "aarch64" => object::Architecture::Aarch64, - "x86_64" => object::Architecture::X86_64, + let target_arch = match sess.target.arch { + Arch::AArch64 => object::Architecture::Aarch64, + Arch::X86_64 => object::Architecture::X86_64, _ => return Ok(None), }; @@ -531,7 +532,7 @@ impl<'a> ArArchiveBuilder<'a> { &entries, archive_kind, false, - /* is_ec = */ Some(self.sess.target.arch == "arm64ec"), + /* is_ec = */ Some(self.sess.target.arch == Arch::Arm64EC), )?; archive_tmpfile.flush()?; drop(archive_tmpfile); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ea538d3d4698..1124b0ac1aee 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -883,7 +883,8 @@ fn link_natively( if is_msvc_link_exe && (code < 1000 || code > 9999) { let is_vs_installed = find_msvc_tools::find_vs_version().is_ok(); let has_linker = - find_msvc_tools::find_tool(&sess.target.arch, "link.exe").is_some(); + find_msvc_tools::find_tool(sess.target.arch.desc(), "link.exe") + .is_some(); sess.dcx().emit_note(errors::LinkExeUnexpectedError); diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 7321bc1da391..45c217168a8d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -11,6 +11,7 @@ use rustc_hir::attrs::NativeLibKind; use rustc_session::Session; use rustc_session::cstore::DllImport; use rustc_span::Symbol; +use rustc_target::spec::Arch; use crate::back::archive::ImportLibraryItem; use crate::back::link::ArchiveBuilderBuilder; @@ -77,7 +78,7 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>( let items: Vec = raw_dylib_imports .iter() .map(|import: &DllImport| { - if sess.target.arch == "x86" { + if sess.target.arch == Arch::X86 { ImportLibraryItem { name: common::i686_decorated_name( import, diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index ac1231437382..eb2740d59b4b 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -17,7 +17,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld}; +use rustc_target::spec::{Arch, Cc, LinkOutputKind, LinkerFlavor, Lld}; use tracing::{debug, warn}; use super::command::Command; @@ -53,7 +53,7 @@ pub(crate) fn get_linker<'a>( target_cpu: &'a str, codegen_backend: &'static str, ) -> Box { - let msvc_tool = find_msvc_tools::find_tool(&sess.target.arch, "link.exe"); + let msvc_tool = find_msvc_tools::find_tool(sess.target.arch.desc(), "link.exe"); // If our linker looks like a batch script on Windows then to execute this // we'll need to spawn `cmd` explicitly. This is primarily done to handle @@ -87,11 +87,11 @@ pub(crate) fn get_linker<'a>( if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(root_lib_path) = original_path.ancestors().nth(4) { - let arch = match t.arch.as_ref() { - "x86_64" => Some("x64"), - "x86" => Some("x86"), - "aarch64" => Some("arm64"), - "arm" => Some("arm"), + let arch = match t.arch { + Arch::X86_64 => Some("x64"), + Arch::X86 => Some("x86"), + Arch::AArch64 => Some("arm64"), + Arch::Arm => Some("arm"), _ => None, }; if let Some(ref a) = arch { @@ -589,7 +589,7 @@ impl<'a> Linker for GccLinker<'a> { // // Currently this makes sense only when using avr-gcc as a linker, since // it brings a couple of hand-written important intrinsics from libgcc. - if self.sess.target.arch == "avr" && !self.uses_lld { + if self.sess.target.arch == Arch::Avr && !self.uses_lld { self.verbatim_arg(format!("-mmcu={}", self.target_cpu)); } } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d9ba5017a422..6fa8725a7871 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolNam use rustc_middle::util::Providers; use rustc_session::config::{CrateType, OomStrategy}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::spec::TlsModel; +use rustc_target::spec::{Arch, TlsModel}; use tracing::debug; use crate::back::symbol_export; @@ -659,11 +659,11 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( return undecorated; } - let prefix = match &target.arch[..] { - "x86" => Some('_'), - "x86_64" => None, + let prefix = match target.arch { + Arch::X86 => Some('_'), + Arch::X86_64 => None, // Only functions are decorated for arm64ec. - "arm64ec" if export_kind == SymbolExportKind::Text => Some('#'), + Arch::Arm64EC if export_kind == SymbolExportKind::Text => Some('#'), // Only x86/64 and arm64ec use symbol decorations. _ => return undecorated, }; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f58be0a3b9a3..a50054758729 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -33,6 +33,7 @@ use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType}; use rustc_span::{DUMMY_SP, Symbol, sym}; use rustc_symbol_mangling::mangle_internal_symbol; +use rustc_target::spec::Arch; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; @@ -982,9 +983,9 @@ impl CrateInfo { // by the compiler, but that's ok because all this stuff is unstable anyway. let target = &tcx.sess.target; if !are_upstream_rust_objects_already_included(tcx.sess) { - let add_prefix = match (target.is_like_windows, target.arch.as_ref()) { - (true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"), - (true, "arm64ec") => { + let add_prefix = match (target.is_like_windows, target.arch) { + (true, Arch::X86) => |name: String, _: SymbolExportKind| format!("_{name}"), + (true, Arch::Arm64EC) => { // Only functions are decorated for arm64ec. |name: String, export_kind: SymbolExportKind| match export_kind { SymbolExportKind::Text => format!("#{name}"), diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index cc3316c7f8cc..aeb740118234 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -4,6 +4,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::sym; +use rustc_target::spec::Arch; use super::FunctionCx; use super::operand::OperandRef; @@ -79,7 +80,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // reinterpretation of values as (chunkable) byte arrays, and the loop in the // block optimization in `ptr::swap_nonoverlapping` is hard to rewrite back // into the (unoptimized) direct swapping implementation, so we disable it. - || bx.sess().target.arch == "spirv" + || bx.sess().target.arch == Arch::SpirV { let align = pointee_layout.align.abi; let x_place = args[0].val.deref(align); diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index e7239ebfecf6..4a47799b2bdc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, ty}; use rustc_span::sym; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; -use rustc_target::spec::BinaryFormat; +use rustc_target::spec::{Arch, BinaryFormat}; use crate::common; use crate::mir::AsmCodegenMethods; @@ -125,7 +125,7 @@ fn prefix_and_suffix<'tcx>( let asm_binary_format = &tcx.sess.target.binary_format; - let is_arm = tcx.sess.target.arch == "arm"; + let is_arm = tcx.sess.target.arch == Arch::Arm; let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode); let attrs = tcx.codegen_instance_attrs(instance.def); diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 54584999d61b..9b86fa961617 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -10,6 +10,7 @@ use rustc_session::Session; use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; +use rustc_target::spec::Arch; use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability}; use smallvec::SmallVec; @@ -73,7 +74,7 @@ pub(crate) fn from_target_feature_attr( if abi_feature_constraints.incompatible.contains(&name.as_str()) { // For "neon" specifically, we emit an FCW instead of a hard error. // See . - if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" { + if tcx.sess.target.arch == Arch::AArch64 && name.as_str() == "neon" { tcx.emit_node_span_lint( AARCH64_SOFTFLOAT_NEON, tcx.local_def_id_to_hir_id(did), diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 15572063d45a..8f51cbe0217c 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -15,7 +15,7 @@ use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, Nati use rustc_session::search_paths::PathKind; use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents}; +use rustc_target::spec::{Arch, BinaryFormat, LinkSelfContainedComponents}; use crate::errors; @@ -393,7 +393,7 @@ impl<'tcx> Collector<'tcx> { // This logic is similar to `AbiMap::canonize_abi` (in rustc_target/src/spec/abi_map.rs) but // we need more detail than those adjustments, and we can't support all ABIs that are // generally supported. - let calling_convention = if self.tcx.sess.target.arch == "x86" { + let calling_convention = if self.tcx.sess.target.arch == Arch::X86 { match abi { ExternAbi::C { .. } | ExternAbi::Cdecl { .. } => DllCallingConvention::C, ExternAbi::Stdcall { .. } => { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 60effa13406b..a00eaef20c08 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2388,7 +2388,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Determines whether identifiers in the assembly have strict naming rules. /// Currently, only NVPTX* targets need it. pub fn has_strict_asm_symbol_naming(self) -> bool { - self.sess.target.arch.contains("nvptx") + self.sess.target.llvm_target.starts_with("nvptx") } /// Returns `&'static core::panic::Location<'static>`. diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index a72f6201dcea..9cb25ad11aac 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -240,7 +240,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { } ins_str!(sym::target_abi, &sess.target.abi); - ins_str!(sym::target_arch, &sess.target.arch); + ins_str!(sym::target_arch, sess.target.arch.desc()); ins_str!(sym::target_endian, sess.target.endian.as_str()); ins_str!(sym::target_env, &sess.target.env); @@ -448,7 +448,7 @@ impl CheckCfg { for target in Target::builtins().chain(iter::once(current_target.clone())) { values_target_abi.insert(Symbol::intern(&target.options.abi)); - values_target_arch.insert(Symbol::intern(&target.arch)); + values_target_arch.insert(Symbol::intern(target.arch.desc())); values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); values_target_env.insert(Symbol::intern(&target.options.env)); values_target_family.extend( diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 522faf1db9ff..63d64b410950 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -32,7 +32,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{ - CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, + Arch, CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target, TargetTuple, TlsModel, apple, }; @@ -1112,7 +1112,7 @@ pub fn build_session( _ => CtfeBacktrace::Disabled, }); - let asm_arch = if target.allow_asm { InlineAsmArch::from_str(&target.arch).ok() } else { None }; + let asm_arch = if target.allow_asm { InlineAsmArch::from_arch(target.arch) } else { None }; let target_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target); let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host); @@ -1202,7 +1202,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { let mut unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers; // Niche: if `fixed-x18`, or effectively switching on `reserved-x18` flag, is enabled // we should allow Shadow Call Stack sanitizer. - if sess.opts.unstable_opts.fixed_x18 && sess.target.arch == "aarch64" { + if sess.opts.unstable_opts.fixed_x18 && sess.target.arch == Arch::AArch64 { unsupported_sanitizers -= SanitizerSet::SHADOWCALLSTACK; } match unsupported_sanitizers.into_iter().count() { @@ -1313,7 +1313,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } - if sess.opts.unstable_opts.branch_protection.is_some() && sess.target.arch != "aarch64" { + if sess.opts.unstable_opts.branch_protection.is_some() && sess.target.arch != Arch::AArch64 { sess.dcx().emit_err(errors::BranchProtectionRequiresAArch64); } @@ -1357,13 +1357,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.unstable_opts.function_return != FunctionReturn::default() { - if sess.target.arch != "x86" && sess.target.arch != "x86_64" { + if !matches!(sess.target.arch, Arch::X86 | Arch::X86_64) { sess.dcx().emit_err(errors::FunctionReturnRequiresX86OrX8664); } } if sess.opts.unstable_opts.indirect_branch_cs_prefix { - if sess.target.arch != "x86" && sess.target.arch != "x86_64" { + if !matches!(sess.target.arch, Arch::X86 | Arch::X86_64) { sess.dcx().emit_err(errors::IndirectBranchCsPrefixRequiresX86OrX8664); } } @@ -1372,12 +1372,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) { if regparm > 3 { sess.dcx().emit_err(errors::UnsupportedRegparm { regparm }); } - if sess.target.arch != "x86" { + if sess.target.arch != Arch::X86 { sess.dcx().emit_err(errors::UnsupportedRegparmArch); } } if sess.opts.unstable_opts.reg_struct_return { - if sess.target.arch != "x86" { + if sess.target.arch != Arch::X86 { sess.dcx().emit_err(errors::UnsupportedRegStructReturnArch); } } @@ -1399,7 +1399,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.cg.soft_float { - if sess.target.arch == "arm" { + if sess.target.arch == Arch::Arm { sess.dcx().emit_warn(errors::SoftFloatDeprecated); } else { // All `use_softfp` does is the equivalent of `-mfloat-abi` in GCC/clang, which only exists on ARM targets. diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 5d9e39d4fc20..e5c140a848c3 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -1,12 +1,11 @@ use std::fmt; -use std::str::FromStr; use rustc_abi::Size; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::Symbol; -use crate::spec::{RelocModel, Target}; +use crate::spec::{Arch, RelocModel, Target}; pub struct ModifierInfo { pub modifier: char, @@ -245,38 +244,36 @@ pub enum InlineAsmArch { CSKY, } -impl FromStr for InlineAsmArch { - type Err = (); - - fn from_str(s: &str) -> Result { - match s { - "x86" => Ok(Self::X86), - "x86_64" => Ok(Self::X86_64), - "arm" => Ok(Self::Arm), - "aarch64" => Ok(Self::AArch64), - "arm64ec" => Ok(Self::Arm64EC), - "riscv32" => Ok(Self::RiscV32), - "riscv64" => Ok(Self::RiscV64), - "nvptx64" => Ok(Self::Nvptx64), - "powerpc" => Ok(Self::PowerPC), - "powerpc64" => Ok(Self::PowerPC64), - "hexagon" => Ok(Self::Hexagon), - "loongarch32" => Ok(Self::LoongArch32), - "loongarch64" => Ok(Self::LoongArch64), - "mips" | "mips32r6" => Ok(Self::Mips), - "mips64" | "mips64r6" => Ok(Self::Mips64), - "s390x" => Ok(Self::S390x), - "sparc" => Ok(Self::Sparc), - "sparc64" => Ok(Self::Sparc64), - "spirv" => Ok(Self::SpirV), - "wasm32" => Ok(Self::Wasm32), - "wasm64" => Ok(Self::Wasm64), - "bpf" => Ok(Self::Bpf), - "avr" => Ok(Self::Avr), - "msp430" => Ok(Self::Msp430), - "m68k" => Ok(Self::M68k), - "csky" => Ok(Self::CSKY), - _ => Err(()), +impl InlineAsmArch { + pub fn from_arch(arch: Arch) -> Option { + match arch { + Arch::X86 => Some(Self::X86), + Arch::X86_64 => Some(Self::X86_64), + Arch::Arm => Some(Self::Arm), + Arch::Arm64EC => Some(Self::Arm64EC), + Arch::AArch64 => Some(Self::AArch64), + Arch::RiscV32 => Some(Self::RiscV32), + Arch::RiscV64 => Some(Self::RiscV64), + Arch::Nvptx64 => Some(Self::Nvptx64), + Arch::Hexagon => Some(Self::Hexagon), + Arch::LoongArch32 => Some(Self::LoongArch32), + Arch::LoongArch64 => Some(Self::LoongArch64), + Arch::Mips | Arch::Mips32r6 => Some(Self::Mips), + Arch::Mips64 | Arch::Mips64r6 => Some(Self::Mips64), + Arch::PowerPC => Some(Self::PowerPC), + Arch::PowerPC64 | Arch::PowerPC64LE => Some(Self::PowerPC64), + Arch::S390x => Some(Self::S390x), + Arch::Sparc => Some(Self::Sparc), + Arch::Sparc64 => Some(Self::Sparc64), + Arch::SpirV => Some(Self::SpirV), + Arch::Wasm32 => Some(Self::Wasm32), + Arch::Wasm64 => Some(Self::Wasm64), + Arch::Bpf => Some(Self::Bpf), + Arch::Avr => Some(Self::Avr), + Arch::Msp430 => Some(Self::Msp430), + Arch::M68k => Some(Self::M68k), + Arch::CSky => Some(Self::CSKY), + Arch::AmdGpu | Arch::Xtensa => None, } } } diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 5411e8f8176b..ef55bc45a774 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -7,7 +7,7 @@ use rustc_abi::{ use rustc_macros::HashStable_Generic; pub use crate::spec::AbiMap; -use crate::spec::{HasTargetSpec, HasX86AbiOpt}; +use crate::spec::{Arch, HasTargetSpec, HasX86AbiOpt}; mod aarch64; mod amdgpu; @@ -633,8 +633,8 @@ impl<'a, Ty> FnAbi<'a, Ty> { } let spec = cx.target_spec(); - match &spec.arch[..] { - "x86" => { + match spec.arch { + Arch::X86 => { let (flavor, regparm) = match abi { ExternAbi::Fastcall { .. } | ExternAbi::Vectorcall { .. } => { (x86::Flavor::FastcallOrVectorcall, None) @@ -652,7 +652,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { x86::compute_abi_info(cx, self, opts); } } - "x86_64" => match abi { + Arch::X86_64 => match abi { ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self), ExternAbi::Win64 { .. } | ExternAbi::Vectorcall { .. } => { x86_win64::compute_abi_info(cx, self) @@ -665,7 +665,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } }, - "aarch64" | "arm64ec" => { + Arch::AArch64 | Arch::Arm64EC => { let kind = if cx.target_spec().is_like_darwin { aarch64::AbiKind::DarwinPCS } else if cx.target_spec().is_like_windows { @@ -675,33 +675,35 @@ impl<'a, Ty> FnAbi<'a, Ty> { }; aarch64::compute_abi_info(cx, self, kind) } - "amdgpu" => amdgpu::compute_abi_info(cx, self), - "arm" => arm::compute_abi_info(cx, self), - "avr" => avr::compute_abi_info(cx, self), - "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self), - "m68k" => m68k::compute_abi_info(cx, self), - "csky" => csky::compute_abi_info(cx, self), - "mips" | "mips32r6" => mips::compute_abi_info(cx, self), - "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self), - "powerpc" => powerpc::compute_abi_info(cx, self), - "powerpc64" => powerpc64::compute_abi_info(cx, self), - "s390x" => s390x::compute_abi_info(cx, self), - "msp430" => msp430::compute_abi_info(cx, self), - "sparc" => sparc::compute_abi_info(cx, self), - "sparc64" => sparc64::compute_abi_info(cx, self), - "nvptx64" => { + Arch::AmdGpu => amdgpu::compute_abi_info(cx, self), + Arch::Arm => arm::compute_abi_info(cx, self), + Arch::Avr => avr::compute_abi_info(cx, self), + Arch::LoongArch32 | Arch::LoongArch64 => loongarch::compute_abi_info(cx, self), + Arch::M68k => m68k::compute_abi_info(cx, self), + Arch::CSky => csky::compute_abi_info(cx, self), + Arch::Mips | Arch::Mips32r6 => mips::compute_abi_info(cx, self), + Arch::Mips64 | Arch::Mips64r6 => mips64::compute_abi_info(cx, self), + Arch::PowerPC => powerpc::compute_abi_info(cx, self), + Arch::PowerPC64 => powerpc64::compute_abi_info(cx, self), + Arch::S390x => s390x::compute_abi_info(cx, self), + Arch::Msp430 => msp430::compute_abi_info(cx, self), + Arch::Sparc => sparc::compute_abi_info(cx, self), + Arch::Sparc64 => sparc64::compute_abi_info(cx, self), + Arch::Nvptx64 => { if abi == ExternAbi::PtxKernel || abi == ExternAbi::GpuKernel { nvptx64::compute_ptx_kernel_abi_info(cx, self) } else { nvptx64::compute_abi_info(cx, self) } } - "hexagon" => hexagon::compute_abi_info(cx, self), - "xtensa" => xtensa::compute_abi_info(cx, self), - "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), - "wasm32" | "wasm64" => wasm::compute_abi_info(cx, self), - "bpf" => bpf::compute_abi_info(cx, self), - arch => panic!("no lowering implemented for {arch}"), + Arch::Hexagon => hexagon::compute_abi_info(cx, self), + Arch::Xtensa => xtensa::compute_abi_info(cx, self), + Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self), + Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self), + Arch::Bpf => bpf::compute_abi_info(cx, self), + arch @ (Arch::PowerPC64LE | Arch::SpirV) => { + panic!("no lowering implemented for {arch}") + } } } @@ -711,12 +713,12 @@ impl<'a, Ty> FnAbi<'a, Ty> { C: HasDataLayout + HasTargetSpec, { let spec = cx.target_spec(); - match &*spec.arch { - "x86" => x86::compute_rust_abi_info(cx, self), - "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self), - "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self), - "aarch64" => aarch64::compute_rust_abi_info(cx, self), - "bpf" => bpf::compute_rust_abi_info(self), + match spec.arch { + Arch::X86 => x86::compute_rust_abi_info(cx, self), + Arch::RiscV32 | Arch::RiscV64 => riscv::compute_rust_abi_info(cx, self), + Arch::LoongArch32 | Arch::LoongArch64 => loongarch::compute_rust_abi_info(cx, self), + Arch::AArch64 => aarch64::compute_rust_abi_info(cx, self), + Arch::Bpf => bpf::compute_rust_abi_info(self), _ => {} }; diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index 5370903d0d6a..8126227d80e4 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -1,6 +1,6 @@ use rustc_abi::{ArmCall, CanonAbi, ExternAbi, InterruptKind, X86Call}; -use crate::spec::Target; +use crate::spec::{Arch, Target}; /// Mapping for ExternAbi to CanonAbi according to a Target /// @@ -47,17 +47,20 @@ impl AbiMap { /// create an AbiMap according to arbitrary fields on the [Target] pub fn from_target(target: &Target) -> Self { // the purpose of this little exercise is to force listing what affects these mappings - let arch = match &*target.arch { - "aarch64" => ArchKind::Aarch64, - "amdgpu" => ArchKind::Amdgpu, - "arm" if target.llvm_target.starts_with("thumbv8m") => ArchKind::Arm(ArmVer::ThumbV8M), - "arm" => ArchKind::Arm(ArmVer::Other), - "avr" => ArchKind::Avr, - "msp430" => ArchKind::Msp430, - "nvptx64" => ArchKind::Nvptx, - "riscv32" | "riscv64" => ArchKind::Riscv, - "x86" => ArchKind::X86, - "x86_64" => ArchKind::X86_64, + let arch = match target.arch { + Arch::AArch64 => ArchKind::Aarch64, + Arch::AmdGpu => ArchKind::Amdgpu, + Arch::Arm => ArchKind::Arm(if target.llvm_target.starts_with("thumbv8m") { + ArmVer::ThumbV8M + } else { + ArmVer::Other + }), + Arch::Avr => ArchKind::Avr, + Arch::Msp430 => ArchKind::Msp430, + Arch::Nvptx64 => ArchKind::Nvptx, + Arch::RiscV32 | Arch::RiscV64 => ArchKind::Riscv, + Arch::X86 => ArchKind::X86, + Arch::X86_64 => ArchKind::X86_64, _ => ArchKind::Other, }; diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 8f0b9a4517f9..cf147e48c501 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -40,13 +40,13 @@ impl Arch { } } - pub(crate) fn target_arch(self) -> Cow<'static, str> { - Cow::Borrowed(match self { - Self::Armv7k | Self::Armv7s => "arm", - Self::Arm64 | Self::Arm64e | Self::Arm64_32 => "aarch64", - Self::I386 | Self::I686 => "x86", - Self::X86_64 | Self::X86_64h => "x86_64", - }) + pub(crate) fn target_arch(self) -> crate::spec::Arch { + match self { + Self::Armv7k | Self::Armv7s => crate::spec::Arch::Arm, + Self::Arm64 | Self::Arm64e | Self::Arm64_32 => crate::spec::Arch::AArch64, + Self::I386 | Self::I686 => crate::spec::Arch::X86, + Self::X86_64 | Self::X86_64h => crate::spec::Arch::X86_64, + } } fn target_cpu(self, env: TargetEnv) -> &'static str { @@ -109,7 +109,7 @@ pub(crate) fn base( os: &'static str, arch: Arch, env: TargetEnv, -) -> (TargetOptions, StaticCow, StaticCow) { +) -> (TargetOptions, StaticCow, crate::spec::Arch) { let mut opts = TargetOptions { llvm_floatabi: Some(FloatAbi::Hard), os: os.into(), @@ -311,18 +311,22 @@ impl OSVersion { /// This matches what LLVM does, see in part: /// pub fn minimum_deployment_target(target: &Target) -> Self { - let (major, minor, patch) = match (&*target.os, &*target.arch, &*target.env) { - ("macos", "aarch64", _) => (11, 0, 0), - ("ios", "aarch64", "macabi") => (14, 0, 0), - ("ios", "aarch64", "sim") => (14, 0, 0), + let (major, minor, patch) = match (&*target.os, target.arch, &*target.env) { + ("macos", crate::spec::Arch::AArch64, _) => (11, 0, 0), + ("ios", crate::spec::Arch::AArch64, "macabi") => (14, 0, 0), + ("ios", crate::spec::Arch::AArch64, "sim") => (14, 0, 0), ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0), // Mac Catalyst defaults to 13.1 in Clang. ("ios", _, "macabi") => (13, 1, 0), - ("tvos", "aarch64", "sim") => (14, 0, 0), - ("watchos", "aarch64", "sim") => (7, 0, 0), + ("tvos", crate::spec::Arch::AArch64, "sim") => (14, 0, 0), + ("watchos", crate::spec::Arch::AArch64, "sim") => (7, 0, 0), // True Aarch64 on watchOS (instead of their Aarch64 Ilp32 called `arm64_32`) has been // available since Xcode 14, but it's only actually used more recently in watchOS 26. - ("watchos", "aarch64", "") if !target.llvm_target.starts_with("arm64_32") => (26, 0, 0), + ("watchos", crate::spec::Arch::AArch64, "") + if !target.llvm_target.starts_with("arm64_32") => + { + (26, 0, 0) + } (os, _, _) => return Self::os_minimum_deployment_target(os), }; Self { major, minor, patch } diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/nto_qnx.rs index 649874291754..119c5ec98f95 100644 --- a/compiler/rustc_target/src/spec/base/nto_qnx.rs +++ b/compiler/rustc_target/src/spec/base/nto_qnx.rs @@ -41,7 +41,7 @@ pub(crate) fn aarch64() -> Target { // n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently. // S128 = 128 bits are the natural alignment of the stack in bits. data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: crate::spec::Arch::AArch64, options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), @@ -57,7 +57,7 @@ pub(crate) fn x86_64() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: crate::spec::Arch::X86_64, options: TargetOptions { cpu: "x86-64".into(), plt_by_default: false, diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index f236be92b3b6..c25628c3939d 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -5,7 +5,7 @@ use rustc_abi::{Align, AlignFromBytesError}; use super::crt_objects::CrtObjects; use super::{ - BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli, + Arch, BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor, MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target, @@ -486,7 +486,7 @@ struct TargetSpecJson { llvm_target: StaticCow, target_pointer_width: u16, data_layout: StaticCow, - arch: StaticCow, + arch: Arch, metadata: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b49e7fc9cff6..892be1e18ca2 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1847,6 +1847,44 @@ enum TargetKind { Builtin, } +crate::target_spec_enum! { + pub enum Arch { + AArch64 = "aarch64", + AmdGpu = "amdgpu", + Arm = "arm", + Arm64EC = "arm64ec", + Avr = "avr", + Bpf = "bpf", + CSky = "csky", + Hexagon = "hexagon", + LoongArch32 = "loongarch32", + LoongArch64 = "loongarch64", + M68k = "m68k", + Mips = "mips", + Mips32r6 = "mips32r6", + Mips64 = "mips64", + Mips64r6 = "mips64r6", + Msp430 = "msp430", + Nvptx64 = "nvptx64", + PowerPC = "powerpc", + PowerPC64 = "powerpc64", + PowerPC64LE = "powerpc64le", + RiscV32 = "riscv32", + RiscV64 = "riscv64", + S390x = "s390x", + Sparc = "sparc", + Sparc64 = "sparc64", + SpirV = "spirv", + Wasm32 = "wasm32", + Wasm64 = "wasm64", + X86 = "x86", + X86_64 = "x86_64", + Xtensa = "xtensa", + } + + parse_error_type = "architecture"; +} + /// Everything `rustc` knows about how to compile for a specific target. /// /// Every field here must be specified, and has no default value. @@ -1866,7 +1904,7 @@ pub struct Target { pub pointer_width: u16, /// Architecture to use for ABI considerations. Valid options include: "x86", /// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others. - pub arch: StaticCow, + pub arch: Arch, /// [Data layout](https://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: StaticCow, /// Optional settings with defaults. @@ -2672,7 +2710,7 @@ impl Target { ); check_eq!( self.is_like_wasm, - self.arch == "wasm32" || self.arch == "wasm64", + matches!(self.arch, Arch::Wasm32 | Arch::Wasm64), "`is_like_wasm` must be set if and only if `arch` is `wasm32` or `wasm64`" ); if self.is_like_msvc { @@ -2704,12 +2742,12 @@ impl Target { "`linker_flavor` must be `em-cc` if and only if `os` is `emscripten`" ); check_eq!( - self.arch == "bpf", + self.arch == Arch::Bpf, matches!(self.linker_flavor, LinkerFlavor::Bpf), "`linker_flavor` must be `bpf` if and only if `arch` is `bpf`" ); check_eq!( - self.arch == "nvptx64", + self.arch == Arch::Nvptx64, matches!(self.linker_flavor, LinkerFlavor::Ptx), "`linker_flavor` must be `ptc` if and only if `arch` is `nvptx64`" ); @@ -2723,7 +2761,7 @@ impl Target { ] { for (&flavor, flavor_args) in args { check!( - !flavor_args.is_empty() || self.arch == "avr", + !flavor_args.is_empty() || self.arch == Arch::Avr, "linker flavor args must not be empty" ); // Check that flavors mentioned in link args are compatible with the default flavor. @@ -2846,10 +2884,7 @@ impl Target { // hexagon: when targeting QuRT, that OS can load dynamic libraries. // wasm{32,64}: dynamic linking is inherent in the definition of the VM. if self.os == "none" - && (self.arch != "bpf" - && self.arch != "hexagon" - && self.arch != "wasm32" - && self.arch != "wasm64") + && !matches!(self.arch, Arch::Bpf | Arch::Hexagon | Arch::Wasm32 | Arch::Wasm64) { check!( !self.dynamic_linking, @@ -2912,8 +2947,8 @@ impl Target { // Check that RISC-V targets always specify which ABI they use, // and that ARM targets specify their float ABI. - match &*self.arch { - "riscv32" => { + match self.arch { + Arch::RiscV32 => { check_matches!( &*self.llvm_abiname, "ilp32" | "ilp32f" | "ilp32d" | "ilp32e", @@ -2921,7 +2956,7 @@ impl Target { self.llvm_abiname, ); } - "riscv64" => { + Arch::RiscV64 => { // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. check_matches!( &*self.llvm_abiname, @@ -2930,7 +2965,7 @@ impl Target { self.llvm_abiname, ); } - "arm" => { + Arch::Arm => { check!( self.llvm_floatabi.is_some(), "ARM targets must set `llvm-floatabi` to `hard` or `soft`", @@ -2943,13 +2978,13 @@ impl Target { if let Some(rust_abi) = self.rustc_abi { match rust_abi { RustcAbi::X86Sse2 => check_matches!( - &*self.arch, - "x86", + self.arch, + Arch::X86, "`x86-sse2` ABI is only valid for x86-32 targets" ), RustcAbi::X86Softfloat => check_matches!( - &*self.arch, - "x86" | "x86_64", + self.arch, + Arch::X86 | Arch::X86_64, "`x86-softfloat` ABI is only valid for x86 targets" ), } @@ -3116,15 +3151,15 @@ impl Target { // Avoid having to duplicate the small data support in every // target file by supporting a default value for each // architecture. - SmallDataThresholdSupport::DefaultForArch => match self.arch.as_ref() { - "mips" | "mips64" | "mips32r6" => { + SmallDataThresholdSupport::DefaultForArch => match self.arch { + Arch::Mips | Arch::Mips64 | Arch::Mips32r6 => { SmallDataThresholdSupport::LlvmArg("mips-ssection-threshold".into()) } - "hexagon" => { + Arch::Hexagon => { SmallDataThresholdSupport::LlvmArg("hexagon-small-data-threshold".into()) } - "m68k" => SmallDataThresholdSupport::LlvmArg("m68k-ssection-threshold".into()), - "riscv32" | "riscv64" => { + Arch::M68k => SmallDataThresholdSupport::LlvmArg("m68k-ssection-threshold".into()), + Arch::RiscV32 | Arch::RiscV64 => { SmallDataThresholdSupport::LlvmModuleFlag("SmallDataLimit".into()) } _ => SmallDataThresholdSupport::None, @@ -3138,9 +3173,9 @@ impl Target { unstable_target_features: &FxIndexSet, ) -> Option<(object::Architecture, Option)> { use object::Architecture; - Some(match self.arch.as_ref() { - "arm" => (Architecture::Arm, None), - "aarch64" => ( + Some(match self.arch { + Arch::Arm => (Architecture::Arm, None), + Arch::AArch64 => ( if self.pointer_width == 32 { Architecture::Aarch64_Ilp32 } else { @@ -3148,11 +3183,11 @@ impl Target { }, None, ), - "x86" => (Architecture::I386, None), - "s390x" => (Architecture::S390x, None), - "m68k" => (Architecture::M68k, None), - "mips" | "mips32r6" => (Architecture::Mips, None), - "mips64" | "mips64r6" => ( + Arch::X86 => (Architecture::I386, None), + Arch::S390x => (Architecture::S390x, None), + Arch::M68k => (Architecture::M68k, None), + Arch::Mips | Arch::Mips32r6 => (Architecture::Mips, None), + Arch::Mips64 | Arch::Mips64r6 => ( // While there are currently no builtin targets // using the N32 ABI, it is possible to specify // it using a custom target specification. N32 @@ -3165,7 +3200,7 @@ impl Target { }, None, ), - "x86_64" => ( + Arch::X86_64 => ( if self.pointer_width == 32 { Architecture::X86_64_X32 } else { @@ -3173,11 +3208,11 @@ impl Target { }, None, ), - "powerpc" => (Architecture::PowerPc, None), - "powerpc64" => (Architecture::PowerPc64, None), - "riscv32" => (Architecture::Riscv32, None), - "riscv64" => (Architecture::Riscv64, None), - "sparc" => { + Arch::PowerPC => (Architecture::PowerPc, None), + Arch::PowerPC64 => (Architecture::PowerPc64, None), + Arch::RiscV32 => (Architecture::Riscv32, None), + Arch::RiscV64 => (Architecture::Riscv64, None), + Arch::Sparc => { if unstable_target_features.contains(&sym::v8plus) { // Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode (Architecture::Sparc32Plus, None) @@ -3186,18 +3221,22 @@ impl Target { (Architecture::Sparc, None) } } - "sparc64" => (Architecture::Sparc64, None), - "avr" => (Architecture::Avr, None), - "msp430" => (Architecture::Msp430, None), - "hexagon" => (Architecture::Hexagon, None), - "xtensa" => (Architecture::Xtensa, None), - "bpf" => (Architecture::Bpf, None), - "loongarch32" => (Architecture::LoongArch32, None), - "loongarch64" => (Architecture::LoongArch64, None), - "csky" => (Architecture::Csky, None), - "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), - // Unsupported architecture. - _ => return None, + Arch::Sparc64 => (Architecture::Sparc64, None), + Arch::Avr => (Architecture::Avr, None), + Arch::Msp430 => (Architecture::Msp430, None), + Arch::Hexagon => (Architecture::Hexagon, None), + Arch::Xtensa => (Architecture::Xtensa, None), + Arch::Bpf => (Architecture::Bpf, None), + Arch::LoongArch32 => (Architecture::LoongArch32, None), + Arch::LoongArch64 => (Architecture::LoongArch64, None), + Arch::CSky => (Architecture::Csky, None), + Arch::Arm64EC => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), + Arch::AmdGpu + | Arch::Nvptx64 + | Arch::PowerPC64LE + | Arch::SpirV + | Arch::Wasm32 + | Arch::Wasm64 => return None, }) } @@ -3213,7 +3252,7 @@ impl Target { // FIXME(#112480) MSVC on x86-32 is unsound and fails to properly align many types with // more-than-4-byte-alignment on the stack. This makes alignments larger than 4 generally // unreliable on 32bit Windows. - if self.is_like_windows && self.arch == "x86" { + if self.is_like_windows && self.arch == Arch::X86 { Align::from_bytes(4).unwrap() } else { Align::MAX diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_hermit.rs index cad57abc2b1e..78ae0f55bb42 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_hermit.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - arch: "aarch64".into(), + arch: Arch::AArch64, data_layout: "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), options: TargetOptions { features: "+v8a,+strict-align,+neon,+fp-armv8".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs index 4b75a6e5dbf6..659bcdc3be74 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs @@ -1,6 +1,8 @@ use rustc_abi::Endian; -use crate::spec::{FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -13,7 +15,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs index 2a16d1de3b51..63a13b8a7d11 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs @@ -1,6 +1,8 @@ use rustc_abi::Endian; -use crate::spec::{FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -16,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { abi: "ilp32".into(), features: "+v8a,+outline-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_musl.rs index be5ac4a843ba..d3bf641a747f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_musl.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs index 97742403c78f..1d77669be680 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { mcount: "__mcount".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs index 7f918e850809..8ba909a79601 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs @@ -8,7 +8,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -37,7 +37,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs index f58aa1ac043c..d6b0e0919512 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs @@ -1,4 +1,4 @@ -use crate::spec::{RelocModel, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, RelocModel, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let base = base::solid::opts("asp3"); @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { linker: Some("aarch64-kmc-elf-gcc".into()), features: "+v8a,+neon,+fp-armv8".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index d8651f305fe9..2bee1cf70b45 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { max_atomic_width: Some(128), // As documented in https://developer.android.com/ndk/guides/cpu-features.html diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs index 61e4cad3fa20..eb8144dd44e2 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, StackProbeType, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a,+neon,+crypto,+crc".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index eee668cc67ed..9b7db11e2f29 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -1,4 +1,4 @@ -use crate::spec::{FramePointer, Target, TargetMetadata, base}; +use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" .into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index cd55576ef816..3453f1d6101b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{FramePointer, Target, TargetMetadata, base}; +use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" .into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 7306a75aa227..69a65e6b0f02 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -1,4 +1,6 @@ -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -11,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 8366b6d9bd82..b5907c6b1af2 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -33,7 +33,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs index 31b4a2111cbf..3e168b6c1566 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, base}; +use crate::spec::{Arch, Target, base}; pub(crate) fn target() -> Target { let mut base = base::helenos::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs index 580a36cb2e92..2cf5c2519d56 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - arch: "aarch64".into(), + arch: Arch::AArch64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), options: TargetOptions { features: "+v8a,+strict-align,+neon,+fp-armv8".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs index 1ed4fdb465d3..e744dc78494d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::illumos::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs index 4220d74dfc89..c4b1f2c05eb1 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs index a22c12896773..5020d893c86b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs @@ -1,4 +1,6 @@ -use crate::spec::{FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -11,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { abi: "ilp32".into(), features: "+v8a,+outline-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs index 158b38e51401..6ba5112342c3 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -27,7 +27,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs index 51cdebf22db2..5f1ab6069ef0 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, FramePointer, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs index 1fa9d7131c50..ede0f78711eb 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, base}; +use crate::spec::{Arch, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::managarm_mlibc::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs index 461730457aa4..d02403007cd7 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a".into(), mcount: "__mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs index 6c14f5df4660..ffb136366acc 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs @@ -7,7 +7,7 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -39,7 +39,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index 35a4dd72b862..387fef3074d4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs @@ -7,7 +7,7 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -35,7 +35,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs index 243d84a12ece..8bcc3e0ae16d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs @@ -7,7 +7,7 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, cvs, }; @@ -41,7 +41,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index c23006adad6d..e5e40cb38b91 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs index 39fe71528d38..81aac17a933b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs index 799ff1a806ee..009f027ca24f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::teeos::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs index 05783fde1adf..3d0560eb7963 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs @@ -1,7 +1,8 @@ // Trusty OS target for AArch64. use crate::spec::{ - LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, TargetOptions, + Arch, LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -15,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+neon,+fp-armv8,+reserve-x18".into(), executables: true, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs index 327b52389b93..e2c1888e4084 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs @@ -1,7 +1,7 @@ // This defines the aarch64 target for UEFI systems as described in the UEFI specification. See the // uefi-base module for generic UEFI options. -use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::uefi_msvc::opts(); @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" .into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs index a40c8c3a3f26..0b39b90b9703 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_uwp_msvc::opts(); @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" .into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs index b68267601838..679d8941b36f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), + arch: Arch::AArch64, options: TargetOptions { features: "+v8a,+reserve-x18".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs index 0d6c6194e269..07772c757337 100644 --- a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs +++ b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs @@ -1,8 +1,10 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata, TargetOptions}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata, TargetOptions, +}; pub(crate) fn target() -> Target { Target { - arch: "amdgpu".into(), + arch: Arch::AmdGpu, data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(), llvm_target: "amdgcn-amd-amdhsa".into(), metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index 7292412a18d8..aa31f53bf0fc 100644 --- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -1,4 +1,6 @@ -use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base}; +use crate::spec::{ + Arch, FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base, +}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -28,7 +30,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" .into(), - arch: "arm64ec".into(), + arch: Arch::Arm64EC, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs index d74468899f56..dad8f5e1c552 100644 --- a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs index 3b6c97167cf4..55136255babc 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs index 0c711d5e71ab..087d4cfe800d 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs index d05f4c79b01f..e5224e4cce48 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs index 9ce752efd6aa..0e958455994c 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs index afb17fd82032..a9794f80e687 100644 --- a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs index 0ae7cd7a3773..bf9519b8a105 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs @@ -3,7 +3,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs index 71ffd8baed57..75a4ab4d877a 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs @@ -3,7 +3,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs index 9571821656c8..2bb35bd6ea20 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs @@ -10,7 +10,7 @@ //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "arm".into(), + arch: Arch::Arm, /* Data layout args are '-' separated: * little endian * stack is 64-bit aligned (EABI) diff --git a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs index beaec71093cb..1e13e02045a1 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs index 75ab941c5cf2..28f2533d7a36 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs @@ -1,6 +1,6 @@ //! Targets the ARMv5TE, with code as `a32` code by default. -use crate::spec::{FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "arm".into(), + arch: Arch::Arm, /* Data layout args are '-' separated: * little endian * stack is 64-bit aligned (EABI) diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs index 7b93672dbe0f..763d68f0495a 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs index 0240450b61d3..a08d1a1c63ef 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs index 860629b08e19..1719ab7314a4 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs index 1625a6b84bbc..2da15219d6ce 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs index af9a43595651..fbd55a371487 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs index 4c32a5e62161..a79c64287012 100644 --- a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs +++ b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; /// A base target for Nintendo 3DS devices using the devkitARM toolchain. @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { os: "horizon".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs index 706fb12a524a..ce6c3c8a6c14 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, TargetOptions, + base, }; // This target if is for the baseline of the Android v7a ABI @@ -23,7 +24,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs index c17db36ee611..0958f617663f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { os: "rtems".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs index 4902dc37d13c..6c02ec26fea4 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; /// A base target for PlayStation Vita devices using the VITASDK toolchain (using newlib). @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { os: "vita".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs index 56f2e090e071..63aee180299e 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs index 603afe2c48bb..6288095fcf4c 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs index a3b35d658e9d..57374b8af9d7 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs index dd8a97bf77f6..20545aba821f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs index c3b7ac5f994c..7028f430ff8f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode or NEON. @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs index f31dedb04e6c..f0946183fcad 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or // hardfloat. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs index a9e9f4651bb2..c2cc2526ec3f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON, // thumb-mode or hardfloat. @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs index a95f12d0230d..0649ba3c5ed5 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs index d155dc58e511..d6cb517759d9 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs index 2b0b0e1d1170..765d1982a679 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FloatAbi, LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, + Arch, FloatAbi, LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, TargetOptions, }; @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs index 05be389b57c3..ef261150f220 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs index 26c251399891..3ceeef4e0696 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let base = base::solid::opts("asp3"); @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs index 7032444bea4c..65af0bda5dfe 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let base = base::solid::opts("asp3"); @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index fb1d7d6c39d7..3d4328abe9b4 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs @@ -15,7 +15,7 @@ // linking. rationale: matches `thumb` targets use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -44,7 +44,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index 217a79d4571e..e3c5dce88fc1 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -6,7 +6,7 @@ // `thumb` & `aarch64` targets. use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs index 052285b98dc8..93302540795d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs @@ -5,7 +5,7 @@ // configuration without hardware floating point support. use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs index 85543e95616b..864517557c30 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs @@ -5,7 +5,7 @@ // configuration with hardware floating point support. use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 06dd26297758..6da1a35474ac 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -38,7 +38,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index 334be483daa0..bd07e724901c 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 2bb3e70483ae..2f89f8042c4a 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index d6e3a03bbba8..58bd9fafde96 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) use crate::spec::{ - Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), diff --git a/compiler/rustc_target/src/spec/targets/avr_none.rs b/compiler/rustc_target/src/spec/targets/avr_none.rs index 65a171e4515a..eaf4e956f55e 100644 --- a/compiler/rustc_target/src/spec/targets/avr_none.rs +++ b/compiler/rustc_target/src/spec/targets/avr_none.rs @@ -1,8 +1,8 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; pub(crate) fn target() -> Target { Target { - arch: "avr".into(), + arch: Arch::Avr, metadata: crate::spec::TargetMetadata { description: None, tier: Some(3), diff --git a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs index 3d39cd26c650..d4a40b2e24c0 100644 --- a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, data_layout: "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), pointer_width: 64, - arch: "bpf".into(), + arch: Arch::Bpf, options: base::bpf::opts(Endian::Big), } } diff --git a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs index 51f45b012449..f9c5f0956d24 100644 --- a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), pointer_width: 64, - arch: "bpf".into(), + arch: Arch::Bpf, options: base::bpf::opts(Endian::Little), } } diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs index 6142c1541f0b..1f7f7899f3a6 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on Csky @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), - arch: "csky".into(), + arch: Arch::CSky, options: TargetOptions { abi: "abiv2".into(), features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs index c233ec3ada73..68fdb69fe9d8 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on Csky @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), - arch: "csky".into(), + arch: Arch::CSky, options: TargetOptions { abi: "abiv2hf".into(), cpu: "ck860fv".into(), diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs index 74a7eab1e0c4..17b371f05e53 100644 --- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { ":2048:2048" ) .into(), - arch: "hexagon".into(), + arch: Arch::Hexagon, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs index e5a927d0953a..6379cd30c355 100644 --- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs @@ -1,4 +1,4 @@ -use crate::spec::{PanicStrategy, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Arch, PanicStrategy, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { ":2048:2048" ) .into(), - arch: "hexagon".into(), + arch: Arch::Hexagon, options: TargetOptions { cpu: "hexagonv60".into(), diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs index 39a71cf17812..92889d6f3517 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::netbsd::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: TargetOptions { mcount: "__mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs index 08281eda42e0..935666630dae 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_linux_android.rs b/compiler/rustc_target/src/spec/targets/i686_linux_android.rs index f2d7ec664439..b4716f8f3ee9 100644 --- a/compiler/rustc_target/src/spec/targets/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/i686_linux_android.rs @@ -1,5 +1,5 @@ use crate::spec::{ - RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; // See https://developer.android.com/ndk/guides/abis.html#x86 @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: TargetOptions { supported_sanitizers: SanitizerSet::ADDRESS, ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs index 6a98a763b364..af7f3b6b8563 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs @@ -1,5 +1,5 @@ use crate::spec::base::nto_qnx; -use crate::spec::{RustcAbi, StackProbeType, Target, TargetOptions, base}; +use crate::spec::{Arch, RustcAbi, StackProbeType, Target, TargetOptions, base}; pub(crate) fn target() -> Target { let mut meta = nto_qnx::meta(); @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: TargetOptions { rustc_abi: Some(RustcAbi::X86Sse2), cpu: "pentium4".into(), diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs index a0d403bd05e6..8ec160748615 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, crt_objects, + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, crt_objects, }; pub(crate) fn target() -> Target { @@ -34,7 +34,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs index 2e2ea8f81be0..7893fc771a47 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); @@ -27,7 +29,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs index 6a95afa1d0d3..8f2746c46166 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs index 1dfea64ebed6..6ff5f6d96b84 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::freebsd::opts(); @@ -20,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs index ab329170a4f3..a5d4be426897 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::haiku::opts(); @@ -20,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs index 1cd32d6f78d9..c653f434fc70 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, Target, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, RustcAbi, Target, base}; pub(crate) fn target() -> Target { let mut base = base::helenos::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs index b01f93f74042..cf65bdd6decf 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::hurd_gnu::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs index c70c026f9f71..932f6034433e 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, + base, }; pub(crate) fn target() -> Target { @@ -34,7 +35,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs index b6b85f5236d8..5c85a3e13820 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, + base, }; pub(crate) fn target() -> Target { @@ -40,7 +41,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs index cbd61cadb360..8cecc2badf11 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: TargetOptions { mcount: "__mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs index 48f7be7dc2b5..572dedb3d30c 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::openbsd::opts(); @@ -20,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs index 1a7923ca89bd..37b202097b46 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs @@ -5,7 +5,7 @@ // The cdecl ABI is used. It differs from the stdcall or fastcall ABI. // "i686-unknown-windows" is used to get the minimal subset of windows-specific features. -use crate::spec::{LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, add_link_args, base}; +use crate::spec::{Arch, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, add_link_args, base}; pub(crate) fn target() -> Target { let mut base = base::uefi_msvc::opts(); @@ -96,7 +96,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs index d95f779774f1..bf2608f8aa77 100644 --- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::windows_uwp_gnu::opts(); @@ -27,7 +29,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs index fa7a103df797..e6d2916d1109 100644 --- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{RustcAbi, Target, TargetMetadata, base}; +use crate::spec::{Arch, RustcAbi, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_uwp_msvc::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs index f364c2cb0327..c026f915906c 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::windows_gnu::opts(); @@ -29,7 +31,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs index 91ab31110978..68131bf65426 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -39,7 +39,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs index 63ede7b4ab89..9ce61da7f950 100644 --- a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::vxworks::opts(); @@ -20,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: Arch::X86, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs index fb4963b88b0f..d9a4708a9c2d 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), - arch: "loongarch32".into(), + arch: Arch::LoongArch32, options: TargetOptions { cpu: "generic".into(), features: "+f,+d".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs index 0e65f83a71cf..4ac9241fb8c6 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), - arch: "loongarch32".into(), + arch: Arch::LoongArch32, options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs index 9e743a355296..255756b5b4f1 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "loongarch64".into(), + arch: Arch::LoongArch64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs index d9010b1e4eeb..74b0efd63e77 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "loongarch64".into(), + arch: Arch::LoongArch64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs index c1c859ef25c8..222cf5c92c56 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "loongarch64".into(), + arch: Arch::LoongArch64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs index b6a08958284f..d8b509582017 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "loongarch64".into(), + arch: Arch::LoongArch64, options: TargetOptions { cpu: "generic".into(), features: "+f,+d,-lsx".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index 24983900683e..e33d8c954fd0 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "loongarch64".into(), + arch: Arch::LoongArch64, options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs index 9bd02e842c24..75bb02c25112 100644 --- a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{LinkSelfContainedDefault, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LinkSelfContainedDefault, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16".into(), - arch: "m68k".into(), + arch: Arch::M68k, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs index 6b66052692a4..56869348df85 100644 --- a/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_none_elf.rs @@ -1,6 +1,8 @@ use rustc_abi::Endian; -use crate::spec::{CodeModel, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions}; +use crate::spec::{ + Arch, CodeModel, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, +}; pub(crate) fn target() -> Target { let options = TargetOptions { @@ -28,7 +30,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16".into(), - arch: "m68k".into(), + arch: Arch::M68k, options, } } diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs index eb1148d5e8fa..0cd93429f6e2 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs @@ -2,7 +2,7 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64".into(), + arch: Arch::Mips64, options: TargetOptions { vendor: "openwrt".into(), abi: "abi64".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs index a26350ff2250..4d06466e6553 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64".into(), + arch: Arch::Mips64, options: TargetOptions { abi: "abi64".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs index e54628acb1ad..a37508c34dbd 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64".into(), + arch: Arch::Mips64, options: TargetOptions { abi: "abi64".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs index 19bceadc6223..9ece84ed5442 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64".into(), + arch: Arch::Mips64, options: TargetOptions { abi: "abi64".into(), // NOTE(mips64r2) matches C toolchain diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs index a256733734f7..759a04d24b7c 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64".into(), + arch: Arch::Mips64, options: TargetOptions { abi: "abi64".into(), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs index def12122416a..54039925e795 100644 --- a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 32, - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { vendor: "mti".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs index 29a451b31a65..ea6e237895ae 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { endian: Endian::Big, cpu: "mips32r2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs index 2d258d7e438f..ab68c2495b5a 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs index c14bfbf46d21..c699f7e20b06 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { endian: Endian::Big, cpu: "mips32r2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs index cc9c19e4a0b5..06c4d14be432 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 32, - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { vendor: "mti".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs index 37ebb3d174b3..200735f4e0fb 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, +}; // The PSP has custom linker requirements. const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld"); @@ -19,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { os: "psp".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index 8475a43ea633..b6d30be589ea 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + cvs, }; pub(crate) fn target() -> Target { @@ -13,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { // The Playstation 1 is mostly bare-metal, but the BIOS does provide some a slight bit diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs index 6c7ea5c56889..79a22e518b0c 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { cpu: "mips32r2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs index f4fb6be33216..8c64b17a37b5 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs index f0056799d66f..295b1788877c 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { cpu: "mips32r2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs index 502d7382b3cf..69b232d71ea1 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::netbsd::opts(); @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { features: "+soft-float".into(), mcount: "__mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs index 6a201c56475e..7012651afc34 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs @@ -3,7 +3,7 @@ //! Can be used for MIPS M4K core (e.g. on PIC32MX devices) use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: Arch::Mips, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs index 0716f2e483b4..b45511446d8d 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips32r6".into(), + arch: Arch::Mips32r6, options: TargetOptions { endian: Endian::Big, cpu: "mips32r6".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs index 81f2424e4dea..36845029de3b 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips32r6".into(), + arch: Arch::Mips32r6, options: TargetOptions { cpu: "mips32r6".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs index cdd5f6b84365..3a95f78482bb 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64r6".into(), + arch: Arch::Mips64r6, options: TargetOptions { abi: "abi64".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs index 88879a25818b..8e5bf3d36559 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), - arch: "mips64r6".into(), + arch: Arch::Mips64r6, options: TargetOptions { abi: "abi64".into(), // NOTE(mips64r6) matches C toolchain diff --git a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs index caf77bb8669d..d8cee79b69d2 100644 --- a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 16, data_layout: "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16".into(), - arch: "msp430".into(), + arch: Arch::Msp430, options: TargetOptions { c_int_width: 16, diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index cada0dd640a4..ac2d31a0d61a 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -1,11 +1,11 @@ use crate::spec::{ - LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, PanicStrategy, Target, TargetMetadata, - TargetOptions, + Arch, LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, PanicStrategy, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { Target { - arch: "nvptx64".into(), + arch: Arch::Nvptx64, data_layout: "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64".into(), llvm_target: "nvptx64-nvidia-cuda".into(), metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs index a14051889997..b4f394643a9d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::aix::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:a-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs index b01ca989282e..de94d2023452 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-Fn32-i64:64-i128:128-n32:64".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs index bc7e445f3f8a..18a3f059039d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index 8fb991d0bd1a..64d4f58a4664 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs index 9dc44aa05cc0..1034a1603026 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-Fn32-i64:64-i128:128-n32:64".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs index 10072f8092de..fb40316d75dc 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { endian: Endian::Big, ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs index a7f4e0eabb0a..7ae74dc882fd 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-Fn32-i64:64-i128:128-n32:64".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs index af5704b51ba3..4d1e3dfae456 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs index 0f8b78fa7307..3813e29229d9 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), - arch: "powerpc64".into(), + arch: Arch::PowerPC64, options: TargetOptions { mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs index 5e1161e2f7d6..54f490e0800d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { endian: Endian::Big, features: "+secure-plt".into(), diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs index 2b713e8a5ff2..9e06faa7d531 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::helenos::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs index 6cde4bd98ac1..aa2b694962dc 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { endian: Endian::Big, features: "+secure-plt".into(), diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs index 3c1d18e07771..8bbed94f2f7a 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { abi: "spe".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs index f5c7cb061988..7e494e065a04 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs index 8ddb45483b3b..0b6535e5debe 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { abi: "spe".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs index 47a61a1aff24..62e50bbd7ad2 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs index bc5a50a05399..59fccb5910be 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::openbsd::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs index ca78be2b2b23..6c587755b832 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { endian: Endian::Big, features: "+secure-plt".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs index e6345629f039..85de246605d7 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), - arch: "powerpc".into(), + arch: Arch::PowerPC, options: TargetOptions { abi: "spe".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs index efc17d8d083b..3ec8891c95ee 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { cpu: "generic-rv32".into(), llvm_abiname: "ilp32d".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs index 00e8532d2384..1f8b2cacd9b5 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { abi: abi.into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs index f814201601fc..1ae868e9b135 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { abi: abi.into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs index 33df429db725..e0958e0f9c5e 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { abi: abi.into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs index 5b7feef70d09..29b0f35a205f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs index a13bb173e248..28116052151e 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs index f9a3b2172205..bd6375fef163 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs index 162f21c42ba2..c0372035cd7e 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { os: "zkvm".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs index 47b408a12d17..5aef58b153d1 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs index a173fb00b329..c455f654b400 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs index 48db9f44eacd..6b3e5a47ad87 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs @@ -1,4 +1,4 @@ -use crate::spec::{PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs index 1608f051ea82..deca348b9e1b 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs index 4ee02c6b2956..70eb7cb78d65 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + cvs, }; pub(crate) fn target() -> Target { @@ -13,7 +14,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs index 0893bd5ad6dc..e50de1cc9371 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { os: "xous".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs index 0929af7bb75f..196a3de95cfb 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs @@ -1,4 +1,4 @@ -use crate::spec::{PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs index 44a84d9082cd..21f683516f7c 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs index 8908c0c53d9f..f7b8bd49e527 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + cvs, }; pub(crate) fn target() -> Target { @@ -13,7 +14,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs index 82a4d58a3986..66c64667d0dc 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs @@ -1,4 +1,4 @@ -use crate::spec::{PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs index 755ffc6154a1..0b8e44744206 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs index 8da0b0e3e6b2..a10ddb2d0569 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + cvs, }; pub(crate) fn target() -> Target { @@ -13,7 +14,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - arch: "riscv32".into(), + arch: Arch::RiscV32, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs index b9176c939f80..404f4143c5be 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use crate::spec::{ - CodeModel, SanitizerSet, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, + Arch, CodeModel, SanitizerSet, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs index 8d8c21952de5..c6fffc251529 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { cpu: "generic-rv64".into(), llvm_abiname: "lp64d".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs index 60f2e7da042c..39db793af0de 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs index e628095b88a6..dbcfbc38ece6 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs index c4466e13d143..c3a45254b712 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, CodeModel, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs index 5c15bdd9f645..68f69044bb25 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs @@ -1,4 +1,6 @@ -use crate::spec::{CodeModel, RelocModel, Target, TargetMetadata, TargetOptions, TlsModel, base}; +use crate::spec::{ + Arch, CodeModel, RelocModel, Target, TargetMetadata, TargetOptions, TlsModel, base, +}; pub(crate) fn target() -> Target { Target { @@ -10,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - arch: "riscv64".into(), + arch: Arch::RiscV64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), options: TargetOptions { cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs index af2f42fa00a2..333a63a25158 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 83fd4e2cfa9e..f5d647d0fc54 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs index abf28310634a..a9ecf27e9134 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, Target, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, Target, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs index 1f359d1e7fe6..bc929a07f9c0 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs index 5a5aad93efba..b06727efc9ee 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, llvm_target: "riscv64".into(), pointer_width: 64, - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs index e8abc926dd0e..93dd6dc7ed1c 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, cvs, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, llvm_target: "riscv64".into(), pointer_width: 64, - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs index 85d7dfe7865e..fb7b077c963d 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs index 01276a8be465..b6e88646d4e2 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{CodeModel, Target, TargetMetadata, base}; +use crate::spec::{Arch, CodeModel, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), - arch: "riscv64".into(), + arch: Arch::RiscV64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs index 5c5d4aa32a2c..60ee41b47dfd 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs index 0928250dba64..25e3e72f9de9 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, cvs, }; @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, llvm_target: "riscv64".into(), pointer_width: 64, - arch: "riscv64".into(), + arch: Arch::RiscV64, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs index cdcf7d62a3e2..a64e867b9a1c 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::{Align, Endian}; -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(), - arch: "s390x".into(), + arch: Arch::S390x, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs index 509105afedcd..69c25d72432c 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs @@ -1,6 +1,6 @@ use rustc_abi::{Align, Endian}; -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(), - arch: "s390x".into(), + arch: Arch::S390x, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs index 8c3def57d0cf..c5d5657bf816 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::helenos::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), - arch: "sparc64".into(), + arch: Arch::Sparc64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs index a52dadba5a51..b6c06af3cc83 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), - arch: "sparc64".into(), + arch: Arch::Sparc64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs index 21eedc5b6bc0..8f9552889310 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::netbsd::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), - arch: "sparc64".into(), + arch: Arch::Sparc64, options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs index b573bdf80a96..6adabeca4a8b 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::openbsd::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), - arch: "sparc64".into(), + arch: Arch::Sparc64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs index ffef69679125..f110acf63d87 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(), - arch: "sparc".into(), + arch: Arch::Sparc, options: TargetOptions { features: "+v8plus".into(), cpu: "v9".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs index c2f64998dddb..de6063301f68 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -29,7 +29,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "sparc".into(), + arch: Arch::Sparc, options, } } diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 1c53e15837cf..79035c791156 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::solaris::opts(); @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { // used widely in the source base. If we ever needed ABI // differentiation from the sparc64, we could, but that would probably // just be confusing. - arch: "sparc64".into(), + arch: Arch::Sparc64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs index 7221bd8d4aef..7a183bf5414e 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs @@ -10,8 +10,8 @@ //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. use crate::spec::{ - FloatAbi, FramePointer, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, base, - cvs, + Arch, FloatAbi, FramePointer, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + base, cvs, }; pub(crate) fn target() -> Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "arm".into(), + arch: Arch::Arm, /* Data layout args are '-' separated: * little endian * stack is 64-bit aligned (EABI) diff --git a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs index 155e25211c1f..b20be27665e0 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs @@ -1,6 +1,6 @@ //! Targets the ARMv5TE, with code as `t32` code by default. -use crate::spec::{FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 32, - arch: "arm".into(), + arch: Arch::Arm, /* Data layout args are '-' separated: * little endian * stack is 64-bit aligned (EABI) diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs index 3b4b94da0577..684e465af4a6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs index 3c6133dc7ceb..c0dd931e66a4 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs index 5660f97c8b57..335c4c1af510 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs @@ -4,7 +4,7 @@ // and will use software floating point operations. This matches the NuttX EABI // configuration without hardware floating point support. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs index d79970b0a0dd..0a0dbaf12554 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs @@ -7,7 +7,7 @@ // This target uses the "hard" floating convention (ABI) where floating point values // are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.). -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs index 33da885cc1a5..808fae366835 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs @@ -1,5 +1,5 @@ use crate::spec::{ - FloatAbi, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata, TargetOptions, base, + Arch, FloatAbi, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3,+neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs index b4cc960939e9..d9ad392fc814 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, PanicStrategy, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, PanicStrategy, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3,+neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs index c747d721b671..c67e955d0856 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs @@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs index 309d32042a03..9a05209b0eb6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs @@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs index 57ef4e75e640..7888587ce9e3 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs @@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs index 0518872dd62d..51e57f77963a 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs @@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs index f261009d854e..fea5f15fe0a6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs index 611795e58f1f..50ab8c5a4ee0 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs index d3a25163c53f..cc6f26d38dea 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, Cc, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, +}; // This target if is for the Android v7a ABI in thumb mode with // NEON unconditionally enabled and, therefore, with 32 FPU registers @@ -21,7 +23,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), llvm_floatabi: Some(FloatAbi::Soft), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs index cce49f274aca..9abbec824b0f 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), llvm_floatabi: Some(FloatAbi::Hard), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs index d58339bc38c2..e8239172409b 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf // target. diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs index b35f7bac93b4..aca7441d34ab 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs index 4e5f6898651a..26bf14d176ba 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs index 38143904efd1..e1cc16aeb5c6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabi".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs index 55b7561da84c..cd3d3327a5c4 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { abi: "eabihf".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs index 56aca0a88297..1fae7a92d923 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs index 47525e704daf..b8de91edfb23 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), - arch: "arm".into(), + arch: Arch::Arm, options: TargetOptions { families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs index 4624c0fd5cba..aa4a1be99291 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs @@ -1,6 +1,6 @@ use crate::spec::{ - LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, base, - cvs, + Arch, LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + base, cvs, }; pub(crate) fn target() -> Target { @@ -35,7 +35,7 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20" .into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs index b5792731a900..3050f17d5efb 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs @@ -10,7 +10,7 @@ //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); @@ -44,7 +44,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs index 06e5cfaed92d..9e4121d97eb8 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs @@ -1,7 +1,7 @@ //! The `wasm32-wali-linux-musl` target is a wasm32 target compliant with the //! [WebAssembly Linux Interface](https://github.com/arjunr2/WALI). -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::linux_wasm::opts(); @@ -30,7 +30,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index 26add451ed25..a7c196c4530f 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs @@ -11,7 +11,7 @@ //! introduced. use crate::spec::{ - Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, + Arch, Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, }; pub(crate) fn target() -> Target { @@ -58,7 +58,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs index c735c72cb1cb..d4953cc9d498 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs @@ -8,7 +8,7 @@ //! Historically this target was known as `wasm32-wasi-preview1-threads`. use crate::spec::{ - Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, + Arch, Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, }; pub(crate) fn target() -> Target { @@ -72,7 +72,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs index 7ad675dc3cf1..717d49004a17 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs @@ -17,7 +17,7 @@ //! . use crate::spec::{ - LinkSelfContainedDefault, RelocModel, Target, TargetMetadata, base, crt_objects, + Arch, LinkSelfContainedDefault, RelocModel, Target, TargetMetadata, base, crt_objects, }; pub(crate) fn target() -> Target { @@ -69,7 +69,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs index e554e2ac0768..41267f0e5708 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs @@ -12,7 +12,7 @@ //! nightly Rust feature `-Zbuild-std`. This target is for people who want to //! use stable Rust, and target a stable set pf WebAssembly features. -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); @@ -51,7 +51,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm32".into(), + arch: Arch::Wasm32, options, } } diff --git a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs index e8ac93a87ca4..850e85591661 100644 --- a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs @@ -7,7 +7,7 @@ //! the standard library is available, most of it returns an error immediately //! (e.g. trying to create a TCP stream or something like that). -use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); @@ -47,7 +47,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), - arch: "wasm64".into(), + arch: Arch::Wasm64, options, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs index bbaee6c1f6d9..6232de48da70 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { let pre_link_args = TargetOptions::link_args( @@ -83,7 +83,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs index 3a0acaa028cb..93d77b9d1dc3 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, - base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: TargetOptions { supported_sanitizers: SanitizerSet::ADDRESS, ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_lynx_lynxos178.rs b/compiler/rustc_target/src/spec/targets/x86_64_lynx_lynxos178.rs index 654ae7c9c5be..933e716236fa 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_lynx_lynxos178.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_lynx_lynxos178.rs @@ -1,4 +1,4 @@ -use crate::spec::{SanitizerSet, StackProbeType, Target, base}; +use crate::spec::{Arch, SanitizerSet, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::lynxos178::opts(); @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs index eac4caf41c8b..1d7ecc25a633 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, base}; pub(crate) fn target() -> Target { let mut base = base::cygwin::opts(); @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, metadata: crate::spec::TargetMetadata { description: Some("64-bit x86 Cygwin".into()), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs index 662bbc4a31c4..7b8d5def3a70 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::solaris::opts(); @@ -21,7 +23,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs index 16bdd3ee6684..ba0882b8693b 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnu::opts(); @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index 1a03390c2b89..28c9e6251255 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs index d88aabaa6d33..1eecec8e6bde 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs index f5bc3ab707db..c5421f3e6b74 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - arch: "x86_64".into(), + arch: Arch::X86_64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), options: TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs index 715c0db632b1..99f10ca7ec3f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::dragonfly::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs index 4a074539aab7..3043fd2a43bd 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs index d7253da7e8d6..0d92097ad456 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs @@ -1,4 +1,4 @@ -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs index ecb9fc80351e..85659373421f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::haiku::opts(); @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs index 82c9807f73e3..42e46fa4ef9d 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, base}; pub(crate) fn target() -> Target { let mut base = base::helenos::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs index 7abde7717981..ee191ac95ae7 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - arch: "x86_64".into(), + arch: Arch::X86_64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), options: TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hurd_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hurd_gnu.rs index 57ce67af36d6..cf282335b966 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hurd_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hurd_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::hurd_gnu::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs index 17f90db0c906..9510ed5791dd 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::illumos::opts(); @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs index 4107249dcf1e..5ab6b094dfa0 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{PanicStrategy, Target, TargetMetadata, base}; +use crate::spec::{Arch, PanicStrategy, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::l4re::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs index 59bb7f596210..adb7a43a6232 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -31,7 +31,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs index c5d556e5cc65..0b3e25bebf36 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-i128:128-f80:128-n8:16:32:64-S128" .into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs index 3cb2a962a562..ee883532ad4a 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -30,7 +30,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs index 896e8a78f863..ecf232f1ab2f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, PanicStrategy, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs index de9027ba9622..c6c55c148f64 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base, }; pub(crate) fn target() -> Target { @@ -27,7 +27,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs index 359e38cb8007..98997c98749c 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::managarm_mlibc::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs index 0fd43357a766..3be05b79954f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs @@ -1,5 +1,5 @@ use crate::spec::{ - CodeModel, LinkSelfContainedDefault, LldFlavor, RelocModel, RelroLevel, Target, base, + Arch, CodeModel, LinkSelfContainedDefault, LldFlavor, RelocModel, RelroLevel, Target, base, }; pub(crate) fn target() -> Target { @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs index 0403c220982d..2561fe48bcc8 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, - base, + Arch, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: TargetOptions { mcount: "__mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs index 1a6343595f54..520a59d6a6f6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs @@ -5,7 +5,7 @@ // features. use crate::spec::{ - Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, RustcAbi, SanitizerSet, + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -39,7 +39,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: opts, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs index 2eb09b8cbada..c911de4aee82 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::openbsd::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs index 65b8e2543a41..562beab760b7 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs index dbcb5fd4e11e..88c66ff6db9f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs @@ -1,8 +1,8 @@ // Trusty OS target for X86_64. use crate::spec::{ - LinkSelfContainedDefault, PanicStrategy, RelroLevel, StackProbeType, Target, TargetMetadata, - TargetOptions, + Arch, LinkSelfContainedDefault, PanicStrategy, RelroLevel, StackProbeType, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: TargetOptions { executables: true, max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs index 0cf6a8794621..8a494d0e56dd 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs @@ -7,7 +7,7 @@ use rustc_abi::{CanonAbi, X86Call}; -use crate::spec::{RustcAbi, Target, TargetMetadata, base}; +use crate::spec::{Arch, RustcAbi, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::uefi_msvc::opts(); @@ -40,7 +40,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs index bf6179cb6c38..96d1bd2764c8 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_uwp_gnu::opts(); @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs index 50b0578da357..3be6abd3d975 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{Arch, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_uwp_msvc::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs index df1fe8e7853c..22a1a126b891 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnu::opts(); @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs index 876ac0118792..99b59154811f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs index 9ab62b3530fa..0bc374971460 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::vxworks::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: Arch::X86_64, options: base, } } diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs index 8a6773811e88..d909271e218e 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs @@ -1,14 +1,14 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, options: TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs index d8638e8ac805..82c6e0cfa3f6 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs @@ -1,12 +1,12 @@ use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: Some("Xtensa ESP32".into()), tier: Some(3), diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs index f38d771f2579..b1ed0ffe264e 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs @@ -1,14 +1,14 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, options: TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs index 7bf5834ab0aa..755f4db3b2dd 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs @@ -1,12 +1,12 @@ use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: Some("Xtensa ESP32-S2".into()), tier: Some(3), diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs index 4ec6e319fd4f..8e1fee4ad657 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs @@ -1,14 +1,14 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, options: TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs index d506888d8ee0..07530d874c09 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs @@ -1,12 +1,12 @@ use crate::spec::base::xtensa; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Arch, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { Target { llvm_target: "xtensa-none-elf".into(), pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), - arch: "xtensa".into(), + arch: Arch::Xtensa, metadata: TargetMetadata { description: Some("Xtensa ESP32-S3".into()), tier: Some(3), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 288ee6357a51..16c3558d535b 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_span::{Symbol, sym}; -use crate::spec::{FloatAbi, RustcAbi, Target}; +use crate::spec::{Arch, FloatAbi, RustcAbi, Target}; /// Features that control behaviour of rustc, rather than the codegen. /// These exist globally and are not in the target-specific lists below. @@ -955,50 +955,62 @@ pub struct FeatureConstraints { impl Target { pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] { - match &*self.arch { - "arm" => ARM_FEATURES, - "aarch64" | "arm64ec" => AARCH64_FEATURES, - "x86" | "x86_64" => X86_FEATURES, - "hexagon" => HEXAGON_FEATURES, - "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES, - "nvptx64" => NVPTX_FEATURES, - "powerpc" | "powerpc64" => POWERPC_FEATURES, - "riscv32" | "riscv64" => RISCV_FEATURES, - "wasm32" | "wasm64" => WASM_FEATURES, - "bpf" => BPF_FEATURES, - "csky" => CSKY_FEATURES, - "loongarch32" | "loongarch64" => LOONGARCH_FEATURES, - "s390x" => IBMZ_FEATURES, - "sparc" | "sparc64" => SPARC_FEATURES, - "m68k" => M68K_FEATURES, - _ => &[], + match self.arch { + Arch::Arm => ARM_FEATURES, + Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES, + Arch::X86 | Arch::X86_64 => X86_FEATURES, + Arch::Hexagon => HEXAGON_FEATURES, + Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => MIPS_FEATURES, + Arch::Nvptx64 => NVPTX_FEATURES, + Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES, + Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES, + Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES, + Arch::Bpf => BPF_FEATURES, + Arch::CSky => CSKY_FEATURES, + Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES, + Arch::S390x => IBMZ_FEATURES, + Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES, + Arch::M68k => M68K_FEATURES, + Arch::AmdGpu + | Arch::Avr + | Arch::Msp430 + | Arch::PowerPC64LE + | Arch::SpirV + | Arch::Xtensa => &[], } } pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] { - match &*self.arch { - "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI, - "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, - "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, - "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, - "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, - "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, - "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, - "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, - "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI, - "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI, - "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI, - "nvptx64" | "bpf" | "m68k" => &[], // no vector ABI - "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI, + match self.arch { + Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::Arm => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::S390x => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { + MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI + } + Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], // no vector ABI + Arch::CSky => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI, // FIXME: for some tier3 targets, we are overly cautious and always give warnings // when passing args in vector registers. - _ => &[], + Arch::AmdGpu + | Arch::Avr + | Arch::Msp430 + | Arch::PowerPC64LE + | Arch::SpirV + | Arch::Xtensa => &[], } } pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] { - match &*self.arch { - "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES, + match self.arch { + Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES, _ => &[], } } @@ -1038,8 +1050,8 @@ impl Target { // defined by target features. When that is the case, those target features must be // "forbidden" in the list above to ensure that there is a consistent answer to the // questions "which ABI is used". - match &*self.arch { - "x86" => { + match self.arch { + Arch::X86 => { // We use our own ABI indicator here; LLVM does not have anything native. // Every case should require or forbid `soft-float`! match self.rustc_abi { @@ -1064,7 +1076,7 @@ impl Target { } } } - "x86_64" => { + Arch::X86_64 => { // We use our own ABI indicator here; LLVM does not have anything native. // Every case should require or forbid `soft-float`! match self.rustc_abi { @@ -1085,7 +1097,7 @@ impl Target { Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"), } } - "arm" => { + Arch::Arm => { // On ARM, ABI handling is reasonably sane; we use `llvm_floatabi` to indicate // to LLVM which ABI we are going for. match self.llvm_floatabi.unwrap() { @@ -1102,7 +1114,7 @@ impl Target { } } } - "aarch64" | "arm64ec" => { + Arch::AArch64 | Arch::Arm64EC => { // Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force // the use of soft-float, so all we can do here is some crude hacks. match &*self.abi { @@ -1121,7 +1133,7 @@ impl Target { } } } - "riscv32" | "riscv64" => { + Arch::RiscV32 | Arch::RiscV64 => { // RISC-V handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. match &*self.llvm_abiname { @@ -1155,7 +1167,7 @@ impl Target { _ => unreachable!(), } } - "loongarch32" | "loongarch64" => { + Arch::LoongArch32 | Arch::LoongArch64 => { // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. match &*self.llvm_abiname { @@ -1177,7 +1189,7 @@ impl Target { _ => unreachable!(), } } - "s390x" => { + Arch::S390x => { // We don't currently support a softfloat target on this architecture. // As usual, we have to reject swapping the `soft-float` target feature. // The "vector" target feature does not affect the ABI for floats diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 3b18545fee6c..27d461f68848 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -31,6 +31,7 @@ use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{Span, SpanData, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use crate::alloc_addresses::EvalContextExt; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; @@ -716,9 +717,9 @@ impl<'tcx> MiriMachine<'tcx> { page_size } else { let target = &tcx.sess.target; - match target.arch.as_ref() { - "wasm32" | "wasm64" => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances - "aarch64" => { + match target.arch { + Arch::Wasm32 | Arch::Wasm64 => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances + Arch::AArch64 => { if target.options.vendor.as_ref() == "apple" { // No "definitive" source, but see: // https://www.wwdcnotes.com/notes/wwdc20/10214/ diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index f498a21c9f90..f85ca4cfa424 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -3,6 +3,7 @@ use rustc_ast::expand::allocator::SpecialAllocatorMethod; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use crate::*; @@ -19,14 +20,40 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. let os = this.tcx.sess.target.os.as_ref(); - let max_fundamental_align = match this.tcx.sess.target.arch.as_ref() { - "riscv32" if matches!(os, "espidf" | "zkvm") => 4, - "xtensa" if matches!(os, "espidf") => 4, - "x86" | "arm" | "m68k" | "csky" | "loongarch32" | "mips" | "mips32r6" | "powerpc" - | "powerpc64" | "sparc" | "wasm32" | "hexagon" | "riscv32" | "xtensa" => 8, - "x86_64" | "aarch64" | "arm64ec" | "loongarch64" | "mips64" | "mips64r6" | "s390x" - | "sparc64" | "riscv64" | "wasm64" => 16, - arch => bug!("unsupported target architecture for malloc: `{}`", arch), + let max_fundamental_align = match this.tcx.sess.target.arch { + Arch::RiscV32 if matches!(os, "espidf" | "zkvm") => 4, + Arch::Xtensa if matches!(os, "espidf") => 4, + Arch::X86 + | Arch::Arm + | Arch::M68k + | Arch::CSky + | Arch::LoongArch32 + | Arch::Mips + | Arch::Mips32r6 + | Arch::PowerPC + | Arch::PowerPC64 + | Arch::Sparc + | Arch::Wasm32 + | Arch::Hexagon + | Arch::RiscV32 + | Arch::Xtensa => 8, + Arch::X86_64 + | Arch::AArch64 + | Arch::Arm64EC + | Arch::LoongArch64 + | Arch::Mips64 + | Arch::Mips64r6 + | Arch::S390x + | Arch::Sparc64 + | Arch::RiscV64 + | Arch::Wasm64 => 16, + arch @ (Arch::AmdGpu + | Arch::Avr + | Arch::Bpf + | Arch::Msp430 + | Arch::Nvptx64 + | Arch::PowerPC64LE + | Arch::SpirV) => bug!("unsupported target architecture for malloc: `{arch}`"), }; // The C standard only requires sufficient alignment for any *type* with size less than or // equal to the size requested. Types one can define in standard C seem to never have an alignment diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 74a1ac729e88..2507e0f6bbfa 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -15,6 +15,7 @@ use rustc_middle::{mir, ty}; use rustc_session::config::OomStrategy; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use super::alloc::EvalContextExt as _; use super::backtrace::EvalContextExt as _; @@ -800,20 +801,24 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Target-specific shims name if name.starts_with("llvm.x86.") - && (this.tcx.sess.target.arch == "x86" - || this.tcx.sess.target.arch == "x86_64") => + && matches!( + this.tcx.sess.target.arch, + Arch::X86 | Arch::X86_64 + ) => { return shims::x86::EvalContextExt::emulate_x86_intrinsic( this, link_name, abi, args, dest, ); } - name if name.starts_with("llvm.aarch64.") && this.tcx.sess.target.arch == "aarch64" => { + name if name.starts_with("llvm.aarch64.") + && this.tcx.sess.target.arch == Arch::AArch64 => + { return shims::aarch64::EvalContextExt::emulate_aarch64_intrinsic( this, link_name, abi, args, dest, ); } // FIXME: Move this to an `arm` submodule. - "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { + "llvm.arm.hint" if this.tcx.sess.target.arch == Arch::Arm => { let [arg] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; // Note that different arguments might have different target feature requirements. diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index c3ca01bbf340..21c9022737bc 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -6,6 +6,7 @@ use rustc_abi::{Align, CanonAbi, Size, X86Call}; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -140,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://github.com/rust-lang/rust/blob/fb00adbdb69266f10df95a4527b767b0ad35ea48/compiler/rustc_target/src/spec/mod.rs#L2766-L2768, // x86-32 Windows uses a different calling convention than other Windows targets // for the "system" ABI. - let sys_conv = if this.tcx.sess.target.arch == "x86" { + let sys_conv = if this.tcx.sess.target.arch == Arch::X86 { CanonAbi::X86(X86Call::Stdcall) } else { CanonAbi::C diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index 140e31cc5133..814823d2acb1 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -2,6 +2,7 @@ use rustc_abi::CanonAbi; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use crate::*; @@ -31,7 +32,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let target_feature = if unprefixed_name == "bextr" { "bmi1" } else { "bmi2" }; this.expect_target_feature_for_intrinsic(link_name, target_feature)?; - if is_64_bit && this.tcx.sess.target.arch != "x86_64" { + if is_64_bit && this.tcx.sess.target.arch != Arch::X86_64 { return interp_ok(EmulateItemResult::NotSupported); } diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 3324b7b024ac..016cb762cece 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -5,6 +5,7 @@ use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use self::helpers::bool_to_simd_element; use crate::*; @@ -41,7 +42,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarry-u32-addcarry-u64.html // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html "addcarry.32" | "addcarry.64" | "subborrow.32" | "subborrow.64" => { - if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != "x86_64" { + if unprefixed_name.ends_with("64") + && this.tcx.sess.target.arch != Arch::X86_64 + { return interp_ok(EmulateItemResult::NotSupported); } @@ -65,7 +68,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.expect_target_feature_for_intrinsic(link_name, "adx")?; let is_u64 = unprefixed_name.ends_with("64"); - if is_u64 && this.tcx.sess.target.arch != "x86_64" { + if is_u64 && this.tcx.sess.target.arch != Arch::X86_64 { return interp_ok(EmulateItemResult::NotSupported); } let [c_in, a, b, out] = diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 72c5039a12d3..aa8aea355883 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -3,6 +3,7 @@ use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Arch; use crate::*; @@ -431,7 +432,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => unreachable!(), }; - if bit_size == 64 && this.tcx.sess.target.arch != "x86_64" { + if bit_size == 64 && this.tcx.sess.target.arch != Arch::X86_64 { return interp_ok(EmulateItemResult::NotSupported); } From b49a1f7aad244d1cd901060808488e825b159811 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 13 Oct 2025 12:41:24 -0400 Subject: [PATCH 398/525] rustc_target: introduce Arch Improve type safety by using an enum rather than strings. --- src/abi/mod.rs | 17 +++++++++-------- src/codegen_f16_f128.rs | 10 +++++++--- src/common.rs | 4 ++-- src/lib.rs | 23 ++++++++++++----------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 9a9a1f4a2c0f..6ea26b02c261 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; +use rustc_target::spec::Arch; use smallvec::SmallVec; use self::pass_mode::*; @@ -155,7 +156,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let ret = self.lib_call_unadjusted(name, params, returns, &args)[0]; Cow::Owned(vec![codegen_bitcast(self, types::I128, ret)]) - } else if ret_single_i128 && self.tcx.sess.target.arch == "s390x" { + } else if ret_single_i128 && self.tcx.sess.target.arch == Arch::S390x { // Return i128 using a return area pointer on s390x. let mut params = params; let mut args = args.to_vec(); @@ -641,7 +642,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), ); - if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == "aarch64" { + if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == 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. @@ -787,25 +788,25 @@ pub(crate) fn codegen_drop<'tcx>( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (&*tcx.sess.target.arch, &*tcx.sess.target.vendor) { - ("x86_64", _) | ("aarch64", "apple") => match (ty, is_signed) { + match (tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { + (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), _ => param, }, - ("aarch64", _) => param, - ("riscv64", _) => match (ty, is_signed) { + (Arch::AArch64, _) => param, + (Arch::RiscV64, _) => match (ty, is_signed) { (types::I32, _) | (_, true) => param.sext(), _ => param.uext(), }, - ("s390x", _) => { + (Arch::S390x, _) => { if is_signed { param.sext() } else { param.uext() } } - _ => unimplemented!("{:?}", tcx.sess.target.arch), + (arch, _) => unimplemented!("{arch:?}"), } } else { param diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index 1e202be1f185..c0f6d9d853db 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -1,8 +1,10 @@ +use rustc_target::spec::Arch; + use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { let (value, arg_ty) = - if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 { ( fx.bcx.ins().bitcast(types::I16, MemFlags::new(), value), lib_call_arg_param(fx.tcx, types::I16, false), @@ -19,7 +21,8 @@ fn f16_to_f64(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { } pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 + { types::I16 } else { types::F16 @@ -34,7 +37,8 @@ pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value } fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == "x86_64" { + let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 + { types::I16 } else { types::F16 diff --git a/src/common.rs b/src/common.rs index 81b1814605a1..de3d2f31af10 100644 --- a/src/common.rs +++ b/src/common.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{ }; use rustc_span::source_map::Spanned; use rustc_target::callconv::FnAbi; -use rustc_target::spec::{HasTargetSpec, Target}; +use rustc_target::spec::{Arch, HasTargetSpec, Target}; use crate::constant::ConstantCx; use crate::debuginfo::FunctionDebugContext; @@ -373,7 +373,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { "size must be a multiple of alignment (size={size}, align={align})" ); - let abi_align = if self.tcx.sess.target.arch == "s390x" { 8 } else { 16 }; + let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 }; if align <= abi_align { let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, diff --git a/src/lib.rs b/src/lib.rs index 5d48d0c94c58..5c23cd02e0d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; +use rustc_target::spec::Arch; pub use crate::config::*; use crate::prelude::*; @@ -186,20 +187,20 @@ impl CodegenBackend for CraneliftCodegenBackend { fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] - let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" { - // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled - vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] - } else if sess.target.arch == "aarch64" { - match &*sess.target.os { + let target_features = match sess.target.arch { + Arch::X86_64 if sess.target.os != "none" => { + // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled + vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] + } + Arch::AArch64 => match &*sess.target.os { "none" => vec![], // On macOS the aes, sha2 and sha3 features are enabled by default and ring // fails to compile on macOS when they are not present. "macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], // AArch64 mandates Neon support _ => vec![sym::neon], - } - } else { - vec![] + }, + _ => vec![], }; // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); @@ -208,14 +209,14 @@ impl CodegenBackend for CraneliftCodegenBackend { // Windows, whereas LLVM 21+ and Cranelift pass it indirectly. This means that `f128` won't // work when linking against a LLVM-built sysroot. let has_reliable_f128 = !sess.target.is_like_windows; - let has_reliable_f16 = match &*sess.target.arch { + let has_reliable_f16 = match sess.target.arch { // FIXME(f16_f128): LLVM 20 does not support `f16` on s390x, meaning the required // builtins are not available in `compiler-builtins`. - "s390x" => false, + Arch::S390x => false, // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU // targets due to GCC using a different ABI than LLVM. Therefore `f16` won't be // available when using a LLVM-built sysroot. - "x86_64" + Arch::X86_64 if sess.target.os == "windows" && sess.target.env == "gnu" && sess.target.abi != "llvm" => From 0c8533d6905a9369d810b4add1efc0c52098cc9e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 13 Oct 2025 16:49:29 -0400 Subject: [PATCH 399/525] compiler: intern architecture at compile time --- compiler/rustc_session/src/config/cfg.rs | 4 +-- compiler/rustc_span/src/symbol.rs | 30 +++++++++++++++++++ compiler/rustc_target/src/spec/mod.rs | 38 ++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 9cb25ad11aac..465452749024 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -240,7 +240,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { } ins_str!(sym::target_abi, &sess.target.abi); - ins_str!(sym::target_arch, sess.target.arch.desc()); + ins_sym!(sym::target_arch, sess.target.arch.desc_symbol()); ins_str!(sym::target_endian, sess.target.endian.as_str()); ins_str!(sym::target_env, &sess.target.env); @@ -448,7 +448,7 @@ impl CheckCfg { for target in Target::builtins().chain(iter::once(current_target.clone())) { values_target_abi.insert(Symbol::intern(&target.options.abi)); - values_target_arch.insert(Symbol::intern(target.arch.desc())); + values_target_arch.insert(target.arch.desc_symbol()); values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); values_target_env.insert(Symbol::intern(&target.options.env)); values_target_family.extend( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 86b6bb16835b..38718bad9e57 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -400,6 +400,7 @@ symbols! { _t, _task_context, a32, + aarch64, aarch64_target_feature, aarch64_unstable_target_feature, aarch64_ver_target_feature, @@ -449,6 +450,7 @@ symbols! { altivec, alu32, always, + amdgpu, analysis, and, and_then, @@ -466,6 +468,7 @@ symbols! { args, arith_offset, arm, + arm64ec, arm_target_feature, array, as_dash_needed: "as-needed", @@ -555,6 +558,7 @@ symbols! { autodiff_reverse, automatically_derived, available_externally, + avr, avx, avx10_target_feature, avx512_target_feature, @@ -587,6 +591,7 @@ symbols! { box_patterns, box_syntax, boxed_slice, + bpf, bpf_target_feature, braced_empty_structs, branch, @@ -791,6 +796,7 @@ symbols! { crate_type, crate_visibility_modifier, crt_dash_static: "crt-static", + csky, csky_target_feature, cstr_type, cstring_as_c_str, @@ -1157,6 +1163,7 @@ symbols! { hashset_drain_ty, hashset_iter, hashset_iter_ty, + hexagon, hexagon_target_feature, hidden, hide, @@ -1343,11 +1350,14 @@ symbols! { logf32, logf64, logf128, + loongarch32, + loongarch64, loongarch_target_feature, loop_break_value, loop_match, lr, lt, + m68k, m68k_target_feature, macro_at_most_once_rep, macro_attr, @@ -1423,6 +1433,10 @@ symbols! { minnumf32, minnumf64, minnumf128, + mips, + mips32r6, + mips64, + mips64r6, mips_target_feature, mir_assume, mir_basic_block, @@ -1471,6 +1485,7 @@ symbols! { move_ref_pattern, move_size_limit, movrs_target_feature, + msp430, mul, mul_assign, mul_with_overflow, @@ -1558,6 +1573,7 @@ symbols! { notable_trait, note, null, + nvptx64, nvptx_target_feature, object_safe_for_dispatch, of, @@ -1683,6 +1699,9 @@ symbols! { post_cleanup: "post-cleanup", post_dash_lto: "post-lto", postfix_match, + powerpc, + powerpc64, + powerpc64le, powerpc_target_feature, powf16, powf32, @@ -1830,6 +1849,8 @@ symbols! { resume, return_position_impl_trait_in_trait, return_type_notation, + riscv32, + riscv64, riscv_target_feature, rlib, ropi, @@ -1977,6 +1998,7 @@ symbols! { rvalue_static_promotion, rwpi, s, + s390x, s390x_target_feature, safety, sanitize, @@ -2105,9 +2127,12 @@ symbols! { slice_patterns, slicing_syntax, soft, + sparc, + sparc64, sparc_target_feature, specialization, speed, + spirv, spotlight, sqrtf16, sqrtf32, @@ -2422,6 +2447,8 @@ symbols! { vtable_size, warn, wasip2, + wasm32, + wasm64, wasm_abi, wasm_import_module, wasm_target_feature, @@ -2448,12 +2475,15 @@ symbols! { write_str, write_via_move, writeln_macro, + x86, + x86_64, x86_amx_intrinsics, x87_reg, x87_target_feature, xer, xmm_reg, xop_target_feature, + xtensa, yeet_desugar_details, yeet_expr, yes, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 892be1e18ca2..7f3fea1d7da7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1885,6 +1885,44 @@ crate::target_spec_enum! { parse_error_type = "architecture"; } +impl Arch { + pub const fn desc_symbol(&self) -> Symbol { + match self { + Self::AArch64 => sym::aarch64, + Self::AmdGpu => sym::amdgpu, + Self::Arm => sym::arm, + Self::Arm64EC => sym::arm64ec, + Self::Avr => sym::avr, + Self::Bpf => sym::bpf, + Self::CSky => sym::csky, + Self::Hexagon => sym::hexagon, + Self::LoongArch32 => sym::loongarch32, + Self::LoongArch64 => sym::loongarch64, + Self::M68k => sym::m68k, + Self::Mips => sym::mips, + Self::Mips32r6 => sym::mips32r6, + Self::Mips64 => sym::mips64, + Self::Mips64r6 => sym::mips64r6, + Self::Msp430 => sym::msp430, + Self::Nvptx64 => sym::nvptx64, + Self::PowerPC => sym::powerpc, + Self::PowerPC64 => sym::powerpc64, + Self::PowerPC64LE => sym::powerpc64le, + Self::RiscV32 => sym::riscv32, + Self::RiscV64 => sym::riscv64, + Self::S390x => sym::s390x, + Self::Sparc => sym::sparc, + Self::Sparc64 => sym::sparc64, + Self::SpirV => sym::spirv, + Self::Wasm32 => sym::wasm32, + Self::Wasm64 => sym::wasm64, + Self::X86 => sym::x86, + Self::X86_64 => sym::x86_64, + Self::Xtensa => sym::xtensa, + } + } +} + /// Everything `rustc` knows about how to compile for a specific target. /// /// Every field here must be specified, and has no default value. From 26b0560b6db4f7116809c81532c2d64f43b74998 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Tue, 28 Oct 2025 19:48:56 -0400 Subject: [PATCH 400/525] rustc_target: allow unenumerated architectures --- .../rustc_codegen_cranelift/src/abi/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/abi.rs | 8 +-- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_codegen_gcc/src/gcc_util.rs | 62 +++++++++---------- compiler/rustc_codegen_llvm/src/abi.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 2 +- .../rustc_codegen_ssa/src/back/archive.rs | 4 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_session/src/session.rs | 2 +- compiler/rustc_target/src/asm/mod.rs | 4 +- compiler/rustc_target/src/callconv/mod.rs | 6 +- compiler/rustc_target/src/lib.rs | 61 ++++++++++++++++++ .../rustc_target/src/spec/base/apple/mod.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 16 +++-- compiler/rustc_target/src/target_features.rs | 14 +++-- compiler/rustc_target/src/tests.rs | 25 ++++++++ src/tools/miri/src/shims/alloc.rs | 5 +- tests/ui/check-cfg/my-awesome-platform.json | 2 +- tests/ui/check-cfg/values-target-json.rs | 15 +++-- 19 files changed, 169 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 6ea26b02c261..d7f17795815d 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -788,7 +788,7 @@ pub(crate) fn codegen_drop<'tcx>( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { + match (&tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index b7d0e19ee272..bcc28e476dba 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -235,12 +235,12 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { #[cfg(feature = "master")] fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { - conv_to_fn_attribute(self.conv, cx.tcx.sess.target.arch) + conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) } } #[cfg(feature = "master")] -pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option> { +pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, CanonAbi::RustCold => FnAttribute::Cold, @@ -254,8 +254,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: Arch) -> Option FnAttribute::ArmPcs("aapcs"), }, CanonAbi::GpuKernel => match arch { - Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, - Arch::Nvptx64 => FnAttribute::NvptxKernel, + &Arch::AmdGpu => FnAttribute::GcnAmdGpuHsaKernel, + &Arch::Nvptx64 => FnAttribute::NvptxKernel, arch => panic!("Arch {arch} does not support GpuKernel calling convention"), }, // TODO(antoyo): check if those AVR attributes are mapped correctly. diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 6084b4fc07fa..c9ae96777de4 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -487,7 +487,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { #[cfg(feature = "master")] - let conv = conv_to_fn_attribute(self.sess().target.entry_abi, self.sess().target.arch); + let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch); #[cfg(not(feature = "master"))] let conv = None; Some(self.declare_entry_fn(entry_name, fn_type, conv)) diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 83d54472e5de..e33b6c92d637 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -67,46 +67,46 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> { // cSpell:disable - match (sess.target.arch, s) { + match (&sess.target.arch, s) { // FIXME: seems like x87 does not exist? - (Arch::X86 | Arch::X86_64, "x87") => smallvec![], - (Arch::X86 | Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], - (Arch::X86 | Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], - (Arch::X86 | Arch::X86_64, "rdrand") => smallvec!["rdrnd"], - (Arch::X86 | Arch::X86_64, "bmi1") => smallvec!["bmi"], - (Arch::X86 | Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], - (Arch::X86 | Arch::X86_64, "avx512vaes") => smallvec!["vaes"], - (Arch::X86 | Arch::X86_64, "avx512gfni") => smallvec!["gfni"], - (Arch::X86 | Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], + (&Arch::X86 | &Arch::X86_64, "x87") => smallvec![], + (&Arch::X86 | &Arch::X86_64, "sse4.2") => smallvec!["sse4.2", "crc32"], + (&Arch::X86 | &Arch::X86_64, "pclmulqdq") => smallvec!["pclmul"], + (&Arch::X86 | &Arch::X86_64, "rdrand") => smallvec!["rdrnd"], + (&Arch::X86 | &Arch::X86_64, "bmi1") => smallvec!["bmi"], + (&Arch::X86 | &Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], + (&Arch::X86 | &Arch::X86_64, "avx512vaes") => smallvec!["vaes"], + (&Arch::X86 | &Arch::X86_64, "avx512gfni") => smallvec!["gfni"], + (&Arch::X86 | &Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], // NOTE: seems like GCC requires 'avx512bw' for 'avx512vbmi2'. - (Arch::X86 | Arch::X86_64, "avx512vbmi2") => { + (&Arch::X86 | &Arch::X86_64, "avx512vbmi2") => { smallvec!["avx512vbmi2", "avx512bw"] } // NOTE: seems like GCC requires 'avx512bw' for 'avx512bitalg'. - (Arch::X86 | Arch::X86_64, "avx512bitalg") => { + (&Arch::X86 | &Arch::X86_64, "avx512bitalg") => { smallvec!["avx512bitalg", "avx512bw"] } - (Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], - (Arch::AArch64, "dpb") => smallvec!["ccpp"], - (Arch::AArch64, "dpb2") => smallvec!["ccdp"], - (Arch::AArch64, "frintts") => smallvec!["fptoint"], - (Arch::AArch64, "fcma") => smallvec!["complxnum"], - (Arch::AArch64, "pmuv3") => smallvec!["perfmon"], - (Arch::AArch64, "paca") => smallvec!["pauth"], - (Arch::AArch64, "pacg") => smallvec!["pauth"], + (&Arch::AArch64, "rcpc2") => smallvec!["rcpc-immo"], + (&Arch::AArch64, "dpb") => smallvec!["ccpp"], + (&Arch::AArch64, "dpb2") => smallvec!["ccdp"], + (&Arch::AArch64, "frintts") => smallvec!["fptoint"], + (&Arch::AArch64, "fcma") => smallvec!["complxnum"], + (&Arch::AArch64, "pmuv3") => smallvec!["perfmon"], + (&Arch::AArch64, "paca") => smallvec!["pauth"], + (&Arch::AArch64, "pacg") => smallvec!["pauth"], // Rust ties fp and neon together. In GCC neon implicitly enables fp, // but we manually enable neon when a feature only implicitly enables fp - (Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], - (Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], - (Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], - (Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], - (Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], - (Arch::AArch64, "sve") => smallvec!["sve", "neon"], - (Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], - (Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], - (Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], - (Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], - (Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], + (&Arch::AArch64, "f32mm") => smallvec!["f32mm", "neon"], + (&Arch::AArch64, "f64mm") => smallvec!["f64mm", "neon"], + (&Arch::AArch64, "fhm") => smallvec!["fp16fml", "neon"], + (&Arch::AArch64, "fp16") => smallvec!["fullfp16", "neon"], + (&Arch::AArch64, "jsconv") => smallvec!["jsconv", "neon"], + (&Arch::AArch64, "sve") => smallvec!["sve", "neon"], + (&Arch::AArch64, "sve2") => smallvec!["sve2", "neon"], + (&Arch::AArch64, "sve2-aes") => smallvec!["sve2-aes", "neon"], + (&Arch::AArch64, "sve2-sm4") => smallvec!["sve2-sm4", "neon"], + (&Arch::AArch64, "sve2-sha3") => smallvec!["sve2-sha3", "neon"], + (&Arch::AArch64, "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"], (_, s) => smallvec![s], } // cSpell:enable diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index b045af3161dc..e6b76f74158b 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -698,7 +698,7 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm: // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. CanonAbi::Custom => llvm::CCallConv, - CanonAbi::GpuKernel => match sess.target.arch { + CanonAbi::GpuKernel => match &sess.target.arch { Arch::AmdGpu => llvm::AmdgpuKernel, Arch::Nvptx64 => llvm::PtxKernel, arch => panic!("Architecture {arch} does not support GpuKernel calling convention"), diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 8f8a3a3aef2f..32ea3987f968 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -342,7 +342,7 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig { /// Determine whether or not experimental float types are reliable based on known bugs. fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { - let target_arch = sess.target.arch; + let target_arch = &sess.target.arch; let target_os = sess.target.options.os.as_ref(); let target_env = sess.target.options.env.as_ref(); let target_abi = sess.target.options.abi.as_ref(); diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index cef7df44abe3..93f6cb3b87e6 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -118,7 +118,7 @@ pub trait ArchiveBuilderBuilder { let exports = items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::>(); - let machine = match sess.target.arch { + let machine = match &sess.target.arch { Arch::X86_64 => MachineTypes::AMD64, Arch::X86 => MachineTypes::I386, Arch::AArch64 => MachineTypes::ARM64, @@ -224,7 +224,7 @@ fn create_mingw_dll_import_lib( }; // dlltool target architecture args from: // https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69 - let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch { + let (dlltool_target_arch, dlltool_target_bitness) = match &sess.target.arch { Arch::X86_64 => ("i386:x86-64", "--64"), Arch::X86 => ("i386", "--32"), Arch::AArch64 => ("arm64", "--64"), diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index a50054758729..ed2815b06c18 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -983,7 +983,7 @@ impl CrateInfo { // by the compiler, but that's ok because all this stuff is unstable anyway. let target = &tcx.sess.target; if !are_upstream_rust_objects_already_included(tcx.sess) { - let add_prefix = match (target.is_like_windows, target.arch) { + let add_prefix = match (target.is_like_windows, &target.arch) { (true, Arch::X86) => |name: String, _: SymbolExportKind| format!("_{name}"), (true, Arch::Arm64EC) => { // Only functions are decorated for arm64ec. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 63d64b410950..16f9774554e1 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1112,7 +1112,7 @@ pub fn build_session( _ => CtfeBacktrace::Disabled, }); - let asm_arch = if target.allow_asm { InlineAsmArch::from_arch(target.arch) } else { None }; + let asm_arch = if target.allow_asm { InlineAsmArch::from_arch(&target.arch) } else { None }; let target_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target); let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host); diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index e5c140a848c3..cd7d9125d7b5 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -245,7 +245,7 @@ pub enum InlineAsmArch { } impl InlineAsmArch { - pub fn from_arch(arch: Arch) -> Option { + pub fn from_arch(arch: &Arch) -> Option { match arch { Arch::X86 => Some(Self::X86), Arch::X86_64 => Some(Self::X86_64), @@ -273,7 +273,7 @@ impl InlineAsmArch { Arch::Msp430 => Some(Self::Msp430), Arch::M68k => Some(Self::M68k), Arch::CSky => Some(Self::CSKY), - Arch::AmdGpu | Arch::Xtensa => None, + Arch::AmdGpu | Arch::Xtensa | Arch::Unknown(_) => None, } } } diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index ef55bc45a774..43e1ca3ef9ce 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -633,7 +633,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { } let spec = cx.target_spec(); - match spec.arch { + match &spec.arch { Arch::X86 => { let (flavor, regparm) = match abi { ExternAbi::Fastcall { .. } | ExternAbi::Vectorcall { .. } => { @@ -701,7 +701,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self), Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self), Arch::Bpf => bpf::compute_abi_info(cx, self), - arch @ (Arch::PowerPC64LE | Arch::SpirV) => { + arch @ (Arch::PowerPC64LE | Arch::SpirV | Arch::Unknown(_)) => { panic!("no lowering implemented for {arch}") } } @@ -713,7 +713,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { C: HasDataLayout + HasTargetSpec, { let spec = cx.target_spec(); - match spec.arch { + match &spec.arch { Arch::X86 => x86::compute_rust_abi_info(cx, self), Arch::RiscV32 | Arch::RiscV64 => riscv::compute_rust_abi_info(cx, self), Arch::LoongArch32 | Arch::LoongArch64 => loongarch::compute_rust_abi_info(cx, self), diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index f664bbb874d6..b38ce20e6095 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -118,6 +118,67 @@ macro_rules! target_spec_enum { } } + crate::target_spec_enum!(@common_impls $Name); + }; + + ( + $( #[$attr:meta] )* + pub enum $Name:ident { + $( + $( #[$variant_attr:meta] )* + $Variant:ident = $string:literal, + )* + } + $( #[$other_variant_attr:meta] )* + other_variant = $OtherVariant:ident; + ) => { + $( #[$attr] )* + #[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] + pub enum $Name { + $( + $( #[$variant_attr:meta] )* + $Variant, + )* + $( #[$other_variant_attr] )* + $OtherVariant(crate::spec::StaticCow), + } + + impl schemars::JsonSchema for $Name { + fn schema_name() -> std::borrow::Cow<'static, str> { + std::borrow::Cow::Borrowed(stringify!($Name)) + } + + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema!({ + "type": "string" + }) + } + } + + impl FromStr for $Name { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + Ok(match s { + $( $string => Self::$Variant, )* + _ => Self::$OtherVariant(s.to_owned().into()), + }) + } + } + + impl $Name { + pub fn desc(&self) -> &str { + match self { + $( Self::$Variant => $string, )* + Self::$OtherVariant(name) => name.as_ref(), + } + } + } + + crate::target_spec_enum!(@common_impls $Name); + }; + + (@common_impls $Name:ident) => { impl crate::json::ToJson for $Name { fn to_json(&self) -> crate::json::Json { self.desc().to_json() diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index cf147e48c501..047bc9b8518b 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -311,7 +311,7 @@ impl OSVersion { /// This matches what LLVM does, see in part: /// pub fn minimum_deployment_target(target: &Target) -> Self { - let (major, minor, patch) = match (&*target.os, target.arch, &*target.env) { + let (major, minor, patch) = match (&*target.os, &target.arch, &*target.env) { ("macos", crate::spec::Arch::AArch64, _) => (11, 0, 0), ("ios", crate::spec::Arch::AArch64, "macabi") => (14, 0, 0), ("ios", crate::spec::Arch::AArch64, "sim") => (14, 0, 0), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 7f3fea1d7da7..74048d351802 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1881,12 +1881,18 @@ crate::target_spec_enum! { X86_64 = "x86_64", Xtensa = "xtensa", } - - parse_error_type = "architecture"; + /// The vast majority of the time, the compiler deals with a fixed set of + /// target architectures, so it is convenient for them to be represented in + /// an enum. However, it is possible to have arbitrary values for the "arch" + /// field in a target JSON file (which can be parsed when `--target` is + /// specified). This might occur, for example, for an out-of-tree codegen + /// backend that supports an architecture that rustc currently doesn't know + /// about. This variant exists as an escape hatch for such cases. + other_variant = Unknown; } impl Arch { - pub const fn desc_symbol(&self) -> Symbol { + pub fn desc_symbol(&self) -> Symbol { match self { Self::AArch64 => sym::aarch64, Self::AmdGpu => sym::amdgpu, @@ -1919,6 +1925,7 @@ impl Arch { Self::X86 => sym::x86, Self::X86_64 => sym::x86_64, Self::Xtensa => sym::xtensa, + Self::Unknown(name) => rustc_span::Symbol::intern(name), } } } @@ -3274,7 +3281,8 @@ impl Target { | Arch::PowerPC64LE | Arch::SpirV | Arch::Wasm32 - | Arch::Wasm64 => return None, + | Arch::Wasm64 + | Arch::Unknown(_) => return None, }) } diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 16c3558d535b..fd95bd062be6 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -955,7 +955,7 @@ pub struct FeatureConstraints { impl Target { pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] { - match self.arch { + match &self.arch { Arch::Arm => ARM_FEATURES, Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES, Arch::X86 | Arch::X86_64 => X86_FEATURES, @@ -976,12 +976,13 @@ impl Target { | Arch::Msp430 | Arch::PowerPC64LE | Arch::SpirV - | Arch::Xtensa => &[], + | Arch::Xtensa + | Arch::Unknown(_) => &[], } } pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] { - match self.arch { + match &self.arch { Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_VECTOR_ABI, Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, Arch::Arm => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, @@ -1004,12 +1005,13 @@ impl Target { | Arch::Msp430 | Arch::PowerPC64LE | Arch::SpirV - | Arch::Xtensa => &[], + | Arch::Xtensa + | Arch::Unknown(_) => &[], } } pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] { - match self.arch { + match &self.arch { Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES, _ => &[], } @@ -1050,7 +1052,7 @@ impl Target { // defined by target features. When that is the case, those target features must be // "forbidden" in the list above to ensure that there is a consistent answer to the // questions "which ABI is used". - match self.arch { + match &self.arch { Arch::X86 => { // We use our own ABI indicator here; LLVM does not have anything native. // Every case should require or forbid `soft-float`! diff --git a/compiler/rustc_target/src/tests.rs b/compiler/rustc_target/src/tests.rs index a2692ea6be5e..bb17dd151b58 100644 --- a/compiler/rustc_target/src/tests.rs +++ b/compiler/rustc_target/src/tests.rs @@ -1,3 +1,4 @@ +use crate::json::ToJson; use crate::spec::Target; #[test] @@ -15,3 +16,27 @@ fn report_unused_fields() { eprintln!("{result:#?}"); assert!(result.is_err()); } + +#[test] +fn custom_arch_propagates_from_json() { + let json = r#" + { + "llvm-target": "x86_64-unknown-none-gnu", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", + "arch": "customarch", + "target-endian": "little", + "target-pointer-width": 64, + "os": "customos", + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "executables": true + } + "#; + rustc_span::create_session_if_not_set_then(rustc_span::edition::DEFAULT_EDITION, |_| { + let (target, warnings) = Target::from_json(json).expect("json target parses"); + assert!(warnings.warning_messages().is_empty()); + assert_eq!(target.arch.desc(), "customarch"); + let serialized = target.to_json(); + assert_eq!(serialized["arch"], "customarch"); + }); +} diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index f85ca4cfa424..217069b8b5d9 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -20,7 +20,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. let os = this.tcx.sess.target.os.as_ref(); - let max_fundamental_align = match this.tcx.sess.target.arch { + let max_fundamental_align = match &this.tcx.sess.target.arch { Arch::RiscV32 if matches!(os, "espidf" | "zkvm") => 4, Arch::Xtensa if matches!(os, "espidf") => 4, Arch::X86 @@ -53,7 +53,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | Arch::Msp430 | Arch::Nvptx64 | Arch::PowerPC64LE - | Arch::SpirV) => bug!("unsupported target architecture for malloc: `{arch}`"), + | Arch::SpirV + | Arch::Unknown(_)) => bug!("unsupported target architecture for malloc: `{arch}`"), }; // The C standard only requires sufficient alignment for any *type* with size less than or // equal to the size requested. Types one can define in standard C seem to never have an alignment diff --git a/tests/ui/check-cfg/my-awesome-platform.json b/tests/ui/check-cfg/my-awesome-platform.json index 3a1f6b1a54c6..c3b3b89a08cf 100644 --- a/tests/ui/check-cfg/my-awesome-platform.json +++ b/tests/ui/check-cfg/my-awesome-platform.json @@ -1,7 +1,7 @@ { "llvm-target": "x86_64-unknown-none-gnu", "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", - "arch": "x86_64", + "arch": "tamirdarch", "target-endian": "little", "target-pointer-width": 64, "os": "ericos", diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index ddfcb24c640c..2912c83b58de 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -6,14 +6,19 @@ //@ needs-llvm-components: x86 //@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json -#![feature(lang_items, no_core, auto_traits)] +#![feature(lang_items, no_core, auto_traits, rustc_attrs)] #![no_core] extern crate minicore; use minicore::*; -#[cfg(target_os = "linux")] -fn target_os_linux() {} +#[rustc_builtin_macro] +macro_rules! compile_error { + () => {}; +} -#[cfg(target_os = "ericos")] -fn target_os_ericos() {} +#[cfg(not(target_os = "ericos"))] +compile_error!("target_os from target JSON not wired through"); + +#[cfg(not(target_arch = "tamirdarch"))] +compile_error!("target_arch from target JSON not wired through"); From f47ad448861edb5f1c9f3bb3cb0228b3c7cd27bd Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Tue, 28 Oct 2025 19:48:56 -0400 Subject: [PATCH 401/525] rustc_target: allow unenumerated architectures --- src/abi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6ea26b02c261..d7f17795815d 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -788,7 +788,7 @@ pub(crate) fn codegen_drop<'tcx>( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { + match (&tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), From 14795f04485a87e6ee1ac6d40ef2be83307d9ccc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 5 Nov 2025 10:51:19 +0100 Subject: [PATCH 402/525] slightly extend PR creation message --- src/tools/miri/triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index c747cbb0a521..060b749676e6 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -20,7 +20,7 @@ contributing_url = "https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.m [assign.custom_welcome_messages] welcome-message = "(unused)" welcome-message-no-reviewer = """ -Thank you for contributing to Miri! +Thank you for contributing to Miri! A reviewer will take a look at your PR, typically within a week or two. Please remember to not force-push to the PR branch except when you need to rebase due to a conflict or when the reviewer asks you for it. """ From bb6f965464d5ff9682a1ab349cdd374b88b58763 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:21:42 +0000 Subject: [PATCH 403/525] Rustup to rustc 1.93.0-nightly (f15a7f385 2025-11-04) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 0836d830186c..0e770c49340f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-10-28" +channel = "nightly-2025-11-05" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 72d94d10df294312c66da9c7bca0d2ea992c17fa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 3 Nov 2025 13:59:50 +0100 Subject: [PATCH 404/525] [rustdoc search] Simplify itemTypes and filter "dependencies" --- src/librustdoc/html/static/js/search.js | 190 +++++++++++------------- 1 file changed, 88 insertions(+), 102 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index e281139ca38f..e3829603072b 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -91,54 +91,55 @@ if (!Promise.withResolvers) { // ==================== Core search logic begin ==================== // This mapping table should match the discriminants of // `rustdoc::formats::item_type::ItemType` type in Rust. -const itemTypes = [ - "keyword", - "primitive", - "mod", - "externcrate", - "import", - "struct", // 5 - "enum", - "fn", - "type", - "static", - "trait", // 10 - "impl", - "tymethod", - "method", - "structfield", - "variant", // 15 - "macro", - "associatedtype", - "constant", - "associatedconstant", - "union", // 20 - "foreigntype", - "existential", - "attr", - "derive", - "traitalias", // 25 - "generic", - "attribute", -]; +const itemTypes = Object.freeze({ + keyword: 0, + primitive: 1, + mod: 2, + externcrate: 3, + import: 4, + struct: 5, + enum: 6, + fn: 7, + type: 8, + static: 9, + trait: 10, + impl: 11, + tymethod: 12, + method: 13, + structfield: 14, + variant: 15, + macro: 16, + associatedtype: 17, + constant: 18, + associatedconstant: 19, + union: 20, + foreigntype: 21, + existential: 22, + attr: 23, + derive: 24, + traitalias: 25, + generic: 26, + attribute: 27, +}); +const itemTypesName = Array.from(Object.keys(itemTypes)); + +// When filtering, some types might be included as well. For example, when you filter on `constant`, +// we also include associated constant items. +// +// This map is built as follows: the first item of the array is the type to be included when the +// second type of the array is used as filter. +const itemParents = new Map([ + [itemTypes.associatedconstant, itemTypes.constant], + [itemTypes.method, itemTypes.fn], + [itemTypes.tymethod, itemTypes.fn], + [itemTypes.primitive, itemTypes.type], + [itemTypes.associatedtype, itemTypes.type], + [itemTypes.traitalias, itemTypes.trait], + [itemTypes.attr, itemTypes.macro], + [itemTypes.derive, itemTypes.macro], + [itemTypes.externcrate, itemTypes.import], +]); -// used for special search precedence -/** @type {rustdoc.ItemType} */ -const TY_PRIMITIVE = 1; -/** @type {rustdoc.ItemType} */ -const TY_GENERIC = 26; -/** @type {rustdoc.ItemType} */ -const TY_IMPORT = 4; -/** @type {rustdoc.ItemType} */ -const TY_TRAIT = 10; -/** @type {rustdoc.ItemType} */ -const TY_FN = 7; -/** @type {rustdoc.ItemType} */ -const TY_METHOD = 13; -/** @type {rustdoc.ItemType} */ -const TY_TYMETHOD = 12; -/** @type {rustdoc.ItemType} */ -const TY_ASSOCTYPE = 17; const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; // Hard limit on how deep to recurse into generics when doing type-driven search. @@ -302,7 +303,7 @@ function isEndCharacter(c) { * @returns */ function isFnLikeTy(ty) { - return ty === TY_FN || ty === TY_METHOD || ty === TY_TYMETHOD; + return ty === itemTypes.fn || ty === itemTypes.method || ty === itemTypes.tymethod; } /** @@ -1205,8 +1206,9 @@ function itemTypeFromName(typename) { if (typename === null) { return NO_TYPE_FILTER; } - const index = itemTypes.findIndex(i => i === typename); - if (index < 0) { + // @ts-expect-error + const index = itemTypes[typename]; + if (index === undefined) { throw ["Unknown type filter ", typename]; } return index; @@ -1329,21 +1331,21 @@ class DocSearch { } return -1; }; - const typeNameIdOfOutput = await first(output, TY_ASSOCTYPE, ""); - const typeNameIdOfFnPtr = await first(fn, TY_PRIMITIVE, ""); - const typeNameIdOfFn = await first(fn, TY_TRAIT, "core::ops"); - const typeNameIdOfFnMut = await first(fnMut, TY_TRAIT, "core::ops"); - const typeNameIdOfFnOnce = await first(fnOnce, TY_TRAIT, "core::ops"); - const typeNameIdOfArray = await first(array, TY_PRIMITIVE, ""); - const typeNameIdOfSlice = await first(slice, TY_PRIMITIVE, ""); - const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, TY_PRIMITIVE, ""); - const typeNameIdOfTuple = await first(tuple, TY_PRIMITIVE, ""); - const typeNameIdOfUnit = await first(unit, TY_PRIMITIVE, ""); - const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, TY_PRIMITIVE, ""); - const typeNameIdOfReference = await first(reference, TY_PRIMITIVE, ""); - const typeNameIdOfPointer = await first(pointer, TY_PRIMITIVE, ""); - const typeNameIdOfHof = await first(hof, TY_PRIMITIVE, ""); - const typeNameIdOfNever = await first(never, TY_PRIMITIVE, ""); + const typeNameIdOfOutput = await first(output, itemTypes.associatedtype, ""); + const typeNameIdOfFnPtr = await first(fn, itemTypes.primitive, ""); + const typeNameIdOfFn = await first(fn, itemTypes.trait, "core::ops"); + const typeNameIdOfFnMut = await first(fnMut, itemTypes.trait, "core::ops"); + const typeNameIdOfFnOnce = await first(fnOnce, itemTypes.trait, "core::ops"); + const typeNameIdOfArray = await first(array, itemTypes.primitive, ""); + const typeNameIdOfSlice = await first(slice, itemTypes.primitive, ""); + const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, itemTypes.primitive, ""); + const typeNameIdOfTuple = await first(tuple, itemTypes.primitive, ""); + const typeNameIdOfUnit = await first(unit, itemTypes.primitive, ""); + const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, itemTypes.primitive, ""); + const typeNameIdOfReference = await first(reference, itemTypes.primitive, ""); + const typeNameIdOfPointer = await first(pointer, itemTypes.primitive, ""); + const typeNameIdOfHof = await first(hof, itemTypes.primitive, ""); + const typeNameIdOfNever = await first(never, itemTypes.primitive, ""); this.typeNameIds = { typeNameIdOfOutput, typeNameIdOfFnPtr, @@ -1520,7 +1522,7 @@ class DocSearch { /** @param {rustdoc.ParserQueryElement} elem */ const checkTypeFilter = elem => { const ty = itemTypeFromName(elem.typeFilter); - if (ty === TY_GENERIC && elem.generics.length !== 0) { + if (ty === itemTypes.generic && elem.generics.length !== 0) { throw [ "Generic type parameter ", elem.name, @@ -2033,7 +2035,7 @@ class DocSearch { result = { id, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2045,7 +2047,7 @@ class DocSearch { result = { id: null, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2062,7 +2064,7 @@ class DocSearch { return { id: null, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2149,7 +2151,7 @@ class DocSearch { let displayPath; let href; let traitPath = null; - const type = itemTypes[item.ty]; + const type = itemTypesName[item.ty]; const name = item.name; let path = item.modulePath; let exactPath = item.exactModulePath; @@ -2173,7 +2175,7 @@ class DocSearch { } else if (item.parent) { const myparent = item.parent; let anchor = type + "." + name; - const parentType = itemTypes[myparent.path.ty]; + const parentType = itemTypesName[myparent.path.ty]; let pageType = parentType; let pageName = myparent.name; exactPath = `${myparent.path.exactModulePath}::${myparent.name}`; @@ -2520,11 +2522,11 @@ class DocSearch { whereClause.set(fnParamNames[-1 - fnType.id], where); } } else { - if (fnType.ty === TY_PRIMITIVE) { + if (fnType.ty === itemTypes.primitive) { if (await writeSpecialPrimitive(fnType, result)) { return; } - } else if (fnType.ty === TY_TRAIT && ( + } else if (fnType.ty === itemTypes.trait && ( fnType.id === typeNameIds.typeNameIdOfFn || fnType.id === typeNameIds.typeNameIdOfFnMut || fnType.id === typeNameIds.typeNameIdOfFnOnce || @@ -2691,8 +2693,8 @@ class DocSearch { // unlike other items, methods have a different ty when they are // in an impl block vs a trait. want to normalize this away. let ty = obj.item.ty; - if (ty === TY_TYMETHOD) { - ty = TY_METHOD; + if (ty === itemTypes.tymethod) { + ty = itemTypes.method; } // To be sure than it some items aren't considered as duplicate. obj.fullPath = res[2] + "|" + ty; @@ -2714,10 +2716,10 @@ class DocSearch { // Exports are specifically not shown if the items they point at // are already in the results. - if (obj.item.ty === TY_IMPORT && duplicates.has(res[2])) { + if (obj.item.ty === itemTypes.import && duplicates.has(res[2])) { continue; } - if (duplicates.has(res[2] + "|" + TY_IMPORT)) { + if (duplicates.has(res[2] + "|" + itemTypes.import)) { continue; } duplicates.add(obj.fullPath); @@ -3894,24 +3896,8 @@ class DocSearch { if (filter <= NO_TYPE_FILTER || filter === type) return true; // Match related items - const name = itemTypes[type]; - switch (itemTypes[filter]) { - case "constant": - return name === "associatedconstant"; - case "fn": - return name === "method" || name === "tymethod"; - case "type": - return name === "primitive" || name === "associatedtype"; - case "trait": - return name === "traitalias"; - case "macro": - return name === "attr" || name === "derive"; - case "import": - return name === "externcrate"; - } - - // No match - return false; + // @ts-expect-error + return filter === itemParents.get(type); } const innerRunNameQuery = @@ -4246,7 +4232,7 @@ class DocSearch { * ]>[]} * */ const typePromises = []; - if (typeFilter !== TY_GENERIC && searchResults) { + if (typeFilter !== itemTypes.generic && searchResults) { for (const id of searchResults.matches().entries()) { typePromises.push(Promise.all([ this.getName(id), @@ -4262,7 +4248,7 @@ class DocSearch { ty && !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && - path && path.ty !== TY_ASSOCTYPE && + path && path.ty !== itemTypes.associatedtype && (elem.pathWithoutLast.length === 0 || checkPath( elem.pathWithoutLast, @@ -4270,14 +4256,14 @@ class DocSearch { ) === 0), ); if (types.length === 0) { - const areGenericsAllowed = typeFilter === TY_GENERIC || ( + const areGenericsAllowed = typeFilter === itemTypes.generic || ( typeFilter === -1 && (parsedQuery.totalElems > 1 || parsedQuery.hasReturnArrow) && elem.pathWithoutLast.length === 0 && elem.generics.length === 0 && elem.bindings.size === 0 ); - if (typeFilter !== TY_GENERIC && + if (typeFilter !== itemTypes.generic && (elem.name.length >= 3 || !areGenericsAllowed) ) { /** @type {string|null} */ @@ -4301,7 +4287,7 @@ class DocSearch { !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && - path.ty !== TY_ASSOCTYPE + path.ty !== itemTypes.associatedtype ) { let dist = editDistance( name, @@ -4363,7 +4349,7 @@ class DocSearch { queryElem: { name: elem.name, id: (-genericId) - 1, - typeFilter: TY_GENERIC, + typeFilter: itemTypes.generic, generics: [], bindings: EMPTY_BINDINGS_MAP, fullPath: elem.fullPath, @@ -4930,7 +4916,7 @@ async function addTab(results, query, display, finishedCallback, isTypeSearch) { count += 1; const name = obj.item.name; - const type = itemTypes[obj.item.ty]; + const type = itemTypesName[obj.item.ty]; const longType = longItemTypes[obj.item.ty]; const typeName = longType.length !== 0 ? `${longType}` : "?"; From 1d344781472791a6e4773871da24dc7fed26afc3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 09:19:25 +0000 Subject: [PATCH 405/525] Move warning reporting from flag_to_backend_features to cfg_target_feature This way warnings are emitted even in a check build. --- compiler/rustc_codegen_gcc/src/gcc_util.rs | 35 ++-- compiler/rustc_codegen_gcc/src/lib.rs | 38 +++-- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 92 +++++------ .../rustc_codegen_ssa/src/target_features.rs | 156 +++++++++--------- compiler/rustc_interface/src/util.rs | 24 ++- ...cv-discoverability-guidance.riscv32.stderr | 10 +- ...cv-discoverability-guidance.riscv64.stderr | 10 +- .../ui/abi/riscv-discoverability-guidance.rs | 3 + tests/ui/abi/simd-abi-checks-s390x.rs | 3 + tests/ui/abi/simd-abi-checks-s390x.z10.stderr | 20 +-- ...simd-abi-checks-s390x.z13_no_vector.stderr | 26 +-- ...imd-abi-checks-s390x.z13_soft_float.stderr | 31 ++-- tests/ui/abi/sparcv8plus.rs | 3 + tests/ui/abi/sparcv8plus.sparc.stderr | 2 +- tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr | 2 +- ...cv8plus.sparc_cpu_v9_feature_v8plus.stderr | 8 +- .../sparcv8plus.sparc_feature_v8plus.stderr | 8 +- tests/ui/abi/sparcv8plus.sparcv8plus.stderr | 2 +- tests/ui/asm/s390x/bad-reg.rs | 2 + tests/ui/asm/s390x/bad-reg.s390x.stderr | 114 +++++++------ .../ui/asm/s390x/bad-reg.s390x_vector.stderr | 100 +++++------ .../s390x/bad-reg.s390x_vector_stable.stderr | 132 ++++++++------- ...le-target-feature-flag-enable.riscv.stderr | 8 +- ...ible-target-feature-flag-enable.x86.stderr | 8 +- ...d-target-feature-flag-disable.riscv.stderr | 8 +- ...red-target-feature-flag-disable.x86.stderr | 8 +- .../tied-features-no-implication.pacg.stderr | 4 +- .../tied-features-no-implication.rs | 2 +- 30 files changed, 447 insertions(+), 416 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 702704ddf136..1c9679ead0db 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -11,7 +11,7 @@ fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { /// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). -pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec { +pub(crate) fn global_gcc_features(sess: &Session) -> Vec { // Features that come earlier are overridden by conflicting features later in the string. // Typically we'll want more explicit settings to override the implicit ones, so: // @@ -36,27 +36,18 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec) -> Box { @@ -446,21 +446,25 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig { - let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| { - // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. - if feature == "neon" { - return false; - } - target_info.cpu_supports(feature) - // cSpell:disable - /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ - // cSpell:enable - }); + let (unstable_target_features, target_features) = cfg_target_feature( + sess, + |feature| to_gcc_features(sess, feature), + |feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if feature == "neon" { + return false; + } + target_info.cpu_supports(feature) + // cSpell:disable + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ + // cSpell:enable + }, + ); let has_reliable_f16 = target_info.supports_target_dependent_type(CType::Float16); let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index cfbb9541ecd2..7f6f7ee64cf1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -107,7 +107,7 @@ pub(crate) fn create_informational_target_machine( let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None }; // Can't use query system here quite yet because this function is invoked before the query // system/tcx is set up. - let features = llvm_util::global_llvm_features(sess, false, only_base_features); + let features = llvm_util::global_llvm_features(sess, only_base_features); target_machine_factory(sess, config::OptLevel::No, &features)(config) .unwrap_or_else(|err| llvm_err(sess.dcx(), err)) } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 982d5cd3ac41..db886ad92731 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -247,7 +247,7 @@ impl CodegenBackend for LlvmCodegenBackend { fn provide(&self, providers: &mut Providers) { providers.global_backend_features = - |tcx, ()| llvm_util::global_llvm_features(tcx.sess, true, false) + |tcx, ()| llvm_util::global_llvm_features(tcx.sess, false) } fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) { diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 0fcad0376b11..3e6250cb0200 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -291,26 +291,34 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option TargetConfig { let target_machine = create_informational_target_machine(sess, true); - let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| { - // This closure determines whether the target CPU has the feature according to LLVM. We do - // *not* consider the `-Ctarget-feature`s here, as that will be handled later in - // `cfg_target_feature`. - if let Some(feat) = to_llvm_features(sess, feature) { - // All the LLVM features this expands to must be enabled. - for llvm_feature in feat { - let cstr = SmallCStr::new(llvm_feature); - // `LLVMRustHasFeature` is moderately expensive. On targets with many - // features (e.g. x86) these calls take a non-trivial fraction of runtime - // when compiling very small programs. - if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } { - return false; + let (unstable_target_features, target_features) = cfg_target_feature( + sess, + |feature| { + to_llvm_features(sess, feature) + .map(|f| SmallVec::<[&str; 2]>::from_iter(f.into_iter())) + .unwrap_or_default() + }, + |feature| { + // This closure determines whether the target CPU has the feature according to LLVM. We do + // *not* consider the `-Ctarget-feature`s here, as that will be handled later in + // `cfg_target_feature`. + if let Some(feat) = to_llvm_features(sess, feature) { + // All the LLVM features this expands to must be enabled. + for llvm_feature in feat { + let cstr = SmallCStr::new(llvm_feature); + // `LLVMRustHasFeature` is moderately expensive. On targets with many + // features (e.g. x86) these calls take a non-trivial fraction of runtime + // when compiling very small programs. + if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } { + return false; + } } + true + } else { + false } - true - } else { - false - } - }); + }, + ); let mut cfg = TargetConfig { target_features, @@ -615,11 +623,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec) { /// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). -pub(crate) fn global_llvm_features( - sess: &Session, - diagnostics: bool, - only_base_features: bool, -) -> Vec { +pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) -> Vec { // Features that come earlier are overridden by conflicting features later in the string. // Typically we'll want more explicit settings to override the implicit ones, so: // @@ -679,39 +683,27 @@ pub(crate) fn global_llvm_features( // -Ctarget-features if !only_base_features { - target_features::flag_to_backend_features( - sess, - diagnostics, - |feature| { - to_llvm_features(sess, feature) - .map(|f| SmallVec::<[&str; 2]>::from_iter(f.into_iter())) - .unwrap_or_default() - }, - |feature, enable| { - let enable_disable = if enable { '+' } else { '-' }; - // We run through `to_llvm_features` when - // passing requests down to LLVM. This means that all in-language - // features also work on the command line instead of having two - // different names when the LLVM name and the Rust name differ. - let Some(llvm_feature) = to_llvm_features(sess, feature) else { return }; + target_features::flag_to_backend_features(sess, |feature, enable| { + let enable_disable = if enable { '+' } else { '-' }; + // We run through `to_llvm_features` when + // passing requests down to LLVM. This means that all in-language + // features also work on the command line instead of having two + // different names when the LLVM name and the Rust name differ. + let Some(llvm_feature) = to_llvm_features(sess, feature) else { return }; - features.extend( - std::iter::once(format!( - "{}{}", - enable_disable, llvm_feature.llvm_feature_name - )) - .chain(llvm_feature.dependencies.into_iter().filter_map( - move |feat| match (enable, feat) { + features.extend( + std::iter::once(format!("{}{}", enable_disable, llvm_feature.llvm_feature_name)) + .chain(llvm_feature.dependencies.into_iter().filter_map(move |feat| { + match (enable, feat) { (_, TargetFeatureFoldStrength::Both(f)) | (true, TargetFeatureFoldStrength::EnableOnly(f)) => { Some(format!("{enable_disable}{f}")) } _ => None, - }, - )), - ) - }, - ); + } + })), + ) + }); } // We add this in the "base target" so that these show up in `sess.unstable_target_features`. diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 54584999d61b..77c0b491888f 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -205,6 +205,9 @@ fn parse_rust_feature_flag<'a>( /// to populate `sess.unstable_target_features` and `sess.target_features` (these are the first and /// 2nd component of the return value, respectively). /// +/// `to_backend_features` converts a Rust feature name into a list of backend feature names; this is +/// used for diagnostic purposes only. +/// /// `target_base_has_feature` should check whether the given feature (a Rust feature name!) is /// enabled in the "base" target machine, i.e., without applying `-Ctarget-feature`. Note that LLVM /// may consider features to be implied that we do not and vice-versa. We want `cfg` to be entirely @@ -212,10 +215,13 @@ fn parse_rust_feature_flag<'a>( /// to target features. /// /// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled elsewhere. -pub fn cfg_target_feature( +pub fn cfg_target_feature<'a, const N: usize>( sess: &Session, + to_backend_features: impl Fn(&'a str) -> SmallVec<[&'a str; N]>, mut target_base_has_feature: impl FnMut(&str) -> bool, ) -> (Vec, Vec) { + let known_features = sess.target.rust_target_features(); + // Compute which of the known target features are enabled in the 'base' target machine. We only // consider "supported" features; "forbidden" features are not reflected in `cfg` as of now. let mut features: UnordSet = sess @@ -234,17 +240,23 @@ pub fn cfg_target_feature( }) .collect(); + let mut enabled_disabled_features = FxHashMap::default(); + // Add enabled and remove disabled features. parse_rust_feature_flag( sess, /* err_callback */ - |_| { - // Errors are already emitted in `flag_to_backend_features`; avoid duplicates. + |feature| { + sess.dcx().emit_warn(errors::UnknownCTargetFeaturePrefix { feature }); }, - |_base_feature, new_features, enabled| { + |base_feature, new_features, enable| { + // Iteration order is irrelevant since this only influences an `FxHashMap`. + #[allow(rustc::potential_query_instability)] + enabled_disabled_features.extend(new_features.iter().map(|&s| (s, enable))); + // Iteration order is irrelevant since this only influences an `UnordSet`. #[allow(rustc::potential_query_instability)] - if enabled { + if enable { features.extend(new_features.into_iter().map(|f| Symbol::intern(f))); } else { // Remove `new_features` from `features`. @@ -252,9 +264,63 @@ pub fn cfg_target_feature( features.remove(&Symbol::intern(new)); } } + + // Check feature validity. + let feature_state = known_features.iter().find(|&&(v, _, _)| v == base_feature); + match feature_state { + None => { + // This is definitely not a valid Rust feature name. Maybe it is a backend + // feature name? If so, give a better error message. + let rust_feature = known_features.iter().find_map(|&(rust_feature, _, _)| { + let backend_features = to_backend_features(rust_feature); + if backend_features.contains(&base_feature) + && !backend_features.contains(&rust_feature) + { + Some(rust_feature) + } else { + None + } + }); + let unknown_feature = if let Some(rust_feature) = rust_feature { + errors::UnknownCTargetFeature { + feature: base_feature, + rust_feature: errors::PossibleFeature::Some { rust_feature }, + } + } else { + errors::UnknownCTargetFeature { + feature: base_feature, + rust_feature: errors::PossibleFeature::None, + } + }; + sess.dcx().emit_warn(unknown_feature); + } + Some((_, stability, _)) => { + if let Err(reason) = stability.toggle_allowed() { + sess.dcx().emit_warn(errors::ForbiddenCTargetFeature { + feature: base_feature, + enabled: if enable { "enabled" } else { "disabled" }, + reason, + }); + } else if stability.requires_nightly().is_some() { + // An unstable feature. Warn about using it. It makes little sense + // to hard-error here since we just warn about fully unknown + // features above. + sess.dcx() + .emit_warn(errors::UnstableCTargetFeature { feature: base_feature }); + } + } + } }, ); + if let Some(f) = check_tied_features(sess, &enabled_disabled_features) { + sess.dcx().emit_err(errors::TargetFeatureDisableOrEnable { + features: f, + span: None, + missing_features: None, + }); + } + // Filter enabled features based on feature gates. let f = |allow_unstable| { sess.target @@ -301,99 +367,27 @@ pub fn check_tied_features( /// Translates the `-Ctarget-feature` flag into a backend target feature list. /// -/// `to_backend_features` converts a Rust feature name into a list of backend feature names; this is -/// used for diagnostic purposes only. -/// /// `extend_backend_features` extends the set of backend features (assumed to be in mutable state /// accessible by that closure) to enable/disable the given Rust feature name. -pub fn flag_to_backend_features<'a, const N: usize>( +pub fn flag_to_backend_features<'a>( sess: &'a Session, - diagnostics: bool, - to_backend_features: impl Fn(&'a str) -> SmallVec<[&'a str; N]>, mut extend_backend_features: impl FnMut(&'a str, /* enable */ bool), ) { - let known_features = sess.target.rust_target_features(); - // Compute implied features let mut rust_features = vec![]; parse_rust_feature_flag( sess, /* err_callback */ - |feature| { - if diagnostics { - sess.dcx().emit_warn(errors::UnknownCTargetFeaturePrefix { feature }); - } + |_feature| { + // Errors are already emitted in `cfg_target_feature`; avoid duplicates. }, - |base_feature, new_features, enable| { + |_base_feature, new_features, enable| { rust_features.extend( UnordSet::from(new_features).to_sorted_stable_ord().iter().map(|&&s| (enable, s)), ); - // Check feature validity. - if diagnostics { - let feature_state = known_features.iter().find(|&&(v, _, _)| v == base_feature); - match feature_state { - None => { - // This is definitely not a valid Rust feature name. Maybe it is a backend - // feature name? If so, give a better error message. - let rust_feature = - known_features.iter().find_map(|&(rust_feature, _, _)| { - let backend_features = to_backend_features(rust_feature); - if backend_features.contains(&base_feature) - && !backend_features.contains(&rust_feature) - { - Some(rust_feature) - } else { - None - } - }); - let unknown_feature = if let Some(rust_feature) = rust_feature { - errors::UnknownCTargetFeature { - feature: base_feature, - rust_feature: errors::PossibleFeature::Some { rust_feature }, - } - } else { - errors::UnknownCTargetFeature { - feature: base_feature, - rust_feature: errors::PossibleFeature::None, - } - }; - sess.dcx().emit_warn(unknown_feature); - } - Some((_, stability, _)) => { - if let Err(reason) = stability.toggle_allowed() { - sess.dcx().emit_warn(errors::ForbiddenCTargetFeature { - feature: base_feature, - enabled: if enable { "enabled" } else { "disabled" }, - reason, - }); - } else if stability.requires_nightly().is_some() { - // An unstable feature. Warn about using it. It makes little sense - // to hard-error here since we just warn about fully unknown - // features above. - sess.dcx().emit_warn(errors::UnstableCTargetFeature { - feature: base_feature, - }); - } - } - } - } }, ); - if diagnostics { - // FIXME(nagisa): figure out how to not allocate a full hashmap here. - if let Some(f) = check_tied_features( - sess, - &FxHashMap::from_iter(rust_features.iter().map(|&(enable, feature)| (feature, enable))), - ) { - sess.dcx().emit_err(errors::TargetFeatureDisableOrEnable { - features: f, - span: None, - missing_features: None, - }); - } - } - // Add this to the backend features. for (enable, feature) in rust_features { extend_backend_features(feature, enable); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 5aacf1f8d960..ade7ec38fb35 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -9,7 +9,7 @@ use rustc_ast as ast; use rustc_attr_parsing::{ShouldEmit, validate_attr}; use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBuilder}; use rustc_codegen_ssa::back::link::link_binary; -use rustc_codegen_ssa::target_features::{self, cfg_target_feature}; +use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenResults, CrateInfo, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; @@ -364,20 +364,16 @@ impl CodegenBackend for DummyCodegenBackend { } fn target_config(&self, sess: &Session) -> TargetConfig { - let (target_features, unstable_target_features) = cfg_target_feature(sess, |feature| { - // This is a standin for the list of features a backend is expected to enable. - // It would be better to parse target.features instead and handle implied features, - // but target.features is a list of LLVM target features, not Rust target features. - // The dummy backend doesn't know the mapping between LLVM and Rust target features. - sess.target.abi_required_features().required.contains(&feature) - }); - - // To report warnings about unknown features - target_features::flag_to_backend_features::<0>( + let (target_features, unstable_target_features) = cfg_target_feature::<0>( sess, - true, - |_| Default::default(), - |_, _| {}, + |_feature| Default::default(), + |feature| { + // This is a standin for the list of features a backend is expected to enable. + // It would be better to parse target.features instead and handle implied features, + // but target.features is a list of LLVM target features, not Rust target features. + // The dummy backend doesn't know the mapping between LLVM and Rust target features. + sess.target.abi_required_features().required.contains(&feature) + }, ); TargetConfig { diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr index 0378b9daafe7..d838af23025c 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -1,5 +1,9 @@ +warning: unstable feature specified for `-Ctarget-feature`: `unaligned-scalar-mem` + | + = note: this feature is not stably supported; its behavior can change in the future + error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:16:8 + --> $DIR/riscv-discoverability-guidance.rs:19:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ invalid ABI @@ -11,7 +15,7 @@ LL | extern "riscv-interrupt-m" fn isr() {} | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:21:8 + --> $DIR/riscv-discoverability-guidance.rs:24:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ invalid ABI @@ -23,6 +27,6 @@ LL - extern "riscv-interrupt-u" fn isr_U() {} LL + extern "riscv-interrupt-m" fn isr_U() {} | -error: aborting due to 2 previous errors +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr index 0378b9daafe7..d838af23025c 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -1,5 +1,9 @@ +warning: unstable feature specified for `-Ctarget-feature`: `unaligned-scalar-mem` + | + = note: this feature is not stably supported; its behavior can change in the future + error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:16:8 + --> $DIR/riscv-discoverability-guidance.rs:19:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ invalid ABI @@ -11,7 +15,7 @@ LL | extern "riscv-interrupt-m" fn isr() {} | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:21:8 + --> $DIR/riscv-discoverability-guidance.rs:24:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ invalid ABI @@ -23,6 +27,6 @@ LL - extern "riscv-interrupt-u" fn isr_U() {} LL + extern "riscv-interrupt-m" fn isr_U() {} | -error: aborting due to 2 previous errors +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs index 7f43f9fcfc79..84a8f7bda5d9 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.rs +++ b/tests/ui/abi/riscv-discoverability-guidance.rs @@ -10,6 +10,9 @@ #![no_core] #![feature(no_core, lang_items, abi_riscv_interrupt)] +//~? WARN unstable feature specified for `-Ctarget-feature` +//~? NOTE this feature is not stably supported; its behavior can change in the future + extern crate minicore; use minicore::*; diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs index 6caddc0e0af5..6434dbea1106 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -11,6 +11,9 @@ //@ ignore-backends: gcc //[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly +//[z13_no_vector,z13_soft_float]~? WARN unstable feature specified for `-Ctarget-feature` +//[z13_soft_float]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` + #![feature(no_core, repr_simd, s390x_target_feature)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr index d5f6657c27e8..769f8a0b1911 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:40:1 + --> $DIR/simd-abi-checks-s390x.rs:43:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:45:1 + --> $DIR/simd-abi-checks-s390x.rs:48:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:91:1 + --> $DIR/simd-abi-checks-s390x.rs:94:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:98:1 + --> $DIR/simd-abi-checks-s390x.rs:101:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:113:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:118:1 + --> $DIR/simd-abi-checks-s390x.rs:121:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:132:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:134:1 + --> $DIR/simd-abi-checks-s390x.rs:137:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:145:1 + --> $DIR/simd-abi-checks-s390x.rs:148:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:150:1 + --> $DIR/simd-abi-checks-s390x.rs:153:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr index d5f6657c27e8..7709c396605e 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr @@ -1,5 +1,9 @@ +warning: unstable feature specified for `-Ctarget-feature`: `vector` + | + = note: this feature is not stably supported; its behavior can change in the future + error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:40:1 + --> $DIR/simd-abi-checks-s390x.rs:43:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +11,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:45:1 + --> $DIR/simd-abi-checks-s390x.rs:48:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -15,7 +19,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:91:1 + --> $DIR/simd-abi-checks-s390x.rs:94:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -25,7 +29,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:98:1 + --> $DIR/simd-abi-checks-s390x.rs:101:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -35,7 +39,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:113:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -43,7 +47,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:118:1 + --> $DIR/simd-abi-checks-s390x.rs:121:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -51,7 +55,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:132:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -59,7 +63,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:134:1 + --> $DIR/simd-abi-checks-s390x.rs:137:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -67,7 +71,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:145:1 + --> $DIR/simd-abi-checks-s390x.rs:148:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -75,12 +79,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:150:1 + --> $DIR/simd-abi-checks-s390x.rs:153:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: aborting due to 10 previous errors +error: aborting due to 10 previous errors; 1 warning emitted diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index d993d6a4e9ea..6a202eac7e1e 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -1,10 +1,19 @@ +warning: unstable feature specified for `-Ctarget-feature`: `vector` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: currently unsupported ABI-configuration feature + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:40:1 + --> $DIR/simd-abi-checks-s390x.rs:43:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -12,7 +21,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:45:1 + --> $DIR/simd-abi-checks-s390x.rs:48:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -20,7 +29,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:91:1 + --> $DIR/simd-abi-checks-s390x.rs:94:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -30,7 +39,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:98:1 + --> $DIR/simd-abi-checks-s390x.rs:101:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -40,7 +49,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:113:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -48,7 +57,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:118:1 + --> $DIR/simd-abi-checks-s390x.rs:121:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -56,7 +65,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:132:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -64,7 +73,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:134:1 + --> $DIR/simd-abi-checks-s390x.rs:137:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -72,7 +81,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:145:1 + --> $DIR/simd-abi-checks-s390x.rs:148:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -80,12 +89,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:150:1 + --> $DIR/simd-abi-checks-s390x.rs:153:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 10 previous errors; 3 warnings emitted diff --git a/tests/ui/abi/sparcv8plus.rs b/tests/ui/abi/sparcv8plus.rs index 00daeaa7f156..8b7d7dd78ad3 100644 --- a/tests/ui/abi/sparcv8plus.rs +++ b/tests/ui/abi/sparcv8plus.rs @@ -12,6 +12,9 @@ //@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc //@ ignore-backends: gcc +//[sparc_feature_v8plus,sparc_cpu_v9_feature_v8plus]~? WARN unstable feature specified for `-Ctarget-feature` +//[sparc_feature_v8plus,sparc_cpu_v9_feature_v8plus]~? NOTE this feature is not stably supported; its behavior can change in the future + #![crate_type = "rlib"] #![feature(no_core, rustc_attrs, lang_items)] #![no_core] diff --git a/tests/ui/abi/sparcv8plus.sparc.stderr b/tests/ui/abi/sparcv8plus.sparc.stderr index e2aa89a92731..779bf597d6f6 100644 --- a/tests/ui/abi/sparcv8plus.sparc.stderr +++ b/tests/ui/abi/sparcv8plus.sparc.stderr @@ -1,5 +1,5 @@ error: -v8plus,-v9 - --> $DIR/sparcv8plus.rs:28:1 + --> $DIR/sparcv8plus.rs:31:1 | LL | compile_error!("-v8plus,-v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr index 2c5699f2dec2..edf75ab70db1 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr @@ -1,5 +1,5 @@ error: -v8plus,+v9 - --> $DIR/sparcv8plus.rs:41:1 + --> $DIR/sparcv8plus.rs:44:1 | LL | compile_error!("-v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr index 4b96e4421f9f..0de9cf69fbfb 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr @@ -1,8 +1,12 @@ +warning: unstable feature specified for `-Ctarget-feature`: `v8plus` + | + = note: this feature is not stably supported; its behavior can change in the future + error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:32:1 + --> $DIR/sparcv8plus.rs:35:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr index dfdec88961be..4ed66d503274 100644 --- a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr @@ -1,8 +1,12 @@ +warning: unstable feature specified for `-Ctarget-feature`: `v8plus` + | + = note: this feature is not stably supported; its behavior can change in the future + error: +v8plus,-v9 (FIXME) - --> $DIR/sparcv8plus.rs:37:1 + --> $DIR/sparcv8plus.rs:40:1 | LL | compile_error!("+v8plus,-v9 (FIXME)"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr index 4b96e4421f9f..37a03abae9b4 100644 --- a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:32:1 + --> $DIR/sparcv8plus.rs:35:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index 97b2b3d50b34..a4baa390be22 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -8,6 +8,8 @@ //@[s390x_vector_stable] needs-llvm-components: systemz //@ ignore-backends: gcc +//~? WARN unstable feature specified for `-Ctarget-feature` + #![crate_type = "rlib"] #![feature(no_core, repr_simd)] #![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))] diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index 238419b376b7..ca5dcab0624f 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,149 +1,153 @@ +warning: unstable feature specified for `-Ctarget-feature`: `vector` + | + = note: this feature is not stably supported; its behavior can change in the future + error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +155,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +163,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +171,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +179,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +187,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +195,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +203,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +211,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +219,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:154:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +227,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +235,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +243,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +251,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +259,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +267,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:166:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,73 +275,73 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:169:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:76:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:78:18 + --> $DIR/bad-reg.rs:80:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:86:18 + --> $DIR/bad-reg.rs:88:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:90:18 + --> $DIR/bad-reg.rs:92:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:95:18 + --> $DIR/bad-reg.rs:97:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:102:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:106:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:108:26 + --> $DIR/bad-reg.rs:110:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:113:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:122:27 | LL | asm!("", in("a2") x); | ^ @@ -345,7 +349,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:125:28 | LL | asm!("", out("a2") x); | ^ @@ -353,12 +357,12 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:128:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 54 previous errors +error: aborting due to 54 previous errors; 1 warning emitted diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 897f872ae72a..8493e37c45ff 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -1,149 +1,153 @@ +warning: unstable feature specified for `-Ctarget-feature`: `vector` + | + = note: this feature is not stably supported; its behavior can change in the future + error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +155,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +163,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +171,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +179,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +187,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +195,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +203,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +211,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +219,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:154:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +227,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +235,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +243,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +251,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +259,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +267,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:166:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,13 +275,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:169:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 + --> $DIR/bad-reg.rs:92:27 | LL | asm!("", in("v0") b); | ^ @@ -285,7 +289,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 + --> $DIR/bad-reg.rs:97:28 | LL | asm!("", out("v0") b); | ^ @@ -293,7 +297,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 + --> $DIR/bad-reg.rs:110:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -301,7 +305,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:122:27 | LL | asm!("", in("a2") x); | ^ @@ -309,7 +313,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:125:28 | LL | asm!("", out("a2") x); | ^ @@ -317,12 +321,12 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:128:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 47 previous errors +error: aborting due to 47 previous errors; 1 warning emitted diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr index e2b3eeef4e92..a6a6a28f1d8b 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr @@ -1,125 +1,129 @@ +warning: unstable feature specified for `-Ctarget-feature`: `vector` + | + = note: this feature is not stably supported; its behavior can change in the future + error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:76:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -129,7 +133,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:78:18 + --> $DIR/bad-reg.rs:80:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -139,7 +143,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -149,7 +153,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:86:18 + --> $DIR/bad-reg.rs:88:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -159,7 +163,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:90:18 + --> $DIR/bad-reg.rs:92:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ @@ -169,7 +173,7 @@ LL | asm!("", in("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:95:18 + --> $DIR/bad-reg.rs:97:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ @@ -179,7 +183,7 @@ LL | asm!("", out("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:102:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -189,7 +193,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:106:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -199,7 +203,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:108:26 + --> $DIR/bad-reg.rs:110:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ @@ -209,7 +213,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:113:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -219,31 +223,31 @@ LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimenta = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -251,7 +255,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -259,7 +263,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -267,7 +271,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -275,7 +279,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -283,7 +287,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -291,7 +295,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -299,7 +303,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -307,7 +311,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -315,7 +319,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:154:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -323,7 +327,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -331,7 +335,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -339,7 +343,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -347,7 +351,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -355,7 +359,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -363,7 +367,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:166:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -371,13 +375,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:169:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:74:27 + --> $DIR/bad-reg.rs:76:27 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^ @@ -387,7 +391,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:78:28 + --> $DIR/bad-reg.rs:80:28 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^ @@ -397,7 +401,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:27 + --> $DIR/bad-reg.rs:84:27 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^ @@ -407,7 +411,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:86:28 + --> $DIR/bad-reg.rs:88:28 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^ @@ -417,7 +421,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 + --> $DIR/bad-reg.rs:92:27 | LL | asm!("", in("v0") b); | ^ @@ -425,7 +429,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 + --> $DIR/bad-reg.rs:97:28 | LL | asm!("", out("v0") b); | ^ @@ -433,7 +437,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:102:35 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^ @@ -443,7 +447,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:104:35 + --> $DIR/bad-reg.rs:106:35 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^ @@ -453,7 +457,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 + --> $DIR/bad-reg.rs:110:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -461,7 +465,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:122:27 | LL | asm!("", in("a2") x); | ^ @@ -469,7 +473,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:125:28 | LL | asm!("", out("a2") x); | ^ @@ -477,13 +481,13 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:128:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 63 previous errors +error: aborting due to 63 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr index 0b2d71f97d0d..11ec86b1e6d8 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr @@ -1,11 +1,11 @@ +warning: unstable feature specified for `-Ctarget-feature`: `d` + | + = note: this feature is not stably supported; its behavior can change in the future + warning: target feature `d` must be disabled to ensure that the ABI of the current target can be implemented correctly | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 -warning: unstable feature specified for `-Ctarget-feature`: `d` - | - = note: this feature is not stably supported; its behavior can change in the future - warning: 2 warnings emitted diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr index e49672f33b9a..90a9665fb41b 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr @@ -1,11 +1,11 @@ +warning: unstable feature specified for `-Ctarget-feature`: `soft-float` + | + = note: this feature is not stably supported; its behavior can change in the future + warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 -warning: unstable feature specified for `-Ctarget-feature`: `soft-float` - | - = note: this feature is not stably supported; its behavior can change in the future - warning: 2 warnings emitted diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr index 35102e0571f4..cc225b353df1 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr @@ -1,11 +1,11 @@ +warning: unstable feature specified for `-Ctarget-feature`: `d` + | + = note: this feature is not stably supported; its behavior can change in the future + warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 -warning: unstable feature specified for `-Ctarget-feature`: `d` - | - = note: this feature is not stably supported; its behavior can change in the future - warning: 2 warnings emitted diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr index 02398d27501c..911bd0382cba 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr @@ -1,11 +1,11 @@ +warning: unstable feature specified for `-Ctarget-feature`: `x87` + | + = note: this feature is not stably supported; its behavior can change in the future + warning: target feature `x87` must be enabled to ensure that the ABI of the current target can be implemented correctly | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 -warning: unstable feature specified for `-Ctarget-feature`: `x87` - | - = note: this feature is not stably supported; its behavior can change in the future - warning: 2 warnings emitted diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr index f82c50098d24..058953de9f21 100644 --- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr +++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr @@ -1,3 +1,5 @@ +error: the target features paca, pacg must all be either enabled or disabled together + error[E0428]: the name `foo` is defined multiple times --> $DIR/tied-features-no-implication.rs:31:1 | @@ -9,6 +11,6 @@ LL | pub unsafe fn foo() {} | = note: `foo` must be defined only once in the value namespace of this module -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 9543065bbf92..d6dd0b4234e2 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -30,4 +30,4 @@ fn foo() {} #[cfg(target_feature = "pacg")] pub unsafe fn foo() {} //[pacg]~ ERROR the name `foo` is defined multiple times -//[paca]~? ERROR the target features paca, pacg must all be either enabled or disabled together +//~? ERROR the target features paca, pacg must all be either enabled or disabled together From 296501b2fa7429c31980947fbd4e4956ddeb60fe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:07:47 +0000 Subject: [PATCH 406/525] Fix rustc test suite --- scripts/test_rustc_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index cbea3caf1211..b5af585a732e 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -87,8 +87,7 @@ rm -r tests/ui/instrument-coverage/ # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same -rm -r tests/run-make/fmt-write-bloat/ # tests an optimization -rm tests/ui/statics/const_generics.rs # same +rm tests/ui/statics/const_generics.rs # tests an optimization rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics # backend specific tests From 8e44e3f6a930e9576fb3281fca36dba7f7bcb12a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 30 Oct 2025 15:36:25 +0100 Subject: [PATCH 407/525] error on non-rustic ABIs using unsized parameters --- compiler/rustc_abi/src/canon_abi.rs | 14 +++ compiler/rustc_monomorphize/messages.ftl | 11 +++ compiler/rustc_monomorphize/src/errors.rs | 12 +++ .../src/mono_checks/abi_check.rs | 41 ++++++++- tests/ui/abi/non-rustic-unsized.rs | 66 ++++++++++++++ tests/ui/abi/non-rustic-unsized.stderr | 88 +++++++++++++++++++ 6 files changed, 228 insertions(+), 4 deletions(-) create mode 100644 tests/ui/abi/non-rustic-unsized.rs create mode 100644 tests/ui/abi/non-rustic-unsized.stderr diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs index 13f9a04b286f..a5294bbf7171 100644 --- a/compiler/rustc_abi/src/canon_abi.rs +++ b/compiler/rustc_abi/src/canon_abi.rs @@ -51,6 +51,20 @@ pub enum CanonAbi { X86(X86Call), } +impl CanonAbi { + pub fn is_rustic_abi(self) -> bool { + match self { + CanonAbi::Rust | CanonAbi::RustCold => true, + CanonAbi::C + | CanonAbi::Custom + | CanonAbi::Arm(_) + | CanonAbi::GpuKernel + | CanonAbi::Interrupt(_) + | CanonAbi::X86(_) => false, + } + } +} + impl fmt::Display for CanonAbi { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // convert to the ExternAbi that *shares a string* with this CanonAbi. diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 9595a5b5ac7f..bfb2edf286a2 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -12,6 +12,17 @@ monomorphize_abi_error_disabled_vector_type = } here .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) +monomorphize_abi_error_unsupported_unsized_parameter = + this function {$is_call -> + [true] call + *[false] definition + } uses unsized type `{$ty}` which is not supported with the chosen ABI + .label = function {$is_call -> + [true] called + *[false] defined + } here + .help = only rustic ABIs support unsized parameters + monomorphize_abi_error_unsupported_vector_type = this function {$is_call -> [true] call diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 89a78897dea9..a5040ef22dd0 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -80,6 +80,18 @@ pub(crate) struct AbiErrorDisabledVectorType<'a> { pub is_call: bool, } +#[derive(Diagnostic)] +#[diag(monomorphize_abi_error_unsupported_unsized_parameter)] +#[help] +pub(crate) struct AbiErrorUnsupportedUnsizedParameter<'a> { + #[primary_span] + #[label] + pub span: Span, + pub ty: Ty<'a>, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, +} + #[derive(Diagnostic)] #[diag(monomorphize_abi_error_unsupported_vector_type)] pub(crate) struct AbiErrorUnsupportedVectorType<'a> { diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index b8c001d357e6..2ee77e9deb0d 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -78,8 +78,37 @@ fn do_check_simd_vector_abi<'tcx>( } } -/// Checks that the ABI of a given instance of a function does not contain vector-passed arguments -/// or return values for which the corresponding target feature is not enabled. +/// Emit an error when a non-rustic ABI has unsized parameters. +/// Unsized types do not have a stable layout, so should not be used with stable ABIs. +/// `is_call` indicates whether this is a call-site check or a definition-site check; +/// this is only relevant for the wording in the emitted error. +fn do_check_unsized_params<'tcx>( + tcx: TyCtxt<'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + is_call: bool, + loc: impl Fn() -> (Span, HirId), +) { + // Unsized parameters are allowed with the (unstable) "Rust" (and similar) ABIs. + if fn_abi.conv.is_rustic_abi() { + return; + } + + for arg_abi in fn_abi.args.iter() { + if !arg_abi.layout.layout.is_sized() { + let (span, _hir_id) = loc(); + tcx.dcx().emit_err(errors::AbiErrorUnsupportedUnsizedParameter { + span, + ty: arg_abi.layout.ty, + is_call, + }); + } + } +} + +/// Checks the ABI of an Instance, emitting an error when: +/// +/// - a non-rustic ABI uses unsized parameters +/// - the signature requires target features that are not enabled fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let typing_env = ty::TypingEnv::fully_monomorphized(); let Ok(abi) = tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) @@ -102,11 +131,14 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { def_id.as_local().map(|did| tcx.local_def_id_to_hir_id(did)).unwrap_or(CRATE_HIR_ID), ) }; + do_check_unsized_params(tcx, abi, /*is_call*/ false, loc); do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, loc); } -/// Checks that a call expression does not try to pass a vector-passed argument which requires a -/// target feature that the caller does not have, as doing so causes UB because of ABI mismatch. +/// Check the ABI at a call site, emitting an error when: +/// +/// - a non-rustic ABI uses unsized parameters +/// - the signature requires target features that are not enabled fn check_call_site_abi<'tcx>( tcx: TyCtxt<'tcx>, callee: Ty<'tcx>, @@ -140,6 +172,7 @@ fn check_call_site_abi<'tcx>( // ABI failed to compute; this will not get through codegen. return; }; + do_check_unsized_params(tcx, callee_abi, /*is_call*/ true, loc); do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, loc); } diff --git a/tests/ui/abi/non-rustic-unsized.rs b/tests/ui/abi/non-rustic-unsized.rs new file mode 100644 index 000000000000..d26c4af72cca --- /dev/null +++ b/tests/ui/abi/non-rustic-unsized.rs @@ -0,0 +1,66 @@ +//@ add-minicore +//@ build-fail +#![no_core] +#![crate_type = "lib"] +#![feature(no_core, unsized_fn_params)] +#![allow(improper_ctypes_definitions, improper_ctypes)] + +extern crate minicore; +use minicore::*; + +fn rust(_: [u8]) {} +extern "C" fn c(_: [u8]) {} +//~^ ERROR this function definition uses unsized type `[u8]` which is not supported with the chosen ABI +extern "system" fn system(_: [u8]) {} +//~^ ERROR this function definition uses unsized type `[u8]` which is not supported with the chosen ABI + +#[repr(C)] +struct CustomUnsized { + a: i64, + b: [u8], +} + +extern "C" fn c_custom_unsized(x: CustomUnsized) {} +//~^ ERROR this function definition uses unsized type `CustomUnsized` which is not supported with the chosen ABI + +#[unsafe(no_mangle)] +fn entry(x: [u8], y: [u8], z: [u8], w: CustomUnsized) { + rust(x); + c(y); + //~^ ERROR this function call uses unsized type `[u8]` which is not supported with the chosen ABI + system(z); + //~^ ERROR this function call uses unsized type `[u8]` which is not supported with the chosen ABI + c_custom_unsized(w); + //~^ ERROR this function call uses unsized type `CustomUnsized` which is not supported with the chosen ABI +} + +#[unsafe(no_mangle)] +fn test_fn_ptr(rust: extern "Rust" fn(_: [u8]), c: extern "C" fn(_: [u8]), x: [u8], y: [u8]) { + rust(x); + c(y); + //~^ ERROR this function call uses unsized type `[u8]` which is not supported with the chosen ABI +} + +#[unsafe(no_mangle)] +fn test_extern(x: [u8], y: [u8]) { + unsafe extern "Rust" { + safe fn rust(_: [u8]); + } + + unsafe extern "system" { + safe fn system(_: [u8]); + } + + rust(x); + system(y); + //~^ ERROR this function call uses unsized type `[u8]` which is not supported with the chosen ABI +} + +extern "C" fn c_polymorphic(_: T) {} +//~^ ERROR this function definition uses unsized type `[u8]` which is not supported with the chosen ABI + +#[unsafe(no_mangle)] +fn test_polymorphic(x: [u8]) { + c_polymorphic(x); + //~^ ERROR this function call uses unsized type `[u8]` which is not supported with the chosen ABI +} diff --git a/tests/ui/abi/non-rustic-unsized.stderr b/tests/ui/abi/non-rustic-unsized.stderr new file mode 100644 index 000000000000..30fbf2922faf --- /dev/null +++ b/tests/ui/abi/non-rustic-unsized.stderr @@ -0,0 +1,88 @@ +error: this function call uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:29:5 + | +LL | c(y); + | ^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function call uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:31:5 + | +LL | system(z); + | ^^^^^^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function call uses unsized type `CustomUnsized` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:33:5 + | +LL | c_custom_unsized(w); + | ^^^^^^^^^^^^^^^^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function definition uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:12:1 + | +LL | extern "C" fn c(_: [u8]) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: only rustic ABIs support unsized parameters + +error: this function definition uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:14:1 + | +LL | extern "system" fn system(_: [u8]) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: only rustic ABIs support unsized parameters + +error: this function definition uses unsized type `CustomUnsized` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:23:1 + | +LL | extern "C" fn c_custom_unsized(x: CustomUnsized) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: only rustic ABIs support unsized parameters + +error: this function call uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:40:5 + | +LL | c(y); + | ^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function call uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:55:5 + | +LL | system(y); + | ^^^^^^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function call uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:64:5 + | +LL | c_polymorphic(x); + | ^^^^^^^^^^^^^^^^ function called here + | + = help: only rustic ABIs support unsized parameters + +error: this function definition uses unsized type `[u8]` which is not supported with the chosen ABI + --> $DIR/non-rustic-unsized.rs:59:1 + | +LL | extern "C" fn c_polymorphic(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: only rustic ABIs support unsized parameters + +note: the above error was encountered while instantiating `fn c_polymorphic::<[u8]>` + --> $DIR/non-rustic-unsized.rs:64:5 + | +LL | c_polymorphic(x); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 10 previous errors + From 973c7527b41f5b39ee84c705f61c0e7b8a712fff Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:16:39 +0000 Subject: [PATCH 408/525] Unify the configuration of the compiler docs Previously it was rather inconsistent which crates got the rust logo and which didn't and setting html_root_url was forgotten in many cases. --- compiler/rustc_abi/src/lib.rs | 2 -- compiler/rustc_arena/src/lib.rs | 7 +------ compiler/rustc_ast/src/lib.rs | 8 +------- compiler/rustc_ast_lowering/src/lib.rs | 3 --- compiler/rustc_ast_passes/src/lib.rs | 3 --- compiler/rustc_ast_pretty/src/lib.rs | 3 --- compiler/rustc_attr_parsing/src/lib.rs | 3 --- compiler/rustc_baked_icu_data/src/lib.rs | 3 --- compiler/rustc_borrowck/src/lib.rs | 2 -- compiler/rustc_builtin_macros/src/lib.rs | 3 --- compiler/rustc_codegen_cranelift/src/lib.rs | 3 --- compiler/rustc_codegen_gcc/src/lib.rs | 3 --- compiler/rustc_codegen_llvm/src/lib.rs | 4 ---- compiler/rustc_codegen_ssa/src/lib.rs | 4 ---- compiler/rustc_const_eval/src/lib.rs | 3 --- compiler/rustc_data_structures/src/lib.rs | 3 --- compiler/rustc_driver/src/lib.rs | 6 ------ compiler/rustc_driver_impl/src/lib.rs | 4 ---- compiler/rustc_error_codes/src/lib.rs | 3 --- compiler/rustc_error_messages/src/lib.rs | 2 -- compiler/rustc_errors/src/lib.rs | 3 --- compiler/rustc_expand/src/lib.rs | 2 -- compiler/rustc_feature/src/lib.rs | 6 ------ compiler/rustc_fluent_macro/src/lib.rs | 4 ---- compiler/rustc_graphviz/src/lib.rs | 8 +------- compiler/rustc_hir_analysis/src/lib.rs | 4 ---- compiler/rustc_incremental/src/lib.rs | 4 ---- compiler/rustc_index/src/lib.rs | 1 - compiler/rustc_infer/src/lib.rs | 4 ---- compiler/rustc_lint/src/lib.rs | 3 --- compiler/rustc_llvm/src/lib.rs | 4 ---- compiler/rustc_metadata/src/lib.rs | 3 --- compiler/rustc_middle/src/lib.rs | 3 --- compiler/rustc_parse_format/src/lib.rs | 6 +----- compiler/rustc_passes/src/lib.rs | 4 ---- compiler/rustc_privacy/src/lib.rs | 4 ---- compiler/rustc_public/src/lib.rs | 5 +---- compiler/rustc_public_bridge/src/lib.rs | 8 +------- compiler/rustc_query_impl/src/lib.rs | 3 --- compiler/rustc_resolve/src/lib.rs | 3 --- compiler/rustc_serialize/src/lib.rs | 8 +------- compiler/rustc_span/src/lib.rs | 3 --- compiler/rustc_symbol_mangling/src/lib.rs | 4 ---- compiler/rustc_target/src/lib.rs | 4 ---- compiler/rustc_trait_selection/src/lib.rs | 4 ---- compiler/rustc_ty_utils/src/lib.rs | 4 ---- src/bootstrap/src/bin/rustdoc.rs | 15 +++++++++++++++ 47 files changed, 22 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 1dc4441f039a..cd85efb2753a 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,9 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr(feature = "nightly", doc(rust_logo))] #![cfg_attr(feature = "nightly", feature(assert_matches))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] // tidy-alphabetical-end diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index d3b7e679d171..40d0d3735de0 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -12,18 +12,13 @@ #![allow(internal_features)] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(no_crate_inject, attr(deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(no_crate_inject, attr(deny(warnings))))] #![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(maybe_uninit_slice)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(unwrap_infallible)] // tidy-alphabetical-end diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 5fe218776e53..f42b70f43aba 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,19 +5,13 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(attr(deny(warnings))))] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(macro_metavar_expr)] -#![feature(rustdoc_internals)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd458ab1ea70..2a2091a26f0d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,11 +31,8 @@ //! in the HIR, especially for multiple identifiers. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(if_let_guard)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 6517fdb55bd3..06795a6be81e 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -3,12 +3,9 @@ //! by `rustc_ast_lowering`. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_is_partitioned)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 1079ccccb03e..a7d9f89fb3df 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,9 +1,6 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(negative_impls)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 2e0c5be587bb..473935abdcd5 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -77,10 +77,7 @@ //! containing both `C` and `packed` annotations. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(decl_macro)] -#![feature(rustdoc_internals)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index ea4c8242c629..75fe473ef999 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -21,10 +21,7 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] -#![allow(internal_features)] #![allow(unreachable_pub)] // because this crate is mostly generated code -#![doc(rust_logo)] -#![feature(rustdoc_internals)] // #![warn(unreachable_pub)] // don't use because this crate is mostly generated code // tidy-alphabetical-end diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4a85859c2f05..0ac3baaa197f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] @@ -10,7 +9,6 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 57cf62ea6121..221e7c3d553a 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,8 +5,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] @@ -14,7 +12,6 @@ #![feature(iter_order_by)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 5c23cd02e0d3..b63773053d3f 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,9 +1,6 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, doc(rust_logo))] -#![cfg_attr(doc, feature(rustdoc_internals))] // Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Only used to define intrinsics in `compiler_builtins.rs`. diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 9f5b03c02a09..c3fa570fb5cc 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -13,9 +13,6 @@ * TODO(antoyo): remove the patches. */ -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(rustc_private)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c8ad8f0c10d0..7e837343bf1d 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,9 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(extern_types)] #![feature(file_buffered)] @@ -15,7 +12,6 @@ #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] -#![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index baba8f9ca3e8..db8706d02ae1 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,15 +1,11 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(negative_impls)] -#![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 9c0ec4e51a0c..2fce4b8c0566 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,14 +1,11 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![doc(rust_logo)] #![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(slice_ptr_get)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 132f04b05100..b4031973fbc2 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -11,8 +11,6 @@ #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(allocator_api)] #![feature(array_windows)] #![feature(ascii_char)] @@ -30,7 +28,6 @@ #![feature(never_type)] #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] #![feature(test)] #![feature(thread_id_value)] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index a03834c519d5..0cd0b51b6ad4 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1,10 +1,4 @@ // This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in // `rustc_driver_impl` to be compiled in parallel with other crates. -// tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] -// tidy-alphabetical-end - pub use rustc_driver_impl::*; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8353aac74fd9..9a3d7cc506cf 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,14 +5,10 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(decl_macro)] #![feature(panic_backtrace_config)] #![feature(panic_update_hook)] -#![feature(rustdoc_internals)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 0aff1c06e0a8..f63f89748884 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -2,10 +2,7 @@ //! their maintenance easier. // tidy-alphabetical-start -#![allow(internal_features)] #![deny(rustdoc::invalid_codeblock_attributes)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 7b7843f6cf31..64dcf3c1f72d 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,8 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(rust_logo)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 17cd466f96b8..2f88e587ae9f 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,8 +7,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(assert_matches)] #![feature(associated_type_defaults)] @@ -18,7 +16,6 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index b54dabbb8e26..e76fca92c586 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,14 +1,12 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(macro_metavar_expr)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index dbc0daa3d838..855c78293acc 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,12 +11,6 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. -// tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] -// tidy-alphabetical-end - mod accepted; mod builtin_attrs; mod removed; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 6f85e05f29aa..c2f49de31c23 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -1,10 +1,6 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::default_hash_types)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(proc_macro_diagnostic)] -#![feature(rustdoc_internals)] #![feature(track_path)] // tidy-alphabetical-end diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index c8f8fd5be023..56adee70465d 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -270,13 +270,7 @@ //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) // tidy-alphabetical-start -#![allow(internal_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 56c0f4e7cee4..eeb783b300c7 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -56,18 +56,14 @@ This API is completely unstable and subject to change. */ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 299ee4876389..e750810c0119 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -1,12 +1,8 @@ //! Support for serializing the dep-graph and reloading it. // tidy-alphabetical-start -#![allow(internal_features)] #![deny(missing_docs)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(file_buffered)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 42d284938468..7fb9deaa1697 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] -#![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] // tidy-alphabetical-end diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index e562c5833134..05ea0f813818 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -13,13 +13,9 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(extend_one)] -#![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index faaeb7706e39..8a83434e10c1 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,15 +21,12 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 14e94121d1cb..a565e1feeb5e 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -1,9 +1,5 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(extern_types)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 3e50689b5acc..01060eb7e32c 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,7 +1,5 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(decl_macro)] #![feature(error_iter)] #![feature(file_buffered)] @@ -11,7 +9,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(proc_macro_internals)] -#![feature(rustdoc_internals)] #![feature(trusted_len)] // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 754a258eef93..72786931ff8a 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,8 +29,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(allocator_api)] #![feature(array_windows)] #![feature(assert_matches)] @@ -52,7 +50,6 @@ #![feature(never_type)] #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 5cda0b813d23..201722b26edb 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -8,11 +8,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(deny(warnings))) -)] +#![doc(test(attr(deny(warnings))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index c98e97118579..149714f943a7 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -5,12 +5,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(if_let_guard)] #![feature(map_try_insert)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_middle::util::Providers; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index bfa0f01d1192..8656ec6e39ae 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,9 +1,5 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(associated_type_defaults)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 958b3b264788..14f246cebbf6 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -7,10 +7,7 @@ //! This API is still completely unstable and subject to change. #![allow(rustc::usage_of_ty_tykind)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] //! //! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index d0b417c550dc..a74b460a912c 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -12,14 +12,8 @@ //! This API is still completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index e499e08c82b9..6904af771f0c 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -2,11 +2,8 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(min_specialization)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9f68b93520d2..7ce70ee9af8d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -10,8 +10,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] @@ -21,7 +19,6 @@ #![feature(iter_intersperse)] #![feature(ptr_as_ref_unchecked)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(trim_prefix_suffix)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 806d880b19c5..88ecb1ffe1f1 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -4,16 +4,10 @@ #![allow(internal_features)] #![allow(rustc::internal)] #![cfg_attr(test, feature(test))] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] // tidy-alphabetical-end diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ededbea57e96..afd4564f1b6f 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -18,8 +18,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(cfg_select)] #![feature(core_io_borrowed_buf)] @@ -28,7 +26,6 @@ #![feature(negative_impls)] #![feature(read_buf)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index b5716b51a91c..71dc81f0139e 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -88,11 +88,7 @@ //! DefPaths which are much more robust in the face of changes to the code base. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index b38ce20e6095..2d83caa07676 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -8,12 +8,8 @@ //! LLVM. // tidy-alphabetical-start -#![allow(internal_features)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(iter_intersperse)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index fc0cf8f140a7..c5dfaa2a60d8 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,11 +11,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] @@ -24,7 +21,6 @@ #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(unwrap_infallible)] #![feature(yeet_expr)] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 929cc074bdac..d8b50b2d2e42 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,16 +5,12 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iterator_try_collect)] #![feature(never_type)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index efb51bdce1e0..784041985b72 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -60,6 +60,21 @@ fn main() { cmd.arg("--cfg=bootstrap"); } + if let Some(crate_name) = parse_value_from_args(&args, "--crate-name") { + // Add rust logo and set html root for all rustc crates. + if crate_name.starts_with("rustc_") { + cmd.arg("-Ainternal_features") + .arg("-Zcrate-attr=doc(rust_logo)") + .arg("-Zcrate-attr=doc(html_root_url = \"https://doc.rust-lang.org/nightly/nightly-rustc/\")"); + + // rustc_proc_macro is another build of library/proc_macro which already enables this + // feature + if crate_name != "rustc_proc_macro" { + cmd.arg("-Zcrate-attr=feature(rustdoc_internals)"); + } + } + } + maybe_dump(format!("stage{}-rustdoc", stage + 1), &cmd); if verbose > 1 { From 2073d1209d755b91873e382747ac8d9fb4038baf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:16:39 +0000 Subject: [PATCH 409/525] Unify the configuration of the compiler docs Previously it was rather inconsistent which crates got the rust logo and which didn't and setting html_root_url was forgotten in many cases. --- src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5c23cd02e0d3..b63773053d3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,6 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, doc(rust_logo))] -#![cfg_attr(doc, feature(rustdoc_internals))] // Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Only used to define intrinsics in `compiler_builtins.rs`. From 222480dcb94c5a27fb10768aae7ccc99da0d805c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:13:23 +0000 Subject: [PATCH 410/525] Allow internal_features lint in doc tests Rustdoc forwards -Zcrate-attr=feature(rustdoc_internals) to doc tests, but deny(warnings) overrides the -Ainternal_features. --- compiler/rustc_arena/src/lib.rs | 2 +- compiler/rustc_ast/src/lib.rs | 2 +- compiler/rustc_graphviz/src/lib.rs | 2 +- compiler/rustc_parse_format/src/lib.rs | 2 +- compiler/rustc_public/src/lib.rs | 2 +- compiler/rustc_public_bridge/src/lib.rs | 2 +- compiler/rustc_serialize/src/lib.rs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 40d0d3735de0..a821d9e7fa23 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -12,7 +12,7 @@ #![allow(internal_features)] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(test(no_crate_inject, attr(deny(warnings))))] +#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] #![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index f42b70f43aba..e19dccbce02a 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,7 +5,7 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![doc(test(attr(deny(warnings))))] +#![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 56adee70465d..9f75578aa636 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -270,7 +270,7 @@ //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) // tidy-alphabetical-start -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 201722b26edb..86326fc6536c 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -8,7 +8,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![doc(test(attr(deny(warnings))))] +#![doc(test(attr(deny(warnings), allow(internal_features))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 14f246cebbf6..66fa4607edcc 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -7,7 +7,7 @@ //! This API is still completely unstable and subject to change. #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(sized_hierarchy)] //! //! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index a74b460a912c..025ec0e7a8c8 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -13,7 +13,7 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(sized_hierarchy)] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 88ecb1ffe1f1..842068a4fc04 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -4,7 +4,7 @@ #![allow(internal_features)] #![allow(rustc::internal)] #![cfg_attr(test, feature(test))] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] From eaf979e8dd98f006767632f0910cd2fdecf8541d Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 5 Nov 2025 20:24:20 +0800 Subject: [PATCH 411/525] Fix ICE from lit_to_mir_constant caused by type error --- .../src/error_reporting/traits/mod.rs | 41 ++++++++++--------- .../ice-from-type-error-issue-148515.rs | 18 ++++++++ .../ice-from-type-error-issue-148515.stderr | 24 +++++++++++ 3 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs create mode 100644 tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index b98547c42789..1825719a3077 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -250,29 +250,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let mut reported = None; - for from_expansion in [false, true] { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { - if !suppressed - && error.obligation.cause.span.from_expansion() == from_expansion - && !error.references_error() - { - let guar = self.report_fulfillment_error(error); - self.infcx.set_tainted_by_errors(guar); - reported = Some(guar); - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; + if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { + if !error.references_error() { + let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); + reported = Some(guar); + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_insert_with(|| (vec![], guar)) + .0 + .push(error.obligation.as_goal()); + } + if let Some(guar) = self.dcx().has_errors() { + self.infcx.set_tainted_by_errors(guar); } - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_insert_with(|| (vec![], guar)) - .0 - .push(error.obligation.as_goal()); } } } diff --git a/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs new file mode 100644 index 000000000000..e9ba69307c40 --- /dev/null +++ b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 + +enum Test { + Value = -5 >> 1_usize, +} + +fn test1(x: impl Iterator) { + //~^ ERROR cannot find type `Foo` in this scope + assert_eq!(Test::Value as u8, -3); +} + +fn test2(_: impl Iterator) { + //~^ ERROR cannot find type `Foo` in this scope + 0u8 == -3; + //~^ ERROR cannot apply unary operator `-` to type `u8` +} + +fn main() {} diff --git a/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr new file mode 100644 index 000000000000..d9f40c7c0f73 --- /dev/null +++ b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr @@ -0,0 +1,24 @@ +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/ice-from-type-error-issue-148515.rs:7:34 + | +LL | fn test1(x: impl Iterator) { + | ^^^ not found in this scope + +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/ice-from-type-error-issue-148515.rs:12:34 + | +LL | fn test2(_: impl Iterator) { + | ^^^ not found in this scope + +error[E0600]: cannot apply unary operator `-` to type `u8` + --> $DIR/ice-from-type-error-issue-148515.rs:14:12 + | +LL | 0u8 == -3; + | ^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0600. +For more information about an error, try `rustc --explain E0412`. From d2cfc47ed07497d8b8e37d17b136937a8af47723 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Wed, 5 Nov 2025 21:29:39 +0800 Subject: [PATCH 412/525] add test for alias self_ty --- .../use_object_if_empty_env.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs index c0bd2b49117b..f8f6ed9a0988 100644 --- a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs +++ b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs @@ -16,4 +16,21 @@ where x } +trait Id<'a> { + type This: ?Sized; +} +impl Id<'_> for T { + type This = T; +} + +// Ensure that we properly normalize alias self_ty before evaluating the goal. +fn alias_foo(x: for<'a> fn( + < as Id<'a>>::This as Trait>::Assoc +)) -> fn(T) +where + dyn Trait: Trait, +{ + x +} + fn main() {} From 28eb8499c3629bf2330c68f34c42f33d0c179640 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 13:29:42 +0000 Subject: [PATCH 413/525] Allow f16 and f128 on s390x and non-mingw windows --- src/lib.rs | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f1d5eeb76dd6..ac0d50fc5b1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -182,36 +182,23 @@ impl CodegenBackend for CraneliftCodegenBackend { // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); - // FIXME(f16_f128): LLVM 20 (currently used by `rustc`) passes `f128` in XMM registers on - // Windows, whereas LLVM 21+ and Cranelift pass it indirectly. This means that `f128` won't - // work when linking against a LLVM-built sysroot. - let has_reliable_f128 = !sess.target.is_like_windows; - let has_reliable_f16 = match &*sess.target.arch { - // FIXME(f16_f128): LLVM 20 does not support `f16` on s390x, meaning the required - // builtins are not available in `compiler-builtins`. - "s390x" => false, - // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU - // targets due to GCC using a different ABI than LLVM. Therefore `f16` won't be - // available when using a LLVM-built sysroot. - "x86_64" - if sess.target.os == "windows" - && sess.target.env == "gnu" - && sess.target.abi != "llvm" => - { - false - } - _ => true, - }; + // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU + // targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128` + // won't be available when using a LLVM-built sysroot. + let has_reliable_f16_f128 = !(sess.target.arch == "x86_64" + && sess.target.os == "windows" + && sess.target.env == "gnu" + && sess.target.abi != "llvm"); TargetConfig { target_features, unstable_target_features, // `rustc_codegen_cranelift` polyfills functionality not yet // available in Cranelift. - has_reliable_f16, - has_reliable_f16_math: has_reliable_f16, - has_reliable_f128, - has_reliable_f128_math: has_reliable_f128, + has_reliable_f16: has_reliable_f16_f128, + has_reliable_f16_math: has_reliable_f16_f128, + has_reliable_f128: has_reliable_f16_f128, + has_reliable_f128_math: has_reliable_f16_f128, } } From fd6466aea7bdc9b99979dca38daab0668cc70d8b Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 5 Nov 2025 14:28:16 +0000 Subject: [PATCH 414/525] run-make tests: use edition 2024 --- tests/run-make/alloc-no-oom-handling/rmake.rs | 2 +- tests/run-make/alloc-no-rc/rmake.rs | 2 +- tests/run-make/alloc-no-sync/rmake.rs | 2 +- .../llvm-location-discriminator-limit-dummy-span/rmake.rs | 6 +++--- tests/run-make/panic-abort-eh_frame/rmake.rs | 2 +- tests/run-make/rustdoc-scrape-examples-macros/rmake.rs | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 89a6636d9a0c..94002eca5736 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index 12171c2148f1..8d8cd4990bc6 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 29f204f30673..a096d3941d46 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs index d28c8463016c..00ae400f71d2 100644 --- a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs @@ -49,21 +49,21 @@ fn main() { rustc() .input("proc.rs") .crate_type("proc-macro") - .edition("2021") + .edition("2024") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("proc", dynamic_lib_name("proc")) .input("other.rs") .crate_type("rlib") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("other", rust_lib_name("other")) .input("main.rs") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .arg("-Clto=fat") diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs index 2eccde627955..5c859a748267 100644 --- a/tests/run-make/panic-abort-eh_frame/rmake.rs +++ b/tests/run-make/panic-abort-eh_frame/rmake.rs @@ -19,7 +19,7 @@ fn main() { .crate_type("lib") .emit("obj=foo.o") .panic("abort") - .edition("2021") + .edition("2024") .arg("-Zvalidate-mir") .arg("-Cforce-unwind-tables=no") .run(); diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index 546a0685b4ee..4f85bf6bef8f 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -19,14 +19,14 @@ fn main() { rustc() .input("src/proc.rs") .crate_name(proc_crate_name) - .edition("2021") + .edition("2024") .crate_type("proc-macro") .emit("dep-info,link") .run(); rustc() .input("src/lib.rs") .crate_name(crate_name) - .edition("2021") + .edition("2024") .crate_type("lib") .emit("dep-info,link") .run(); From 457cbb06a1efea69d97d85817857a90f006a67bd Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 28 Oct 2025 12:53:40 -0600 Subject: [PATCH 415/525] chore: Update annotate-snippets to 0.12.8 --- Cargo.lock | 6 +++--- compiler/rustc_errors/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a838c0775b7b..0f42738ecbf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47224528f74de27d1d06aad6a5dda4f865b6ebe2e56c538943d746a7270cb67e" +checksum = "025c7edcdffa4ccc5c0905f472a0ae3759378cfbef88ef518a3575e19ae3aebd" dependencies = [ "anstyle", "unicode-width 0.2.2", @@ -3766,7 +3766,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.12.7", + "annotate-snippets 0.12.8", "anstream", "anstyle", "derive_setters", diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 6ade87ea3b25..6606092e421e 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -annotate-snippets = "0.12.7" +annotate-snippets = "0.12.8" anstream = "0.6.20" anstyle = "1.0.13" derive_setters = "0.1.6" From 37bb0c262a1354ea7c3b3c72a9f0711f355f62cd Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 28 Oct 2025 00:00:34 -0600 Subject: [PATCH 416/525] chore: Make AnnotateSnippetEmitter match revert of "all spans must be disjoint" --- .../src/annotate_snippet_emitter_writer.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 854e3ddf15e4..5d22a8b8e30a 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -329,7 +329,7 @@ impl AnnotateSnippetEmitter { let substitutions = suggestion .substitutions .into_iter() - .filter_map(|mut subst| { + .filter(|subst| { // Suggestions coming from macros can have malformed spans. This is a heavy // handed approach to avoid ICEs by ignoring the suggestion outright. let invalid = @@ -337,12 +337,14 @@ impl AnnotateSnippetEmitter { if invalid { debug!("suggestion contains an invalid span: {:?}", subst); } - + !invalid + }) + .filter_map(|mut subst| { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. subst.parts.sort_by_key(|part| part.span.lo()); // Verify the assumption that all spans are disjoint - assert_eq!( + debug_assert_eq!( subst.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), None, "all spans must be disjoint", @@ -355,13 +357,11 @@ impl AnnotateSnippetEmitter { let item_span = subst.parts.first()?; let file = sm.lookup_source_file(item_span.span.lo()); - if !invalid - && should_show_source_code( - &self.ignored_directories_in_source_blocks, - sm, - &file, - ) - { + if should_show_source_code( + &self.ignored_directories_in_source_blocks, + sm, + &file, + ) { Some(subst) } else { None From a75bd03fb914530b95f27b40acf120df0c28f216 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 18:27:08 -0600 Subject: [PATCH 417/525] fix: Respect HumanReadableErrorType::AnnotateSnippet --- compiler/rustc_errors/src/json.rs | 54 +++++++++++++++++++-------- compiler/rustc_session/src/session.rs | 30 ++++++++++----- src/librustdoc/core.rs | 43 ++++++++++++++------- 3 files changed, 90 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 03ce1d82ef3c..260559a9ef33 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -25,6 +25,7 @@ use rustc_span::hygiene::ExpnData; use rustc_span::source_map::{FilePathMapping, SourceMap}; use serde::Serialize; +use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use crate::diagnostic::IsLint; use crate::emitter::{ ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme, @@ -378,21 +379,44 @@ impl Diagnostic { choice => choice, }, ); - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + if let HumanReadableErrorType::AnnotateSnippet = je.json_rendered { + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .emit_diagnostic(diag, registry); + } else { + HumanEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .emit_diagnostic(diag, registry); + } + let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); let buf = String::from_utf8(buf).unwrap(); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 16f9774554e1..fa8646d8e207 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1501,15 +1501,27 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .short_message(short), - ) + if let HumanReadableErrorType::AnnotateSnippet = kind { + Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .theme(if let HumanReadableErrorType::Unicode = kind { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .short_message(short), + ) + } else { + Box::new( + HumanEmitter::new(stderr_destination(color_config), translator) + .theme(if let HumanReadableErrorType::Unicode = kind { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .short_message(short), + ) + } } config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 44bac8197539..8ee2fc7a43ee 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,6 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_driver::USING_INTERNAL_FEATURES; use rustc_errors::TerminalUrl; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; use rustc_errors::emitter::{ DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, @@ -154,19 +155,35 @@ pub(crate) fn new_dcx( let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map.map(|sm| sm as _)) - .short_message(short) - .diagnostic_width(diagnostic_width) - .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .ui_testing(unstable_opts.ui_testing), - ) + if let HumanReadableErrorType::AnnotateSnippet = kind { + Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .sm(source_map.map(|sm| sm as _)) + .short_message(short) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .theme(if let HumanReadableErrorType::Unicode = kind { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .ui_testing(unstable_opts.ui_testing), + ) + } else { + Box::new( + HumanEmitter::new(stderr_destination(color_config), translator) + .sm(source_map.map(|sm| sm as _)) + .short_message(short) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .theme(if let HumanReadableErrorType::Unicode = kind { + OutputTheme::Unicode + } else { + OutputTheme::Ascii + }) + .ui_testing(unstable_opts.ui_testing), + ) + } } ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { From 4748d92a9571f8ed009cfa8aec0aefec0390cb5e Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 17:49:34 -0600 Subject: [PATCH 418/525] feat: Always use annotate-snippets for Unicode output --- compiler/rustc_errors/src/emitter.rs | 3 +- compiler/rustc_errors/src/json.rs | 18 ++++------- compiler/rustc_parse/src/parser/tests.rs | 24 ++++++++++----- compiler/rustc_session/src/config.rs | 10 +++---- compiler/rustc_session/src/session.rs | 29 ++++-------------- src/librustdoc/core.rs | 14 ++------- src/librustdoc/doctest.rs | 2 +- ...dth-unicode-multiline-label.unicode.stderr | 30 +++++++++---------- tests/ui/error-emitter/unicode-output.svg | 2 +- 9 files changed, 54 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d98d6e563645..2c5fb64998fd 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -48,8 +48,7 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { Default, - Unicode, - AnnotateSnippet, + AnnotateSnippet { unicode: bool }, Short, } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 260559a9ef33..d495d6b6b1a7 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -379,7 +379,7 @@ impl Diagnostic { choice => choice, }, ); - if let HumanReadableErrorType::AnnotateSnippet = je.json_rendered { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = je.json_rendered { AnnotateSnippetEmitter::new(dst, je.translator.clone()) .short_message(short) .sm(je.sm.clone()) @@ -391,12 +391,8 @@ impl Diagnostic { .ignored_directories_in_source_blocks( je.ignored_directories_in_source_blocks.clone(), ) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry) } else { HumanEmitter::new(dst, je.translator.clone()) .short_message(short) @@ -409,12 +405,8 @@ impl Diagnostic { .ignored_directories_in_source_blocks( je.ignored_directories_in_source_blocks.clone(), ) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + .theme(OutputTheme::Ascii) + .emit_diagnostic(diag, registry) } let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 5fe921da1381..9b157cb6c7bf 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -1,5 +1,4 @@ #![allow(rustc::symbol_intern_string_literal)] - use std::assert_matches::assert_matches; use std::io::prelude::*; use std::iter::Peekable; @@ -12,6 +11,7 @@ use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{self as ast, PatKind, visit}; use rustc_ast_pretty::pprust::item_to_string; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{HumanEmitter, OutputTheme}; use rustc_errors::translation::Translator; use rustc_errors::{AutoStream, DiagCtxt, MultiSpan, PResult}; @@ -43,12 +43,22 @@ fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc, Arc = Box::new(Shared { data: output.clone() }); + let auto_stream = AutoStream::never(shared); + let dcx = DiagCtxt::new(match theme { + OutputTheme::Ascii => Box::new( + HumanEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + OutputTheme::Unicode => Box::new( + AnnotateSnippetEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + }); (dcx, source_map, output) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index ce6f6434e793..b980ff5f2ae7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2060,7 +2060,7 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json match sub_option { "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, "diagnostic-unicode" => { - json_rendered = HumanReadableErrorType::Unicode; + json_rendered = HumanReadableErrorType::AnnotateSnippet { unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2099,7 +2099,7 @@ pub fn parse_error_format( match matches.opt_str("error-format").as_deref() { None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet, + kind: HumanReadableErrorType::AnnotateSnippet { unicode: false }, color_config, }, Some("json") => { @@ -2112,7 +2112,7 @@ pub fn parse_error_format( ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } } Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::Unicode, + kind: HumanReadableErrorType::AnnotateSnippet { unicode: true }, color_config, }, Some(arg) => { @@ -2180,8 +2180,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs", - HumanReadableErrorType::Unicode => "human-unicode", + HumanReadableErrorType::AnnotateSnippet { unicode: false } => "human-annotate-rs", + HumanReadableErrorType::AnnotateSnippet { unicode: true } => "human-unicode", _ => return, }, _ => return, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fa8646d8e207..243e1ee9f949 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -952,8 +952,7 @@ fn default_emitter( match sopts.error_format { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -962,11 +961,7 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ignored_directories_in_source_blocks( sopts .unstable_opts @@ -982,11 +977,7 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ignored_directories_in_source_blocks( sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), ); @@ -1501,24 +1492,16 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .short_message(short), ) } else { Box::new( HumanEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .short_message(short), ) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8ee2fc7a43ee..abbdef05ef83 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -155,18 +155,14 @@ pub(crate) fn new_dcx( let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map.map(|sm| sm as _)) .short_message(short) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ui_testing(unstable_opts.ui_testing), ) } else { @@ -176,11 +172,7 @@ pub(crate) fn new_dcx( .short_message(short) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ui_testing(unstable_opts.ui_testing), ) } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 631c48a4fdb8..c67bf2d891e6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -600,7 +600,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::Unicode; + let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr index 4dff15642aeb..6220a6ba7b31 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr @@ -1,11 +1,11 @@ error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:8:237 │ -LL │ …👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ … 👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -16,11 +16,11 @@ LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:10:384 │ -LL │ …👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ … 👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -31,11 +31,11 @@ LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:12:260 │ -LL │ …࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ …࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference diff --git a/tests/ui/error-emitter/unicode-output.svg b/tests/ui/error-emitter/unicode-output.svg index 9c1b7c80f433..5623421ab788 100644 --- a/tests/ui/error-emitter/unicode-output.svg +++ b/tests/ui/error-emitter/unicode-output.svg @@ -55,7 +55,7 @@ LL )>>) {} - ╰╴└───┘ + ╰╴└───┘ From 9cb7deb0b56114d76ee5ecba12eb338b50824df0 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 27 Oct 2025 11:22:39 -0600 Subject: [PATCH 419/525] refactor: Make short a field on HumanReadableErrorType varinants --- compiler/rustc_errors/src/emitter.rs | 10 +++-- compiler/rustc_errors/src/json.rs | 60 +++++++++++++------------ compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 26 ++++++----- compiler/rustc_session/src/session.rs | 38 +++++++--------- src/librustdoc/core.rs | 44 +++++++++--------- src/librustdoc/doctest.rs | 2 +- 8 files changed, 92 insertions(+), 92 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2c5fb64998fd..81a7ee1ff45f 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -47,14 +47,16 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { - Default, - AnnotateSnippet { unicode: bool }, - Short, + Default { short: bool }, + AnnotateSnippet { short: bool, unicode: bool }, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - *self == HumanReadableErrorType::Short + match self { + HumanReadableErrorType::Default { short } + | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, + } } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index d495d6b6b1a7..ce5c830bbfcd 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -371,7 +371,6 @@ impl Diagnostic { .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je)); } let buf = BufWriter(Arc::new(Mutex::new(Vec::new()))); - let short = je.json_rendered.short(); let dst: Destination = AutoStream::new( Box::new(buf.clone()), match je.color_config.to_color_choice() { @@ -379,34 +378,37 @@ impl Diagnostic { choice => choice, }, ); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = je.json_rendered { - AnnotateSnippetEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .emit_diagnostic(diag, registry) - } else { - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(OutputTheme::Ascii) - .emit_diagnostic(diag, registry) + match je.json_rendered { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry) + } + HumanReadableErrorType::Default { short } => { + HumanEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(OutputTheme::Ascii) + .emit_diagnostic(diag, registry) + } } let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 8cf81f467d84..79bb5054dfef 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -50,7 +50,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { Some(sm), translator, true, // pretty - HumanReadableErrorType::Short, + HumanReadableErrorType::Default { short: true }, ColorConfig::Never, ); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 6c08b37dec08..9848b11ce814 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -321,7 +321,7 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default, + json_rendered: HumanReadableErrorType::Default { short: false }, color_config: ColorConfig::Never, }; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b980ff5f2ae7..e162bcb2b56e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -826,7 +826,7 @@ pub enum ErrorOutputType { /// Output meant for the consumption of humans. #[default] HumanReadable { - kind: HumanReadableErrorType = HumanReadableErrorType::Default, + kind: HumanReadableErrorType = HumanReadableErrorType::Default { short: false }, color_config: ColorConfig = ColorConfig::Auto, }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. @@ -2042,7 +2042,7 @@ impl JsonUnusedExterns { /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered = HumanReadableErrorType::Default; + let mut json_rendered = HumanReadableErrorType::Default { short: false }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -2058,9 +2058,12 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json for sub_option in option.split(',') { match sub_option { - "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, + "diagnostic-short" => { + json_rendered = HumanReadableErrorType::Default { short: true } + } "diagnostic-unicode" => { - json_rendered = HumanReadableErrorType::AnnotateSnippet { unicode: true }; + json_rendered = + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2099,7 +2102,7 @@ pub fn parse_error_format( match matches.opt_str("error-format").as_deref() { None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { unicode: false }, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, color_config, }, Some("json") => { @@ -2108,11 +2111,12 @@ pub fn parse_error_format( Some("pretty-json") => { ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } - Some("short") => { - ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } - } + Some("short") => ErrorOutputType::HumanReadable { + kind: HumanReadableErrorType::Default { short: true }, + color_config, + }, Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { unicode: true }, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }, color_config, }, Some(arg) => { @@ -2180,8 +2184,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet { unicode: false } => "human-annotate-rs", - HumanReadableErrorType::AnnotateSnippet { unicode: true } => "human-unicode", + HumanReadableErrorType::AnnotateSnippet { unicode: false, .. } => "human-annotate-rs", + HumanReadableErrorType::AnnotateSnippet { unicode: true, .. } => "human-unicode", _ => return, }, _ => return, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 243e1ee9f949..f336c62e4288 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -950,9 +950,8 @@ fn default_emitter( let source_map = if sopts.unstable_opts.link_only { None } else { Some(source_map) }; match sopts.error_format { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -969,7 +968,8 @@ fn default_emitter( .clone(), ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) - } else { + } + HumanReadableErrorType::Default { short } => { let emitter = HumanEmitter::new(stderr_destination(color_config), translator) .sm(source_map) .short_message(short) @@ -983,7 +983,7 @@ fn default_emitter( ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } - } + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), @@ -1490,22 +1490,18 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let translator = Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { - Box::new( - AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .short_message(short), - ) - } else { - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(OutputTheme::Ascii) - .short_message(short), - ) - } - } + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .short_message(short), + ), + HumanReadableErrorType::Default { short } => Box::new( + HumanEmitter::new(stderr_destination(color_config), translator) + .theme(OutputTheme::Ascii) + .short_message(short), + ), + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index abbdef05ef83..451d0b4f5be9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -153,30 +153,26 @@ pub(crate) fn new_dcx( ) -> rustc_errors::DiagCtxt { let translator = rustc_driver::default_translator(); let emitter: Box = match error_format { - ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { - Box::new( - AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) - .sm(source_map.map(|sm| sm as _)) - .short_message(short) - .diagnostic_width(diagnostic_width) - .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .ui_testing(unstable_opts.ui_testing), - ) - } else { - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map.map(|sm| sm as _)) - .short_message(short) - .diagnostic_width(diagnostic_width) - .track_diagnostics(unstable_opts.track_diagnostics) - .theme(OutputTheme::Ascii) - .ui_testing(unstable_opts.ui_testing), - ) - } - } + ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .sm(source_map.map(|sm| sm as _)) + .short_message(short) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .ui_testing(unstable_opts.ui_testing), + ), + HumanReadableErrorType::Default { short } => Box::new( + HumanEmitter::new(stderr_destination(color_config), translator) + .sm(source_map.map(|sm| sm as _)) + .short_message(short) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .theme(OutputTheme::Ascii) + .ui_testing(unstable_opts.ui_testing), + ), + }, ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { Arc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c67bf2d891e6..44af97b434ac 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -600,7 +600,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true }; + let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true, short }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); From 9243928c6cd1939c0eae15f01cd94baeec1b90ac Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 19:19:46 -0600 Subject: [PATCH 420/525] feat: Use annotate-snippets by default on nightly --- compiler/rustc_session/src/config.rs | 66 +++++++++++++++---- src/librustdoc/config.rs | 19 ++++-- .../tests/ui/bool_assert_comparison.stderr | 12 ++-- tests/crashes/131762.rs | 1 + .../main-alongside-macro-calls.fail.stdout | 2 + ...width-unicode-multiline-label.ascii.stderr | 30 ++++----- .../non-whitespace-trimming-unicode.stderr | 8 +-- .../ui/diagnostic-width/tabs-trimming.stderr | 20 +++--- .../ui/include-macros/mismatched-types.stderr | 2 + tests/ui/macros/same-sequence-span.stderr | 10 +-- .../statics/check-values-constraints.stderr | 4 +- .../typeck_type_placeholder_item.stderr | 10 +-- 12 files changed, 113 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e162bcb2b56e..3403745084c5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2041,8 +2041,16 @@ impl JsonUnusedExterns { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered = HumanReadableErrorType::Default { short: false }; +pub fn parse_json( + early_dcx: &EarlyDiagCtxt, + matches: &getopts::Matches, + is_nightly_build: bool, +) -> JsonConfig { + let mut json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -2059,7 +2067,11 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json for sub_option in option.split(',') { match sub_option { "diagnostic-short" => { - json_rendered = HumanReadableErrorType::Default { short: true } + json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }; } "diagnostic-unicode" => { json_rendered = @@ -2093,14 +2105,22 @@ pub fn parse_error_format( color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, + is_nightly_build: bool, ) -> ErrorOutputType { + let default_kind = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; // We need the `opts_present` check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use `opts_present` not // `opt_present` because the latter will panic. let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_deref() { - None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, + None | Some("human") => { + ErrorOutputType::HumanReadable { color_config, kind: default_kind } + } Some("human-annotate-rs") => ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, color_config, @@ -2112,7 +2132,11 @@ pub fn parse_error_format( ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } Some("short") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::Default { short: true }, + kind: if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }, color_config, }, Some("human-unicode") => ErrorOutputType::HumanReadable { @@ -2120,7 +2144,10 @@ pub fn parse_error_format( color_config, }, Some(arg) => { - early_dcx.set_error_format(ErrorOutputType::HumanReadable { color_config, .. }); + early_dcx.set_error_format(ErrorOutputType::HumanReadable { + color_config, + kind: default_kind, + }); early_dcx.early_fatal(format!( "argument for `--error-format` must be `human`, `human-annotate-rs`, \ `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" @@ -2128,7 +2155,7 @@ pub fn parse_error_format( } } } else { - ErrorOutputType::HumanReadable { color_config, .. } + ErrorOutputType::HumanReadable { color_config, kind: default_kind } }; match error_format { @@ -2176,9 +2203,10 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches fn check_error_format_stability( early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions, + is_nightly_build: bool, format: ErrorOutputType, ) { - if unstable_opts.unstable_options { + if unstable_opts.unstable_options || is_nightly_build { return; } let format = match format { @@ -2606,6 +2634,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let edition = parse_crate_edition(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); let JsonConfig { json_rendered, json_color, @@ -2613,9 +2643,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M json_timings, json_unused_externs, json_future_incompat, - } = parse_json(early_dcx, matches); + } = parse_json(early_dcx, matches, unstable_features.is_nightly_build()); - let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); + let error_format = parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); early_dcx.set_error_format(error_format); @@ -2636,7 +2673,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`"); } - check_error_format_stability(early_dcx, &unstable_opts, error_format); + check_error_format_stability( + early_dcx, + &unstable_opts, + unstable_features.is_nightly_build(), + error_format, + ); let output_types = parse_output_types(early_dcx, &unstable_opts, matches); @@ -2823,8 +2865,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M ) } - let crate_name = matches.opt_str("crate-name"); - let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); // Parse any `-l` flags, which link to native libraries. let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 55e04671b83c..da19f506a370 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -389,10 +389,19 @@ impl Options { } let color = config::parse_color(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = + rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = - config::parse_json(early_dcx, matches); - let error_format = - config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); + config::parse_json(early_dcx, matches, unstable_features.is_nightly_build()); + let error_format = config::parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let mut target_modifiers = BTreeMap::::new(); @@ -753,7 +762,6 @@ impl Options { } }; - let crate_name = matches.opt_str("crate-name"); let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); @@ -815,9 +823,6 @@ impl Options { crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths); let doctest_build_args = matches.opt_strs("doctest-build-arg"); - let unstable_features = - rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); - let disable_minification = matches.opt_present("disable-minification"); let options = Options { diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index f823f08f31dc..72aa6303a202 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -272,10 +272,8 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(a!()); +LL - assert_eq!(a!(), true); +LL + assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -286,10 +284,8 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(b!()); +LL - assert_eq!(true, b!()); +LL + assert!(b!()); | error: used `debug_assert_eq!` with a literal bool diff --git a/tests/crashes/131762.rs b/tests/crashes/131762.rs index 85cb9c8f20a8..4080272226d9 100644 --- a/tests/crashes/131762.rs +++ b/tests/crashes/131762.rs @@ -1,3 +1,4 @@ +//@ needs-rustc-debug-assertions //@ known-bug: #131762 // ignore-tidy-linelength diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout index 65989a8ef47c..1048db07ae95 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout @@ -19,6 +19,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:30:1 | LL | println!(); @@ -41,6 +42,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:34:1 | LL | println!(); diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr index fe1ecfbe71d4..66d5a808d03c 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr @@ -1,11 +1,11 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:8:237 | -LL | ...👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ... 👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -16,11 +16,11 @@ LL | let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:10:384 | -LL | ...👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ... 👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -31,11 +31,11 @@ LL | let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:12:260 | -LL | ...࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ...࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr index e74afbfeac47..46369c551cf3 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr @@ -1,10 +1,10 @@ error[E0308]: mismatched types --> $DIR/non-whitespace-trimming-unicode.rs:5:415 | -LL | ...♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽ ... - | -- ^^ expected `()`, found integer - | | - | expected due to this +LL | ...♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳... + | -- ^^ expected `()`, found integer + | | + | expected due to this error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/tabs-trimming.stderr b/tests/ui/diagnostic-width/tabs-trimming.stderr index e0d1c2d95a96..dfda30e6005b 100644 --- a/tests/ui/diagnostic-width/tabs-trimming.stderr +++ b/tests/ui/diagnostic-width/tabs-trimming.stderr @@ -1,20 +1,20 @@ error[E0408]: variable `v` is not bound in all patterns --> $DIR/tabs-trimming.rs:9:16 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ ^ pattern doesn't bind `v` - | | | - | | pattern doesn't bind `v` - | variable not in all patterns +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ ^ pattern doesn't bind `v` + | | | + | | pattern doesn't bind `v` + | variable not in all patterns error[E0381]: used binding `v` is possibly-uninitialized --> $DIR/tabs-trimming.rs:9:67 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ `v` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - | binding declared here but left uninitialized +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ `v` used here but it is possibly-uninitialized + | | + | binding initialized here in some conditions + | binding declared here but left uninitialized error: aborting due to 2 previous errors diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 8d541966a6a4..4fab832c2d8e 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/file.txt:0:1 | +LL | + | ^ expected `&[u8]`, found `&str` | ::: $DIR/mismatched-types.rs:2:12 | diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 1ca89b6b595c..d6652453e9a9 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -17,14 +17,8 @@ LL | $(= $z:tt)* error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | -LL | | // `proc_macro_sequence.rs`. - | |_____________________________^not allowed after `expr` fragments -... -LL | proc_macro_sequence::make_foo!(); - | ^------------------------------- - | | - | _in this macro invocation - | | +LL | proc_macro_sequence::make_foo!(); + | -------------------------------- in this macro invocation | = note: allowed there are: `=>`, `,` or `;` = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index c54f4830533a..f6fa8df45e5e 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -38,10 +38,10 @@ LL | field2: SafeEnum::Variant4("str".to_string()), note: method `to_string` is not const because trait `ToString` is not const --> $SRC_DIR/alloc/src/string.rs:LL:COL | - = note: this trait is not const + = note: this method is not const ::: $SRC_DIR/alloc/src/string.rs:LL:COL | - = note: this method is not const + = note: this trait is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b70ac97fd43..747d032dfd4b 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -686,11 +686,12 @@ LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | note: method `filter` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants @@ -701,11 +702,12 @@ LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | note: method `map` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors From 32c93ccc89394a317ad272864d3970420bd4dc81 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 5 Nov 2025 17:01:21 +0100 Subject: [PATCH 421/525] Merge `Vec::push{,_mut}_within_capacity` --- library/alloc/src/vec/mod.rs | 50 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 45d6c28e186e..dc610d7b4674 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2564,8 +2564,8 @@ impl Vec { let _ = self.push_mut(value); } - /// Appends an element if there is sufficient spare capacity, otherwise an error is returned - /// with the element. + /// Appends an element and returns a reference to it if there is sufficient spare capacity, + /// otherwise an error is returned with the element. /// /// Unlike [`push`] this method will not reallocate when there's insufficient capacity. /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity. @@ -2601,8 +2601,20 @@ impl Vec { /// Takes *O*(1) time. #[inline] #[unstable(feature = "vec_push_within_capacity", issue = "100486")] - pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> { - self.push_mut_within_capacity(value).map(|_| ()) + // #[unstable(feature = "push_mut", issue = "135974")] + pub fn push_within_capacity(&mut self, value: T) -> Result<&mut T, T> { + if self.len == self.buf.capacity() { + return Err(value); + } + + unsafe { + let end = self.as_mut_ptr().add(self.len); + ptr::write(end, value); + self.len += 1; + + // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. + Ok(&mut *end) + } } /// Appends an element to the back of a collection, returning a reference to it. @@ -2654,36 +2666,6 @@ impl Vec { } } - /// Appends an element and returns a reference to it if there is sufficient spare capacity, - /// otherwise an error is returned with the element. - /// - /// Unlike [`push_mut`] this method will not reallocate when there's insufficient capacity. - /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity. - /// - /// [`push_mut`]: Vec::push_mut - /// [`reserve`]: Vec::reserve - /// [`try_reserve`]: Vec::try_reserve - /// - /// # Time complexity - /// - /// Takes *O*(1) time. - #[unstable(feature = "push_mut", issue = "135974")] - // #[unstable(feature = "vec_push_within_capacity", issue = "100486")] - #[inline] - #[must_use = "if you don't need a reference to the value, use `Vec::push_within_capacity` instead"] - pub fn push_mut_within_capacity(&mut self, value: T) -> Result<&mut T, T> { - if self.len == self.buf.capacity() { - return Err(value); - } - unsafe { - let end = self.as_mut_ptr().add(self.len); - ptr::write(end, value); - self.len += 1; - // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. - Ok(&mut *end) - } - } - /// Removes the last element from a vector and returns it, or [`None`] if it /// is empty. /// From 5943d07fb34198b7eb7d70e9df060cfbc445270a Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 5 Nov 2025 10:19:49 -0800 Subject: [PATCH 422/525] Add Allocator proxy impls for Box, Rc, and Arc This adds to the existing proxy impl for &T. --- library/alloc/src/boxed.rs | 52 ++++++++++++++++++++++++++++++++++++++ library/alloc/src/rc.rs | 52 ++++++++++++++++++++++++++++++++++++++ library/alloc/src/sync.rs | 52 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7ad1679b1c82..39b17514a699 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2241,3 +2241,55 @@ impl Error for Box { Error::provide(&**self, request); } } + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Allocator for Box { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate(layout) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate_zeroed(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).deallocate(ptr, layout) } + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).shrink(ptr, old_layout, new_layout) } + } +} diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a24ea6e526c4..d25d7044e000 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -4413,3 +4413,55 @@ impl Drop for UniqueRcUninit { } } } + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Allocator for Rc { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate(layout) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate_zeroed(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).deallocate(ptr, layout) } + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).shrink(ptr, old_layout, new_layout) } + } +} diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 13b5cf23e72d..6618d3f8ad98 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -4780,3 +4780,55 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc { unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; } } + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Allocator for Arc { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate(layout) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate_zeroed(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).deallocate(ptr, layout) } + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).shrink(ptr, old_layout, new_layout) } + } +} From 71e2e0cded7c5f54a4b39a27cdf1268a187e7572 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 5 Nov 2025 11:29:12 -0700 Subject: [PATCH 423/525] Minor fixes to StdNonZeroNumberProvider for gdb While looking at the pretty-printers, I found a few minor oddities in StdNonZeroNumberProvider. First, gdb.Type.fields() already returns a sequence, so there's no need to call list(). Second, it's more idiomatic for the (somewhat misnamed) to_string method to simply return the underlying gdb.Value. This also lets gdb apply whatever formats were passed to `print`, as the new test shows. Third, there's no need to use the field's name when looking up a field in a value, the gdb.Field itself can be used. --- src/etc/gdb_providers.py | 8 ++++---- tests/debuginfo/numeric-types.rs | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index c8f4a32cb17e..2c8959da957b 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -252,15 +252,15 @@ class StdNonZeroNumberProvider(printer_base): def __init__(self, valobj): fields = valobj.type.fields() assert len(fields) == 1 - field = list(fields)[0] + field = fields[0] - inner_valobj = valobj[field.name] + inner_valobj = valobj[field] inner_fields = inner_valobj.type.fields() assert len(inner_fields) == 1 - inner_field = list(inner_fields)[0] + inner_field = inner_fields[0] - self._value = str(inner_valobj[inner_field.name]) + self._value = inner_valobj[inner_field] def to_string(self): return self._value diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs index 9f7ef5c537d2..37b6abf921ea 100644 --- a/tests/debuginfo/numeric-types.rs +++ b/tests/debuginfo/numeric-types.rs @@ -202,6 +202,8 @@ // gdb-command:print nz_usize // gdb-check:[...]$12 = 122 +// gdb-command:print/x nz_i8 +// gdb-check:[...]$13 = 0xb // === LLDB TESTS ================================================================================== From d2b021c340650061c7bd291d8a7e3f3d858ead3b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 5 Nov 2025 11:12:05 -0700 Subject: [PATCH 424/525] Add num_children method to some gdb pretty-printers gdb doesn't have a way to know when an object hasn't yet been initialized, and in this case, if a pretty-printer returns an absurd number of children, this can result in apparent hangs in some modes. This came up specifically with DAP, see this bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=33594 This patch (mostly) addresses this potential issue in the Rust pretty-printers, by adding 'num_children' methods. In particular a method like this is added when the number of children is variable and also relatively easy to compute. (I.e., I didn't attempt the btree printers.) Supplying num_children is good for DAP regardless of the initialization problem, because DAP requires a count of child objects and this is more efficient than enumerating the children, which is gdb's fallback approach. --- src/etc/gdb_providers.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index c8f4a32cb17e..b5c2d26817cd 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -128,6 +128,9 @@ class StdSliceProvider(printer_base): self._data_ptr + index for index in xrange(self._length) ) + def num_children(self): + return self._length + @staticmethod def display_hint(): return "array" @@ -149,6 +152,9 @@ class StdVecProvider(printer_base): self._data_ptr + index for index in xrange(self._length) ) + def num_children(self): + return self._length + @staticmethod def display_hint(): return "array" @@ -177,6 +183,9 @@ class StdVecDequeProvider(printer_base): for index in xrange(self._size) ) + def num_children(self): + return self._size + @staticmethod def display_hint(): return "array" @@ -478,5 +487,11 @@ class StdHashMapProvider(printer_base): else: yield "[{}]".format(index), element[ZERO_FIELD] + def num_children(self): + result = self._size + if self._show_values: + result *= 2 + return result + def display_hint(self): return "map" if self._show_values else "array" From 2c3c82c4c5a2e2b49d1bfac0ebeab6f5d14e5b8f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 3 Nov 2025 20:55:54 +0100 Subject: [PATCH 425/525] Add new `run_make_support::CompletedProcess::assert_ice` method --- src/tools/run-make-support/src/command.rs | 7 +++++++ .../diagnostics-traits-from-duplicate-crates/rmake.rs | 2 +- tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs | 2 +- tests/run-make/rustdoc-test-builder/rmake.rs | 7 +++---- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index b46ddd1d3154..0aeb189bb6a5 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -387,6 +387,13 @@ impl CompletedProcess { self } + /// Checks that `stderr` doesn't contain the Internal Compiler Error message. + #[track_caller] + pub fn assert_not_ice(&self) -> &Self { + self.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug"); + self + } + /// Checks that `stderr` does not contain the regex pattern `unexpected`. #[track_caller] pub fn assert_stderr_not_contains_regex>(&self, unexpected: S) -> &Self { diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs index 5bc0a0c9519f..abd7b8cc8a8a 100644 --- a/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs +++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs @@ -43,5 +43,5 @@ fn main() { .extern_("minibevy", "libminibevy-b.rmeta") .extern_("minirapier", "libminirapier.rmeta") .run_fail() - .assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug"); + .assert_not_ice(); } diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs index 0b1e1948d5fc..d750a36f4453 100644 --- a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs +++ b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs @@ -24,5 +24,5 @@ fn main() { .arg(format!("--include-parts-dir={}", parts_out_dir.display())) .arg("--merge=finalize") .run(); - output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + output.assert_not_ice(); } diff --git a/tests/run-make/rustdoc-test-builder/rmake.rs b/tests/run-make/rustdoc-test-builder/rmake.rs index c243b784eb9b..9aa8143dc1dc 100644 --- a/tests/run-make/rustdoc-test-builder/rmake.rs +++ b/tests/run-make/rustdoc-test-builder/rmake.rs @@ -15,9 +15,8 @@ fn main() { .arg(&absolute_path) .run_fail(); - // We also double-check that we don't have the panic text in the output. + // We check that rustdoc outputs the error correctly... output.assert_stdout_contains("Failed to spawn "); - output.assert_stderr_not_contains("the compiler unexpectedly panicked. this is a bug."); - // Just in case... - output.assert_stdout_not_contains("the compiler unexpectedly panicked. this is a bug."); + // ... and that we didn't panic. + output.assert_not_ice(); } From 71e599b91a8e0f54abed66a4e1223765ad8e933c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 25 Jun 2025 21:56:14 -0500 Subject: [PATCH 426/525] Make named asm_labels lint not trigger on hexagon register spans --- compiler/rustc_lint/src/builtin.rs | 73 ++++++++++++++++++++++ compiler/rustc_lint/src/tests.rs | 27 ++++++++ tests/ui/asm/hexagon-register-pairs.rs | 35 +++++++++++ tests/ui/asm/hexagon-register-pairs.stderr | 21 +++++++ 4 files changed, 156 insertions(+) create mode 100644 tests/ui/asm/hexagon-register-pairs.rs create mode 100644 tests/ui/asm/hexagon-register-pairs.stderr diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index d3468499b4b3..83de7d389231 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2875,6 +2875,71 @@ enum AsmLabelKind { Binary, } +/// Checks if a potential label is actually a Hexagon register span notation. +/// +/// Hexagon assembly uses register span notation like `r1:0`, `V5:4.w`, `p1:0` etc. +/// These follow the pattern: `[letter][digit(s)]:[digit(s)][optional_suffix]` +/// +/// Returns `true` if the string matches a valid Hexagon register span pattern. +pub fn is_hexagon_register_span(possible_label: &str) -> bool { + // Extract the full register span from the context + if let Some(colon_idx) = possible_label.find(':') { + let after_colon = &possible_label[colon_idx + 1..]; + is_hexagon_register_span_impl(&possible_label[..colon_idx], after_colon) + } else { + false + } +} + +/// Helper function for use within the lint when we have statement context. +fn is_hexagon_register_span_context( + possible_label: &str, + statement: &str, + colon_idx: usize, +) -> bool { + // Extract what comes after the colon in the statement + let after_colon_start = colon_idx + 1; + if after_colon_start >= statement.len() { + return false; + } + + // Get the part after the colon, up to the next whitespace or special character + let after_colon_full = &statement[after_colon_start..]; + let after_colon = after_colon_full + .chars() + .take_while(|&c| c.is_ascii_alphanumeric() || c == '.') + .collect::(); + + is_hexagon_register_span_impl(possible_label, &after_colon) +} + +/// Core implementation for checking hexagon register spans. +fn is_hexagon_register_span_impl(before_colon: &str, after_colon: &str) -> bool { + if before_colon.len() < 1 || after_colon.is_empty() { + return false; + } + + let mut chars = before_colon.chars(); + let start = chars.next().unwrap(); + + // Must start with a letter (r, V, p, etc.) + if !start.is_ascii_alphabetic() { + return false; + } + + let rest = &before_colon[1..]; + + // Check if the part after the first letter is all digits and non-empty + if rest.is_empty() || !rest.chars().all(|c| c.is_ascii_digit()) { + return false; + } + + // Check if after colon starts with digits (may have suffix like .w, .h) + let digits_after = after_colon.chars().take_while(|c| c.is_ascii_digit()).collect::(); + + !digits_after.is_empty() +} + impl<'tcx> LateLintPass<'tcx> for AsmLabels { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { if let hir::Expr { @@ -2957,6 +3022,14 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { break 'label_loop; } + // Check for Hexagon register span notation (e.g., "r1:0", "V5:4", "V3:2.w") + // This is valid Hexagon assembly syntax, not a label + if matches!(cx.tcx.sess.asm_arch, Some(InlineAsmArch::Hexagon)) + && is_hexagon_register_span_context(possible_label, statement, idx) + { + break 'label_loop; + } + for c in chars { // Inside a template format arg, any character is permitted for the // purposes of label detection because we assume that it can be diff --git a/compiler/rustc_lint/src/tests.rs b/compiler/rustc_lint/src/tests.rs index f49301b0215d..b3c91583914a 100644 --- a/compiler/rustc_lint/src/tests.rs +++ b/compiler/rustc_lint/src/tests.rs @@ -2,6 +2,7 @@ use rustc_span::{Symbol, create_default_session_globals_then}; +use crate::builtin::is_hexagon_register_span; use crate::levels::parse_lint_and_tool_name; #[test] @@ -27,3 +28,29 @@ fn parse_lint_multiple_path() { ) }); } + +#[test] +fn test_hexagon_register_span_patterns() { + // Valid Hexagon register span patterns + assert!(is_hexagon_register_span("r1:0")); + assert!(is_hexagon_register_span("r15:14")); + assert!(is_hexagon_register_span("V5:4")); + assert!(is_hexagon_register_span("V3:2")); + assert!(is_hexagon_register_span("V5:4.w")); + assert!(is_hexagon_register_span("V3:2.h")); + assert!(is_hexagon_register_span("r99:98")); + assert!(is_hexagon_register_span("V123:122.whatever")); + + // Invalid patterns - these should be treated as potential labels + assert!(!is_hexagon_register_span("label1")); + assert!(!is_hexagon_register_span("foo:")); + assert!(!is_hexagon_register_span(":0")); + assert!(!is_hexagon_register_span("r:0")); // missing digits before colon + assert!(!is_hexagon_register_span("r1:")); // missing digits after colon + assert!(!is_hexagon_register_span("r1:a")); // non-digit after colon + assert!(!is_hexagon_register_span("1:0")); // starts with digit, not letter + assert!(!is_hexagon_register_span("r1")); // no colon + assert!(!is_hexagon_register_span("r")); // too short + assert!(!is_hexagon_register_span("")); // empty + assert!(!is_hexagon_register_span("ra:0")); // letter in first digit group +} diff --git a/tests/ui/asm/hexagon-register-pairs.rs b/tests/ui/asm/hexagon-register-pairs.rs new file mode 100644 index 000000000000..f0f77738ac83 --- /dev/null +++ b/tests/ui/asm/hexagon-register-pairs.rs @@ -0,0 +1,35 @@ +//@ add-core-stubs +//@ compile-flags: --target hexagon-unknown-linux-musl -C target-feature=+hvx-length128b +//@ needs-llvm-components: hexagon +//@ ignore-backends: gcc + +#![feature(no_core, asm_experimental_arch)] +#![crate_type = "lib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +fn test_register_spans() { + unsafe { + // These are valid Hexagon register span notations, not labels + // Should NOT trigger the named labels lint + + // General register pairs + asm!("r1:0 = memd(r29+#0)", lateout("r0") _, lateout("r1") _); + asm!("r3:2 = combine(#1, #0)", lateout("r2") _, lateout("r3") _); + asm!("r15:14 = memd(r30+#8)", lateout("r14") _, lateout("r15") _); + asm!("memd(r29+#0) = r5:4", in("r4") 0u32, in("r5") 0u32); + + // These patterns look like register spans but test different edge cases + // All should NOT trigger the lint as they match valid hexagon register syntax patterns + asm!("V5:4 = vaddw(v1:0, v1:0)", options(nostack)); // Uppercase V register pair + asm!("v1:0.w = vsub(v1:0.w,v1:0.w):sat", options(nostack)); // Lowercase v with suffix + + // Mixed with actual labels should still trigger for the labels + asm!("label1: r7:6 = combine(#2, #3)"); //~ ERROR avoid using named labels + + // Regular labels should still trigger + asm!("hexagon_label: nop"); //~ ERROR avoid using named labels + } +} diff --git a/tests/ui/asm/hexagon-register-pairs.stderr b/tests/ui/asm/hexagon-register-pairs.stderr new file mode 100644 index 000000000000..6de55c34a8bc --- /dev/null +++ b/tests/ui/asm/hexagon-register-pairs.stderr @@ -0,0 +1,21 @@ +error: avoid using named labels in inline assembly + --> $DIR/hexagon-register-pairs.rs:30:15 + | +LL | asm!("label1: r7:6 = combine(#2, #3)"); + | ^^^^^^ + | + = 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 + = note: `#[deny(named_asm_labels)]` on by default + +error: avoid using named labels in inline assembly + --> $DIR/hexagon-register-pairs.rs:33:15 + | +LL | asm!("hexagon_label: nop"); + | ^^^^^^^^^^^^^ + | + = 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 + +error: aborting due to 2 previous errors + From 0717a3929fe7cb3e131380aaed0b0db29d3ddbf0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 5 Nov 2025 14:37:38 -0800 Subject: [PATCH 427/525] Fix broken qemu-cskyv2 link The link had a stray character that generated an invalid link. --- .../rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md index e69d606ccd2f..bd4cd3df7dae 100644 --- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md +++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md @@ -65,7 +65,7 @@ To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-csky To use: -* Install `qemu-cskyv2` (If you don't already have a qemu, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1689324918932/xuantie-qemu-x86_64-Ubuntu-18.04-20230714-0202.tar.gz"), and unpack it into a directory.) +* Install `qemu-cskyv2` (If you don't already have a qemu, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1689324918932/xuantie-qemu-x86_64-Ubuntu-18.04-20230714-0202.tar.gz), and unpack it into a directory.) * Link your built toolchain via: * `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2` * Create a test program From 55b0125d16bc6a5195fc722d45a528c76dab93e1 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 6 Nov 2025 09:41:16 +0800 Subject: [PATCH 428/525] Add regression test for ice --- tests/ui/pattern/const-error-ice-issue-148542.rs | 13 +++++++++++++ .../ui/pattern/const-error-ice-issue-148542.stderr | 14 ++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/ui/pattern/const-error-ice-issue-148542.rs create mode 100644 tests/ui/pattern/const-error-ice-issue-148542.stderr diff --git a/tests/ui/pattern/const-error-ice-issue-148542.rs b/tests/ui/pattern/const-error-ice-issue-148542.rs new file mode 100644 index 000000000000..3c3645dc2c01 --- /dev/null +++ b/tests/ui/pattern/const-error-ice-issue-148542.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +// Regression test for #148542 +// Ensure we don't ICE with "Invalid `ConstKind` for `const_to_pat`: {const error}" + +fn foo() where &str:, { + //~^ ERROR `&` without an explicit lifetime name cannot be used here + match 42_u8 { + -10.. => {} + } +} + +fn main() {} diff --git a/tests/ui/pattern/const-error-ice-issue-148542.stderr b/tests/ui/pattern/const-error-ice-issue-148542.stderr new file mode 100644 index 000000000000..ee39ba4feb09 --- /dev/null +++ b/tests/ui/pattern/const-error-ice-issue-148542.stderr @@ -0,0 +1,14 @@ +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-error-ice-issue-148542.rs:6:16 + | +LL | fn foo() where &str:, { + | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here + | +LL | fn foo() where for<'a> &'a str:, { + | +++++++ ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0637`. From 54df8dae294fde0dc370abb66db55a3a10b64e6e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 5 Nov 2025 19:43:29 -0600 Subject: [PATCH 429/525] CI fixes after recent rebase changes --- tests/ui/asm/hexagon-register-pairs.rs | 4 +++- tests/ui/asm/hexagon-register-pairs.stderr | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/ui/asm/hexagon-register-pairs.rs b/tests/ui/asm/hexagon-register-pairs.rs index f0f77738ac83..75f296077845 100644 --- a/tests/ui/asm/hexagon-register-pairs.rs +++ b/tests/ui/asm/hexagon-register-pairs.rs @@ -1,4 +1,4 @@ -//@ add-core-stubs +//@ add-minicore //@ compile-flags: --target hexagon-unknown-linux-musl -C target-feature=+hvx-length128b //@ needs-llvm-components: hexagon //@ ignore-backends: gcc @@ -7,6 +7,8 @@ #![crate_type = "lib"] #![no_core] +//~? WARN unstable feature specified for `-Ctarget-feature`: `hvx-length128b` + extern crate minicore; use minicore::*; diff --git a/tests/ui/asm/hexagon-register-pairs.stderr b/tests/ui/asm/hexagon-register-pairs.stderr index 6de55c34a8bc..c5974ba01f17 100644 --- a/tests/ui/asm/hexagon-register-pairs.stderr +++ b/tests/ui/asm/hexagon-register-pairs.stderr @@ -1,5 +1,9 @@ +warning: unstable feature specified for `-Ctarget-feature`: `hvx-length128b` + | + = note: this feature is not stably supported; its behavior can change in the future + error: avoid using named labels in inline assembly - --> $DIR/hexagon-register-pairs.rs:30:15 + --> $DIR/hexagon-register-pairs.rs:32:15 | LL | asm!("label1: r7:6 = combine(#2, #3)"); | ^^^^^^ @@ -9,7 +13,7 @@ LL | asm!("label1: r7:6 = combine(#2, #3)"); = note: `#[deny(named_asm_labels)]` on by default error: avoid using named labels in inline assembly - --> $DIR/hexagon-register-pairs.rs:33:15 + --> $DIR/hexagon-register-pairs.rs:35:15 | LL | asm!("hexagon_label: nop"); | ^^^^^^^^^^^^^ @@ -17,5 +21,5 @@ LL | asm!("hexagon_label: nop"); = 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 -error: aborting due to 2 previous errors +error: aborting due to 2 previous errors; 1 warning emitted From f3fe6bad2fceceabfc309f981f36ee21d8896e79 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 5 Nov 2025 18:10:07 -0800 Subject: [PATCH 430/525] Fix rust-by-example spanish translation A spanish translation was added in https://github.com/rust-lang/rust-by-example/pull/1910, but the upstream integration was never added. --- src/bootstrap/src/core/build_steps/doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 6622aae069d5..020ee8527e99 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -73,7 +73,7 @@ book!( EditionGuide, "src/doc/edition-guide", "edition-guide", &[]; EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[]; Nomicon, "src/doc/nomicon", "nomicon", &[]; - RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja", "zh"]; + RustByExample, "src/doc/rust-by-example", "rust-by-example", &["es", "ja", "zh"]; RustdocBook, "src/doc/rustdoc", "rustdoc", &[]; StyleGuide, "src/doc/style-guide", "style-guide", &[]; ); From a9795db06881c32f7804f4f8faf754def364a809 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 6 Nov 2025 11:18:38 +0800 Subject: [PATCH 431/525] Fix ICE from async closure variance --- compiler/rustc_middle/src/ty/diagnostics.rs | 1 + ...ice-async-closure-variance-issue-148488.rs | 12 +++++++++ ...async-closure-variance-issue-148488.stderr | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs create mode 100644 tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index b9a6f67ab0dc..2e64fc290fcc 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -698,6 +698,7 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { } Closure(..) + | CoroutineClosure(..) | FnDef(..) | Infer(..) | Coroutine(..) diff --git a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs new file mode 100644 index 000000000000..f5926e19a150 --- /dev/null +++ b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs @@ -0,0 +1,12 @@ +//@ edition: 2024 + +struct T<'g>(); +//~^ ERROR lifetime parameter `'g` is never used + +fn ord
() -> _ { + //~^ WARN type parameter `a` should have an upper camel case name + //~| ERROR the placeholder `_` is not allowed within types on item signatures for return types + async || {} +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr new file mode 100644 index 000000000000..ca98d210579f --- /dev/null +++ b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr @@ -0,0 +1,26 @@ +warning: type parameter `a` should have an upper camel case name + --> $DIR/ice-async-closure-variance-issue-148488.rs:6:8 + | +LL | fn ord() -> _ { + | ^ help: convert the identifier to upper camel case: `A` + | + = note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/ice-async-closure-variance-issue-148488.rs:6:16 + | +LL | fn ord() -> _ { + | ^ not allowed in type signatures + +error[E0392]: lifetime parameter `'g` is never used + --> $DIR/ice-async-closure-variance-issue-148488.rs:3:10 + | +LL | struct T<'g>(); + | ^^ unused lifetime parameter + | + = help: consider removing `'g`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0121, E0392. +For more information about an error, try `rustc --explain E0121`. From 4384d431dd581a74d650d1accbf737cfee934c63 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 6 Nov 2025 04:55:11 +0000 Subject: [PATCH 432/525] Prepare for merging from rust-lang/rust This updates the rust-version file to 401ae55427522984e4a89c37cff6562a4ddcf6b7. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 036282b12f5d..5bdb8bd8369f 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -5f9dd05862d2e4bceb3be1031b6c936e35671501 +401ae55427522984e4a89c37cff6562a4ddcf6b7 From 3d08696807fbd42c6be092e5b798b261a35eff77 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 6 Nov 2025 05:03:41 +0000 Subject: [PATCH 433/525] fmt --- src/tools/miri/src/shims/foreign_items.rs | 5 +---- src/tools/miri/src/shims/x86/mod.rs | 4 +--- .../fail/intrinsics/simd_masked_load_element_misaligned.rs | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index a92d8f87af81..bffe633f7797 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -800,10 +800,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Target-specific shims name if name.starts_with("llvm.x86.") - && matches!( - this.tcx.sess.target.arch, - Arch::X86 | Arch::X86_64 - ) => + && matches!(this.tcx.sess.target.arch, Arch::X86 | Arch::X86_64) => { return shims::x86::EvalContextExt::emulate_x86_intrinsic( this, link_name, abi, args, dest, diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 016cb762cece..91893737b060 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -42,9 +42,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarry-u32-addcarry-u64.html // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html "addcarry.32" | "addcarry.64" | "subborrow.32" | "subborrow.64" => { - if unprefixed_name.ends_with("64") - && this.tcx.sess.target.arch != Arch::X86_64 - { + if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != Arch::X86_64 { return interp_ok(EmulateItemResult::NotSupported); } diff --git a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs index 3b5e389cf27e..47a51dbbab51 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs +++ b/src/tools/miri/tests/fail/intrinsics/simd_masked_load_element_misaligned.rs @@ -6,7 +6,7 @@ use std::simd::*; fn main() { unsafe { let buf = [0u32; 5]; - //~v ERROR: accessing memory with alignment + //~v ERROR: accessing memory with alignment simd_masked_load::<_, _, _, { SimdAlign::Element }>( i32x4::splat(-1), // This is not i32-aligned From c8b2a9af2b10295436828e6678c466536bada981 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 5 Nov 2025 23:37:51 -0700 Subject: [PATCH 434/525] rustdoc-search: remove broken index special case --- src/librustdoc/html/render/search_index.rs | 35 ++++++++---------- tests/rustdoc-js/auxiliary/emptytype.rs | 41 ++++++++++++++++++++++ tests/rustdoc-js/empty-type.js | 8 +++++ tests/rustdoc-js/empty-type.rs | 8 +++++ 4 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 tests/rustdoc-js/auxiliary/emptytype.rs create mode 100644 tests/rustdoc-js/empty-type.js create mode 100644 tests/rustdoc-js/empty-type.rs diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 96e941b598ad..9c072eed51ae 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1051,28 +1051,21 @@ impl Serialize for TypeData { where S: Serializer, { - if self.search_unbox - || !self.inverted_function_inputs_index.is_empty() - || !self.inverted_function_output_index.is_empty() - { - let mut seq = serializer.serialize_seq(None)?; - let mut buf = Vec::new(); - encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf); - let mut serialized_result = Vec::new(); - stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); - seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; - buf.clear(); - serialized_result.clear(); - encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf); - stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); - seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; - if self.search_unbox { - seq.serialize_element(&1)?; - } - seq.end() - } else { - None::<()>.serialize(serializer) + let mut seq = serializer.serialize_seq(None)?; + let mut buf = Vec::new(); + encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf); + let mut serialized_result = Vec::new(); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; + buf.clear(); + serialized_result.clear(); + encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; + if self.search_unbox { + seq.serialize_element(&1)?; } + seq.end() } } diff --git a/tests/rustdoc-js/auxiliary/emptytype.rs b/tests/rustdoc-js/auxiliary/emptytype.rs new file mode 100644 index 000000000000..2a06b4ec9f8c --- /dev/null +++ b/tests/rustdoc-js/auxiliary/emptytype.rs @@ -0,0 +1,41 @@ +// https://github.com/rust-lang/rust/issues/148431 + +// This test is designed to hit a case where, thanks to the +// recursion limit, the where clause gets generated, but not +// used, because we run out of fuel. +// +// This results in a reverse index with nothing in it, which +// used to crash when we parsed it. +pub fn foobar1, B: T2, C: T3, D: T4>(a: A) {} + +pub trait T1 {} +pub trait T2 {} +pub trait T3 {} +pub trait T4 {} + +// foobar1 is the version that worked at the time this test was written +// the rest are here to try to make the test at least a little more +// robust, in the sense that it actually tests the code and isn't magically +// fixed by the recursion limit changing +pub fn foobar2, B: U2, C: U3, D: U4, E: U5>(a: A) {} + +pub trait U1 {} +pub trait U2 {} +pub trait U3 {} +pub trait U4 {} +pub trait U5 {} + +pub fn foobar3, B: V2, C: V3, D: V4, E: V5, F: V6>(a: A) {} + +pub trait V1 {} +pub trait V2 {} +pub trait V3 {} +pub trait V4 {} +pub trait V5 {} +pub trait V6 {} + +pub fn foobar4, B: W2, C: W3>(a: A) {} + +pub trait W1 {} +pub trait W2 {} +pub trait W3 {} diff --git a/tests/rustdoc-js/empty-type.js b/tests/rustdoc-js/empty-type.js new file mode 100644 index 000000000000..e4c8f9954cb7 --- /dev/null +++ b/tests/rustdoc-js/empty-type.js @@ -0,0 +1,8 @@ +const EXPECTED = [ + { + query: 'baz', + others: [ + { name: 'baz' } + ], + }, +]; diff --git a/tests/rustdoc-js/empty-type.rs b/tests/rustdoc-js/empty-type.rs new file mode 100644 index 000000000000..87ea73709b6b --- /dev/null +++ b/tests/rustdoc-js/empty-type.rs @@ -0,0 +1,8 @@ +//@ aux-crate:emptytype=emptytype.rs +//@ compile-flags: --extern emptytype +//@ aux-build:emptytype.rs +//@ build-aux-docs + +extern crate emptytype; + +pub fn baz() {} From 360b38cceb1d20cffb00057be2078cdf7fa0b25a Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Sun, 31 Aug 2025 19:49:40 -0700 Subject: [PATCH 435/525] Fix device code generation, to account for an implicit dyn_ptr argument. --- compiler/rustc_codegen_llvm/src/back/lto.rs | 3 +- compiler/rustc_codegen_llvm/src/back/write.rs | 70 ++++++++++++++++++- .../src/builder/gpu_offload.rs | 3 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 6 ++ compiler/rustc_codegen_llvm/src/type_.rs | 5 ++ compiler/rustc_codegen_ssa/src/back/write.rs | 2 + .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 24 +++++++ compiler/rustc_target/src/callconv/mod.rs | 1 + compiler/rustc_target/src/spec/json.rs | 3 + compiler/rustc_target/src/spec/mod.rs | 8 +++ .../src/spec/targets/amdgcn_amd_amdhsa.rs | 3 + .../src/spec/targets/nvptx64_nvidia_cuda.rs | 3 + 12 files changed, 129 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 02b50fa8a697..b820b992105f 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -616,7 +616,8 @@ pub(crate) fn run_pass_manager( write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage); } - if enable_gpu && !thin { + // Here we only handle the GPU host (=cpu) code. + if enable_gpu && !thin && !cgcx.target_is_like_gpu { let cx = SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size); crate::builder::gpu_offload::handle_gpu_code(cgcx, &cx); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b582d587d9f8..5b71d6b6ba8e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -43,7 +43,7 @@ use crate::errors::{ use crate::llvm::diagnostic::OptimizationDiagnosticKind::*; use crate::llvm::{self, DiagnosticInfo}; use crate::type_::llvm_type_ptr; -use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util}; +use crate::{LlvmCodegenBackend, ModuleLlvm, SimpleCx, base, common, llvm_util}; pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> ! { match llvm::last_error() { @@ -645,6 +645,74 @@ pub(crate) unsafe fn llvm_optimize( None }; + fn handle_offload<'ll>(cx: &'ll SimpleCx<'_>, old_fn: &llvm::Value) { + let old_fn_ty = cx.get_type_of_global(old_fn); + let old_param_types = cx.func_params_types(old_fn_ty); + let old_param_count = old_param_types.len(); + if old_param_count == 0 { + return; + } + + let first_param = llvm::get_param(old_fn, 0); + let c_name = llvm::get_value_name(first_param); + let first_arg_name = str::from_utf8(&c_name).unwrap(); + // We might call llvm_optimize (and thus this code) multiple times on the same IR, + // but we shouldn't add this helper ptr multiple times. + // FIXME(offload): This could break if the user calls his first argument `dyn_ptr`. + if first_arg_name == "dyn_ptr" { + return; + } + + // Create the new parameter list, with ptr as the first argument + let mut new_param_types = Vec::with_capacity(old_param_count as usize + 1); + new_param_types.push(cx.type_ptr()); + new_param_types.extend(old_param_types); + + // Create the new function type + let ret_ty = unsafe { llvm::LLVMGetReturnType(old_fn_ty) }; + let new_fn_ty = cx.type_func(&new_param_types, ret_ty); + + // Create the new function, with a temporary .offload name to avoid a name collision. + let old_fn_name = String::from_utf8(llvm::get_value_name(old_fn)).unwrap(); + let new_fn_name = format!("{}.offload", &old_fn_name); + let new_fn = cx.add_func(&new_fn_name, new_fn_ty); + let a0 = llvm::get_param(new_fn, 0); + llvm::set_value_name(a0, CString::new("dyn_ptr").unwrap().as_bytes()); + + // Here we map the old arguments to the new arguments, with an offset of 1 to make sure + // that we don't use the newly added `%dyn_ptr`. + unsafe { + llvm::LLVMRustOffloadMapper(cx.llmod(), old_fn, new_fn); + } + + llvm::set_linkage(new_fn, llvm::get_linkage(old_fn)); + llvm::set_visibility(new_fn, llvm::get_visibility(old_fn)); + + // Replace all uses of old_fn with new_fn (RAUW) + unsafe { + llvm::LLVMReplaceAllUsesWith(old_fn, new_fn); + } + let name = llvm::get_value_name(old_fn); + unsafe { + llvm::LLVMDeleteFunction(old_fn); + } + // Now we can re-use the old name, without name collision. + llvm::set_value_name(new_fn, &name); + } + + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + let cx = + SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size); + // For now we only support up to 10 kernels named kernel_0 ... kernel_9, a follow-up PR is + // introducing a proper offload intrinsic to solve this limitation. + for num in 0..9 { + let name = format!("kernel_{num}"); + if let Some(kernel) = cx.get_function(&name) { + handle_offload(&cx, kernel); + } + } + } + let mut llvm_profiler = cgcx .prof .llvm_recording_enabled() diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 3d55064ea130..5c2f8f700627 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -19,6 +19,9 @@ pub(crate) fn handle_gpu_code<'ll>( let mut memtransfer_types = vec![]; let mut region_ids = vec![]; let offload_entry_ty = TgtOffloadEntry::new_decl(&cx); + // This is a temporary hack, we only search for kernel_0 to kernel_9 functions. + // There is a draft PR in progress which will introduce a proper offload intrinsic to remove + // this limitation. for num in 0..9 { let kernel = cx.get_function(&format!("kernel_{num}")); if let Some(kernel) = kernel { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 9a391d57d6fb..74d268ad5dd2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1127,6 +1127,11 @@ unsafe extern "C" { // Operations on functions pub(crate) fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint); + pub(crate) fn LLVMAddFunction<'a>( + Mod: &'a Module, + Name: *const c_char, + FunctionTy: &'a Type, + ) -> &'a Value; pub(crate) fn LLVMDeleteFunction(Fn: &Value); // Operations about llvm intrinsics @@ -2017,6 +2022,7 @@ unsafe extern "C" { ) -> &Attribute; // Operations on functions + pub(crate) fn LLVMRustOffloadMapper<'a>(M: &'a Module, Fn: &'a Value, Fn: &'a Value); pub(crate) fn LLVMRustGetOrInsertFunction<'a>( M: &'a Module, Name: *const c_char, diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 81bb70c95879..55f053f4fad3 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -68,6 +68,11 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMVectorType(ty, len as c_uint) } } + pub(crate) fn add_func(&self, name: &str, ty: &'ll Type) -> &'ll Value { + let name = SmallCStr::new(name); + unsafe { llvm::LLVMAddFunction(self.llmod(), name.as_ptr(), ty) } + } + pub(crate) fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { unsafe { let n_args = llvm::LLVMCountParamTypes(ty) as usize; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 368a2e307bb2..edaf65bdb922 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -342,6 +342,7 @@ pub struct CodegenContext { pub target_arch: String, pub target_is_like_darwin: bool, pub target_is_like_aix: bool, + pub target_is_like_gpu: bool, pub split_debuginfo: rustc_target::spec::SplitDebuginfo, pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, @@ -1309,6 +1310,7 @@ fn start_executing_work( target_arch: tcx.sess.target.arch.to_string(), target_is_like_darwin: tcx.sess.target.is_like_darwin, target_is_like_aix: tcx.sess.target.is_like_aix, + target_is_like_gpu: tcx.sess.target.is_like_gpu, split_debuginfo: tcx.sess.split_debuginfo(), split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind, parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 2d87ea232eea..df811ddd8d4f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -35,6 +35,8 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/ValueMapper.h" #include // for raw `write` in the bad-alloc handler @@ -142,6 +144,28 @@ extern "C" void LLVMRustPrintStatistics(RustStringRef OutBuf) { llvm::PrintStatistics(OS); } +extern "C" void LLVMRustOffloadMapper(LLVMModuleRef M, LLVMValueRef OldFn, + LLVMValueRef NewFn) { + llvm::Module *module = llvm::unwrap(M); + llvm::Function *oldFn = llvm::unwrap(OldFn); + llvm::Function *newFn = llvm::unwrap(NewFn); + + // Map old arguments to new arguments. We skip the first dyn_ptr argument, + // since it can't be used directly by user code. + llvm::ValueToValueMapTy vmap; + auto newArgIt = newFn->arg_begin(); + newArgIt->setName("dyn_ptr"); + ++newArgIt; // skip %dyn_ptr + for (auto &oldArg : oldFn->args()) { + vmap[&oldArg] = &*newArgIt++; + } + + llvm::SmallVector returns; + llvm::CloneFunctionInto(newFn, oldFn, vmap, + llvm::CloneFunctionChangeType::LocalChangesOnly, + returns); +} + extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name, size_t NameLen) { return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen))); diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 43e1ca3ef9ce..147b17b24bb5 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -578,6 +578,7 @@ impl RiscvInterruptKind { /// /// The signature represented by this type may not match the MIR function signature. /// Certain attributes, like `#[track_caller]` can introduce additional arguments, which are present in [`FnAbi`], but not in `FnSig`. +/// The std::offload module also adds an addition dyn_ptr argument to the GpuKernel ABI. /// While this difference is rarely relevant, it should still be kept in mind. /// /// I will do my best to describe this structure, but these diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index c25628c3939d..563ba0c4131a 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -147,6 +147,7 @@ impl Target { forward!(is_like_darwin); forward!(is_like_solaris); forward!(is_like_windows); + forward!(is_like_gpu); forward!(is_like_msvc); forward!(is_like_wasm); forward!(is_like_android); @@ -337,6 +338,7 @@ impl ToJson for Target { target_option_val!(is_like_darwin); target_option_val!(is_like_solaris); target_option_val!(is_like_windows); + target_option_val!(is_like_gpu); target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); target_option_val!(is_like_android); @@ -556,6 +558,7 @@ struct TargetSpecJson { is_like_darwin: Option, is_like_solaris: Option, is_like_windows: Option, + is_like_gpu: Option, is_like_msvc: Option, is_like_wasm: Option, is_like_android: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 74048d351802..5d8ef47efe31 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2180,6 +2180,8 @@ pub struct TargetOptions { /// Also indicates whether to use Apple-specific ABI changes, such as extending function /// parameters to 32-bits. pub is_like_darwin: bool, + /// Whether the target is a GPU (e.g. NVIDIA, AMD, Intel). + pub is_like_gpu: bool, /// Whether the target toolchain is like Solaris's. /// Only useful for compiling against Illumos/Solaris, /// as they have a different set of linker flags. Defaults to false. @@ -2583,6 +2585,7 @@ impl Default for TargetOptions { abi_return_struct_as_int: false, is_like_aix: false, is_like_darwin: false, + is_like_gpu: false, is_like_solaris: false, is_like_windows: false, is_like_msvc: false, @@ -2748,6 +2751,11 @@ impl Target { self.os == "solaris" || self.os == "illumos", "`is_like_solaris` must be set if and only if `os` is `solaris` or `illumos`" ); + check_eq!( + self.is_like_gpu, + self.arch == Arch::Nvptx64 || self.arch == Arch::AmdGpu, + "`is_like_gpu` must be set if and only if `target` is `nvptx64` or `amdgcn`" + ); check_eq!( self.is_like_windows, self.os == "windows" || self.os == "uefi" || self.os == "cygwin", diff --git a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs index 07772c757337..d80a3ffd0c7f 100644 --- a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs +++ b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs @@ -34,6 +34,9 @@ pub(crate) fn target() -> Target { no_builtins: true, simd_types_indirect: false, + // Clearly a GPU + is_like_gpu: true, + // Allow `cdylib` crate type. dynamic_linking: true, only_cdylib: true, diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index ac2d31a0d61a..5bbf40b5fadd 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -42,6 +42,9 @@ pub(crate) fn target() -> Target { // Let the `ptx-linker` to handle LLVM lowering into MC / assembly. obj_is_bitcode: true, + // Clearly a GPU + is_like_gpu: true, + // Convenient and predicable naming scheme. dll_prefix: "".into(), dll_suffix: ".ptx".into(), From ff5440e3fa03ca14787d76cd835f84c1d138ae95 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 6 Nov 2025 17:34:48 +0800 Subject: [PATCH 436/525] Fix incorrect precedence caused by range expression --- compiler/rustc_hir_typeck/src/expr.rs | 8 ++++++++ .../feature-gate-new_range.stderr | 12 ++++++------ .../into-convert-range-issue-148344.fixed | 15 +++++++++++++++ .../into-convert-range-issue-148344.rs | 15 +++++++++++++++ .../into-convert-range-issue-148344.stderr | 18 ++++++++++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 tests/ui/suggestions/into-convert-range-issue-148344.fixed create mode 100644 tests/ui/suggestions/into-convert-range-issue-148344.rs create mode 100644 tests/ui/suggestions/into-convert-range-issue-148344.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 78b16ffee81c..e533ee78cc82 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -77,6 +77,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } false }; + + // Special case: range expressions are desugared to struct literals in HIR, + // so they would normally return `Unambiguous` precedence in expr.precedence. + // we should return `Range` precedence for correct parenthesization in suggestions. + if is_range_literal(expr) { + return ExprPrecedence::Range; + } + expr.precedence(&has_attr) } diff --git a/tests/ui/feature-gates/feature-gate-new_range.stderr b/tests/ui/feature-gates/feature-gate-new_range.stderr index c4241390418b..b7f70d30bfa0 100644 --- a/tests/ui/feature-gates/feature-gate-new_range.stderr +++ b/tests/ui/feature-gates/feature-gate-new_range.stderr @@ -10,8 +10,8 @@ LL | let a: core::range::RangeFrom = 1..; found struct `std::ops::RangeFrom<{integer}>` help: call `Into::into` on this expression to convert `std::ops::RangeFrom<{integer}>` into `std::range::RangeFrom` | -LL | let a: core::range::RangeFrom = 1...into(); - | +++++++ +LL | let a: core::range::RangeFrom = (1..).into(); + | + ++++++++ error[E0308]: mismatched types --> $DIR/feature-gate-new_range.rs:6:37 @@ -25,8 +25,8 @@ LL | let b: core::range::Range = 2..3; found struct `std::ops::Range<{integer}>` help: call `Into::into` on this expression to convert `std::ops::Range<{integer}>` into `std::range::Range` | -LL | let b: core::range::Range = 2..3.into(); - | +++++++ +LL | let b: core::range::Range = (2..3).into(); + | + ++++++++ error[E0308]: mismatched types --> $DIR/feature-gate-new_range.rs:8:46 @@ -40,8 +40,8 @@ LL | let c: core::range::RangeInclusive = 4..=5; found struct `std::ops::RangeInclusive<{integer}>` help: call `Into::into` on this expression to convert `std::ops::RangeInclusive<{integer}>` into `std::range::RangeInclusive` | -LL | let c: core::range::RangeInclusive = 4..=5.into(); - | +++++++ +LL | let c: core::range::RangeInclusive = (4..=5).into(); + | + ++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/into-convert-range-issue-148344.fixed b/tests/ui/suggestions/into-convert-range-issue-148344.fixed new file mode 100644 index 000000000000..5bf0e8e3063b --- /dev/null +++ b/tests/ui/suggestions/into-convert-range-issue-148344.fixed @@ -0,0 +1,15 @@ +//@ run-rustfix +use std::ops::Range; + +struct Strange; +impl From> for Strange { + fn from(_: Range) -> Self { + Self + } +} + +fn main() { + let _: Strange = (0..10).into(); + //~^ ERROR mismatched types + //~| HELP call `Into::into` on this expression +} diff --git a/tests/ui/suggestions/into-convert-range-issue-148344.rs b/tests/ui/suggestions/into-convert-range-issue-148344.rs new file mode 100644 index 000000000000..aa1df2d4103a --- /dev/null +++ b/tests/ui/suggestions/into-convert-range-issue-148344.rs @@ -0,0 +1,15 @@ +//@ run-rustfix +use std::ops::Range; + +struct Strange; +impl From> for Strange { + fn from(_: Range) -> Self { + Self + } +} + +fn main() { + let _: Strange = 0..10; + //~^ ERROR mismatched types + //~| HELP call `Into::into` on this expression +} diff --git a/tests/ui/suggestions/into-convert-range-issue-148344.stderr b/tests/ui/suggestions/into-convert-range-issue-148344.stderr new file mode 100644 index 000000000000..ce5342f5789b --- /dev/null +++ b/tests/ui/suggestions/into-convert-range-issue-148344.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/into-convert-range-issue-148344.rs:12:22 + | +LL | let _: Strange = 0..10; + | ------- ^^^^^ expected `Strange`, found `Range<{integer}>` + | | + | expected due to this + | + = note: expected struct `Strange` + found struct `std::ops::Range<{integer}>` +help: call `Into::into` on this expression to convert `std::ops::Range<{integer}>` into `Strange` + | +LL | let _: Strange = (0..10).into(); + | + ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From d956fa10ce7cf10eeb5faa523f0f740dcc1f3766 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Wed, 5 Nov 2025 19:19:36 +0900 Subject: [PATCH 437/525] style: Update doctests for `highest_one` and `lowest_one` Use binary literals instead of hex literals. --- library/core/src/num/int_macros.rs | 16 ++++++++-------- library/core/src/num/nonzero.rs | 12 ++++++------ library/core/src/num/uint_macros.rs | 16 ++++++++-------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 16f85c71403a..7d395eb78034 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -217,10 +217,10 @@ macro_rules! int_impl { /// ``` /// #![feature(int_lowest_highest_one)] /// - #[doc = concat!("assert_eq!(0x0_", stringify!($SelfT), ".highest_one(), None);")] - #[doc = concat!("assert_eq!(0x1_", stringify!($SelfT), ".highest_one(), Some(0));")] - #[doc = concat!("assert_eq!(0x10_", stringify!($SelfT), ".highest_one(), Some(4));")] - #[doc = concat!("assert_eq!(0x1f_", stringify!($SelfT), ".highest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".highest_one(), None);")] + #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".highest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".highest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".highest_one(), Some(4));")] /// ``` #[unstable(feature = "int_lowest_highest_one", issue = "145203")] #[must_use = "this returns the result of the operation, \ @@ -238,10 +238,10 @@ macro_rules! int_impl { /// ``` /// #![feature(int_lowest_highest_one)] /// - #[doc = concat!("assert_eq!(0x0_", stringify!($SelfT), ".lowest_one(), None);")] - #[doc = concat!("assert_eq!(0x1_", stringify!($SelfT), ".lowest_one(), Some(0));")] - #[doc = concat!("assert_eq!(0x10_", stringify!($SelfT), ".lowest_one(), Some(4));")] - #[doc = concat!("assert_eq!(0x1f_", stringify!($SelfT), ".lowest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".lowest_one(), None);")] + #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".lowest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".lowest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".lowest_one(), Some(0));")] /// ``` #[unstable(feature = "int_lowest_highest_one", issue = "145203")] #[must_use = "this returns the result of the operation, \ diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index efb0665b7f46..92bca0eebfd9 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -708,9 +708,9 @@ macro_rules! nonzero_integer { /// # use core::num::NonZero; /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x1)?.highest_one(), 0);")] - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x10)?.highest_one(), 4);")] - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x1f)?.highest_one(), 4);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1)?.highest_one(), 0);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1_0000)?.highest_one(), 4);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1_1111)?.highest_one(), 4);")] /// # Some(()) /// # } /// ``` @@ -732,9 +732,9 @@ macro_rules! nonzero_integer { /// # use core::num::NonZero; /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x1)?.lowest_one(), 0);")] - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x10)?.lowest_one(), 4);")] - #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0x1f)?.lowest_one(), 0);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1)?.lowest_one(), 0);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1_0000)?.lowest_one(), 4);")] + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1_1111)?.lowest_one(), 0);")] /// # Some(()) /// # } /// ``` diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 1efc551d670a..2996e7b00da4 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -272,10 +272,10 @@ macro_rules! uint_impl { /// ``` /// #![feature(int_lowest_highest_one)] /// - #[doc = concat!("assert_eq!(0x0_", stringify!($SelfT), ".highest_one(), None);")] - #[doc = concat!("assert_eq!(0x1_", stringify!($SelfT), ".highest_one(), Some(0));")] - #[doc = concat!("assert_eq!(0x10_", stringify!($SelfT), ".highest_one(), Some(4));")] - #[doc = concat!("assert_eq!(0x1f_", stringify!($SelfT), ".highest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".highest_one(), None);")] + #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".highest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".highest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".highest_one(), Some(4));")] /// ``` #[unstable(feature = "int_lowest_highest_one", issue = "145203")] #[must_use = "this returns the result of the operation, \ @@ -296,10 +296,10 @@ macro_rules! uint_impl { /// ``` /// #![feature(int_lowest_highest_one)] /// - #[doc = concat!("assert_eq!(0x0_", stringify!($SelfT), ".lowest_one(), None);")] - #[doc = concat!("assert_eq!(0x1_", stringify!($SelfT), ".lowest_one(), Some(0));")] - #[doc = concat!("assert_eq!(0x10_", stringify!($SelfT), ".lowest_one(), Some(4));")] - #[doc = concat!("assert_eq!(0x1f_", stringify!($SelfT), ".lowest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".lowest_one(), None);")] + #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".lowest_one(), Some(0));")] + #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".lowest_one(), Some(4));")] + #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".lowest_one(), Some(0));")] /// ``` #[unstable(feature = "int_lowest_highest_one", issue = "145203")] #[must_use = "this returns the result of the operation, \ From 72cec248e86458a22d0423aeca0a0becbeb47a01 Mon Sep 17 00:00:00 2001 From: Tom Fryers Date: Thu, 6 Nov 2025 10:59:46 +0000 Subject: [PATCH 438/525] Fix mismatched brackets in generated .dir-locals.el This caused Emacs to throw errors when opening files. Introduced in 3fe3edbcdee. --- src/bootstrap/src/core/build_steps/setup.rs | 2 +- src/etc/rust_analyzer_eglot.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 4b0080f1c80a..380c774b143c 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -587,7 +587,7 @@ Select which editor you would like to set up [default: None]: "; "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", - "e260553b71e4773c30a63c4b23b42b279fc73e72f95b775c47b7b7c511c51595", + "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", ], EditorKind::Helix => &[ "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", diff --git a/src/etc/rust_analyzer_eglot.el b/src/etc/rust_analyzer_eglot.el index e5abf67235a5..d33760007c32 100644 --- a/src/etc/rust_analyzer_eglot.el +++ b/src/etc/rust_analyzer_eglot.el @@ -28,7 +28,7 @@ "--build-dir" "build-rust-analyzer" "--json-output" - "--compile-time-deps"])] + "--compile-time-deps"]) :sysrootSrc "./library" :extraEnv (:RUSTC_BOOTSTRAP "1")) :rustc ( :source "./Cargo.toml" ))))))) From 0645ac31cb67d506faf7bfd6b33975db558d16c6 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 12:08:27 +0200 Subject: [PATCH 439/525] extract s390x `vector` and friends to their own rust feature --- compiler/rustc_feature/src/unstable.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/target_features.rs | 24 +++++++++---------- library/core/src/lib.rs | 1 + library/stdarch/crates/core_arch/src/lib.rs | 2 +- tests/assembly-llvm/s390x-vector-abi.rs | 2 +- tests/codegen-llvm/s390x-simd.rs | 2 +- tests/codegen-llvm/simd/extract-insert-dyn.rs | 2 +- tests/ui/abi/simd-abi-checks-s390x.rs | 2 +- tests/ui/target-feature/gate.rs | 1 + tests/ui/target-feature/gate.stderr | 2 +- 11 files changed, 22 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8397cd294e0a..b4fc1e8d9c1c 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -343,6 +343,7 @@ declare_features! ( (unstable, riscv_target_feature, "1.45.0", Some(44839)), (unstable, rtm_target_feature, "1.35.0", Some(44839)), (unstable, s390x_target_feature, "1.82.0", Some(44839)), + (unstable, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)), (unstable, sparc_target_feature, "1.84.0", Some(132783)), (unstable, wasm_target_feature, "1.30.0", Some(44839)), (unstable, x87_target_feature, "1.85.0", Some(44839)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38718bad9e57..b7357b322ee8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2000,6 +2000,7 @@ symbols! { s, s390x, s390x_target_feature, + s390x_target_feature_vector, safety, sanitize, sanitizer_cfi_generalize_pointers, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index fd95bd062be6..d2684183821f 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -844,20 +844,20 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]), ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]), ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]), - ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature), &[]), - ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]), - ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]), - ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]), + ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature_vector), &[]), + ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature_vector), &[]), + ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature_vector), &[]), + ("nnp-assist", Unstable(sym::s390x_target_feature_vector), &["vector"]), ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]), ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), - ("vector", Unstable(sym::s390x_target_feature), &[]), - ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]), - ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]), - ("vector-enhancements-3", Unstable(sym::s390x_target_feature), &["vector-enhancements-2"]), - ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]), - ("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature), &["vector-packed-decimal"]), - ("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement"]), - ("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement-2"]), + ("vector", Unstable(sym::s390x_target_feature_vector), &[]), + ("vector-enhancements-1", Unstable(sym::s390x_target_feature_vector), &["vector"]), + ("vector-enhancements-2", Unstable(sym::s390x_target_feature_vector), &["vector-enhancements-1"]), + ("vector-enhancements-3", Unstable(sym::s390x_target_feature_vector), &["vector-enhancements-2"]), + ("vector-packed-decimal", Unstable(sym::s390x_target_feature_vector), &["vector"]), + ("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal"]), + ("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal-enhancement"]), + ("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal-enhancement-2"]), // tidy-alphabetical-end ]; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f1948fc778ce..1c0a5631665e 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -204,6 +204,7 @@ #![feature(riscv_target_feature)] #![feature(rtm_target_feature)] #![feature(s390x_target_feature)] +#![feature(s390x_target_feature_vector)] #![feature(wasm_target_feature)] #![feature(x86_amx_intrinsics)] // tidy-alphabetical-end diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index 26a9cb589918..7aa71a49837e 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -22,7 +22,7 @@ arm_target_feature, mips_target_feature, powerpc_target_feature, - s390x_target_feature, + s390x_target_feature_vector, loongarch_target_feature, wasm_target_feature, abi_unadjusted, diff --git a/tests/assembly-llvm/s390x-vector-abi.rs b/tests/assembly-llvm/s390x-vector-abi.rs index 9635bb6cb440..0de5fb15eb4c 100644 --- a/tests/assembly-llvm/s390x-vector-abi.rs +++ b/tests/assembly-llvm/s390x-vector-abi.rs @@ -12,7 +12,7 @@ //@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector //@[z13_no_vector] needs-llvm-components: systemz -#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![feature(no_core, lang_items, repr_simd, s390x_target_feature_vector)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] diff --git a/tests/codegen-llvm/s390x-simd.rs b/tests/codegen-llvm/s390x-simd.rs index 50df08524f52..83e9d274bb55 100644 --- a/tests/codegen-llvm/s390x-simd.rs +++ b/tests/codegen-llvm/s390x-simd.rs @@ -6,7 +6,7 @@ #![crate_type = "rlib"] #![feature(no_core, asm_experimental_arch)] -#![feature(s390x_target_feature, simd_ffi, intrinsics, repr_simd)] +#![feature(s390x_target_feature_vector, simd_ffi, intrinsics, repr_simd)] #![no_core] extern crate minicore; diff --git a/tests/codegen-llvm/simd/extract-insert-dyn.rs b/tests/codegen-llvm/simd/extract-insert-dyn.rs index 9c17b82e5535..019fa1d72e36 100644 --- a/tests/codegen-llvm/simd/extract-insert-dyn.rs +++ b/tests/codegen-llvm/simd/extract-insert-dyn.rs @@ -5,7 +5,7 @@ repr_simd, arm_target_feature, mips_target_feature, - s390x_target_feature, + s390x_target_feature_vector, riscv_target_feature )] #![no_std] diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs index 6434dbea1106..e5d737db2123 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -14,7 +14,7 @@ //[z13_no_vector,z13_soft_float]~? WARN unstable feature specified for `-Ctarget-feature` //[z13_soft_float]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` -#![feature(no_core, repr_simd, s390x_target_feature)] +#![feature(no_core, repr_simd, s390x_target_feature_vector)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types, improper_ctypes_definitions)] diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs index fc3763820cbe..9afc6fb2b0f4 100644 --- a/tests/ui/target-feature/gate.rs +++ b/tests/ui/target-feature/gate.rs @@ -17,6 +17,7 @@ // gate-test-lahfsahf_target_feature // gate-test-prfchw_target_feature // gate-test-s390x_target_feature +// gate-test-s390x_target_feature_vector // gate-test-sparc_target_feature // gate-test-x87_target_feature // gate-test-m68k_target_feature diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index 345dc2006d0b..b3567c0091c6 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `x87` is currently unstable - --> $DIR/gate.rs:24:18 + --> $DIR/gate.rs:25:18 | LL | #[target_feature(enable = "x87")] | ^^^^^^^^^^^^^^ From d69442fe9c186b371236c1cebd6b5e76e168ee72 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 12:17:19 +0200 Subject: [PATCH 440/525] `std_detect`: remove unneeded stability lines from s390x features macro --- library/std_detect/src/detect/arch/s390x.rs | 23 --------------------- 1 file changed, 23 deletions(-) diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index d59fbc7de3bd..4c81f55aa823 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -12,73 +12,50 @@ features! { #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] deflate_conversion: "deflate-conversion"; /// s390x deflate-conversion facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] enhanced_sort: "enhanced-sort"; /// s390x enhanced-sort facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] guarded_storage: "guarded-storage"; /// s390x guarded-storage facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] high_word: "high-word"; /// s390x high-word facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension3: "message-security-assist-extension3"; /// s390x message-security-assist-extension3 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension4: "message-security-assist-extension4"; /// s390x message-security-assist-extension4 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension5: "message-security-assist-extension5"; /// s390x message-security-assist-extension5 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension8: "message-security-assist-extension8"; /// s390x message-security-assist-extension8 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension9: "message-security-assist-extension9"; /// s390x message-security-assist-extension9 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; /// s390x miscellaneous-extensions-3 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector: "vector"; /// s390x vector facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_1: "vector-enhancements-1"; /// s390x vector-enhancements-1 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_2: "vector-enhancements-2"; /// s390x vector-enhancements-2 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_3: "vector-enhancements-3"; /// s390x vector-enhancements-3 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal: "vector-packed-decimal"; /// s390x vector-packed-decimal facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; /// s390x vector-packed-decimal-enhancement facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; /// s390x vector-packed-decimal-enhancement-2 facility - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; /// s390x vector-packed-decimal-enhancement-3 facility } From 02e4db5cc6ca335a9e65889a26eda8b9a881e6f7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 12:23:22 +0200 Subject: [PATCH 441/525] `std_detect`: give s390x features more accurate features / tracking issues --- library/std_detect/src/detect/arch/s390x.rs | 48 ++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index 4c81f55aa823..da3c8fce036c 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -10,52 +10,52 @@ features! { /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) /// the macro expands to `true`. #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] concurrent_functions: "concurrent-functions"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] deflate_conversion: "deflate-conversion"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion"; /// s390x deflate-conversion facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] enhanced_sort: "enhanced-sort"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] enhanced_sort: "enhanced-sort"; /// s390x enhanced-sort facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] guarded_storage: "guarded-storage"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] guarded_storage: "guarded-storage"; /// s390x guarded-storage facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] high_word: "high-word"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] high_word: "high-word"; /// s390x high-word facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension3: "message-security-assist-extension3"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension3: "message-security-assist-extension3"; /// s390x message-security-assist-extension3 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension4: "message-security-assist-extension4"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension4: "message-security-assist-extension4"; /// s390x message-security-assist-extension4 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension5: "message-security-assist-extension5"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension5: "message-security-assist-extension5"; /// s390x message-security-assist-extension5 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension8: "message-security-assist-extension8"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension8: "message-security-assist-extension8"; /// s390x message-security-assist-extension8 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension9: "message-security-assist-extension9"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension9: "message-security-assist-extension9"; /// s390x message-security-assist-extension9 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension12: "message-security-assist-extension12"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; /// s390x miscellaneous-extensions-3 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] nnp_assist: "nnp-assist"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] transactional_execution: "transactional-execution"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector: "vector"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector: "vector"; /// s390x vector facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_1: "vector-enhancements-1"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_1: "vector-enhancements-1"; /// s390x vector-enhancements-1 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_2: "vector-enhancements-2"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_2: "vector-enhancements-2"; /// s390x vector-enhancements-2 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_enhancements_3: "vector-enhancements-3"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_3: "vector-enhancements-3"; /// s390x vector-enhancements-3 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal: "vector-packed-decimal"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal: "vector-packed-decimal"; /// s390x vector-packed-decimal facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; /// s390x vector-packed-decimal-enhancement facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; /// s390x vector-packed-decimal-enhancement-2 facility - @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; + @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; /// s390x vector-packed-decimal-enhancement-3 facility } From c59298da36b30490381778726287a6fbdaac45c0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 12:41:19 +0200 Subject: [PATCH 442/525] stabilize `stdarch_s390x_feature_detection` --- library/std/src/lib.rs | 2 +- library/std/tests/run-time-detect.rs | 4 ---- library/std_detect/src/detect/arch/mod.rs | 2 +- library/std_detect/src/detect/arch/s390x.rs | 2 +- library/std_detect/tests/cpu-detection.rs | 1 - library/std_detect/tests/macro_trailing_commas.rs | 1 - library/stdarch/crates/core_arch/src/lib.rs | 6 +----- 7 files changed, 4 insertions(+), 14 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index a8c50cec01e0..7b6cfbfe0f25 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -672,7 +672,7 @@ pub mod arch { pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] pub use std_detect::is_s390x_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index ae0c3385d2ad..b2c3d0d3f9f8 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -8,10 +8,6 @@ all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")), feature(stdarch_aarch64_feature_detection) )] -#![cfg_attr( - all(target_arch = "s390x", target_os = "linux"), - feature(stdarch_s390x_feature_detection) -)] #![cfg_attr( all(target_arch = "powerpc", target_os = "linux"), feature(stdarch_powerpc_feature_detection) diff --git a/library/std_detect/src/detect/arch/mod.rs b/library/std_detect/src/detect/arch/mod.rs index c066b9cc6815..23e7a30b985b 100644 --- a/library/std_detect/src/detect/arch/mod.rs +++ b/library/std_detect/src/detect/arch/mod.rs @@ -60,7 +60,7 @@ cfg_select! { pub use loongarch::*; } target_arch = "s390x" => { - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] pub use s390x::*; } _ => { diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index da3c8fce036c..44961abcf3a0 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -9,7 +9,7 @@ features! { /// /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) /// the macro expands to `true`. - #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion"; diff --git a/library/std_detect/tests/cpu-detection.rs b/library/std_detect/tests/cpu-detection.rs index 0c4fa57f2b46..3e36abda97df 100644 --- a/library/std_detect/tests/cpu-detection.rs +++ b/library/std_detect/tests/cpu-detection.rs @@ -11,7 +11,6 @@ )] #![cfg_attr(target_arch = "powerpc", feature(stdarch_powerpc_feature_detection))] #![cfg_attr(target_arch = "powerpc64", feature(stdarch_powerpc_feature_detection))] -#![cfg_attr(target_arch = "s390x", feature(stdarch_s390x_feature_detection))] #![allow(clippy::unwrap_used, clippy::use_debug, clippy::print_stdout)] #[cfg_attr( diff --git a/library/std_detect/tests/macro_trailing_commas.rs b/library/std_detect/tests/macro_trailing_commas.rs index 6072ddf5ac45..29bd3f1162a4 100644 --- a/library/std_detect/tests/macro_trailing_commas.rs +++ b/library/std_detect/tests/macro_trailing_commas.rs @@ -25,7 +25,6 @@ any(target_arch = "powerpc", target_arch = "powerpc64"), feature(stdarch_powerpc_feature_detection) )] -#![cfg_attr(target_arch = "s390x", feature(stdarch_s390x_feature_detection))] #![cfg_attr( any(target_arch = "riscv32", target_arch = "riscv64"), feature(stdarch_riscv_feature_detection) diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index 7aa71a49837e..ed9138f343a1 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -64,11 +64,7 @@ )] #![cfg_attr( test, - feature( - stdarch_arm_feature_detection, - stdarch_powerpc_feature_detection, - stdarch_s390x_feature_detection - ) + feature(stdarch_arm_feature_detection, stdarch_powerpc_feature_detection,) )] #[cfg(test)] From 7516645928ea1086e2a4a8e796fc88c0a7584573 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 20 Aug 2025 13:04:58 +0200 Subject: [PATCH 443/525] stabilize `s390x_target_feature_vector` --- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/unstable.rs | 1 - compiler/rustc_target/src/target_features.rs | 24 ++-- library/core/src/lib.rs | 1 - library/std_detect/src/detect/arch/s390x.rs | 24 ++-- library/stdarch/crates/core_arch/src/lib.rs | 1 - tests/assembly-llvm/s390x-vector-abi.rs | 2 +- tests/codegen-llvm/s390x-simd.rs | 2 +- tests/codegen-llvm/simd/extract-insert-dyn.rs | 1 - tests/ui/abi/simd-abi-checks-s390x.rs | 4 +- tests/ui/abi/simd-abi-checks-s390x.z10.stderr | 20 +-- ...simd-abi-checks-s390x.z13_no_vector.stderr | 26 ++-- ...imd-abi-checks-s390x.z13_soft_float.stderr | 26 ++-- tests/ui/asm/s390x/bad-reg.rs | 2 - tests/ui/asm/s390x/bad-reg.s390x.stderr | 114 ++++++++------- .../ui/asm/s390x/bad-reg.s390x_vector.stderr | 100 +++++++------ .../s390x/bad-reg.s390x_vector_stable.stderr | 132 +++++++++--------- tests/ui/target-feature/gate.rs | 1 - tests/ui/target-feature/gate.stderr | 2 +- 19 files changed, 229 insertions(+), 256 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 364a1202b05c..0ee4ad409e4b 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -387,6 +387,8 @@ declare_features! ( (accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)), /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). (accepted, rvalue_static_promotion, "1.21.0", Some(38865)), + /// Allows use of the `vector` and related s390x target features. + (accepted, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)), /// Allows `Self` in type definitions (RFC 2300). (accepted, self_in_typedefs, "1.32.0", Some(49303)), /// Allows `Self` struct constructor (RFC 2302). diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index b4fc1e8d9c1c..8397cd294e0a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -343,7 +343,6 @@ declare_features! ( (unstable, riscv_target_feature, "1.45.0", Some(44839)), (unstable, rtm_target_feature, "1.35.0", Some(44839)), (unstable, s390x_target_feature, "1.82.0", Some(44839)), - (unstable, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)), (unstable, sparc_target_feature, "1.84.0", Some(132783)), (unstable, wasm_target_feature, "1.30.0", Some(44839)), (unstable, x87_target_feature, "1.85.0", Some(44839)), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index d2684183821f..1789e52ed26f 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -844,20 +844,20 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]), ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]), ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]), - ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature_vector), &[]), - ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature_vector), &[]), - ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature_vector), &[]), - ("nnp-assist", Unstable(sym::s390x_target_feature_vector), &["vector"]), + ("miscellaneous-extensions-2", Stable, &[]), + ("miscellaneous-extensions-3", Stable, &[]), + ("miscellaneous-extensions-4", Stable, &[]), + ("nnp-assist", Stable, &["vector"]), ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]), ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), - ("vector", Unstable(sym::s390x_target_feature_vector), &[]), - ("vector-enhancements-1", Unstable(sym::s390x_target_feature_vector), &["vector"]), - ("vector-enhancements-2", Unstable(sym::s390x_target_feature_vector), &["vector-enhancements-1"]), - ("vector-enhancements-3", Unstable(sym::s390x_target_feature_vector), &["vector-enhancements-2"]), - ("vector-packed-decimal", Unstable(sym::s390x_target_feature_vector), &["vector"]), - ("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal"]), - ("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal-enhancement"]), - ("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature_vector), &["vector-packed-decimal-enhancement-2"]), + ("vector", Stable, &[]), + ("vector-enhancements-1", Stable, &["vector"]), + ("vector-enhancements-2", Stable, &["vector-enhancements-1"]), + ("vector-enhancements-3", Stable, &["vector-enhancements-2"]), + ("vector-packed-decimal", Stable, &["vector"]), + ("vector-packed-decimal-enhancement", Stable, &["vector-packed-decimal"]), + ("vector-packed-decimal-enhancement-2", Stable, &["vector-packed-decimal-enhancement"]), + ("vector-packed-decimal-enhancement-3", Stable, &["vector-packed-decimal-enhancement-2"]), // tidy-alphabetical-end ]; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1c0a5631665e..f1948fc778ce 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -204,7 +204,6 @@ #![feature(riscv_target_feature)] #![feature(rtm_target_feature)] #![feature(s390x_target_feature)] -#![feature(s390x_target_feature_vector)] #![feature(wasm_target_feature)] #![feature(x86_amx_intrinsics)] // tidy-alphabetical-end diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index 44961abcf3a0..6122e8f5b837 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -32,30 +32,30 @@ features! { /// s390x message-security-assist-extension9 facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; /// s390x miscellaneous-extensions-3 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] nnp_assist: "nnp-assist"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector: "vector"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector: "vector"; /// s390x vector facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_1: "vector-enhancements-1"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_1: "vector-enhancements-1"; /// s390x vector-enhancements-1 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_2: "vector-enhancements-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_2: "vector-enhancements-2"; /// s390x vector-enhancements-2 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_enhancements_3: "vector-enhancements-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_3: "vector-enhancements-3"; /// s390x vector-enhancements-3 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal: "vector-packed-decimal"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal: "vector-packed-decimal"; /// s390x vector-packed-decimal facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; /// s390x vector-packed-decimal-enhancement facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; /// s390x vector-packed-decimal-enhancement-2 facility - @FEATURE: #[unstable(feature = "s390x_target_feature_vector", issue = "145649")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; /// s390x vector-packed-decimal-enhancement-3 facility } diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index ed9138f343a1..06cbd32d6772 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -22,7 +22,6 @@ arm_target_feature, mips_target_feature, powerpc_target_feature, - s390x_target_feature_vector, loongarch_target_feature, wasm_target_feature, abi_unadjusted, diff --git a/tests/assembly-llvm/s390x-vector-abi.rs b/tests/assembly-llvm/s390x-vector-abi.rs index 0de5fb15eb4c..90139df17ca1 100644 --- a/tests/assembly-llvm/s390x-vector-abi.rs +++ b/tests/assembly-llvm/s390x-vector-abi.rs @@ -12,7 +12,7 @@ //@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector //@[z13_no_vector] needs-llvm-components: systemz -#![feature(no_core, lang_items, repr_simd, s390x_target_feature_vector)] +#![feature(no_core, lang_items, repr_simd)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] diff --git a/tests/codegen-llvm/s390x-simd.rs b/tests/codegen-llvm/s390x-simd.rs index 83e9d274bb55..8439e7971674 100644 --- a/tests/codegen-llvm/s390x-simd.rs +++ b/tests/codegen-llvm/s390x-simd.rs @@ -6,7 +6,7 @@ #![crate_type = "rlib"] #![feature(no_core, asm_experimental_arch)] -#![feature(s390x_target_feature_vector, simd_ffi, intrinsics, repr_simd)] +#![feature(simd_ffi, intrinsics, repr_simd)] #![no_core] extern crate minicore; diff --git a/tests/codegen-llvm/simd/extract-insert-dyn.rs b/tests/codegen-llvm/simd/extract-insert-dyn.rs index 019fa1d72e36..e634841fae79 100644 --- a/tests/codegen-llvm/simd/extract-insert-dyn.rs +++ b/tests/codegen-llvm/simd/extract-insert-dyn.rs @@ -5,7 +5,6 @@ repr_simd, arm_target_feature, mips_target_feature, - s390x_target_feature_vector, riscv_target_feature )] #![no_std] diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs index e5d737db2123..c8f4483650cc 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -10,11 +10,9 @@ //@[z13_soft_float] needs-llvm-components: systemz //@ ignore-backends: gcc //[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly - -//[z13_no_vector,z13_soft_float]~? WARN unstable feature specified for `-Ctarget-feature` //[z13_soft_float]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` -#![feature(no_core, repr_simd, s390x_target_feature_vector)] +#![feature(no_core, repr_simd)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types, improper_ctypes_definitions)] diff --git a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr index 769f8a0b1911..0a40658fa66b 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:43:1 + --> $DIR/simd-abi-checks-s390x.rs:41:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:48:1 + --> $DIR/simd-abi-checks-s390x.rs:46:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:94:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:101:1 + --> $DIR/simd-abi-checks-s390x.rs:99:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:116:1 + --> $DIR/simd-abi-checks-s390x.rs:114:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:121:1 + --> $DIR/simd-abi-checks-s390x.rs:119:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:132:1 + --> $DIR/simd-abi-checks-s390x.rs:130:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:137:1 + --> $DIR/simd-abi-checks-s390x.rs:135:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:148:1 + --> $DIR/simd-abi-checks-s390x.rs:146:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:153:1 + --> $DIR/simd-abi-checks-s390x.rs:151:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr index 7709c396605e..0a40658fa66b 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr @@ -1,9 +1,5 @@ -warning: unstable feature specified for `-Ctarget-feature`: `vector` - | - = note: this feature is not stably supported; its behavior can change in the future - error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:43:1 + --> $DIR/simd-abi-checks-s390x.rs:41:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -11,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:48:1 + --> $DIR/simd-abi-checks-s390x.rs:46:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -19,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:94:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -29,7 +25,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:101:1 + --> $DIR/simd-abi-checks-s390x.rs:99:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -39,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:116:1 + --> $DIR/simd-abi-checks-s390x.rs:114:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -47,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:121:1 + --> $DIR/simd-abi-checks-s390x.rs:119:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -55,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:132:1 + --> $DIR/simd-abi-checks-s390x.rs:130:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -63,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:137:1 + --> $DIR/simd-abi-checks-s390x.rs:135:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -71,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:148:1 + --> $DIR/simd-abi-checks-s390x.rs:146:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -79,12 +75,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:153:1 + --> $DIR/simd-abi-checks-s390x.rs:151:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 10 previous errors diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index 6a202eac7e1e..0e8e6637507d 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -1,7 +1,3 @@ -warning: unstable feature specified for `-Ctarget-feature`: `vector` - | - = note: this feature is not stably supported; its behavior can change in the future - warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: currently unsupported ABI-configuration feature | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -13,7 +9,7 @@ warning: target feature `soft-float` must be disabled to ensure that the ABI of = note: for more information, see issue #116344 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:43:1 + --> $DIR/simd-abi-checks-s390x.rs:41:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -21,7 +17,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:48:1 + --> $DIR/simd-abi-checks-s390x.rs:46:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -29,7 +25,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:94:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -39,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:101:1 + --> $DIR/simd-abi-checks-s390x.rs:99:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -49,7 +45,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:116:1 + --> $DIR/simd-abi-checks-s390x.rs:114:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -57,7 +53,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:121:1 + --> $DIR/simd-abi-checks-s390x.rs:119:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -65,7 +61,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:132:1 + --> $DIR/simd-abi-checks-s390x.rs:130:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -73,7 +69,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:137:1 + --> $DIR/simd-abi-checks-s390x.rs:135:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -81,7 +77,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:148:1 + --> $DIR/simd-abi-checks-s390x.rs:146:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -89,12 +85,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:153:1 + --> $DIR/simd-abi-checks-s390x.rs:151:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: aborting due to 10 previous errors; 3 warnings emitted +error: aborting due to 10 previous errors; 2 warnings emitted diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index a4baa390be22..97b2b3d50b34 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -8,8 +8,6 @@ //@[s390x_vector_stable] needs-llvm-components: systemz //@ ignore-backends: gcc -//~? WARN unstable feature specified for `-Ctarget-feature` - #![crate_type = "rlib"] #![feature(no_core, repr_simd)] #![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))] diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index ca5dcab0624f..238419b376b7 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,153 +1,149 @@ -warning: unstable feature specified for `-Ctarget-feature`: `vector` - | - = note: this feature is not stably supported; its behavior can change in the future - error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:71:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:18 + --> $DIR/bad-reg.rs:120:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:125:18 + --> $DIR/bad-reg.rs:123:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:128:26 + --> $DIR/bad-reg.rs:126:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:131:26 + --> $DIR/bad-reg.rs:129:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:134:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -155,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -163,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -171,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -179,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -187,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -195,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -203,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -211,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -219,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:154:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -227,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:154:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -235,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -243,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -251,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -259,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -267,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:166:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -275,73 +271,73 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:169:32 + --> $DIR/bad-reg.rs:167:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:76:18 + --> $DIR/bad-reg.rs:74:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:80:18 + --> $DIR/bad-reg.rs:78:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:84:18 + --> $DIR/bad-reg.rs:82:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:88:18 + --> $DIR/bad-reg.rs:86:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:92:18 + --> $DIR/bad-reg.rs:90:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:102:26 + --> $DIR/bad-reg.rs:100:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:108:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:115:26 + --> $DIR/bad-reg.rs:113:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:122:27 + --> $DIR/bad-reg.rs:120:27 | LL | asm!("", in("a2") x); | ^ @@ -349,7 +345,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:125:28 + --> $DIR/bad-reg.rs:123:28 | LL | asm!("", out("a2") x); | ^ @@ -357,12 +353,12 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:128:35 + --> $DIR/bad-reg.rs:126:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 54 previous errors; 1 warning emitted +error: aborting due to 54 previous errors diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 8493e37c45ff..897f872ae72a 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -1,153 +1,149 @@ -warning: unstable feature specified for `-Ctarget-feature`: `vector` - | - = note: this feature is not stably supported; its behavior can change in the future - error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:71:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:18 + --> $DIR/bad-reg.rs:120:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:125:18 + --> $DIR/bad-reg.rs:123:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:128:26 + --> $DIR/bad-reg.rs:126:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:131:26 + --> $DIR/bad-reg.rs:129:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:134:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -155,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -163,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -171,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -179,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -187,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -195,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -203,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -211,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -219,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:154:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -227,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:154:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -235,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -243,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -251,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -259,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -267,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:166:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -275,13 +271,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:169:32 + --> $DIR/bad-reg.rs:167:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:92:27 + --> $DIR/bad-reg.rs:90:27 | LL | asm!("", in("v0") b); | ^ @@ -289,7 +285,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:95:28 | LL | asm!("", out("v0") b); | ^ @@ -297,7 +293,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:110:35 + --> $DIR/bad-reg.rs:108:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -305,7 +301,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:122:27 + --> $DIR/bad-reg.rs:120:27 | LL | asm!("", in("a2") x); | ^ @@ -313,7 +309,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:125:28 + --> $DIR/bad-reg.rs:123:28 | LL | asm!("", out("a2") x); | ^ @@ -321,12 +317,12 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:128:35 + --> $DIR/bad-reg.rs:126:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 47 previous errors; 1 warning emitted +error: aborting due to 47 previous errors diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr index a6a6a28f1d8b..e2b3eeef4e92 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr @@ -1,129 +1,125 @@ -warning: unstable feature specified for `-Ctarget-feature`: `vector` - | - = note: this feature is not stably supported; its behavior can change in the future - error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:71:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:76:18 + --> $DIR/bad-reg.rs:74:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -133,7 +129,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:80:18 + --> $DIR/bad-reg.rs:78:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -143,7 +139,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:84:18 + --> $DIR/bad-reg.rs:82:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -153,7 +149,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:88:18 + --> $DIR/bad-reg.rs:86:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -163,7 +159,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:92:18 + --> $DIR/bad-reg.rs:90:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ @@ -173,7 +169,7 @@ LL | asm!("", in("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ @@ -183,7 +179,7 @@ LL | asm!("", out("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:102:26 + --> $DIR/bad-reg.rs:100:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -193,7 +189,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -203,7 +199,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:108:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ @@ -213,7 +209,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:115:26 + --> $DIR/bad-reg.rs:113:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -223,31 +219,31 @@ LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimenta = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:18 + --> $DIR/bad-reg.rs:120:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:125:18 + --> $DIR/bad-reg.rs:123:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:128:26 + --> $DIR/bad-reg.rs:126:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:131:26 + --> $DIR/bad-reg.rs:129:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:134:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -255,7 +251,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:136:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -263,7 +259,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:138:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -271,7 +267,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:140:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -279,7 +275,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:142:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -287,7 +283,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:144:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -295,7 +291,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:146:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -303,7 +299,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:148:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -311,7 +307,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:150:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -319,7 +315,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:154:31 + --> $DIR/bad-reg.rs:152:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -327,7 +323,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:154:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -335,7 +331,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:156:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -343,7 +339,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:158:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -351,7 +347,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:160:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -359,7 +355,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:162:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -367,7 +363,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:166:32 + --> $DIR/bad-reg.rs:164:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -375,13 +371,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:169:32 + --> $DIR/bad-reg.rs:167:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:76:27 + --> $DIR/bad-reg.rs:74:27 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^ @@ -391,7 +387,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:80:28 + --> $DIR/bad-reg.rs:78:28 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^ @@ -401,7 +397,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:84:27 + --> $DIR/bad-reg.rs:82:27 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^ @@ -411,7 +407,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:88:28 + --> $DIR/bad-reg.rs:86:28 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^ @@ -421,7 +417,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:92:27 + --> $DIR/bad-reg.rs:90:27 | LL | asm!("", in("v0") b); | ^ @@ -429,7 +425,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:95:28 | LL | asm!("", out("v0") b); | ^ @@ -437,7 +433,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:102:35 + --> $DIR/bad-reg.rs:100:35 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^ @@ -447,7 +443,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:106:35 + --> $DIR/bad-reg.rs:104:35 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^ @@ -457,7 +453,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:110:35 + --> $DIR/bad-reg.rs:108:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -465,7 +461,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:122:27 + --> $DIR/bad-reg.rs:120:27 | LL | asm!("", in("a2") x); | ^ @@ -473,7 +469,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:125:28 + --> $DIR/bad-reg.rs:123:28 | LL | asm!("", out("a2") x); | ^ @@ -481,13 +477,13 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:128:35 + --> $DIR/bad-reg.rs:126:35 | LL | asm!("/* {} */", in(areg) x); | ^ | = note: register class `areg` supports these types: -error: aborting due to 63 previous errors; 1 warning emitted +error: aborting due to 63 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs index 9afc6fb2b0f4..fc3763820cbe 100644 --- a/tests/ui/target-feature/gate.rs +++ b/tests/ui/target-feature/gate.rs @@ -17,7 +17,6 @@ // gate-test-lahfsahf_target_feature // gate-test-prfchw_target_feature // gate-test-s390x_target_feature -// gate-test-s390x_target_feature_vector // gate-test-sparc_target_feature // gate-test-x87_target_feature // gate-test-m68k_target_feature diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index b3567c0091c6..345dc2006d0b 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `x87` is currently unstable - --> $DIR/gate.rs:25:18 + --> $DIR/gate.rs:24:18 | LL | #[target_feature(enable = "x87")] | ^^^^^^^^^^^^^^ From e77e5d1bc1c23d16fce69f19ffbd06a77c8c1835 Mon Sep 17 00:00:00 2001 From: Vyacheslav <91011801+vyacheslavhere@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:17:03 +0500 Subject: [PATCH 444/525] fix dev guide link in rustc_query_system/dep_graph/README.MD --- compiler/rustc_query_system/src/dep_graph/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/README.md b/compiler/rustc_query_system/src/dep_graph/README.md index b9d91cd35a8d..3dd107f2feab 100644 --- a/compiler/rustc_query_system/src/dep_graph/README.md +++ b/compiler/rustc_query_system/src/dep_graph/README.md @@ -1,4 +1,3 @@ -To learn more about how dependency tracking works in rustc, see the [rustc -guide]. +To learn more about how dependency tracking works in rustc, see the [rustc dev guide]. [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html From bc883e24b8e1719f843ccf8be0217c1207425715 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Sat, 26 Jul 2025 12:02:35 +0200 Subject: [PATCH 445/525] replace SanitizerSet in CodegenFnAttrs by new type --- compiler/rustc_codegen_llvm/src/attributes.rs | 8 ++--- compiler/rustc_codegen_llvm/src/base.rs | 8 ++--- compiler/rustc_codegen_llvm/src/builder.rs | 4 +-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 30 +++++++++---------- compiler/rustc_middle/src/lib.rs | 2 ++ .../src/middle/codegen_fn_attrs.rs | 20 ++++++++++--- compiler/rustc_middle/src/query/erase.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 8 ++--- compiler/rustc_mir_transform/src/inline.rs | 2 +- tests/ui/sanitizer/inline-always-sanitize.rs | 2 +- .../sanitizer/inline-always-sanitize.stderr | 2 +- 11 files changed, 51 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 96af90cd272b..7b8b7ff3c291 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -2,7 +2,7 @@ use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{ - CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; @@ -98,10 +98,10 @@ fn patchable_function_entry_attrs<'ll>( pub(crate) fn sanitize_attrs<'ll, 'tcx>( cx: &SimpleCx<'ll>, tcx: TyCtxt<'tcx>, - no_sanitize: SanitizerSet, + sanitizer_fn_attr: SanitizerFnAttrs, ) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); - let enabled = tcx.sess.sanitizers() - no_sanitize; + let enabled = tcx.sess.sanitizers() - sanitizer_fn_attr.disabled; if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) { attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx)); } @@ -411,7 +411,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( // not used. } else { // Do not set sanitizer attributes for naked functions. - to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.no_sanitize)); + to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.sanitizers)); // For non-naked functions, set branch protection attributes on aarch64. if let Some(BranchProtection { bti, pac_ret, gcs }) = diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 4523d629b1ef..6cbddfec4631 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -20,7 +20,7 @@ use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::attrs::Linkage; use rustc_middle::dep_graph; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; @@ -105,7 +105,7 @@ pub(crate) fn compile_codegen_unit( if let Some(entry) = maybe_create_entry_wrapper::>(&cx, cx.codegen_unit) { - let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerSet::empty()); + let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerFnAttrs::default()); attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs); } @@ -191,10 +191,10 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { } pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) { - if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) { unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) }; } - if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) { unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) }; } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d441cd119a74..4cef7bff9206 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1798,7 +1798,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { && is_indirect_call { if let Some(fn_attrs) = fn_attrs - && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) + && fn_attrs.sanitizers.disabled.contains(SanitizerSet::CFI) { return; } @@ -1856,7 +1856,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { && is_indirect_call { if let Some(fn_attrs) = fn_attrs - && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) + && fn_attrs.sanitizers.disabled.contains(SanitizerSet::KCFI) { return None; } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 44de48a3ada5..5dd1365f2645 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; use rustc_middle::middle::codegen_fn_attrs::{ - CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; use rustc_middle::query::Providers; use rustc_middle::span_bug; @@ -16,7 +16,6 @@ use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, sym}; -use rustc_target::spec::SanitizerSet; use crate::errors; use crate::target_features::{ @@ -351,7 +350,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment); // Compute the disabled sanitizers. - codegen_fn_attrs.no_sanitize |= tcx.disabled_sanitizers_for(did); + codegen_fn_attrs.sanitizers.disabled |= + tcx.sanitizer_settings_for(did).disabled; // On trait methods, inherit the `#[align]` of the trait's method prototype. codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did)); @@ -455,14 +455,14 @@ fn check_result( } // warn that inline has no effect when no_sanitize is present - if !codegen_fn_attrs.no_sanitize.is_empty() + if codegen_fn_attrs.sanitizers != SanitizerFnAttrs::default() && codegen_fn_attrs.inline.always() - && let (Some(no_sanitize_span), Some(inline_span)) = + && let (Some(sanitize_span), Some(inline_span)) = (interesting_spans.sanitize, interesting_spans.inline) { let hir_id = tcx.local_def_id_to_hir_id(did); - tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| { - lint.primary_message("setting `sanitize` off will have no effect after inlining"); + tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| { + lint.primary_message("non-default `sanitize` will have no effect after inlining"); lint.span_note(inline_span, "inlining requested here"); }) } @@ -576,14 +576,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs } -fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { +fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs { // Backtrack to the crate root. - let mut disabled = match tcx.opt_local_parent(did) { + let mut settings = match tcx.opt_local_parent(did) { // Check the parent (recursively). - Some(parent) => tcx.disabled_sanitizers_for(parent), + Some(parent) => tcx.sanitizer_settings_for(parent), // We reached the crate root without seeing an attribute, so // there is no sanitizers to exclude. - None => SanitizerSet::empty(), + None => SanitizerFnAttrs::default(), }; // Check for a sanitize annotation directly on this def. @@ -591,15 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { { // the on set is the set of sanitizers explicitly enabled. // we mask those out since we want the set of disabled sanitizers here - disabled &= !*on_set; + settings.disabled &= !*on_set; // the off set is the set of sanitizers explicitly disabled. // we or those in here. - disabled |= *off_set; + settings.disabled |= *off_set; // the on set and off set are distjoint since there's a third option: unset. // a node may not set the sanitizer setting in which case it inherits from parents. // the code above in this function does this backtracking } - disabled + settings } /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller @@ -731,7 +731,7 @@ pub(crate) fn provide(providers: &mut Providers) { codegen_fn_attrs, should_inherit_track_caller, inherited_align, - disabled_sanitizers_for, + sanitizer_settings_for, ..*providers }; } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 72786931ff8a..8d4385a2fd32 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -36,6 +36,8 @@ #![feature(box_as_ptr)] #![feature(box_patterns)] #![feature(closure_track_caller)] +#![feature(const_default)] +#![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(debug_closure_helpers)] #![feature(decl_macro)] diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index d47d811610a7..fd1f5791de4d 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -80,9 +80,9 @@ pub struct CodegenFnAttrs { /// The `#[link_section = "..."]` attribute, or what executable section this /// should be placed in. pub link_section: Option, - /// The `#[sanitize(xyz = "off")]` attribute. Indicates sanitizers for which - /// instrumentation should be disabled inside the function. - pub no_sanitize: SanitizerSet, + /// The `#[sanitize(xyz = "off")]` attribute. Indicates the settings for each + /// sanitizer for this function. + pub sanitizers: SanitizerFnAttrs, /// The `#[instruction_set(set)]` attribute. Indicates if the generated code should /// be generated against a specific instruction set. Only usable on architectures which allow /// switching between multiple instruction sets. @@ -209,7 +209,7 @@ impl CodegenFnAttrs { linkage: None, import_linkage: None, link_section: None, - no_sanitize: SanitizerSet::empty(), + sanitizers: SanitizerFnAttrs::default(), instruction_set: None, alignment: None, patchable_function_entry: None, @@ -241,3 +241,15 @@ impl CodegenFnAttrs { } } } + +#[derive(Clone, Copy, Debug, HashStable, TyEncodable, TyDecodable, Eq, PartialEq)] +pub struct SanitizerFnAttrs { + pub disabled: SanitizerSet, +} + +impl const Default for SanitizerFnAttrs { + fn default() -> Self { + Self { disabled: SanitizerSet::empty() } + } + +} diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 46100358c7d7..404330a9a45a 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -348,6 +348,7 @@ trivial! { rustc_middle::ty::UnusedGenericParams, rustc_middle::ty::util::AlwaysRequiresDrop, rustc_middle::ty::Visibility, + rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, rustc_session::config::CrateType, rustc_session::config::EntryFnType, rustc_session::config::OptLevel, @@ -365,7 +366,6 @@ trivial! { rustc_span::Symbol, rustc_span::Ident, rustc_target::spec::PanicStrategy, - rustc_target::spec::SanitizerSet, rustc_type_ir::Variance, u32, usize, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e6bbdc87d995..a2fb797c3f28 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -97,7 +97,7 @@ use rustc_session::lint::LintExpectationId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; -use rustc_target::spec::{PanicStrategy, SanitizerSet}; +use rustc_target::spec::PanicStrategy; use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir}; pub use self::keys::{AsLocalKey, Key, LocalCrate}; @@ -105,7 +105,7 @@ pub use self::plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsur use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; -use crate::middle::codegen_fn_attrs::CodegenFnAttrs; +use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::middle::deduced_param_attrs::DeducedParamAttrs; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; @@ -2735,8 +2735,8 @@ rustc_queries! { /// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the /// crate root. /// - /// Returns the set of sanitizers that is explicitly disabled for this def. - query disabled_sanitizers_for(key: LocalDefId) -> SanitizerSet { + /// Returns the sanitizer settings for this def. + query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs { desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } feedable } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7e1dd76f903d..9e3ca9b30d53 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -818,7 +818,7 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>( } let codegen_fn_attrs = tcx.codegen_fn_attrs(inliner.caller_def_id()); - if callee_attrs.no_sanitize != codegen_fn_attrs.no_sanitize { + if callee_attrs.sanitizers != codegen_fn_attrs.sanitizers { return Err("incompatible sanitizer set"); } diff --git a/tests/ui/sanitizer/inline-always-sanitize.rs b/tests/ui/sanitizer/inline-always-sanitize.rs index d6ee214e9b37..97bb60df72a6 100644 --- a/tests/ui/sanitizer/inline-always-sanitize.rs +++ b/tests/ui/sanitizer/inline-always-sanitize.rs @@ -5,7 +5,7 @@ #[inline(always)] //~^ NOTE inlining requested here #[sanitize(address = "off")] -//~^ WARN setting `sanitize` off will have no effect after inlining +//~^ WARN non-default `sanitize` will have no effect after inlining //~| NOTE on by default fn x() { } diff --git a/tests/ui/sanitizer/inline-always-sanitize.stderr b/tests/ui/sanitizer/inline-always-sanitize.stderr index ed4794721695..fbfe5378c092 100644 --- a/tests/ui/sanitizer/inline-always-sanitize.stderr +++ b/tests/ui/sanitizer/inline-always-sanitize.stderr @@ -1,4 +1,4 @@ -warning: setting `sanitize` off will have no effect after inlining +warning: non-default `sanitize` will have no effect after inlining --> $DIR/inline-always-sanitize.rs:7:1 | LL | #[sanitize(address = "off")] From d198633b958627b718dbd19cb24adf0c80f936c9 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Fri, 23 May 2025 14:35:28 +0200 Subject: [PATCH 446/525] add realtime sanitizer --- .../src/attributes/codegen_attrs.rs | 20 +++++++++-- compiler/rustc_codegen_llvm/src/attributes.rs | 14 +++++++- compiler/rustc_codegen_llvm/src/back/write.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 3 ++ compiler/rustc_codegen_ssa/src/back/link.rs | 3 ++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 14 +++++--- .../rustc_hir/src/attrs/data_structures.rs | 18 +++++++++- compiler/rustc_hir/src/lib.rs | 3 ++ .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 9 +++++ .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 6 ++++ .../src/middle/codegen_fn_attrs.rs | 6 ++-- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_session/src/options.rs | 3 +- compiler/rustc_span/src/symbol.rs | 4 +++ compiler/rustc_target/src/spec/mod.rs | 3 ++ .../src/spec/targets/aarch64_apple_darwin.rs | 5 ++- .../src/spec/targets/aarch64_apple_ios.rs | 4 ++- .../src/spec/targets/aarch64_apple_ios_sim.rs | 4 ++- .../spec/targets/aarch64_unknown_linux_gnu.rs | 3 +- .../src/spec/targets/x86_64_apple_darwin.rs | 3 +- .../spec/targets/x86_64_unknown_linux_gnu.rs | 3 +- src/bootstrap/download-ci-llvm-stamp | 2 +- src/bootstrap/src/core/build_steps/llvm.rs | 18 +++++----- src/doc/rustc-dev-guide/src/sanitizers.md | 2 +- src/tools/compiletest/src/common.rs | 1 + .../src/directives/directive_names.rs | 1 + src/tools/compiletest/src/directives/needs.rs | 7 ++++ tests/ui/attributes/malformed-attrs.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 2 +- tests/ui/sanitize-attr/invalid-sanitize.rs | 3 ++ .../ui/sanitize-attr/invalid-sanitize.stderr | 36 +++++++++++++++---- tests/ui/sanitizer/realtime-alloc.rs | 20 +++++++++++ tests/ui/sanitizer/realtime-blocking.rs | 25 +++++++++++++ tests/ui/sanitizer/realtime-caller.rs | 28 +++++++++++++++ 34 files changed, 240 insertions(+), 38 deletions(-) create mode 100644 tests/ui/sanitizer/realtime-alloc.rs create mode 100644 tests/ui/sanitizer/realtime-blocking.rs create mode 100644 tests/ui/sanitizer/realtime-caller.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 1270f8759d1b..b4ecbe6e4de6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy}; +use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy}; use rustc_session::parse::feature_err; use super::prelude::*; @@ -592,7 +592,8 @@ impl SingleAttributeParser for SanitizeParser { r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, - r#"thread = "on|off""# + r#"thread = "on|off""#, + r#"realtime = "nonblocking|blocking|caller""#, ]); const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; @@ -606,6 +607,7 @@ impl SingleAttributeParser for SanitizeParser { let mut on_set = SanitizerSet::empty(); let mut off_set = SanitizerSet::empty(); + let mut rtsan = None; for item in list.mixed() { let Some(item) = item.meta_item() else { @@ -654,6 +656,17 @@ impl SingleAttributeParser for SanitizeParser { Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK), Some(sym::thread) => apply(SanitizerSet::THREAD), Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS), + Some(sym::realtime) => match value.value_as_str() { + Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking), + Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking), + Some(sym::caller) => rtsan = Some(RtsanSetting::Caller), + _ => { + cx.expected_specific_argument_strings( + value.value_span, + &[sym::nonblocking, sym::blocking, sym::caller], + ); + } + }, _ => { cx.expected_specific_argument_strings( item.path().span(), @@ -666,6 +679,7 @@ impl SingleAttributeParser for SanitizeParser { sym::shadow_call_stack, sym::thread, sym::hwaddress, + sym::realtime, ], ); continue; @@ -673,7 +687,7 @@ impl SingleAttributeParser for SanitizeParser { } } - Some(AttributeKind::Sanitize { on_set, off_set, span: cx.attr_span }) + Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span }) } } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 7b8b7ff3c291..89878d1e7e20 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,5 +1,5 @@ //! Set and unset common attributes on LLVM values. -use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr, RtsanSetting}; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, @@ -131,6 +131,18 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>( if enabled.contains(SanitizerSet::SAFESTACK) { attrs.push(llvm::AttributeKind::SanitizeSafeStack.create_attr(cx.llcx)); } + if tcx.sess.sanitizers().contains(SanitizerSet::REALTIME) { + match sanitizer_fn_attr.rtsan_setting { + RtsanSetting::Nonblocking => { + attrs.push(llvm::AttributeKind::SanitizeRealtimeNonblocking.create_attr(cx.llcx)) + } + RtsanSetting::Blocking => { + attrs.push(llvm::AttributeKind::SanitizeRealtimeBlocking.create_attr(cx.llcx)) + } + // caller is the default, so no llvm attribute + RtsanSetting::Caller => (), + } + } attrs } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b582d587d9f8..1880e43ca76a 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -633,6 +633,7 @@ pub(crate) unsafe fn llvm_optimize( sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY), sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY), sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int, + sanitize_realtime: config.sanitizer.contains(SanitizerSet::REALTIME), sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD), sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS), sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS), diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 9a391d57d6fb..1a9a6f7e112c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -290,6 +290,8 @@ pub(crate) enum AttributeKind { DeadOnReturn = 44, CapturesReadOnly = 45, CapturesNone = 46, + SanitizeRealtimeNonblocking = 47, + SanitizeRealtimeBlocking = 48, } /// LLVMIntPredicate @@ -482,6 +484,7 @@ pub(crate) struct SanitizerOptions { pub sanitize_memory: bool, pub sanitize_memory_recover: bool, pub sanitize_memory_track_origins: c_int, + pub sanitize_realtime: bool, pub sanitize_thread: bool, pub sanitize_hwaddress: bool, pub sanitize_hwaddress_recover: bool, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index fa730bae610c..ce496c713791 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1252,6 +1252,9 @@ fn add_sanitizer_libraries( if sanitizer.contains(SanitizerSet::SAFESTACK) { link_sanitizer_runtime(sess, flavor, linker, "safestack"); } + if sanitizer.contains(SanitizerSet::REALTIME) { + link_sanitizer_runtime(sess, flavor, linker, "rtsan"); + } } fn link_sanitizer_runtime( diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 5dd1365f2645..8fbd41020fb0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -349,9 +349,10 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment); - // Compute the disabled sanitizers. - codegen_fn_attrs.sanitizers.disabled |= - tcx.sanitizer_settings_for(did).disabled; + // Passed in sanitizer settings are always the default. + assert!(codegen_fn_attrs.sanitizers == SanitizerFnAttrs::default()); + // Replace with #[sanitize] value + codegen_fn_attrs.sanitizers = tcx.sanitizer_settings_for(did); // On trait methods, inherit the `#[align]` of the trait's method prototype. codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did)); @@ -587,7 +588,7 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs }; // Check for a sanitize annotation directly on this def. - if let Some((on_set, off_set)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, ..} => (on_set, off_set)) + if let Some((on_set, off_set, rtsan)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, rtsan, ..} => (on_set, off_set, rtsan)) { // the on set is the set of sanitizers explicitly enabled. // we mask those out since we want the set of disabled sanitizers here @@ -598,6 +599,11 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs // the on set and off set are distjoint since there's a third option: unset. // a node may not set the sanitizer setting in which case it inherits from parents. // the code above in this function does this backtracking + + // if rtsan was specified here override the parent + if let Some(rtsan) = rtsan { + settings.rtsan_setting = *rtsan; + } } settings } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index a5f7debe1787..b1b872808c8f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -382,6 +382,16 @@ pub struct DebugVisualizer { pub path: Symbol, } +#[derive(Clone, Copy, Debug, Decodable, Encodable, Eq, PartialEq)] +#[derive(HashStable_Generic, PrintAttribute)] +#[derive_const(Default)] +pub enum RtsanSetting { + Nonblocking, + Blocking, + #[default] + Caller, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -689,7 +699,13 @@ pub enum AttributeKind { /// /// the on set and off set are distjoint since there's a third option: unset. /// a node may not set the sanitizer setting in which case it inherits from parents. - Sanitize { on_set: SanitizerSet, off_set: SanitizerSet, span: Span }, + /// rtsan is unset if None + Sanitize { + on_set: SanitizerSet, + off_set: SanitizerSet, + rtsan: Option, + span: Span, + }, /// Represents `#[should_panic]` ShouldPanic { reason: Option, span: Span }, diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 0d0a1f6b76a2..7a5776f0d5a9 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -6,6 +6,9 @@ #![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] +#![feature(const_default)] +#![feature(const_trait_impl)] +#![feature(derive_const)] #![feature(exhaustive_patterns)] #![feature(never_type)] #![feature(variant_count)] diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 178b43c93ef6..143cc9479089 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -38,6 +38,7 @@ #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" +#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" #include "llvm/Transforms/Scalar/AnnotationRemarks.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" @@ -531,6 +532,7 @@ struct LLVMRustSanitizerOptions { bool SanitizeMemory; bool SanitizeMemoryRecover; int SanitizeMemoryTrackOrigins; + bool SanitizerRealtime; bool SanitizeThread; bool SanitizeHWAddress; bool SanitizeHWAddressRecover; @@ -786,6 +788,13 @@ extern "C" LLVMRustResult LLVMRustOptimize( MPM.addPass(HWAddressSanitizerPass(opts)); }); } + if (SanitizerOptions->SanitizerRealtime) { + OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM, + OptimizationLevel Level, + ThinOrFullLTOPhase phase) { + MPM.addPass(RealtimeSanitizerPass()); + }); + } } ModulePassManager MPM; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 2d87ea232eea..f8b7cb257da8 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -246,6 +246,8 @@ enum class LLVMRustAttributeKind { DeadOnReturn = 44, CapturesReadOnly = 45, CapturesNone = 46, + SanitizeRealtimeNonblocking = 47, + SanitizeRealtimeBlocking = 48, }; static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { @@ -342,6 +344,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { case LLVMRustAttributeKind::CapturesReadOnly: case LLVMRustAttributeKind::CapturesNone: report_fatal_error("Should be handled separately"); + case LLVMRustAttributeKind::SanitizeRealtimeNonblocking: + return Attribute::SanitizeRealtime; + case LLVMRustAttributeKind::SanitizeRealtimeBlocking: + return Attribute::SanitizeRealtimeBlocking; } report_fatal_error("bad LLVMRustAttributeKind"); } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index fd1f5791de4d..5a28d56d4e54 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use rustc_abi::Align; -use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr}; +use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr, RtsanSetting}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; @@ -245,11 +245,11 @@ impl CodegenFnAttrs { #[derive(Clone, Copy, Debug, HashStable, TyEncodable, TyDecodable, Eq, PartialEq)] pub struct SanitizerFnAttrs { pub disabled: SanitizerSet, + pub rtsan_setting: RtsanSetting, } impl const Default for SanitizerFnAttrs { fn default() -> Self { - Self { disabled: SanitizerSet::empty() } + Self { disabled: SanitizerSet::empty(), rtsan_setting: RtsanSetting::default() } } - } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5944a1e8da5d..81259f343375 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -212,7 +212,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => { self.check_custom_mir(dialect, phase, attr_span) } - &Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, span: attr_span}) => { + &Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, rtsan: _, span: attr_span}) => { self.check_sanitize(attr_span, on_set | off_set, span, target); }, Attribute::Parsed(AttributeKind::Link(_, attr_span)) => { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b49194b82f3a..acb3316c027c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -808,7 +808,7 @@ mod desc { pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy; pub(crate) const parse_oom_strategy: &str = "either `panic` or `abort`"; pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; - pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`"; + pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'"; pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; pub(crate) const parse_cfguard: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; @@ -1253,6 +1253,7 @@ pub mod parse { "thread" => SanitizerSet::THREAD, "hwaddress" => SanitizerSet::HWADDRESS, "safestack" => SanitizerSet::SAFESTACK, + "realtime" => SanitizerSet::REALTIME, _ => return false, } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38718bad9e57..6570557c6500 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -583,6 +583,7 @@ symbols! { bitxor_assign, black_box, block, + blocking, bool, bool_then, borrowck_graphviz_format, @@ -616,6 +617,7 @@ symbols! { call_once, call_once_future, call_ref_future, + caller, caller_location, capture_disjoint_fields, carrying_mul_add, @@ -1561,6 +1563,7 @@ symbols! { non_exhaustive_omitted_patterns_lint, non_lifetime_binders, non_modrs_mods, + nonblocking, none, nontemporal_store, noop_method_borrow, @@ -1801,6 +1804,7 @@ symbols! { read_via_copy, readonly, realloc, + realtime, reason, reborrow, receiver, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 023c62812c86..e0741f8c824f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1177,6 +1177,7 @@ bitflags::bitflags! { const KERNELADDRESS = 1 << 9; const SAFESTACK = 1 << 10; const DATAFLOW = 1 << 11; + const REALTIME = 1 << 12; } } rustc_data_structures::external_bitflags_debug! { SanitizerSet } @@ -1227,6 +1228,7 @@ impl SanitizerSet { SanitizerSet::SHADOWCALLSTACK => "shadow-call-stack", SanitizerSet::THREAD => "thread", SanitizerSet::HWADDRESS => "hwaddress", + SanitizerSet::REALTIME => "realtime", _ => return None, }) } @@ -1271,6 +1273,7 @@ impl FromStr for SanitizerSet { "shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK, "thread" => SanitizerSet::THREAD, "hwaddress" => SanitizerSet::HWADDRESS, + "realtime" => SanitizerSet::REALTIME, s => return Err(format!("unknown sanitizer {s}")), }) } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index e19604725559..ecfd6ebba863 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -20,7 +20,10 @@ pub(crate) fn target() -> Target { cpu: "apple-m1".into(), max_atomic_width: Some(128), // FIXME: The leak sanitizer currently fails the tests, see #88132. - supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD, + supported_sanitizers: SanitizerSet::ADDRESS + | SanitizerSet::CFI + | SanitizerSet::THREAD + | SanitizerSet::REALTIME, supports_xray: true, ..opts }, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index 3b522c34522b..85b4a0614a85 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -18,7 +18,9 @@ pub(crate) fn target() -> Target { options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), - supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD, + supported_sanitizers: SanitizerSet::ADDRESS + | SanitizerSet::THREAD + | SanitizerSet::REALTIME, ..opts }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index d366ed264820..2924ba5ebb10 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -18,7 +18,9 @@ pub(crate) fn target() -> Target { options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), - supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD, + supported_sanitizers: SanitizerSet::ADDRESS + | SanitizerSet::THREAD + | SanitizerSet::REALTIME, ..opts }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs index c4b1f2c05eb1..f7e1cbfac263 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs @@ -30,7 +30,8 @@ pub(crate) fn target() -> Target { | SanitizerSet::MEMORY | SanitizerSet::MEMTAG | SanitizerSet::THREAD - | SanitizerSet::HWADDRESS, + | SanitizerSet::HWADDRESS + | SanitizerSet::REALTIME, supports_xray: true, ..base::linux_gnu::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index 8892c50d8447..cb517b2a357a 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -21,7 +21,8 @@ pub(crate) fn target() -> Target { supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK - | SanitizerSet::THREAD, + | SanitizerSet::THREAD + | SanitizerSet::REALTIME, supports_xray: true, ..opts }, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs index adb7a43a6232..defa9f146d79 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs @@ -17,7 +17,8 @@ pub(crate) fn target() -> Target { | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::SAFESTACK - | SanitizerSet::THREAD; + | SanitizerSet::THREAD + | SanitizerSet::REALTIME; base.supports_xray = true; Target { diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index b70d452b427c..e79391a107aa 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/139931 +Last change is for: https://github.com/rust-lang/rust/pull/147935 diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index d43d261ad6c3..7e1b59351e04 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1262,13 +1262,13 @@ fn supported_sanitizers( }; match &*target.triple { - "aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), - "aarch64-apple-ios" => darwin_libs("ios", &["asan", "tsan"]), - "aarch64-apple-ios-sim" => darwin_libs("iossim", &["asan", "tsan"]), + "aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan", "rtsan"]), + "aarch64-apple-ios" => darwin_libs("ios", &["asan", "tsan", "rtsan"]), + "aarch64-apple-ios-sim" => darwin_libs("iossim", &["asan", "tsan", "rtsan"]), "aarch64-apple-ios-macabi" => darwin_libs("osx", &["asan", "lsan", "tsan"]), "aarch64-unknown-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]), "aarch64-unknown-linux-gnu" => { - common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) + common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan", "rtsan"]) } "aarch64-unknown-linux-ohos" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) @@ -1276,7 +1276,7 @@ fn supported_sanitizers( "loongarch64-unknown-linux-gnu" | "loongarch64-unknown-linux-musl" => { common_libs("linux", "loongarch64", &["asan", "lsan", "msan", "tsan"]) } - "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), + "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan", "rtsan"]), "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), "x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]), "x86_64-apple-ios-macabi" => darwin_libs("osx", &["asan", "lsan", "tsan"]), @@ -1286,9 +1286,11 @@ fn supported_sanitizers( } "x86_64-unknown-illumos" => common_libs("illumos", "x86_64", &["asan"]), "x86_64-pc-solaris" => common_libs("solaris", "x86_64", &["asan"]), - "x86_64-unknown-linux-gnu" => { - common_libs("linux", "x86_64", &["asan", "dfsan", "lsan", "msan", "safestack", "tsan"]) - } + "x86_64-unknown-linux-gnu" => common_libs( + "linux", + "x86_64", + &["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan"], + ), "x86_64-unknown-linux-musl" => { common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"]) } diff --git a/src/doc/rustc-dev-guide/src/sanitizers.md b/src/doc/rustc-dev-guide/src/sanitizers.md index fd91fdb2504d..53df27412f05 100644 --- a/src/doc/rustc-dev-guide/src/sanitizers.md +++ b/src/doc/rustc-dev-guide/src/sanitizers.md @@ -45,7 +45,7 @@ implementation: [marked][sanitizer-attribute] with appropriate LLVM attribute: `SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or `SanitizeThread`. By default all functions are instrumented, but this - behaviour can be changed with `#[sanitize(xyz = "on|off")]`. + behaviour can be changed with `#[sanitize(xyz = "on|off|")]`. * The decision whether to perform instrumentation or not is possible only at a function granularity. In the cases were those decision differ between diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 1f893fecb54b..aa8e340ee755 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -174,6 +174,7 @@ pub enum Sanitizer { ShadowCallStack, Thread, Hwaddress, + Realtime, } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 1474df146f9c..d60819653f6c 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -165,6 +165,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-sanitizer-leak", "needs-sanitizer-memory", "needs-sanitizer-memtag", + "needs-sanitizer-realtime", "needs-sanitizer-safestack", "needs-sanitizer-shadow-call-stack", "needs-sanitizer-support", diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 5e9fe59d8d1c..713a63317b72 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -69,6 +69,11 @@ pub(super) fn handle_needs( condition: cache.sanitizer_memtag, ignore_reason: "ignored on targets without memory tagging sanitizer", }, + Need { + name: "needs-sanitizer-realtime", + condition: cache.sanitizer_realtime, + ignore_reason: "ignored on targets without realtime sanitizer", + }, Need { name: "needs-sanitizer-shadow-call-stack", condition: cache.sanitizer_shadow_call_stack, @@ -320,6 +325,7 @@ pub(super) struct CachedNeedsConditions { sanitizer_thread: bool, sanitizer_hwaddress: bool, sanitizer_memtag: bool, + sanitizer_realtime: bool, sanitizer_shadow_call_stack: bool, sanitizer_safestack: bool, xray: bool, @@ -346,6 +352,7 @@ impl CachedNeedsConditions { sanitizer_thread: sanitizers.contains(&Sanitizer::Thread), sanitizer_hwaddress: sanitizers.contains(&Sanitizer::Hwaddress), sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag), + sanitizer_realtime: sanitizers.contains(&Sanitizer::Realtime), sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack), sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack), xray: config.target_cfg().xray, diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5627cb452a81..d8d9c182529e 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -513,7 +513,7 @@ LL | #[sanitize(hwaddress = "on|off")] | ++++++++++++++++++++++ LL | #[sanitize(kcfi = "on|off")] | +++++++++++++++++ - = and 5 other candidates + = and 6 other candidates error[E0565]: malformed `no_implicit_prelude` attribute input --> $DIR/malformed-attrs.rs:101:1 diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 8205756d64dd..d9a9981177d2 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -120,7 +120,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, and `thread` + = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/sanitize-attr/invalid-sanitize.rs b/tests/ui/sanitize-attr/invalid-sanitize.rs index 957ce780ad0f..707e1a3be777 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.rs +++ b/tests/ui/sanitize-attr/invalid-sanitize.rs @@ -19,3 +19,6 @@ fn name_value() {} #[sanitize] //~ ERROR malformed `sanitize` attribute input fn just_word() {} + +#[sanitize(realtime = "on")] //~ ERROR malformed `sanitize` attribute input +fn wrong_value_realtime() {} diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index ec0a93be1420..08aa5257f3f0 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr @@ -4,7 +4,7 @@ error[E0539]: malformed `sanitize` attribute input LL | #[sanitize(brontosaurus = "off")] | ^^^^^^^^^^^------------^^^^^^^^^^ | | - | valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread" or "hwaddress" + | valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime" | help: try changing it to one of the following valid forms of the attribute | @@ -20,7 +20,7 @@ LL + #[sanitize(hwaddress = "on|off")] LL - #[sanitize(brontosaurus = "off")] LL + #[sanitize(kcfi = "on|off")] | - = and 5 other candidates + = and 6 other candidates error: multiple `sanitize` attributes --> $DIR/invalid-sanitize.rs:6:1 @@ -68,7 +68,7 @@ LL + #[sanitize(hwaddress = "on|off")] LL - #[sanitize(address = "bogus")] LL + #[sanitize(kcfi = "on|off")] | - = and 5 other candidates + = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:17:1 @@ -90,7 +90,7 @@ LL + #[sanitize(hwaddress = "on|off")] LL - #[sanitize = "off"] LL + #[sanitize(kcfi = "on|off")] | - = and 5 other candidates + = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:20:1 @@ -108,8 +108,32 @@ LL | #[sanitize(hwaddress = "on|off")] | ++++++++++++++++++++++ LL | #[sanitize(kcfi = "on|off")] | +++++++++++++++++ - = and 5 other candidates + = and 6 other candidates -error: aborting due to 6 previous errors +error[E0539]: malformed `sanitize` attribute input + --> $DIR/invalid-sanitize.rs:23:1 + | +LL | #[sanitize(realtime = "on")] + | ^^^^^^^^^^^^^^^^^^^^^^----^^ + | | + | valid arguments are "nonblocking", "blocking" or "caller" + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[sanitize(realtime = "on")] +LL + #[sanitize(address = "on|off")] + | +LL - #[sanitize(realtime = "on")] +LL + #[sanitize(cfi = "on|off")] + | +LL - #[sanitize(realtime = "on")] +LL + #[sanitize(hwaddress = "on|off")] + | +LL - #[sanitize(realtime = "on")] +LL + #[sanitize(kcfi = "on|off")] + | + = and 6 other candidates + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/sanitizer/realtime-alloc.rs b/tests/ui/sanitizer/realtime-alloc.rs new file mode 100644 index 000000000000..2b4039dcf308 --- /dev/null +++ b/tests/ui/sanitizer/realtime-alloc.rs @@ -0,0 +1,20 @@ +//@ needs-sanitizer-support +//@ needs-sanitizer-realtime +// +//@ compile-flags: -Z sanitizer=realtime +//@ exec-env: RTSAN_OPTIONS=abort_on_error=0 +// +//@ run-fail +//@ error-pattern: Intercepted call to real-time unsafe function `malloc` in real-time context! +//@ ignore-backends: gcc +#![feature(sanitize)] + +#[sanitize(realtime = "nonblocking")] +fn sanitizer_on() { + let mut vec = vec![0, 1, 2]; + println!("alloc not detected"); +} + +fn main() { + sanitizer_on(); +} diff --git a/tests/ui/sanitizer/realtime-blocking.rs b/tests/ui/sanitizer/realtime-blocking.rs new file mode 100644 index 000000000000..a27448a346f0 --- /dev/null +++ b/tests/ui/sanitizer/realtime-blocking.rs @@ -0,0 +1,25 @@ +//@ needs-sanitizer-support +//@ needs-sanitizer-realtime +// +//@ compile-flags: -Z sanitizer=realtime +//@ exec-env: RTSAN_OPTIONS=abort_on_error=0 +// +//@ run-fail +//@ error-pattern: Call to blocking function +//@ error-pattern: realtime_blocking::blocking:: +//@ ignore-backends: gcc +#![feature(sanitize)] + +#[sanitize(realtime = "nonblocking")] +fn sanitizer_on() { + blocking(); +} + +#[sanitize(realtime = "blocking")] +fn blocking() { + println!("blocking call not detected"); +} + +fn main() { + sanitizer_on(); +} diff --git a/tests/ui/sanitizer/realtime-caller.rs b/tests/ui/sanitizer/realtime-caller.rs new file mode 100644 index 000000000000..d606d71cba02 --- /dev/null +++ b/tests/ui/sanitizer/realtime-caller.rs @@ -0,0 +1,28 @@ +//@ needs-sanitizer-support +//@ needs-sanitizer-realtime +// +//@ compile-flags: -Z sanitizer=realtime +//@ exec-env: RTSAN_OPTIONS=abort_on_error=0 +// +//@ run-fail +//@ error-pattern: RealtimeSanitizer: blocking-call +//@ ignore-backends: gcc +#![feature(sanitize)] + +#[sanitize(realtime = "nonblocking")] +fn sanitizer_on() { + caller(); +} + +fn caller() { + blocking() +} + +#[sanitize(realtime = "blocking")] +fn blocking() { + println!("blocking call not detected"); +} + +fn main() { + sanitizer_on(); +} From 8e926c814fed80ec9a666078410e6d163e151ad1 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Tue, 26 Aug 2025 20:58:53 +0200 Subject: [PATCH 447/525] add warning for async --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 24 ++++++++++- compiler/rustc_lint_defs/src/builtin.rs | 32 +++++++++++++++ tests/ui/sanitize-attr/invalid-sanitize.rs | 16 ++++++++ .../ui/sanitize-attr/invalid-sanitize.stderr | 40 ++++++++++++++----- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8fbd41020fb0..720f8061c4e6 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; -use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, UsedBy}; +use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, RtsanSetting, UsedBy}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; @@ -468,6 +468,28 @@ fn check_result( }) } + // warn for nonblocking async fn. + // This doesn't behave as expected, because the executor can run blocking code without the sanitizer noticing. + if codegen_fn_attrs.sanitizers.rtsan_setting == RtsanSetting::Nonblocking + && let Some(sanitize_span) = interesting_spans.sanitize + // async function + && (tcx.asyncness(did).is_async() || (tcx.is_closure_like(did.into()) + // async block + && (tcx.coroutine_is_async(did.into()) + // async closure + || tcx.coroutine_is_async(tcx.coroutine_for_closure(did))))) + { + let hir_id = tcx.local_def_id_to_hir_id(did); + tcx.node_span_lint( + lint::builtin::RTSAN_NONBLOCKING_ASYNC, + hir_id, + sanitize_span, + |lint| { + lint.primary_message(r#"the async executor can run blocking code, without realtime sanitizer catching it"#); + } + ); + } + // error when specifying link_name together with link_ordinal if let Some(_) = codegen_fn_attrs.symbol_name && let Some(_) = codegen_fn_attrs.link_ordinal diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 86aa6341aff8..7e762a878078 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -88,6 +88,7 @@ declare_lint_pass! { RENAMED_AND_REMOVED_LINTS, REPR_C_ENUMS_LARGER_THAN_INT, REPR_TRANSPARENT_NON_ZST_FIELDS, + RTSAN_NONBLOCKING_ASYNC, RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, RUST_2021_INCOMPATIBLE_OR_PATTERNS, RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, @@ -2333,6 +2334,37 @@ declare_lint! { r#"detects incompatible use of `#[inline(always)]` and `#[sanitize(... = "off")]`"#, } +declare_lint! { + /// The `rtsan_nonblocking_async` lint detects incompatible use of + /// [`#[sanitize(realtime = "nonblocking")]`][sanitize] on async functions. + /// + /// [sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html + /// ### Example + /// + #[cfg_attr(bootstrap, doc = "```ignore")] + #[cfg_attr(not(bootstrap), doc = "```rust,no_run")] + /// #![feature(sanitize)] + /// + /// #[sanitize(realtime = "nonblocking")] + /// async fn x() {} + /// + /// fn main() { + /// x(); + /// } + #[cfg_attr(bootstrap, doc = "```")] + #[cfg_attr(not(bootstrap), doc = "```")] + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The sanitizer only considers the async function body nonblocking. The executor, which runs on + /// every `.await` point can run non-realtime code, without the sanitizer catching it. + pub RTSAN_NONBLOCKING_ASYNC, + Warn, + r#"detects incompatible uses of `#[sanitize(realtime = "nonblocking")]` on async functions"#, +} + declare_lint! { /// The `asm_sub_register` lint detects using only a subset of a register /// for inline asm inputs. diff --git a/tests/ui/sanitize-attr/invalid-sanitize.rs b/tests/ui/sanitize-attr/invalid-sanitize.rs index 707e1a3be777..63eef5166484 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.rs +++ b/tests/ui/sanitize-attr/invalid-sanitize.rs @@ -1,3 +1,4 @@ +//@ edition:2018 #![feature(sanitize)] #[sanitize(brontosaurus = "off")] //~ ERROR malformed `sanitize` attribute input @@ -22,3 +23,18 @@ fn just_word() {} #[sanitize(realtime = "on")] //~ ERROR malformed `sanitize` attribute input fn wrong_value_realtime() {} + +#[sanitize(realtime = "nonblocking")] //~ WARN: the async executor can run blocking code, without realtime sanitizer catching it [rtsan_nonblocking_async] +async fn async_nonblocking() {} + +fn test() { + let _async_block = { + #[sanitize(realtime = "nonblocking")] //~ WARN: the async executor can run blocking code, without realtime sanitizer catching it [rtsan_nonblocking_async] + async {} + }; + + let _async_closure = { + #[sanitize(realtime = "nonblocking")] //~ WARN: the async executor can run blocking code, without realtime sanitizer catching it [rtsan_nonblocking_async] + async || {} + }; +} diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index 08aa5257f3f0..9c1a6e5c4528 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `sanitize` attribute input - --> $DIR/invalid-sanitize.rs:3:1 + --> $DIR/invalid-sanitize.rs:4:1 | LL | #[sanitize(brontosaurus = "off")] | ^^^^^^^^^^^------------^^^^^^^^^^ @@ -23,31 +23,31 @@ LL + #[sanitize(kcfi = "on|off")] = and 6 other candidates error: multiple `sanitize` attributes - --> $DIR/invalid-sanitize.rs:6:1 + --> $DIR/invalid-sanitize.rs:7:1 | LL | #[sanitize(address = "off")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-sanitize.rs:7:1 + --> $DIR/invalid-sanitize.rs:8:1 | LL | #[sanitize(address = "off")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: multiple `sanitize` attributes - --> $DIR/invalid-sanitize.rs:10:1 + --> $DIR/invalid-sanitize.rs:11:1 | LL | #[sanitize(address = "on")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-sanitize.rs:11:1 + --> $DIR/invalid-sanitize.rs:12:1 | LL | #[sanitize(address = "off")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `sanitize` attribute input - --> $DIR/invalid-sanitize.rs:14:1 + --> $DIR/invalid-sanitize.rs:15:1 | LL | #[sanitize(address = "bogus")] | ^^^^^^^^^^^^^^^^^^^^^-------^^ @@ -71,7 +71,7 @@ LL + #[sanitize(kcfi = "on|off")] = and 6 other candidates error[E0539]: malformed `sanitize` attribute input - --> $DIR/invalid-sanitize.rs:17:1 + --> $DIR/invalid-sanitize.rs:18:1 | LL | #[sanitize = "off"] | ^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -93,7 +93,7 @@ LL + #[sanitize(kcfi = "on|off")] = and 6 other candidates error[E0539]: malformed `sanitize` attribute input - --> $DIR/invalid-sanitize.rs:20:1 + --> $DIR/invalid-sanitize.rs:21:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list @@ -111,7 +111,7 @@ LL | #[sanitize(kcfi = "on|off")] = and 6 other candidates error[E0539]: malformed `sanitize` attribute input - --> $DIR/invalid-sanitize.rs:23:1 + --> $DIR/invalid-sanitize.rs:24:1 | LL | #[sanitize(realtime = "on")] | ^^^^^^^^^^^^^^^^^^^^^^----^^ @@ -134,6 +134,26 @@ LL + #[sanitize(kcfi = "on|off")] | = and 6 other candidates -error: aborting due to 7 previous errors +warning: the async executor can run blocking code, without realtime sanitizer catching it + --> $DIR/invalid-sanitize.rs:27:1 + | +LL | #[sanitize(realtime = "nonblocking")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(rtsan_nonblocking_async)]` on by default + +warning: the async executor can run blocking code, without realtime sanitizer catching it + --> $DIR/invalid-sanitize.rs:32:9 + | +LL | ... #[sanitize(realtime = "nonblocking")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: the async executor can run blocking code, without realtime sanitizer catching it + --> $DIR/invalid-sanitize.rs:37:9 + | +LL | ... #[sanitize(realtime = "nonblocking")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0539`. From 9d671a89295af277886b8e3717883c5184452141 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Sat, 26 Jul 2025 13:42:35 +0200 Subject: [PATCH 448/525] add docs --- .../src/compiler-flags/sanitizer.md | 78 +++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 493256de99d5..f32013d75e50 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -24,6 +24,8 @@ This feature allows for use of one of following sanitizers: AddressSanitizer, but based on partial hardware assistance. * [LeakSanitizer](#leaksanitizer) a run-time memory leak detector. * [MemorySanitizer](#memorysanitizer) a detector of uninitialized reads. + * [RealtimeSanitizer](#realtimesanitizer) a detector of calls to function with + non-deterministic execution time in realtime contexts. * [ThreadSanitizer](#threadsanitizer) a fast data race detector. * Those that apart from testing, may be used in production: @@ -43,11 +45,11 @@ This feature allows for use of one of following sanitizers: To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=cfi`, `-Zsanitizer=dataflow`,`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, -`-Zsanitizer=memory`, `-Zsanitizer=memtag`, `-Zsanitizer=shadow-call-stack`, or -`-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags. -If you're working with other languages that are also instrumented with sanitizers, -you might need the `external-clangrt` flag. See the section on -[working with other languages](#working-with-other-languages). +`-Zsanitizer=memory`, `-Zsanitizer=memtag`, `-Zsanitizer=realtime`, +`-Zsanitizer=shadow-call-stack` or `-Zsanitizer=thread`. You might also need the +`--target` and `build-std` flags. If you're working with other languages that are also +instrumented with sanitizers, you might need the `external-clangrt` flag. See +the section on [working with other languages](#working-with-other-languages). Example: ```shell @@ -865,6 +867,70 @@ WARNING: ThreadSanitizer: data race (pid=10574) Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030) ``` +# RealtimeSanitizer +RealtimeSanitizer detects non-deterministic execution time calls in real-time contexts. +Functions marked with the `#[sanitize(realtime = "nonblocking")]` attribute are considered real-time functions. +When RTSan detects a call to a function with a non-deterministic execution time, like `malloc` or `free` +while in a real-time context, it reports an error. + +Besides "nonblocking" the attribute can also be used with "blocking" and "caller". +- "blocking" allows the programmer to mark their own functions as having a non-deterministic execution time. +When reaching such a function while in a real-time context a violation will be reported. A typical use +case is a userland spinlock. +- functions marked with "caller" will be sanitized if they were called from a real-time context. +If no attribute is set, this is the default. Between entering a "nonblocking" function and exiting that +function again the program will get sanitized. + +The santizer checks can be disabled using the external functions `__rtsan_disable()` and `__rtsan_enable()`. +Each call to `__rtsan_disable()` must be paired with one following call to `__rtsan_enable()`, otherwise the behaviour is undefined. + +```rust +unsafe extern "C" { + fn __rtsan_disable(); + fn __rtsan_enable(); +} +``` + +```rust,ignore (log is just a example and doesn't exist) +// in a real-time context +#[cfg(debug_assertions)] +{ + unsafe { __rtsan_disable() }; + log!("logging xyz"); + unsafe { __rtsan_enable() }; +} +``` + +See the [Clang RealtimeSanitizer documentation][clang-rtsan] for more details. + +## Example + +```rust,no_run +#![feature(sanitize)] +#[sanitize(realtime = "nonblocking")] +fn real_time() { + let vec = vec![0, 1, 2]; // call to malloc is detected and reported as an error +} +``` + +```shell +==8670==ERROR: RealtimeSanitizer: unsafe-library-call +Intercepted call to real-time unsafe function `malloc` in real-time context! + #0 0x00010107b0d8 in malloc rtsan_interceptors_posix.cpp:792 + #1 0x000100d94e70 in alloc::alloc::Global::alloc_impl::h9e1fc3206c868eea+0xa0 (realtime_vec:arm64+0x100000e70) + #2 0x000100d94d90 in alloc::alloc::exchange_malloc::hd45b5788339eb5c8+0x48 (realtime_vec:arm64+0x100000d90) + #3 0x000100d95020 in realtime_vec::main::hea6bd69b03eb9ca1+0x24 (realtime_vec:arm64+0x100001020) + #4 0x000100d94a28 in core::ops::function::FnOnce::call_once::h493b6cb9dd87d87c+0xc (realtime_vec:arm64+0x100000a28) + #5 0x000100d949b8 in std::sys::backtrace::__rust_begin_short_backtrace::hfcddb06c73c19eea+0x8 (realtime_vec:arm64+0x1000009b8) + #6 0x000100d9499c in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h202288c05a2064f0+0xc (realtime_vec:arm64+0x10000099c) + #7 0x000100d9fa34 in std::rt::lang_start_internal::h6c763158a05ac05f+0x6c (realtime_vec:arm64+0x10000ba34) + #8 0x000100d94980 in std::rt::lang_start::h1c29cc56df0598b4+0x38 (realtime_vec:arm64+0x100000980) + #9 0x000100d95118 in main+0x20 (realtime_vec:arm64+0x100001118) + #10 0x000183a46b94 in start+0x17b8 (dyld:arm64+0xfffffffffff3ab94) + +SUMMARY: RealtimeSanitizer: unsafe-library-call rtsan_interceptors_posix.cpp:792 in malloc +``` + # Instrumentation of external dependencies and std The sanitizers to varying degrees work correctly with partially instrumented @@ -918,6 +984,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT * [MemorySanitizer in Clang][clang-msan] * [MemTagSanitizer in LLVM][llvm-memtag] * [ThreadSanitizer in Clang][clang-tsan] +* [RealtimeSanitizer in Clang][clang-rtsan] [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html [clang-cfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html @@ -926,6 +993,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-kcfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-kcfi [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html +[clan-rtsan]: https://clang.llvm.org/docs/RealtimeSanitizer.html [clang-safestack]: https://clang.llvm.org/docs/SafeStack.html [clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html From 893f0d2cfff0d62ddb954ee9ec3a3f90f285ece4 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 6 Nov 2025 15:22:30 +0100 Subject: [PATCH 449/525] core docs: add notes about availability of `Atomic*::from_mut_slice` --- library/core/src/sync/atomic.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 30a42d4eb5e6..a3ceac89ef12 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1558,6 +1558,8 @@ impl AtomicPtr { /// Gets atomic access to a pointer. /// + /// **Note:** This function is only available on targets where `AtomicPtr` has the same alignment as `*const T` + /// /// # Examples /// /// ``` @@ -1625,6 +1627,8 @@ impl AtomicPtr { /// Gets atomic access to a slice of pointers. /// + /// **Note:** This function is only available on targets where `AtomicPtr` has the same alignment as `*const T` + /// /// # Examples /// /// ```ignore-wasm @@ -2804,6 +2808,14 @@ macro_rules! atomic_int { #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")] /// + #[doc = if_8_bit! { + $int_type, + no = [ + "**Note:** This function is only available on targets where `", + stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`." + ], + }] + /// /// # Examples /// /// ```ignore-wasm From 3edd25f04962dd37bd4d0f460883d0c16ff480d4 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 6 Nov 2025 10:47:47 +0800 Subject: [PATCH 450/525] Add typo suggestion for a misspelt Cargo environment variable --- compiler/rustc_builtin_macros/messages.ftl | 1 + compiler/rustc_builtin_macros/src/env.rs | 53 +++++++++++++++++ compiler/rustc_builtin_macros/src/errors.rs | 8 +++ .../env-cargo-var-typo-issue-148439.rs | 50 ++++++++++++++++ .../env-cargo-var-typo-issue-148439.stderr | 58 +++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs create mode 100644 tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 5e498bf98fb5..c9dd92ff2f24 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -156,6 +156,7 @@ builtin_macros_duplicate_macro_attribute = duplicated attribute builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead + .cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}` .custom = use `std::env::var({$var_expr})` to read the variable at run time builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index f3ac932e1b7e..af78db156a22 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -10,6 +10,7 @@ use rustc_ast::token::{self, LitKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ExprKind, GenericArg, Mutability}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; +use rustc_span::edit_distance::edit_distance; use rustc_span::{Ident, Span, Symbol, kw, sym}; use thin_vec::thin_vec; @@ -144,6 +145,12 @@ pub(crate) fn expand_env<'cx>( if let Some(msg_from_user) = custom_msg { cx.dcx() .emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user }) + } else if let Some(suggested_var) = find_similar_cargo_var(var.as_str()) { + cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVarTypo { + span, + var: *symbol, + suggested_var: Symbol::intern(suggested_var), + }) } else if is_cargo_env_var(var.as_str()) { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar { span, @@ -176,3 +183,49 @@ fn is_cargo_env_var(var: &str) -> bool { || var.starts_with("DEP_") || matches!(var, "OUT_DIR" | "OPT_LEVEL" | "PROFILE" | "HOST" | "TARGET") } + +const KNOWN_CARGO_VARS: &[&str] = &[ + // List of known Cargo environment variables that are set for crates (not build scripts, OUT_DIR etc). + // See: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates + "CARGO_PKG_VERSION", + "CARGO_PKG_VERSION_MAJOR", + "CARGO_PKG_VERSION_MINOR", + "CARGO_PKG_VERSION_PATCH", + "CARGO_PKG_VERSION_PRE", + "CARGO_PKG_AUTHORS", + "CARGO_PKG_NAME", + "CARGO_PKG_DESCRIPTION", + "CARGO_PKG_HOMEPAGE", + "CARGO_PKG_REPOSITORY", + "CARGO_PKG_LICENSE", + "CARGO_PKG_LICENSE_FILE", + "CARGO_PKG_RUST_VERSION", + "CARGO_PKG_README", + "CARGO_MANIFEST_DIR", + "CARGO_MANIFEST_PATH", + "CARGO_CRATE_NAME", + "CARGO_BIN_NAME", + "CARGO_PRIMARY_PACKAGE", +]; + +fn find_similar_cargo_var(var: &str) -> Option<&'static str> { + if !var.starts_with("CARGO_") { + return None; + } + + let lookup_len = var.chars().count(); + let max_dist = std::cmp::max(lookup_len, 3) / 3; + let mut best_match = None; + let mut best_distance = usize::MAX; + + for &known_var in KNOWN_CARGO_VARS { + if let Some(distance) = edit_distance(var, known_var, max_dist) { + if distance < best_distance { + best_distance = distance; + best_match = Some(known_var); + } + } + } + + best_match +} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index d6ffbb5a4101..dd6a5a20cceb 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -535,6 +535,14 @@ pub(crate) enum EnvNotDefined<'a> { var_expr: &'a rustc_ast::Expr, }, #[diag(builtin_macros_env_not_defined)] + #[help(builtin_macros_cargo_typo)] + CargoEnvVarTypo { + #[primary_span] + span: Span, + var: Symbol, + suggested_var: Symbol, + }, + #[diag(builtin_macros_env_not_defined)] #[help(builtin_macros_custom)] CustomEnvVar { #[primary_span] diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs new file mode 100644 index 000000000000..f859decd09ec --- /dev/null +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs @@ -0,0 +1,50 @@ +//@ edition: 2021 + +// Regression test for issue #148439 +// Ensure that when using misspelled Cargo environment variables in env!(), + +fn test_cargo_package_version() { + let _ = env!("CARGO_PACKAGE_VERSION"); + //~^ ERROR environment variable `CARGO_PACKAGE_VERSION` not defined at compile time + //~| HELP there is a similar Cargo environment variable: `CARGO_PKG_VERSION` +} + +fn test_cargo_package_name() { + let _ = env!("CARGO_PACKAGE_NAME"); + //~^ ERROR environment variable `CARGO_PACKAGE_NAME` not defined at compile time + //~| HELP there is a similar Cargo environment variable: `CARGO_PKG_NAME` +} + +fn test_cargo_package_authors() { + let _ = env!("CARGO_PACKAGE_AUTHORS"); + //~^ ERROR environment variable `CARGO_PACKAGE_AUTHORS` not defined at compile time + //~| HELP there is a similar Cargo environment variable: `CARGO_PKG_AUTHORS` +} + +fn test_cargo_manifest_directory() { + let _ = env!("CARGO_MANIFEST_DIRECTORY"); + //~^ ERROR environment variable `CARGO_MANIFEST_DIRECTORY` not defined at compile time + //~| HELP there is a similar Cargo environment variable: `CARGO_MANIFEST_DIR` +} + +fn test_cargo_pkg_version_typo() { + let _ = env!("CARGO_PKG_VERSIO"); + //~^ ERROR environment variable `CARGO_PKG_VERSIO` not defined at compile time + //~| HELP there is a similar Cargo environment variable: `CARGO_PKG_VERSION` +} + +fn test_non_cargo_var() { + // Non-Cargo variable should get different help message + let _ = env!("MY_CUSTOM_VAR"); + //~^ ERROR environment variable `MY_CUSTOM_VAR` not defined at compile time + //~| HELP use `std::env::var("MY_CUSTOM_VAR")` to read the variable at run time +} + +fn test_cargo_unknown_var() { + // Cargo-prefixed but not similar to any known variable + let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); + //~^ ERROR environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time + //~| HELP Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead +} + +fn main() {} diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr new file mode 100644 index 000000000000..e16c4d9a1f4c --- /dev/null +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr @@ -0,0 +1,58 @@ +error: environment variable `CARGO_PACKAGE_VERSION` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:7:13 + | +LL | let _ = env!("CARGO_PACKAGE_VERSION"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` + +error: environment variable `CARGO_PACKAGE_NAME` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:13:13 + | +LL | let _ = env!("CARGO_PACKAGE_NAME"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there is a similar Cargo environment variable: `CARGO_PKG_NAME` + +error: environment variable `CARGO_PACKAGE_AUTHORS` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:19:13 + | +LL | let _ = env!("CARGO_PACKAGE_AUTHORS"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there is a similar Cargo environment variable: `CARGO_PKG_AUTHORS` + +error: environment variable `CARGO_MANIFEST_DIRECTORY` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:25:13 + | +LL | let _ = env!("CARGO_MANIFEST_DIRECTORY"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there is a similar Cargo environment variable: `CARGO_MANIFEST_DIR` + +error: environment variable `CARGO_PKG_VERSIO` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:31:13 + | +LL | let _ = env!("CARGO_PKG_VERSIO"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` + +error: environment variable `MY_CUSTOM_VAR` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:38:13 + | +LL | let _ = env!("MY_CUSTOM_VAR"); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `std::env::var("MY_CUSTOM_VAR")` to read the variable at run time + +error: environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:45:13 + | +LL | let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead + +error: aborting due to 7 previous errors + From 8d597aa36528dada3cbd9bcfec889c2da6ecaaac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 4 Nov 2025 23:01:07 +0100 Subject: [PATCH 451/525] Remove implementation of LLVM SIMD intrinsics that are not needed anymore --- src/tools/miri/src/shims/x86/avx.rs | 46 +++---------- src/tools/miri/src/shims/x86/avx2.rs | 96 +++------------------------ src/tools/miri/src/shims/x86/mod.rs | 52 --------------- src/tools/miri/src/shims/x86/sse.rs | 23 ------- src/tools/miri/src/shims/x86/sse2.rs | 46 ++----------- src/tools/miri/src/shims/x86/sse3.rs | 17 ----- src/tools/miri/src/shims/x86/sse41.rs | 15 ++--- src/tools/miri/src/shims/x86/ssse3.rs | 26 +++----- 8 files changed, 35 insertions(+), 286 deletions(-) diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index ec365aa1b45e..636d308d78d9 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -1,14 +1,12 @@ use rustc_abi::CanonAbi; use rustc_apfloat::ieee::{Double, Single}; -use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, - horizontal_bin_op, mask_load, mask_store, round_all, test_bits_masked, test_high_bits_masked, - unary_op_ps, + mask_load, mask_store, round_all, test_bits_masked, test_high_bits_masked, unary_op_ps, }; use crate::*; @@ -93,21 +91,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { conditional_dot_product(this, left, right, imm, dest)?; } - // Used to implement the _mm256_h{add,sub}_p{s,d} functions. - // Horizontally add/subtract adjacent floating point values - // in `left` and `right`. - "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => { - let [left, right] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - let which = match unprefixed_name { - "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add, - "hsub.ps.256" | "hsub.pd.256" => mir::BinOp::Sub, - _ => unreachable!(), - }; - - horizontal_bin_op(this, which, /*saturating*/ false, left, right, dest)?; - } // Used to implement the _mm256_cmp_ps function. // Performs a comparison operation on each component of `left` // and `right`. For each component, returns 0 if false or u32::MAX @@ -251,40 +234,31 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unaligned copy, which is what we want. this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; } - // Used to implement the _mm256_testz_si256, _mm256_testc_si256 and - // _mm256_testnzc_si256 functions. - // Tests `op & mask == 0`, `op & mask == mask` or - // `op & mask != 0 && op & mask != mask` - "ptestz.256" | "ptestc.256" | "ptestnzc.256" => { + // Used to implement the _mm256_testnzc_si256 function. + // Tests `op & mask != 0 && op & mask != mask` + "ptestnzc.256" => { let [op, mask] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; - let res = match unprefixed_name { - "ptestz.256" => all_zero, - "ptestc.256" => masked_set, - "ptestnzc.256" => !all_zero && !masked_set, - _ => unreachable!(), - }; + let res = !all_zero && !masked_set; this.write_scalar(Scalar::from_i32(res.into()), dest)?; } // Used to implement the _mm256_testz_pd, _mm256_testc_pd, _mm256_testnzc_pd - // _mm_testz_pd, _mm_testc_pd, _mm_testnzc_pd, _mm256_testz_ps, - // _mm256_testc_ps, _mm256_testnzc_ps, _mm_testz_ps, _mm_testc_ps and + // _mm_testnzc_pd, _mm256_testz_ps, _mm256_testc_ps, _mm256_testnzc_ps and // _mm_testnzc_ps functions. // Calculates two booleans: // `direct`, which is true when the highest bit of each element of `op & mask` is zero. // `negated`, which is true when the highest bit of each element of `!op & mask` is zero. // Return `direct` (testz), `negated` (testc) or `!direct & !negated` (testnzc) - "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd" - | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" - | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => { + "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestnzc.pd" + | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" | "vtestnzc.ps" => { let [op, mask] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let (direct, negated) = test_high_bits_masked(this, op, mask)?; let res = match unprefixed_name { - "vtestz.pd.256" | "vtestz.pd" | "vtestz.ps.256" | "vtestz.ps" => direct, - "vtestc.pd.256" | "vtestc.pd" | "vtestc.ps.256" | "vtestc.ps" => negated, + "vtestz.pd.256" | "vtestz.ps.256" => direct, + "vtestc.pd.256" | "vtestc.ps.256" => negated, "vtestnzc.pd.256" | "vtestnzc.pd" | "vtestnzc.ps.256" | "vtestnzc.ps" => !direct && !negated, _ => unreachable!(), diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index ca80c0eba1e5..01e1ac6de59d 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -5,8 +5,8 @@ use rustc_span::Symbol; use rustc_target::callconv::FnAbi; use super::{ - ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb, - packusdw, packuswb, pmulhrsw, psign, shift_simd_by_scalar, shift_simd_by_simd, + ShiftOp, horizontal_bin_op, mask_load, mask_store, mpsadbw, packssdw, packsswb, packusdw, + packuswb, pmulhrsw, psign, shift_simd_by_scalar, shift_simd_by_simd, }; use crate::*; @@ -25,29 +25,20 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.avx2.").unwrap(); match unprefixed_name { - // Used to implement the _mm256_abs_epi{8,16,32} functions. - // Calculates the absolute value of packed 8/16/32-bit integers. - "pabs.b" | "pabs.w" | "pabs.d" => { - let [op] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - int_abs(this, op, dest)?; - } - // Used to implement the _mm256_h{add,adds,sub}_epi{16,32} functions. - // Horizontally add / add with saturation / subtract adjacent 16/32-bit + // Used to implement the _mm256_h{adds,subs}_epi16 functions. + // Horizontally add / subtract with saturation adjacent 16-bit // integer values in `left` and `right`. - "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => { + "phadd.sw" | "phsub.sw" => { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (which, saturating) = match unprefixed_name { - "phadd.w" | "phadd.d" => (mir::BinOp::Add, false), - "phadd.sw" => (mir::BinOp::Add, true), - "phsub.w" | "phsub.d" => (mir::BinOp::Sub, false), - "phsub.sw" => (mir::BinOp::Sub, true), + let which = match unprefixed_name { + "phadd.sw" => mir::BinOp::Add, + "phsub.sw" => mir::BinOp::Sub, _ => unreachable!(), }; - horizontal_bin_op(this, which, saturating, left, right, dest)?; + horizontal_bin_op(this, which, /*saturating*/ true, left, right, dest)?; } // Used to implement `_mm{,_mask}_{i32,i64}gather_{epi32,epi64,pd,ps}` functions // Gathers elements from `slice` using `offsets * scale` as indices. @@ -110,42 +101,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; } } - // Used to implement the _mm256_madd_epi16 function. - // Multiplies packed signed 16-bit integers in `left` and `right`, producing - // intermediate signed 32-bit integers. Horizontally add adjacent pairs of - // intermediate 32-bit integers, and pack the results in `dest`. - "pmadd.wd" => { - let [left, right] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(left_len, right_len); - assert_eq!(dest_len.strict_mul(2), left_len); - - for i in 0..dest_len { - let j1 = i.strict_mul(2); - let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; - let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - - let j2 = j1.strict_add(1); - let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; - let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; - - let dest = this.project_index(&dest, i)?; - - // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).strict_mul(right1.into()); - let mul2 = i32::from(left2).strict_mul(right2.into()); - // However, this addition can overflow in the most extreme case - // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 - let res = mul1.wrapping_add(mul2); - - this.write_scalar(Scalar::from_i32(res), &dest)?; - } - } // Used to implement the _mm256_maddubs_epi16 function. // Multiplies packed 8-bit unsigned integers from `left` and packed // signed 8-bit integers from `right` into 16-bit signed integers. Then, @@ -285,39 +240,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.copy_op(&left, &dest)?; } } - // Used to implement the _mm256_permute2x128_si256 function. - // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern. - "vperm2i128" => { - let [left, right, imm] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - assert_eq!(left.layout.size.bits(), 256); - assert_eq!(right.layout.size.bits(), 256); - assert_eq!(dest.layout.size.bits(), 256); - - // Transmute to `[i128; 2]` - - let array_layout = - this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.i128, 2))?; - let left = left.transmute(array_layout, this)?; - let right = right.transmute(array_layout, this)?; - let dest = dest.transmute(array_layout, this)?; - - let imm = this.read_scalar(imm)?.to_u8()?; - - for i in 0..2 { - let dest = this.project_index(&dest, i)?; - let src = match (imm >> i.strict_mul(4)) & 0b11 { - 0 => this.project_index(&left, 0)?, - 1 => this.project_index(&left, 1)?, - 2 => this.project_index(&right, 0)?, - 3 => this.project_index(&right, 1)?, - _ => unreachable!(), - }; - - this.copy_op(&src, &dest)?; - } - } // Used to implement the _mm256_sad_epu8 function. // Compute the absolute differences of packed unsigned 8-bit integers // in `left` and `right`, then horizontally sum each consecutive 8 diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 91893737b060..63d2b2d044b4 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -59,28 +59,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*sum, &this.project_field(dest, FieldIdx::ONE)?)?; } - // Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions, - // except for a slightly different type signature and the requirement for the "adx" target feature. - // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarryx-u32-addcarryx-u64.html - "addcarryx.u32" | "addcarryx.u64" => { - this.expect_target_feature_for_intrinsic(link_name, "adx")?; - - let is_u64 = unprefixed_name.ends_with("64"); - if is_u64 && this.tcx.sess.target.arch != Arch::X86_64 { - return interp_ok(EmulateItemResult::NotSupported); - } - let [c_in, a, b, out] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let out = this.deref_pointer_as( - out, - if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, - )?; - - let (sum, c_out) = carrying_add(this, c_in, a, b, mir::BinOp::AddWithOverflow)?; - this.write_scalar(c_out, dest)?; - this.write_immediate(*sum, &out)?; - } - // Used to implement the `_mm_pause` function. // The intrinsic is used to hint the processor that the code is in a spin-loop. // It is compiled down to a `pause` instruction. When SSE2 is not available, @@ -719,36 +697,6 @@ fn convert_float_to_int<'tcx>( interp_ok(()) } -/// Calculates absolute value of integers in `op` and stores the result in `dest`. -/// -/// In case of overflow (when the operand is the minimum value), the operation -/// will wrap around. -fn int_abs<'tcx>( - ecx: &mut crate::MiriInterpCx<'tcx>, - op: &OpTy<'tcx>, - dest: &MPlaceTy<'tcx>, -) -> InterpResult<'tcx, ()> { - let (op, op_len) = ecx.project_to_simd(op)?; - let (dest, dest_len) = ecx.project_to_simd(dest)?; - - assert_eq!(op_len, dest_len); - - let zero = ImmTy::from_int(0, op.layout.field(ecx, 0)); - - for i in 0..dest_len { - let op = ecx.read_immediate(&ecx.project_index(&op, i)?)?; - let dest = ecx.project_index(&dest, i)?; - - let lt_zero = ecx.binary_op(mir::BinOp::Lt, &op, &zero)?; - let res = - if lt_zero.to_scalar().to_bool()? { ecx.unary_op(mir::UnOp::Neg, &op)? } else { op }; - - ecx.write_immediate(*res, &dest)?; - } - - interp_ok(()) -} - /// Splits `op` (which must be a SIMD vector) into 128-bit chunks. /// /// Returns a tuple where: diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 6d8def5b53fc..309fbb61de5a 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -180,29 +180,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*res, dest)?; } - // Used to implement the _mm_cvtsi32_ss and _mm_cvtsi64_ss functions. - // Converts `right` from i32/i64 to f32. Returns a SIMD vector with - // the result in the first component and the remaining components - // are copied from `left`. - // https://www.felixcloutier.com/x86/cvtsi2ss - "cvtsi2ss" | "cvtsi642ss" => { - let [left, right] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - let (left, left_len) = this.project_to_simd(left)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - - let right = this.read_immediate(right)?; - let dest0 = this.project_index(&dest, 0)?; - let res0 = this.int_to_int_or_float(&right, dest0.layout)?; - this.write_immediate(*res0, &dest0)?; - - for i in 1..dest_len { - this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?; - } - } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 8f53adfb5ecf..9af7f05d3b27 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -36,42 +36,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Intrinsincs sufixed with "epiX" or "epuX" operate with X-bit signed or unsigned // vectors. match unprefixed_name { - // Used to implement the _mm_madd_epi16 function. - // Multiplies packed signed 16-bit integers in `left` and `right`, producing - // intermediate signed 32-bit integers. Horizontally add adjacent pairs of - // intermediate 32-bit integers, and pack the results in `dest`. - "pmadd.wd" => { - let [left, right] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(left_len, right_len); - assert_eq!(dest_len.strict_mul(2), left_len); - - for i in 0..dest_len { - let j1 = i.strict_mul(2); - let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; - let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - - let j2 = j1.strict_add(1); - let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; - let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; - - let dest = this.project_index(&dest, i)?; - - // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).strict_mul(right1.into()); - let mul2 = i32::from(left2).strict_mul(right2.into()); - // However, this addition can overflow in the most extreme case - // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 - let res = mul1.wrapping_add(mul2); - - this.write_scalar(Scalar::from_i32(res), &dest)?; - } - } // Used to implement the _mm_sad_epu8 function. // Computes the absolute differences of packed unsigned 8-bit integers in `a` // and `b`, then horizontally sum each consecutive 8 differences to produce @@ -320,10 +284,10 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*res, dest)?; } - // Used to implement the _mm_cvtsd_ss and _mm_cvtss_sd functions. - // Converts the first f64/f32 from `right` to f32/f64 and copies - // the remaining elements from `left` - "cvtsd2ss" | "cvtss2sd" => { + // Used to implement the _mm_cvtsd_ss function. + // Converts the first f64 from `right` to f32 and copies the remaining + // elements from `left` + "cvtsd2ss" => { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; @@ -336,8 +300,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Convert first element of `right` let right0 = this.read_immediate(&this.project_index(&right, 0)?)?; let dest0 = this.project_index(&dest, 0)?; - // `float_to_float_or_int` here will convert from f64 to f32 (cvtsd2ss) or - // from f32 to f64 (cvtss2sd). let res0 = this.float_to_float_or_int(&right0, dest0.layout)?; this.write_immediate(*res0, &dest0)?; diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 0fd8c3bc389b..17c8360d3399 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -1,10 +1,8 @@ use rustc_abi::CanonAbi; -use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::horizontal_bin_op; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -22,21 +20,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap(); match unprefixed_name { - // Used to implement the _mm_h{add,sub}_p{s,d} functions. - // Horizontally add/subtract adjacent floating point values - // in `left` and `right`. - "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { - let [left, right] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - let which = match unprefixed_name { - "hadd.ps" | "hadd.pd" => mir::BinOp::Add, - "hsub.ps" | "hsub.pd" => mir::BinOp::Sub, - _ => unreachable!(), - }; - - horizontal_bin_op(this, which, /*saturating*/ false, left, right, dest)?; - } // Used to implement the _mm_lddqu_si128 function. // Reads a 128-bit vector from an unaligned pointer. This intrinsic // is expected to perform better than a regular unaligned read when diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index 7736b5e443d0..1e8b0f34428d 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -157,20 +157,13 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { mpsadbw(this, left, right, imm, dest)?; } - // Used to implement the _mm_testz_si128, _mm_testc_si128 - // and _mm_testnzc_si128 functions. - // Tests `(op & mask) == 0`, `(op & mask) == mask` or - // `(op & mask) != 0 && (op & mask) != mask` - "ptestz" | "ptestc" | "ptestnzc" => { + // Used to implement the _mm_testnzc_si128 function. + // Tests `(op & mask) != 0 && (op & mask) != mask` + "ptestnzc" => { let [op, mask] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; - let res = match unprefixed_name { - "ptestz" => all_zero, - "ptestc" => masked_set, - "ptestnzc" => !all_zero && !masked_set, - _ => unreachable!(), - }; + let res = !all_zero && !masked_set; this.write_scalar(Scalar::from_i32(res.into()), dest)?; } diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 52ad6bd44199..398f538e1ba0 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -4,7 +4,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; +use super::{horizontal_bin_op, pmulhrsw, psign}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -22,13 +22,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.ssse3.").unwrap(); match unprefixed_name { - // Used to implement the _mm_abs_epi{8,16,32} functions. - // Calculates the absolute value of packed 8/16/32-bit integers. - "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => { - let [op] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - - int_abs(this, op, dest)?; - } // Used to implement the _mm_shuffle_epi8 intrinsic. // Shuffles bytes from `left` using `right` as pattern. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 @@ -58,23 +51,20 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, &dest)?; } } - // Used to implement the _mm_h{add,adds,sub}_epi{16,32} functions. - // Horizontally add / add with saturation / subtract adjacent 16/32-bit + // Used to implement the _mm_h{adds,subs}_epi16 functions. + // Horizontally add / subtract with saturation adjacent 16-bit // integer values in `left` and `right`. - "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" - | "phsub.d.128" => { + "phadd.sw.128" | "phsub.sw.128" => { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (which, saturating) = match unprefixed_name { - "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), - "phadd.sw.128" => (mir::BinOp::Add, true), - "phsub.w.128" | "phsub.d.128" => (mir::BinOp::Sub, false), - "phsub.sw.128" => (mir::BinOp::Sub, true), + let which = match unprefixed_name { + "phadd.sw.128" => mir::BinOp::Add, + "phsub.sw.128" => mir::BinOp::Sub, _ => unreachable!(), }; - horizontal_bin_op(this, which, saturating, left, right, dest)?; + horizontal_bin_op(this, which, /*saturating*/ true, left, right, dest)?; } // Used to implement the _mm_maddubs_epi16 function. // Multiplies packed 8-bit unsigned integers from `left` and packed From 1a9cc7857760043487f00c86690938d0638dd91a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 6 Nov 2025 19:45:44 +0100 Subject: [PATCH 452/525] re-use `self.get_all_attrs` result for pass indirectly attribute --- compiler/rustc_middle/src/ty/mod.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d253deb2fe8f..faa8420c20d0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1512,9 +1512,8 @@ impl<'tcx> TyCtxt<'tcx> { field_shuffle_seed ^= user_seed; } - if let Some(reprs) = - find_attr!(self.get_all_attrs(did), AttributeKind::Repr { reprs, .. } => reprs) - { + let attributes = self.get_all_attrs(did); + if let Some(reprs) = find_attr!(attributes, AttributeKind::Repr { reprs, .. } => reprs) { for (r, _) in reprs { flags.insert(match *r { attr::ReprRust => ReprFlags::empty(), @@ -1574,10 +1573,7 @@ impl<'tcx> TyCtxt<'tcx> { } // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. - if find_attr!( - self.get_all_attrs(did), - AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) - ) { + if find_attr!(attributes, AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)) { flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS); } From eec36b390e26a73e03b6750acbd4458e4ba38df0 Mon Sep 17 00:00:00 2001 From: Emily Albini Date: Thu, 6 Nov 2025 19:09:12 +0100 Subject: [PATCH 453/525] update release notes --- RELEASES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 74b0d4424c16..b14cc499b46d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,11 @@ +Version 1.91.1 (2025-11-10) +=========================== + + + +- [Enable file locking support in illumos](https://github.com/rust-lang/rust/pull/148322). This fixes Cargo not locking the build directory on illumos. +- [Fix `wasm_import_module` attribute cross-crate](https://github.com/rust-lang/rust/pull/148363). This fixes linker errors on WASM targets. + Version 1.91.0 (2025-10-30) ========================== From d59e58b744d8aaf6e729b4d9378d6c1a6aecfb5a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:06:50 +0000 Subject: [PATCH 454/525] Use the dummy codegen backend This allows getting rid of all the argument mangling hacks as well as the exported_non_generic_symbols override hack by doing cargo build instead of cargo check. This is also a prerequisite for using native jit mode support in miri that I hope to add to rustc in the future to be used with cg_clif too. --- src/tools/miri/cargo-miri/src/phases.rs | 77 ++----------------- src/tools/miri/cargo-miri/src/setup.rs | 2 +- src/tools/miri/src/bin/miri.rs | 40 ++++------ src/tools/miri/src/lib.rs | 1 + src/tools/miri/test-cargo-miri/Cargo.lock | 8 -- src/tools/miri/test-cargo-miri/Cargo.toml | 1 - .../miri/test-cargo-miri/cdylib/Cargo.toml | 12 --- .../miri/test-cargo-miri/cdylib/src/lib.rs | 6 -- .../run.local_crate.stdout.ref | 2 +- 9 files changed, 28 insertions(+), 121 deletions(-) delete mode 100644 src/tools/miri/test-cargo-miri/cdylib/Cargo.toml delete mode 100644 src/tools/miri/test-cargo-miri/cdylib/src/lib.rs diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 0716f4add9d0..0f04397b72d2 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -52,18 +52,6 @@ fn show_version() { println!(); } -fn forward_patched_extern_arg(args: &mut impl Iterator, cmd: &mut Command) { - cmd.arg("--extern"); // always forward flag, but adjust filename: - let path = args.next().expect("`--extern` should be followed by a filename"); - if let Some(lib) = path.strip_suffix(".rlib") { - // If this is an rlib, make it an rmeta. - cmd.arg(format!("{lib}.rmeta")); - } else { - // Some other extern file (e.g. a `.so`). Forward unchanged. - cmd.arg(path); - } -} - pub fn phase_cargo_miri(mut args: impl Iterator) { // Require a subcommand before any flags. // We cannot know which of those flags take arguments and which do not, @@ -276,7 +264,7 @@ pub enum RustcPhase { Rustdoc, } -pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { +pub fn phase_rustc(args: impl Iterator, phase: RustcPhase) { /// Determines if we are being invoked (as rustc) to build a crate for /// the "target" architecture, in contrast to the "host" architecture. /// Host crates are for build scripts and proc macros and still need to @@ -444,7 +432,6 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { } let mut cmd = miri(); - let mut emit_link_hack = false; // Arguments are treated very differently depending on whether this crate is // for interpretation by Miri, or for use by a build script / proc macro. if target_crate { @@ -455,7 +442,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { } // Forward arguments, but patched. - let emit_flag = "--emit"; + // This hack helps bootstrap run standard library tests in Miri. The issue is as follows: // when running `cargo miri test` on libcore, cargo builds a local copy of core and makes it // a dependency of the integration test crate. This copy duplicates all the lang items, so @@ -471,30 +458,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some() && !runnable_crate && phase == RustcPhase::Build; - while let Some(arg) = args.next() { - // Patch `--emit`: remove "link" from "--emit" to make this a check-only build. - if let Some(val) = arg.strip_prefix(emit_flag) { - // Patch this argument. First, extract its value. - let val = - val.strip_prefix('=').expect("`cargo` should pass `--emit=X` as one argument"); - let mut val: Vec<_> = val.split(',').collect(); - // Now make sure "link" is not in there, but "metadata" is. - if let Some(i) = val.iter().position(|&s| s == "link") { - emit_link_hack = true; - val.remove(i); - if !val.contains(&"metadata") { - val.push("metadata"); - } - } - cmd.arg(format!("{emit_flag}={}", val.join(","))); - continue; - } - // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files: - // https://github.com/rust-lang/miri/issues/1705 - if arg == "--extern" { - forward_patched_extern_arg(&mut args, &mut cmd); - continue; - } + for arg in args { // If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a // `lib.miri.rs` file exists, then build that instead. if replace_librs { @@ -543,17 +507,6 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { eprintln!("[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate}"); } - // Create a stub .rlib file if "link" was requested by cargo. - // This is necessary to prevent cargo from doing rebuilds all the time. - if emit_link_hack { - for filename in out_filenames() { - if verbose > 0 { - eprintln!("[cargo-miri rustc] creating fake lib file at `{}`", filename.display()); - } - File::create(filename).expect("failed to create fake lib file"); - } - } - debug_cmd("[cargo-miri rustc]", verbose, &cmd); exec(cmd); } @@ -624,17 +577,11 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); } // Forward rustc arguments. - // We need to patch "--extern" filenames because we forced a check-only - // build without cargo knowing about that: replace `.rlib` suffix by - // `.rmeta`. - // We also need to remove `--error-format` as cargo specifies that to be JSON, + // We need to remove `--error-format` as cargo specifies that to be JSON, // but when we run here, cargo does not interpret the JSON any more. `--json` // then also needs to be dropped. - let mut args = info.args.iter(); - while let Some(arg) = args.next() { - if arg == "--extern" { - forward_patched_extern_arg(&mut (&mut args).cloned(), &mut cmd); - } else if let Some(suffix) = arg.strip_prefix("--error-format") { + for arg in &info.args { + if let Some(suffix) = arg.strip_prefix("--error-format") { assert!(suffix.starts_with('=')); // Drop this argument. } else if let Some(suffix) = arg.strip_prefix("--json") { @@ -668,7 +615,7 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner } } -pub fn phase_rustdoc(mut args: impl Iterator) { +pub fn phase_rustdoc(args: impl Iterator) { let verbose = env::var("MIRI_VERBOSE") .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer")); @@ -676,15 +623,7 @@ pub fn phase_rustdoc(mut args: impl Iterator) { // of the old value into MIRI_ORIG_RUSTDOC. So that's what we have to invoke now. let rustdoc = env::var("MIRI_ORIG_RUSTDOC").unwrap_or("rustdoc".to_string()); let mut cmd = Command::new(rustdoc); - - while let Some(arg) = args.next() { - if arg == "--extern" { - // Patch --extern arguments to use *.rmeta files, since phase_cargo_rustc only creates stub *.rlib files. - forward_patched_extern_arg(&mut args, &mut cmd); - } else { - cmd.arg(arg); - } - } + cmd.args(args); // Doctests of `proc-macro` crates (and their dependencies) are always built for the host, // so we are not able to run them in Miri. diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs index e399f66fbc9c..c7682093663e 100644 --- a/src/tools/miri/cargo-miri/src/setup.rs +++ b/src/tools/miri/cargo-miri/src/setup.rs @@ -160,7 +160,7 @@ pub fn setup( // Do the build. let status = SysrootBuilder::new(&sysroot_dir, target) - .build_mode(BuildMode::Check) + .build_mode(BuildMode::Build) // not a real build, since we use dummy codegen .rustc_version(rustc_version.clone()) .sysroot_config(sysroot_config) .rustflags(rustflags) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 6ef6e340b3d9..920fc2948191 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -16,7 +16,6 @@ extern crate rustc_hir; extern crate rustc_hir_analysis; extern crate rustc_interface; extern crate rustc_log; -extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; @@ -26,10 +25,8 @@ mod log; use std::env; use std::num::NonZero; use std::ops::Range; -use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use std::sync::Arc; use std::sync::atomic::{AtomicI32, AtomicU32, Ordering}; use miri::{ @@ -51,10 +48,8 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::query::LocalCrate; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::util::Providers; use rustc_session::EarlyDiagCtxt; use rustc_session::config::{CrateType, ErrorOutputType, OptLevel}; -use rustc_session::search_paths::PathKind; use rustc_span::def_id::DefId; use crate::log::setup::{deinit_loggers, init_early_loggers, init_late_loggers}; @@ -126,21 +121,6 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) { } impl rustc_driver::Callbacks for MiriCompilerCalls { - fn config(&mut self, config: &mut Config) { - config.override_queries = Some(|_, providers| { - providers.extern_queries.used_crate_source = |tcx, cnum| { - let mut providers = Providers::default(); - rustc_metadata::provide(&mut providers); - let mut crate_source = (providers.extern_queries.used_crate_source)(tcx, cnum); - // HACK: rustc will emit "crate ... required to be available in rlib format, but - // was not found in this form" errors once we use `tcx.dependency_formats()` if - // there's no rlib provided, so setting a dummy path here to workaround those errors. - Arc::make_mut(&mut crate_source).rlib = Some((PathBuf::new(), PathKind::All)); - crate_source - }; - }); - } - fn after_analysis<'tcx>( &mut self, _: &rustc_interface::interface::Compiler, @@ -253,12 +233,26 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { #[allow(rustc::potential_query_instability)] // rustc_codegen_ssa (where this code is copied from) also allows this lint fn config(&mut self, config: &mut Config) { if config.opts.prints.is_empty() && self.target_crate { + #[allow(rustc::bad_opt_access)] // tcx does not exist yet + { + let any_crate_types = !config.opts.crate_types.is_empty(); + // Avoid warnings about unsupported crate types. + config + .opts + .crate_types + .retain(|&c| c == CrateType::Executable || c == CrateType::Rlib); + if any_crate_types { + // Assert that we didn't remove all crate types if any crate type was passed on + // the cli. Otherwise we might silently change what kind of crate we are building. + assert!(!config.opts.crate_types.is_empty()); + } + } + // Queries overridden here affect the data stored in `rmeta` files of dependencies, // which will be used later in non-`MIRI_BE_RUSTC` mode. config.override_queries = Some(|_, local_providers| { - // `exported_non_generic_symbols` and `reachable_non_generics` provided by rustc always returns - // an empty result if `tcx.sess.opts.output_types.should_codegen()` is false. - // In addition we need to add #[used] symbols to exported_symbols for `lookup_link_section`. + // We need to add #[used] symbols to exported_symbols for `lookup_link_section`. + // FIXME handle this somehow in rustc itself to avoid this hack. local_providers.exported_non_generic_symbols = |tcx, LocalCrate| { let reachable_set = tcx.with_stable_hashing_context(|hcx| { tcx.reachable_set(()).to_sorted(&hcx, true) diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index b756fbb901bc..bd0f12fd1896 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -165,6 +165,7 @@ pub use crate::shims::unwind::{CatchUnwindData, EvalContextExt as _}; /// Also disable the MIR pass that inserts an alignment check on every pointer dereference. Miri /// does that too, and with a better error message. pub const MIRI_DEFAULT_ARGS: &[&str] = &[ + "-Zcodegen-backend=dummy", "--cfg=miri", "-Zalways-encode-mir", "-Zextra-const-ub-checks", diff --git a/src/tools/miri/test-cargo-miri/Cargo.lock b/src/tools/miri/test-cargo-miri/Cargo.lock index 32119426184d..dd81c3b03bd3 100644 --- a/src/tools/miri/test-cargo-miri/Cargo.lock +++ b/src/tools/miri/test-cargo-miri/Cargo.lock @@ -27,7 +27,6 @@ dependencies = [ "autocfg", "byteorder 0.5.3", "byteorder 1.5.0", - "cdylib", "exported_symbol", "eyre", "issue_1567", @@ -38,13 +37,6 @@ dependencies = [ "proc_macro_crate", ] -[[package]] -name = "cdylib" -version = "0.1.0" -dependencies = [ - "byteorder 1.5.0", -] - [[package]] name = "exported_symbol" version = "0.1.0" diff --git a/src/tools/miri/test-cargo-miri/Cargo.toml b/src/tools/miri/test-cargo-miri/Cargo.toml index f5092a4748f3..3f08f802cf42 100644 --- a/src/tools/miri/test-cargo-miri/Cargo.toml +++ b/src/tools/miri/test-cargo-miri/Cargo.toml @@ -10,7 +10,6 @@ edition = "2024" [dependencies] byteorder = "1.0" -cdylib = { path = "cdylib" } exported_symbol = { path = "exported-symbol" } proc_macro_crate = { path = "proc-macro-crate" } issue_1567 = { path = "issue-1567" } diff --git a/src/tools/miri/test-cargo-miri/cdylib/Cargo.toml b/src/tools/miri/test-cargo-miri/cdylib/Cargo.toml deleted file mode 100644 index 527602e0a888..000000000000 --- a/src/tools/miri/test-cargo-miri/cdylib/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "cdylib" -version = "0.1.0" -authors = ["Miri Team"] -edition = "2018" - -[lib] -# cargo-miri used to handle `cdylib` crate-type specially (https://github.com/rust-lang/miri/pull/1577). -crate-type = ["cdylib"] - -[dependencies] -byteorder = "1.0" # to test dependencies of sub-crates diff --git a/src/tools/miri/test-cargo-miri/cdylib/src/lib.rs b/src/tools/miri/test-cargo-miri/cdylib/src/lib.rs deleted file mode 100644 index e47e588251e4..000000000000 --- a/src/tools/miri/test-cargo-miri/cdylib/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -use byteorder::{BigEndian, ByteOrder}; - -#[no_mangle] -extern "C" fn use_the_dependency() { - let _n = ::read_u64(&[1, 2, 3, 4, 5, 6, 7, 8]); -} diff --git a/src/tools/miri/test-cargo-miri/run.local_crate.stdout.ref b/src/tools/miri/test-cargo-miri/run.local_crate.stdout.ref index 1587de9ff3f8..60cd9d371ad6 100644 --- a/src/tools/miri/test-cargo-miri/run.local_crate.stdout.ref +++ b/src/tools/miri/test-cargo-miri/run.local_crate.stdout.ref @@ -1 +1 @@ -subcrate,issue_1567,exported_symbol_dep,test_local_crate_detection,cargo_miri_test,cdylib,exported_symbol,issue_1691,issue_1705,issue_rust_86261,proc_macro_crate +subcrate,issue_1567,exported_symbol_dep,test_local_crate_detection,cargo_miri_test,exported_symbol,issue_1691,issue_1705,issue_rust_86261,proc_macro_crate From b975c570fab6e04ab81aca6db357456a2964761c Mon Sep 17 00:00:00 2001 From: Dmitry Marakasov Date: Fri, 7 Nov 2025 00:58:04 +0300 Subject: [PATCH 455/525] Sync str::rsplit_once example with str::split_once --- library/core/src/str/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 37dc401ed009..45308c4b3e9c 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -1953,6 +1953,7 @@ impl str { /// /// ``` /// assert_eq!("cfg".rsplit_once('='), None); + /// assert_eq!("cfg=".rsplit_once('='), Some(("cfg", ""))); /// assert_eq!("cfg=foo".rsplit_once('='), Some(("cfg", "foo"))); /// assert_eq!("cfg=foo=bar".rsplit_once('='), Some(("cfg=foo", "bar"))); /// ``` From 62ccf14c143d9141173993f3b2a468a30938617e Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Mon, 6 Oct 2025 20:44:50 +0000 Subject: [PATCH 456/525] add check if macro from expansion --- .../src/error_reporting/traits/suggestions.rs | 5 +++++ .../macros/macro-expansion-empty-span-147255.rs | 10 ++++++++++ .../macro-expansion-empty-span-147255.stderr | 15 +++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/ui/macros/macro-expansion-empty-span-147255.rs create mode 100644 tests/ui/macros/macro-expansion-empty-span-147255.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 37e622102e70..75d7d32d25f8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -942,6 +942,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.span_label(block.span, "this empty block is missing a tail expression"); return; }; + // FIXME expr and stmt have the same span if expr comes from expansion + // cc: https://github.com/rust-lang/rust/pull/147416#discussion_r2499407523 + if stmt.span.from_expansion() { + return; + } let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; diff --git a/tests/ui/macros/macro-expansion-empty-span-147255.rs b/tests/ui/macros/macro-expansion-empty-span-147255.rs new file mode 100644 index 000000000000..311cf5bf9b1b --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147255.rs @@ -0,0 +1,10 @@ +//! Regression test for + +fn main() { + let mut x = 4; + let x_str = { + format!("{}", x); + //() + }; + println!("{}", x_str); //~ ERROR `()` doesn't implement `std::fmt::Display` +} diff --git a/tests/ui/macros/macro-expansion-empty-span-147255.stderr b/tests/ui/macros/macro-expansion-empty-span-147255.stderr new file mode 100644 index 000000000000..99396622b34e --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147255.stderr @@ -0,0 +1,15 @@ +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/macro-expansion-empty-span-147255.rs:9:20 + | +LL | println!("{}", x_str); + | -- ^^^^^ `()` cannot be formatted with the default formatter + | | + | required by this formatting parameter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 5f29f11a4de9b731fe7e74434d3e2fba73cfc1f4 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 12 Oct 2025 22:41:03 -0700 Subject: [PATCH 457/525] Add -Zannotate-moves for profiler visibility of move/copy operations This implements a new unstable compiler flag `-Zannotate-moves` that makes move and copy operations visible in profilers by creating synthetic debug information. This is achieved with zero runtime cost by manipulating debug info scopes to make moves/copies appear as calls to `compiler_move` and `compiler_copy` marker functions in profiling tools. This allows developers to identify expensive move/copy operations in their code using standard profiling tools, without requiring specialized tooling or runtime instrumentation. The implementation works at codegen time. When processing MIR operands (`Operand::Move` and `Operand::Copy`), the codegen creates an `OperandRef` with an optional `move_annotation` field containing an `Instance` of the appropriate profiling marker function. When storing the operand, `store_with_annotation()` wraps the store operation in a synthetic debug scope that makes it appear inlined from the marker. Two marker functions (`compiler_move` and `compiler_copy`) are defined in `library/core/src/profiling.rs`. These are never actually called - they exist solely as debug info anchors. Operations are only annotated if the type: - Meets the size threshold (default: 65 bytes, configurable via `-Zannotate-moves=SIZE`) - Has a non-scalar backend representation (scalars use registers, not memcpy) This has a very small size impact on object file size. With the default limit it's well under 0.1%, and even with a very small limit of 8 bytes it's still ~1.5%. This could be enabled by default. --- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/debuginfo.rs | 2 +- compiler/rustc_codegen_llvm/src/abi.rs | 2 +- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 53 ++++- compiler/rustc_codegen_ssa/src/mir/block.rs | 14 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 + compiler/rustc_codegen_ssa/src/mir/operand.rs | 122 ++++++++++- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 47 +++-- .../rustc_codegen_ssa/src/traits/builder.rs | 2 +- .../rustc_codegen_ssa/src/traits/debuginfo.rs | 16 +- compiler/rustc_hir/src/lang_items.rs | 4 + compiler/rustc_interface/src/tests.rs | 3 +- compiler/rustc_session/src/config.rs | 25 ++- compiler/rustc_session/src/options.rs | 28 +++ compiler/rustc_span/src/symbol.rs | 2 + library/core/src/lib.rs | 2 + library/core/src/profiling.rs | 33 +++ .../src/compiler-flags/annotate-moves.md | 92 +++++++++ .../annotate-moves/call-arg-scope.rs | 114 +++++++++++ tests/codegen-llvm/annotate-moves/disabled.rs | 35 ++++ .../annotate-moves/integration.rs | 192 ++++++++++++++++++ .../codegen-llvm/annotate-moves/size-limit.rs | 112 ++++++++++ .../ui/annotate-moves/annotate-moves-basic.rs | 15 ++ .../annotate-moves-invalid-flag.rs | 10 + .../annotate-moves-invalid-flag.stderr | 2 + .../annotate-moves-size-limit-invalid.rs | 10 + .../annotate-moves-size-limit-invalid.stderr | 2 + 28 files changed, 897 insertions(+), 48 deletions(-) create mode 100644 library/core/src/profiling.rs create mode 100644 src/doc/unstable-book/src/compiler-flags/annotate-moves.md create mode 100644 tests/codegen-llvm/annotate-moves/call-arg-scope.rs create mode 100644 tests/codegen-llvm/annotate-moves/disabled.rs create mode 100644 tests/codegen-llvm/annotate-moves/integration.rs create mode 100644 tests/codegen-llvm/annotate-moves/size-limit.rs create mode 100644 tests/ui/annotate-moves/annotate-moves-basic.rs create mode 100644 tests/ui/annotate-moves/annotate-moves-invalid-flag.rs create mode 100644 tests/ui/annotate-moves/annotate-moves-invalid-flag.stderr create mode 100644 tests/ui/annotate-moves/annotate-moves-size-limit-invalid.rs create mode 100644 tests/ui/annotate-moves/annotate-moves-size-limit-invalid.stderr diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 5657620879ca..86031a8a4634 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1069,7 +1069,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.val) }; - OperandRef { val, layout: place.layout } + OperandRef { val, layout: place.layout, move_annotation: None } } fn write_operand_repeatedly( diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 0f015cc23f52..3979f62987f2 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -19,7 +19,7 @@ use crate::context::CodegenCx; pub(super) const UNKNOWN_LINE_NUMBER: u32 = 0; pub(super) const UNKNOWN_COLUMN_NUMBER: u32 = 0; -impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { +impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 8b7aa1d6b4e9..c3c1caf086f0 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -253,7 +253,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { ); bx.lifetime_end(llscratch, scratch_size); } - _ => { + PassMode::Pair(..) | PassMode::Direct { .. } => { OperandRef::from_immediate_or_packed_pair(bx, val, self.layout).val.store(bx, dst); } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d441cd119a74..e9cd921cc781 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -751,7 +751,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { OperandValue::Ref(place.val) }; - OperandRef { val, layout: place.layout } + OperandRef { val, layout: place.layout, move_annotation: None } } fn write_operand_repeatedly( diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b95ad03b70e0..c2c55ee2b64f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -146,7 +146,7 @@ impl<'ll> Builder<'_, 'll, '_> { } } -impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { +impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( @@ -284,6 +284,57 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { llvm::set_value_name(value, name.as_bytes()); } } + + /// Annotate move/copy operations with debug info for profiling. + /// + /// This creates a temporary debug scope that makes the move/copy appear as an inlined call to + /// `compiler_move()` or `compiler_copy()`. The provided closure is executed + /// with this temporary debug location active. + /// + /// The `instance` parameter should be the monomorphized instance of the `compiler_move` or + /// `compiler_copy` function with the actual type and size. + fn with_move_annotation( + &mut self, + instance: ty::Instance<'tcx>, + f: impl FnOnce(&mut Self) -> R, + ) -> R { + // Save the current debug location + let saved_loc = self.get_dbg_loc(); + + // Create a DIScope for the compiler_move/compiler_copy function + // We use the function's FnAbi for debug info generation + let fn_abi = self + .cx() + .tcx + .fn_abi_of_instance( + self.cx().typing_env().as_query_input((instance, ty::List::empty())), + ) + .unwrap(); + + let di_scope = self.cx().dbg_scope_fn(instance, fn_abi, None); + + // Create an inlined debug location: + // - scope: the compiler_move/compiler_copy function + // - inlined_at: the current location (where the move/copy actually occurs) + // - span: use the function's definition span + let fn_span = self.cx().tcx.def_span(instance.def_id()); + let inlined_loc = self.cx().dbg_loc(di_scope, saved_loc, fn_span); + + // Set the temporary debug location + self.set_dbg_loc(inlined_loc); + + // Execute the closure (which will generate the memcpy) + let result = f(self); + + // Restore the original debug location + if let Some(loc) = saved_loc { + self.set_dbg_loc(loc); + } else { + self.clear_dbg_loc(); + } + + result + } } /// A source code location used to generate debug information. diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 0d1e27a34dc5..cce33107e2c2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -557,9 +557,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let op = match self.locals[mir::RETURN_PLACE] { LocalRef::Operand(op) => op, LocalRef::PendingOperand => bug!("use of return before def"), - LocalRef::Place(cg_place) => { - OperandRef { val: Ref(cg_place.val), layout: cg_place.layout } - } + LocalRef::Place(cg_place) => OperandRef { + val: Ref(cg_place.val), + layout: cg_place.layout, + move_annotation: None, + }, LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), }; let llslot = match op.val { @@ -1155,7 +1157,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | (&mir::Operand::Constant(_), Ref(PlaceValue { llextra: None, .. })) => { let tmp = PlaceRef::alloca(bx, op.layout); bx.lifetime_start(tmp.val.llval, tmp.layout.size); - op.val.store(bx, tmp); + op.store_with_annotation(bx, tmp); op.val = Ref(tmp.val); lifetime_ends_after_call.push((tmp.val.llval, tmp.layout.size)); } @@ -1563,13 +1565,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); bx.lifetime_start(scratch.llval, arg.layout.size); - op.val.store(bx, scratch.with_type(arg.layout)); + op.store_with_annotation(bx, scratch.with_type(arg.layout)); lifetime_ends_after_call.push((scratch.llval, arg.layout.size)); (scratch.llval, scratch.align, true) } PassMode::Cast { .. } => { let scratch = PlaceRef::alloca(bx, arg.layout); - op.val.store(bx, scratch); + op.store_with_annotation(bx, scratch); (scratch.val.llval, scratch.val.align, true) } _ => (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 1670e2da71fb..819abb9ae644 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -480,6 +480,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( return local(OperandRef { val: OperandValue::Pair(a, b), layout: arg.layout, + move_annotation: None, }); } _ => {} @@ -552,6 +553,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx.caller_location = Some(OperandRef { val: OperandValue::Immediate(bx.get_param(llarg_idx)), layout: arg.layout, + move_annotation: None, }); } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 88a8e2a844cb..5a139702f81d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -5,12 +5,13 @@ use rustc_abi as abi; use rustc_abi::{ Align, BackendRepr, FIRST_VARIANT, FieldIdx, Primitive, Size, TagEncoding, VariantIdx, Variants, }; +use rustc_hir::LangItem; use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range}; use rustc_middle::mir::{self, ConstValue}; -use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, span_bug}; -use rustc_session::config::OptLevel; +use rustc_session::config::{AnnotateMoves, DebugInfo, OptLevel}; use tracing::{debug, instrument}; use super::place::{PlaceRef, PlaceValue}; @@ -131,6 +132,10 @@ pub struct OperandRef<'tcx, V> { /// The layout of value, based on its Rust type. pub layout: TyAndLayout<'tcx>, + + /// Annotation for profiler visibility of move/copy operations. + /// When set, the store operation should appear as an inlined call to this function. + pub move_annotation: Option>, } impl fmt::Debug for OperandRef<'_, V> { @@ -142,7 +147,7 @@ impl fmt::Debug for OperandRef<'_, V> { impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn zero_sized(layout: TyAndLayout<'tcx>) -> OperandRef<'tcx, V> { assert!(layout.is_zst()); - OperandRef { val: OperandValue::ZeroSized, layout } + OperandRef { val: OperandValue::ZeroSized, layout, move_annotation: None } } pub(crate) fn from_const>( @@ -180,7 +185,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } }; - OperandRef { val, layout } + OperandRef { val, layout, move_annotation: None } } fn from_const_alloc>( @@ -214,7 +219,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let size = s.size(bx); assert_eq!(size, layout.size, "abi::Scalar size does not match layout size"); let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout)); - OperandRef { val: OperandValue::Immediate(val), layout } + OperandRef { val: OperandValue::Immediate(val), layout, move_annotation: None } } BackendRepr::ScalarPair( a @ abi::Scalar::Initialized { .. }, @@ -235,7 +240,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { b, bx.scalar_pair_element_backend_type(layout, 1, true), ); - OperandRef { val: OperandValue::Pair(a_val, b_val), layout } + OperandRef { val: OperandValue::Pair(a_val, b_val), layout, move_annotation: None } } _ if layout.is_zst() => OperandRef::zero_sized(layout), _ => { @@ -285,6 +290,22 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { self.val.deref(layout.align.abi).with_type(layout) } + /// Store this operand into a place, applying move/copy annotation if present. + /// + /// This is the preferred method for storing operands, as it automatically + /// applies profiler annotations for tracked move/copy operations. + pub fn store_with_annotation>( + self, + bx: &mut Bx, + dest: PlaceRef<'tcx, V>, + ) { + if let Some(instance) = self.move_annotation { + bx.with_move_annotation(instance, |bx| self.val.store(bx, dest)) + } else { + self.val.store(bx, dest) + } + } + /// If this operand is a `Pair`, we return an aggregate with the two values. /// For other cases, see `immediate`. pub fn immediate_or_packed_pair>( @@ -320,7 +341,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } else { OperandValue::Immediate(llval) }; - OperandRef { val, layout } + OperandRef { val, layout, move_annotation: None } } pub(crate) fn extract_field>( @@ -388,7 +409,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { }) }; - OperandRef { val, layout: field } + OperandRef { val, layout: field, move_annotation: None } } /// Obtain the actual discriminant of a value. @@ -828,10 +849,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> { } }, }; - OperandRef { val, layout } + OperandRef { val, layout, move_annotation: None } } } +/// Default size limit for move/copy annotations (in bytes). 64 bytes is a common size of a cache +/// line, and the assumption is that anything this size or below is very cheap to move/copy, so only +/// annotate copies larger than this. +const MOVE_ANNOTATION_DEFAULT_LIMIT: u64 = 65; + impl<'a, 'tcx, V: CodegenObject> OperandValue { /// Returns an `OperandValue` that's generally UB to use in any way. /// @@ -961,7 +987,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { abi::Variants::Single { index: vidx }, ); let layout = o.layout.for_variant(bx.cx(), vidx); - o = OperandRef { val: o.val, layout } + o = OperandRef { layout, ..o } } _ => return None, } @@ -1014,7 +1040,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match *operand { mir::Operand::Copy(ref place) | mir::Operand::Move(ref place) => { - self.codegen_consume(bx, place.as_ref()) + let kind = match operand { + mir::Operand::Move(_) => LangItem::CompilerMove, + mir::Operand::Copy(_) => LangItem::CompilerCopy, + _ => unreachable!(), + }; + + // Check if we should annotate this move/copy for profiling + let move_annotation = self.move_copy_annotation_instance(bx, place.as_ref(), kind); + + OperandRef { move_annotation, ..self.codegen_consume(bx, place.as_ref()) } } mir::Operand::Constant(ref constant) => { @@ -1030,6 +1065,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return OperandRef { val: OperandValue::Immediate(llval), layout: bx.layout_of(ty), + move_annotation: None, }; } } @@ -1037,4 +1073,68 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } + + /// Creates an `Instance` for annotating a move/copy operation at codegen time. + /// + /// Returns `Some(instance)` if the operation should be annotated with debug info, `None` + /// otherwise. The instance represents a monomorphized `compiler_move` or + /// `compiler_copy` function that can be used to create debug scopes. + /// + /// There are a number of conditions that must be met for an annotation to be created, but aside + /// from the basics (annotation is enabled, we're generating debuginfo), the primary concern is + /// moves/copies which could result in a real `memcpy`. So we check for the size limit, but also + /// that the underlying representation of the type is in memory. + fn move_copy_annotation_instance( + &self, + bx: &Bx, + place: mir::PlaceRef<'tcx>, + kind: LangItem, + ) -> Option> { + let tcx = bx.tcx(); + let sess = tcx.sess; + + // Skip if we're not generating debuginfo + if sess.opts.debuginfo == DebugInfo::None { + return None; + } + + // Check if annotation is enabled and get size limit (otherwise skip) + let size_limit = match sess.opts.unstable_opts.annotate_moves { + AnnotateMoves::Disabled => return None, + AnnotateMoves::Enabled(None) => MOVE_ANNOTATION_DEFAULT_LIMIT, + AnnotateMoves::Enabled(Some(limit)) => limit, + }; + + let ty = self.monomorphized_place_ty(place); + let layout = bx.cx().layout_of(ty); + let ty_size = layout.size.bytes(); + + // Only annotate if type has a memory representation and exceeds size limit (and has a + // non-zero size) + if layout.is_zst() + || ty_size < size_limit + || !matches!(layout.backend_repr, BackendRepr::Memory { .. }) + { + return None; + } + + // Look up the DefId for compiler_move or compiler_copy lang item + let def_id = tcx.lang_items().get(kind)?; + + // Create generic args: compiler_move or compiler_copy + let size_const = ty::Const::from_target_usize(tcx, ty_size); + let generic_args = tcx.mk_args(&[ty.into(), size_const.into()]); + + // Create the Instance + let typing_env = self.mir.typing_env(tcx); + let instance = ty::Instance::expect_resolve( + tcx, + typing_env, + def_id, + generic_args, + rustc_span::DUMMY_SP, // span only used for error messages + ); + + Some(instance) + } } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 640f7211dc99..e31dc86b926f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } // FIXME: consider not copying constants through stack. (Fixable by codegen'ing // constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?) - cg_operand.val.store(bx, dest); + cg_operand.store_with_annotation(bx, dest); } mir::Rvalue::Cast( @@ -50,7 +50,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Into-coerce of a thin pointer to a wide pointer -- just // use the operand path. let temp = self.codegen_rvalue_operand(bx, rvalue); - temp.val.store(bx, dest); + temp.store_with_annotation(bx, dest); return; } @@ -70,7 +70,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { debug!("codegen_rvalue: creating ugly alloca"); let scratch = PlaceRef::alloca(bx, operand.layout); scratch.storage_live(bx); - operand.val.store(bx, scratch); + operand.store_with_annotation(bx, scratch); base::coerce_unsized_into(bx, scratch, dest); scratch.storage_dead(bx); } @@ -183,7 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { variant_dest.project_field(bx, field_index.as_usize()) }; - op.val.store(bx, field); + op.store_with_annotation(bx, field); } } dest.codegen_set_discr(bx, variant_index); @@ -191,7 +191,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => { let temp = self.codegen_rvalue_operand(bx, rvalue); - temp.val.store(bx, dest); + temp.store_with_annotation(bx, dest); } } } @@ -221,7 +221,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Since in this path we have a place anyway, we can store or copy to it, // making sure we use the destination place's alignment even if the // source would normally have a higher one. - src.val.store(bx, dst.val.with_type(src.layout)); + src.store_with_annotation(bx, dst.val.with_type(src.layout)); } } @@ -320,7 +320,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let size = Ord::max(operand.layout.size, cast.size); let temp = PlaceValue::alloca(bx, size, align); bx.lifetime_start(temp.llval, size); - operand.val.store(bx, temp.with_type(operand.layout)); + operand.store_with_annotation(bx, temp.with_type(operand.layout)); let val = bx.load_operand(temp.with_type(cast)).val; bx.lifetime_end(temp.llval, size); val @@ -478,7 +478,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let to_backend_ty = bx.cx().immediate_backend_type(cast); if operand.layout.is_uninhabited() { let val = OperandValue::Immediate(bx.cx().const_poison(to_backend_ty)); - return OperandRef { val, layout: cast }; + return OperandRef { val, layout: cast, move_annotation: None }; } let abi::BackendRepr::Scalar(to_scalar) = cast.layout.backend_repr else { bug!("Found non-scalar for cast {cast:?}"); @@ -494,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_transmute_operand(bx, operand, cast) } }; - OperandRef { val, layout: cast } + OperandRef { val, layout: cast, move_annotation: None } } mir::Rvalue::Ref(_, bk, place) => { @@ -525,7 +525,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); let operand_ty = Ty::new_tup(bx.tcx(), &[val_ty, bx.tcx().types.bool]); - OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) } + OperandRef { + val: result, + layout: bx.cx().layout_of(operand_ty), + move_annotation: None, + } } mir::Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => { let lhs = self.codegen_operand(bx, lhs); @@ -559,6 +563,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(llresult), layout: bx.cx().layout_of(op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)), + move_annotation: None, } } @@ -593,7 +598,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { val.is_expected_variant_for_type(self.cx, layout), "Made wrong variant {val:?} for type {layout:?}", ); - OperandRef { val, layout } + OperandRef { val, layout, move_annotation: None } } mir::Rvalue::Discriminant(ref place) => { @@ -604,6 +609,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(discr), layout: self.cx.layout_of(discr_ty), + move_annotation: None, } } @@ -631,6 +637,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(val), layout: self.cx.layout_of(null_op.ty(tcx)), + move_annotation: None, } } @@ -663,7 +670,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { bx.get_static(def_id) }; - OperandRef { val: OperandValue::Immediate(static_), layout } + OperandRef { val: OperandValue::Immediate(static_), layout, move_annotation: None } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), mir::Rvalue::Repeat(ref elem, len_const) => { @@ -675,7 +682,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let array_ty = self.monomorphize(array_ty); let array_layout = bx.layout_of(array_ty); assert!(array_layout.is_zst()); - OperandRef { val: OperandValue::ZeroSized, layout: array_layout } + OperandRef { + val: OperandValue::ZeroSized, + layout: array_layout, + move_annotation: None, + } } mir::Rvalue::Aggregate(ref kind, ref fields) => { let (variant_index, active_field_index) = match **kind { @@ -704,7 +715,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // more optimizability, if that turns out to be helpful. bx.abort(); let val = OperandValue::poison(bx, layout); - OperandRef { val, layout } + OperandRef { val, layout, move_annotation: None } } Ok(maybe_tag_value) => { if let Some((tag_field, tag_imm)) = maybe_tag_value { @@ -718,7 +729,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let operand = self.codegen_operand(bx, operand); let binder_ty = self.monomorphize(binder_ty); let layout = bx.cx().layout_of(binder_ty); - OperandRef { val: operand.val, layout } + OperandRef { val: operand.val, layout, move_annotation: None } } mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), mir::Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), @@ -745,7 +756,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "Address of place was unexpectedly {val:?} for pointee type {ty:?}", ); - OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) } + OperandRef { + val, + layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)), + move_annotation: None, + } } fn codegen_scalar_binop( diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 60296e36e0c1..f57f9108f744 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -37,7 +37,7 @@ pub trait BuilderMethods<'a, 'tcx>: + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>> + Deref + CoverageInfoBuilderMethods<'tcx> - + DebugInfoBuilderMethods + + DebugInfoBuilderMethods<'tcx> + ArgAbiBuilderMethods<'tcx> + AbiBuilderMethods + IntrinsicCallBuilderMethods<'tcx> diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index a4da6c915dee..268d863dcbd2 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -64,7 +64,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes { ) -> Self::DIVariable; } -pub trait DebugInfoBuilderMethods: BackendTypes { +pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( @@ -95,4 +95,18 @@ pub trait DebugInfoBuilderMethods: BackendTypes { fn clear_dbg_loc(&mut self); fn insert_reference_to_gdb_debug_scripts_section_global(&mut self); fn set_var_name(&mut self, value: Self::Value, name: &str); + + /// Hook to allow move/copy operations to be annotated for profiling. + /// + /// The `instance` parameter should be the monomorphized instance of the + /// `compiler_move` or `compiler_copy` function with the actual type and size. + /// + /// Default implementation does no annotation (just executes the closure). + fn with_move_annotation( + &mut self, + _instance: Instance<'tcx>, + f: impl FnOnce(&mut Self) -> R, + ) -> R { + f(self) + } } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 9f7f4c758341..e454ed58699c 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -345,6 +345,10 @@ language_item_table! { EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None; EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None; + // Profiling markers for move/copy operations (used by -Z annotate-moves) + CompilerMove, sym::compiler_move, compiler_move_fn, Target::Fn, GenericRequirement::Exact(2); + CompilerCopy, sym::compiler_copy, compiler_copy_fn, Target::Fn, GenericRequirement::Exact(2); + OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1); GlobalAlloc, sym::global_alloc_ty, global_alloc_ty, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9848b11ce814..8bf9f8420c05 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -10,7 +10,7 @@ use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, registry}; use rustc_hir::attrs::NativeLibKind; use rustc_session::config::{ - AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, @@ -764,6 +764,7 @@ fn test_unstable_options_tracking_hash() { // tidy-alphabetical-start tracked!(allow_features, Some(vec![String::from("lang_items")])); tracked!(always_encode_mir, true); + tracked!(annotate_moves, AnnotateMoves::Enabled(Some(1234))); tracked!(assume_incomplete_release, true); tracked!(autodiff, vec![AutoDiff::Enable, AutoDiff::NoTT]); tracked!(binary_dep_depinfo, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3403745084c5..1a00a72d8149 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -262,6 +262,16 @@ pub enum AutoDiff { NoTT, } +/// The different settings that the `-Z annotate-moves` flag can have. +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum AnnotateMoves { + /// `-Z annotate-moves=no` (or `off`, `false` etc.) + Disabled, + /// `-Z annotate-moves` or `-Z annotate-moves=yes` (use default size limit) + /// `-Z annotate-moves=SIZE` (use specified size limit) + Enabled(Option), +} + /// Settings for `-Z instrument-xray` flag. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub struct InstrumentXRay { @@ -3283,13 +3293,13 @@ pub(crate) mod dep_tracking { }; use super::{ - AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions, - CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, - InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OomStrategy, OptLevel, OutFileName, - OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents, - ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, - SymbolManglingVersion, WasiExecModel, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, + CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, + FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, + LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OomStrategy, + OptLevel, OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, + RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, + SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3332,6 +3342,7 @@ pub(crate) mod dep_tracking { impl_dep_tracking_hash_via_hash!( (), + AnnotateMoves, AutoDiff, Offload, bool, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b49194b82f3a..3809abc81e3d 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -864,6 +864,8 @@ mod desc { pub(crate) const parse_linker_features: &str = "a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`"; pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`"; + pub(crate) const parse_annotate_moves: &str = + "either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes"; pub(crate) const parse_stack_protector: &str = "one of (`none` (default), `basic`, `strong`, or `all`)"; pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)"; @@ -949,6 +951,29 @@ pub mod parse { } } + pub(crate) fn parse_annotate_moves(slot: &mut AnnotateMoves, v: Option<&str>) -> bool { + let mut bslot = false; + let mut nslot = 0u64; + + *slot = match v { + // No value provided: -Z annotate-moves (enable with default limit) + None => AnnotateMoves::Enabled(None), + // Explicit boolean value provided: -Z annotate-moves=yes/no + s @ Some(_) if parse_bool(&mut bslot, s) => { + if bslot { + AnnotateMoves::Enabled(None) + } else { + AnnotateMoves::Disabled + } + } + // With numeric limit provided: -Z annotate-moves=1234 + s @ Some(_) if parse_number(&mut nslot, s) => AnnotateMoves::Enabled(Some(nslot)), + _ => return false, + }; + + true + } + /// Use this for any string option that has a static default. pub(crate) fn parse_string(slot: &mut String, v: Option<&str>) -> bool { match v { @@ -2198,6 +2223,9 @@ options! { "only allow the listed language features to be enabled in code (comma separated)"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata (default: no)"), + annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], + "emit debug info for compiler-generated move and copy operations \ + to make them visible in profilers. Can be a boolean or a size limit in bytes (default: disabled)"), assert_incr_state: Option = (None, parse_opt_string, [UNTRACKED], "assert that the incremental cache is in given state: \ either `loaded` or `not-loaded`."), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38718bad9e57..6387ff699b87 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -700,7 +700,9 @@ symbols! { compile_error, compiler, compiler_builtins, + compiler_copy, compiler_fence, + compiler_move, concat, concat_bytes, concat_idents, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f1948fc778ce..121d26c8a3e3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -282,6 +282,8 @@ pub mod num; pub mod hint; pub mod intrinsics; pub mod mem; +#[unstable(feature = "profiling_marker_api", issue = "148197")] +pub mod profiling; pub mod ptr; #[unstable(feature = "ub_checks", issue = "none")] pub mod ub_checks; diff --git a/library/core/src/profiling.rs b/library/core/src/profiling.rs new file mode 100644 index 000000000000..db4a62480a3a --- /dev/null +++ b/library/core/src/profiling.rs @@ -0,0 +1,33 @@ +//! Profiling markers for compiler instrumentation. + +/// Profiling marker for move operations. +/// +/// This function is never called at runtime. When `-Z annotate-moves` is enabled, +/// the compiler creates synthetic debug info that makes move operations appear as +/// calls to this function in profilers. +/// +/// The `SIZE` parameter encodes the size of the type being copied. It's the same as +/// `size_of::()`, and is only present for convenience. +#[unstable(feature = "profiling_marker_api", issue = "148197")] +#[lang = "compiler_move"] +pub fn compiler_move(_src: *const T, _dst: *mut T) { + unreachable!( + "compiler_move marks where the compiler-generated a memcpy for moves. It is never actually called." + ) +} + +/// Profiling marker for copy operations. +/// +/// This function is never called at runtime. When `-Z annotate-moves` is enabled, +/// the compiler creates synthetic debug info that makes copy operations appear as +/// calls to this function in profilers. +/// +/// The `SIZE` parameter encodes the size of the type being copied. It's the same as +/// `size_of::()`, and is only present for convenience. +#[unstable(feature = "profiling_marker_api", issue = "148197")] +#[lang = "compiler_copy"] +pub fn compiler_copy(_src: *const T, _dst: *mut T) { + unreachable!( + "compiler_copy marks where the compiler-generated a memcpy for Copies. It is never actually called." + ) +} diff --git a/src/doc/unstable-book/src/compiler-flags/annotate-moves.md b/src/doc/unstable-book/src/compiler-flags/annotate-moves.md new file mode 100644 index 000000000000..46d8faf18fa0 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/annotate-moves.md @@ -0,0 +1,92 @@ +# `annotate-moves` + +The tracking issue for this feature is: [#148197](https://github.com/rust-lang/rust/issues/148197). + +------------------------ + + +The `-Z annotate-moves` flag enables annotation of compiler-generated +move and copy operations, making them visible in profilers and stack traces +for performance debugging. + +When enabled, the compiler manipulates debug info to make large move and copy +operations appear as if they were inlined calls to `core::profiling::compiler_move` +and `core::profiling::compiler_copy`. No actual function calls are generated - +this is purely a debug info transformation that makes expensive memory operations +visible in profilers and stack traces. + +## Syntax + +```bash +rustc -Z annotate-moves[=] +``` + +Where `` can be: +- A boolean: `true`, `false`, `yes`, `no`, `on`, `off` +- A number: size threshold in bytes (e.g., `128`) +- Omitted: enables with default threshold (65 bytes) + +## Options + +- `-Z annotate-moves` or `-Z annotate-moves=true`: Enable with default size limit +- `-Z annotate-moves=false`: Disable annotation +- `-Z annotate-moves=N`: Enable with custom size limit of N bytes + +## Examples + +```bash +# Enable annotation with default threshold (65 bytes) +rustc -Z annotate-moves main.rs + +# Enable with custom 128-byte threshold +rustc -Z annotate-moves=128 main.rs + +# Only annotate very large moves (1KB+) +rustc -Z annotate-moves=1024 main.rs + +# Explicitly disable +rustc -Z annotate-moves=false main.rs +``` + +## Behavior + +The annotation only applies to: +- Types equal or larger than the specified size threshold +- Non-immediate types (those that would generate `memcpy`) +- Operations that actually move/copy data (not ZST types) + +Stack traces will show the operations: +```text +0: memcpy +1: core::profiling::compiler_move:: +2: my_function +``` + +The `compiler_move` and `compiler_copy` functions have two generic parameters: +the type being moved/copied and its size in bytes. The size is identical to +`size_of::()`, and is present just so that it's easy to immediately tell how +large the copy is. + +Note that this requires v0 mangling to be properly encoded; legacy mangling does +not substitute these with a specific type and size. + +## Example + +```rust +#[derive(Clone)] +struct LargeData { + buffer: [u8; 1000], +} + +fn example() { + let data = LargeData { buffer: [0; 1000] }; + let copy = data.clone(); // Shows as compiler_copy in profiler + let moved = data; // Shows as compiler_move in profiler +} +``` + +## Overhead + +This has no effect on generated code; it only adds debuginfo. The overhead is +typically very small; on rustc itself, the default limit of 65 bytes adds about +0.055% to the binary size. diff --git a/tests/codegen-llvm/annotate-moves/call-arg-scope.rs b/tests/codegen-llvm/annotate-moves/call-arg-scope.rs new file mode 100644 index 000000000000..214e3908609e --- /dev/null +++ b/tests/codegen-llvm/annotate-moves/call-arg-scope.rs @@ -0,0 +1,114 @@ +//@ compile-flags: -Z annotate-moves=8 -Copt-level=0 -g +// +// This test verifies that function call and return instructions use the correct debug scopes +// when passing/returning large values. The actual move/copy operations may be annotated, +// but the CALL and RETURN instructions themselves should reference the source location, +// NOT have an inlinedAt scope pointing to compiler_move/compiler_copy. + +#![crate_type = "lib"] + +#[derive(Clone, Copy)] +pub struct LargeStruct { + pub data: [u64; 20], // 160 bytes +} + +#[derive(Clone, Copy)] +pub struct MediumStruct { + pub data: [u64; 5], // 40 bytes +} + +pub struct SmallStruct { + pub x: u32, // 4 bytes +} + +// ============================================================================ +// Test 1: Single argument call +// ============================================================================ + +// CHECK-LABEL: call_arg_scope::test_call_with_single_arg +pub fn test_call_with_single_arg(s: LargeStruct) { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CALL1_ARG_LOC:]] + // CHECK: call {{.*}}@{{.*}}helper_single{{.*}}({{.*}}){{.*}}, !dbg ![[#CALL1_LOC:]] + helper_single(s); +} + +#[inline(never)] +fn helper_single(_s: LargeStruct) {} + +// ============================================================================ +// Test 2: Multiple arguments of different types +// ============================================================================ + +// CHECK-LABEL: call_arg_scope::test_call_with_multiple_args +pub fn test_call_with_multiple_args(large: LargeStruct, medium: MediumStruct, small: SmallStruct) { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CALL2_ARG1_LOC:]] + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CALL2_ARG2_LOC:]] + // CHECK: call {{.*}}@{{.*}}helper_multiple{{.*}}({{.*}}){{.*}}, !dbg ![[#CALL2_LOC:]] + helper_multiple(large, medium, small); +} + +#[inline(never)] +fn helper_multiple(_l: LargeStruct, _m: MediumStruct, _s: SmallStruct) {} + +// ============================================================================ +// Test 3: Return value +// ============================================================================ + +// CHECK-LABEL: call_arg_scope::test_return_large_value +pub fn test_return_large_value() -> LargeStruct { + let s = LargeStruct { data: [42; 20] }; + // CHECK: ret {{.*}}, !dbg ![[#RET1_LOC:]] + s +} + +// ============================================================================ +// Test 4: Calling a function that returns a large value +// ============================================================================ + +// CHECK-LABEL: call_arg_scope::test_call_returning_large +pub fn test_call_returning_large() { + // CHECK: call {{.*}}@{{.*}}make_large_struct{{.*}}({{.*}}){{.*}}, !dbg ![[#CALL3_LOC:]] + let _result = make_large_struct(); +} + +#[inline(never)] +fn make_large_struct() -> LargeStruct { + LargeStruct { data: [1; 20] } +} + +// ============================================================================ +// Test 5: Mixed scenario - passing and returning large values +// ============================================================================ + +// CHECK-LABEL: call_arg_scope::test_mixed_call +pub fn test_mixed_call(input: LargeStruct) -> LargeStruct { + // CHECK: call {{.*}}@{{.*}}transform_large{{.*}}({{.*}}){{.*}}, !dbg ![[#CALL4_LOC:]] + transform_large(input) +} + +#[inline(never)] +fn transform_large(mut s: LargeStruct) -> LargeStruct { + s.data[0] += 1; + s +} + +// CHECK-DAG: ![[#CALL1_ARG_LOC]] = !DILocation({{.*}}scope: ![[#CALL1_ARG_SCOPE:]] +// CHECK-DAG: ![[#CALL1_ARG_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy" +// CHECK-DAG: ![[#CALL1_LOC]] = !DILocation({{.*}}scope: ![[#CALL1_SCOPE:]] +// CHECK-DAG: ![[#CALL1_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "test_call_with_single_arg" + +// CHECK-DAG: ![[#CALL2_ARG1_LOC]] = !DILocation({{.*}}scope: ![[#CALL2_ARG1_SCOPE:]] +// CHECK-DAG: ![[#CALL2_ARG1_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy" +// CHECK-DAG: ![[#CALL2_ARG2_LOC]] = !DILocation({{.*}}scope: ![[#CALL2_ARG2_SCOPE:]] +// CHECK-DAG: ![[#CALL2_ARG2_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy" +// CHECK-DAG: ![[#CALL2_LOC]] = !DILocation({{.*}}scope: ![[#CALL2_SCOPE:]] +// CHECK-DAG: ![[#CALL2_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "test_call_with_multiple_args" + +// CHECK-DAG: ![[#CALL3_LOC]] = !DILocation({{.*}}scope: ![[#CALL3_SCOPE:]] +// CHECK-DAG: ![[#CALL3_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "test_call_returning_large" + +// CHECK-DAG: ![[#CALL4_LOC]] = !DILocation({{.*}}scope: ![[#CALL4_SCOPE:]] +// CHECK-DAG: ![[#CALL4_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "test_mixed_call" + +// CHECK-DAG: ![[#RET1_LOC]] = !DILocation({{.*}}scope: ![[#RET1_SCOPE:]] +// CHECK-DAG: ![[#RET1_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "test_return_large_value" diff --git a/tests/codegen-llvm/annotate-moves/disabled.rs b/tests/codegen-llvm/annotate-moves/disabled.rs new file mode 100644 index 000000000000..2a0e78672318 --- /dev/null +++ b/tests/codegen-llvm/annotate-moves/disabled.rs @@ -0,0 +1,35 @@ +//@ compile-flags: -Zannotate-moves=no -Copt-level=0 -g +// Test that move/copy operations are NOT annotated when the flag is disabled + +#![crate_type = "lib"] + +struct LargeStruct { + data: [u64; 20], // 160 bytes - would normally trigger annotation +} + +impl Clone for LargeStruct { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // Should NOT be annotated when flag is disabled + // CHECK-NOT: compiler_copy + LargeStruct { data: self.data } + } +} + +// CHECK-LABEL: disabled::test_large_copy_no_annotation +pub fn test_large_copy_no_annotation() { + let large = LargeStruct { data: [42; 20] }; + // CHECK-NOT: compiler_copy + let _copy = large.clone(); +} + +// CHECK-LABEL: disabled::test_large_move_no_annotation +pub fn test_large_move_no_annotation() { + let large = LargeStruct { data: [42; 20] }; + // CHECK-NOT: compiler_move + let _moved = large; +} + +// Verify that no compiler_move or compiler_copy annotations exist anywhere +// CHECK-NOT: compiler_move +// CHECK-NOT: compiler_copy diff --git a/tests/codegen-llvm/annotate-moves/integration.rs b/tests/codegen-llvm/annotate-moves/integration.rs new file mode 100644 index 000000000000..11b28ac038bc --- /dev/null +++ b/tests/codegen-llvm/annotate-moves/integration.rs @@ -0,0 +1,192 @@ +//@ compile-flags: -Z annotate-moves=1 -Copt-level=0 -g + +#![crate_type = "lib"] + +// Test with large array (non-struct type, Copy) +type LargeArray = [u64; 20]; // 160 bytes + +#[derive(Clone, Default)] +struct NonCopyU64(u64); + +// Test with Copy implementation +#[derive(Copy)] +struct ExplicitCopy { + data: [u64; 20], // 160 bytes +} + +impl Clone for ExplicitCopy { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#EXPLICIT_COPY_LOC:]] + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#EXPLICIT_RETURN_LOC:]] + Self { data: self.data } + } +} + +// Test with hand-implemented Clone (non-Copy) +struct NonCopyStruct { + data: [u64; 20], // 160 bytes +} + +impl Clone for NonCopyStruct { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CLONE_COPY_LOC:]] + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CLONE_RETURN_LOC:]] + NonCopyStruct { data: self.data } + } +} + +// CHECK-LABEL: integration::test_pure_assignment_move +pub fn test_pure_assignment_move() { + let arr: LargeArray = [42; 20]; + // Arrays are initialized with a loop + // CHECK-NOT: call void @llvm.memcpy{{.*}}, !dbg ![[#]] + let _moved = arr; +} + +// CHECK-LABEL: integration::test_pure_assignment_copy +pub fn test_pure_assignment_copy() { + let s = ExplicitCopy { data: [42; 20] }; + // Arrays are initialized with a loop + // CHECK-NOT: call void @llvm.memcpy{{.*}}, !dbg ![[#]] + let _copied = s; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#ASSIGN_COPY2_LOC:]] + let _copied_2 = s; +} + +#[derive(Default)] +struct InitializeStruct { + field1: String, + field2: String, + field3: String, +} + +// CHECK-LABEL: integration::test_init_struct +pub fn test_init_struct() { + let mut s = InitializeStruct::default(); + + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#INIT_STRUCT_LOC:]] + s = InitializeStruct { + field1: String::from("Hello"), + field2: String::from("from"), + field3: String::from("Rust"), + }; +} + +// CHECK-LABEL: integration::test_tuple_of_scalars +pub fn test_tuple_of_scalars() { + // Tuple of scalars (even if large) may use scalar-pair repr, so may not be annotated + let t: (u64, u64, u64, u64) = (1, 2, 3, 4); // 32 bytes + // Copied with explicit stores + // CHECK-NOT: call void @llvm.memcpy{{.*}}, !dbg ![[#]] + let _moved = t; +} + +// CHECK-LABEL: integration::test_tuple_of_structs +pub fn test_tuple_of_structs() { + let s1 = NonCopyStruct { data: [1; 20] }; + let s2 = NonCopyStruct { data: [2; 20] }; + let tuple = (s1, s2); // Large tuple containing structs (320 bytes) + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#TUPLE_MOVE_LOC:]] + let _moved = tuple; +} + +// CHECK-LABEL: integration::test_tuple_mixed +pub fn test_tuple_mixed() { + let s = NonCopyStruct { data: [1; 20] }; + let tuple = (42u64, s); // Mixed tuple (168 bytes: 8 for u64 + 160 for struct) + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#MIXED_TUPLE_LOC:]] + let _moved = tuple; +} + +// CHECK-LABEL: integration::test_explicit_copy_assignment +pub fn test_explicit_copy_assignment() { + let c1 = ExplicitCopy { data: [1; 20] }; + // Initialized with loop + // CHECK-NOT: call void @llvm.memcpy{{.*}}, !dbg ![[#]] + let c2 = c1; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#COPY2_LOC:]] + let _c3 = c1; // Can still use c1 (it was copied) + let _ = c2; +} + +// CHECK-LABEL: integration::test_array_move +pub fn test_array_move() { + let arr: [String; 20] = std::array::from_fn(|i| i.to_string()); + + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#ARRAY_MOVE_LOC:]] + let _moved = arr; +} + +// CHECK-LABEL: integration::test_array_in_struct_field +pub fn test_array_in_struct_field() { + let s = NonCopyStruct { data: [1; 20] }; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#FIELD_MOVE_LOC:]] + let data = s.data; // Move array field out of struct + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#FIELD_MOVE2_LOC:]] + let _moved = data; +} + +// CHECK-LABEL: integration::test_clone_noncopy +pub fn test_clone_noncopy() { + let s = NonCopyStruct { data: [1; 20] }; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CALL_CLONE_NONCOPY_LOC:]] + let _cloned = s.clone(); // The copy happens inside the clone() impl above +} + +// CHECK-LABEL: integration::test_clone_explicit_copy +pub fn test_clone_explicit_copy() { + let c = ExplicitCopy { data: [1; 20] }; + // Derived Clone on Copy type - the copy happens inside the generated clone impl + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#CALL_CLONE_COPY_LOC:]] + let _cloned = c.clone(); +} + +// CHECK-LABEL: integration::test_copy_ref +pub fn test_copy_ref(x: &ExplicitCopy) { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#LOCAL_COPY_LOC:]] + let _local = *x; +} + +// CHECK-DAG: ![[#EXPLICIT_COPY_LOC]] = !DILocation({{.*}}scope: ![[#EXPLICIT_COPY_SCOPE:]] +// CHECK-DAG: ![[#EXPLICIT_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" +// CHECK-DAG: ![[#EXPLICIT_RETURN_LOC]] = !DILocation({{.*}}scope: ![[#EXPLICIT_RETURN_SCOPE:]] +// CHECK-DAG: ![[#EXPLICIT_RETURN_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#CLONE_COPY_LOC]] = !DILocation({{.*}}scope: ![[#CLONE_COPY_SCOPE:]] +// CHECK-DAG: ![[#CLONE_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" +// CHECK-DAG: ![[#CLONE_RETURN_LOC]] = !DILocation({{.*}}scope: ![[#CLONE_RETURN_SCOPE:]] +// CHECK-DAG: ![[#CLONE_RETURN_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#ASSIGN_COPY2_LOC]] = !DILocation({{.*}}scope: ![[#ASSIGN_COPY2_SCOPE:]] +// CHECK-DAG: ![[#ASSIGN_COPY2_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#INIT_STRUCT_LOC]] = !DILocation({{.*}}scope: ![[#INIT_STRUCT_SCOPE:]] +// CHECK-DAG: ![[#INIT_STRUCT_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move" + +// CHECK-DAG: ![[#TUPLE_MOVE_LOC]] = !DILocation({{.*}}scope: ![[#TUPLE_MOVE_SCOPE:]] +// CHECK-DAG: ![[#TUPLE_MOVE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#MIXED_TUPLE_LOC]] = !DILocation({{.*}}scope: ![[#MIXED_TUPLE_SCOPE:]] +// CHECK-DAG: ![[#MIXED_TUPLE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#COPY2_LOC]] = !DILocation({{.*}}scope: ![[#COPY2_SCOPE:]] +// CHECK-DAG: ![[#COPY2_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#ARRAY_MOVE_LOC]] = !DILocation({{.*}}scope: ![[#ARRAY_MOVE_SCOPE:]] +// CHECK-DAG: ![[#ARRAY_MOVE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)alloc::string::String[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#FIELD_MOVE_LOC]] = !DILocation({{.*}}scope: ![[#FIELD_MOVE_SCOPE:]] +// CHECK-DAG: ![[#FIELD_MOVE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" +// CHECK-DAG: ![[#FIELD_MOVE2_LOC]] = !DILocation({{.*}}scope: ![[#FIELD_MOVE2_SCOPE:]] +// CHECK-DAG: ![[#FIELD_MOVE2_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#CALL_CLONE_NONCOPY_LOC]] = !DILocation({{.*}}scope: ![[#CALL_CLONE_NONCOPY_SCOPE:]] +// CHECK-DAG: ![[#CALL_CLONE_NONCOPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#CALL_CLONE_COPY_LOC]] = !DILocation({{.*}}scope: ![[#CALL_CLONE_COPY_SCOPE:]] +// CHECK-DAG: ![[#CALL_CLONE_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u64[,;].*}},{{ *[0-9]+}}>" + +// CHECK-DAG: ![[#LOCAL_COPY_LOC]] = !DILocation({{.*}}scope: ![[#LOCAL_COPY_SCOPE:]] +// CHECK-DAG: ![[#LOCAL_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy" diff --git a/tests/codegen-llvm/annotate-moves/size-limit.rs b/tests/codegen-llvm/annotate-moves/size-limit.rs new file mode 100644 index 000000000000..2329c255f497 --- /dev/null +++ b/tests/codegen-llvm/annotate-moves/size-limit.rs @@ -0,0 +1,112 @@ +//@ compile-flags: -Z annotate-moves=100 -Copt-level=0 -g +// Test that custom size limits work correctly +#![crate_type = "lib"] + +struct Struct99 { + data: [u8; 99], // just below custom 100-byte threshold +} + +const _: () = { assert!(size_of::() == 99) }; + +impl Clone for Struct99 { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // Should NOT be annotated since 99 < 100 + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ99_COPY_LOC:]] + Struct99 { data: self.data } + } +} + +// CHECK-LABEL: size_limit::test_99_copy +pub fn test_99_copy() { + let sz99 = Struct99 { data: [42; 99] }; + let _copy = sz99.clone(); +} + +// CHECK-LABEL: size_limit::test_99_move +pub fn test_99_move() { + let sz99 = Struct99 { data: [42; 99] }; + // Should NOT be annotated + // CHECK-NOT: compiler_move + let _moved = sz99; +} + +struct Struct100 { + data: [u8; 100], // 100 bytes - equal to custom 100-byte threshold +} + +const _: () = { assert!(size_of::() == 100) }; + +impl Clone for Struct100 { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ100_COPY_LOC:]] + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ100_RETURN_LOC:]] + Struct100 { data: self.data } + } +} + +// CHECK-LABEL: size_limit::test_100_copy +pub fn test_100_copy() { + let sz100 = Struct100 { data: [42; 100] }; + let _copy = sz100.clone(); +} + +// CHECK-LABEL: size_limit::test_100_move +pub fn test_100_move() { + let sz100 = Struct100 { data: [42; 100] }; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ100_MOVE_LOC:]] + let _moved = sz100; +} + +struct Struct101 { + data: [u8; 101], // 101 bytes - above custom 100-byte threshold +} + +const _: () = { assert!(size_of::() == 101) }; + +impl Clone for Struct101 { + // CHECK-LABEL: ::clone + fn clone(&self) -> Self { + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ101_COPY_LOC:]] + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ101_RETURN_LOC:]] + Struct101 { data: self.data } + } +} + +// CHECK-LABEL: size_limit::test_101_copy +pub fn test_101_copy() { + let sz101 = Struct101 { data: [42; 101] }; + let _copy = sz101.clone(); +} + +// CHECK-LABEL: size_limit::test_101_move +pub fn test_101_move() { + let sz101 = Struct101 { data: [42; 101] }; + // CHECK: call void @llvm.memcpy{{.*}}, !dbg ![[#SZ101_MOVE_LOC:]] + let _moved = sz101; +} + +// The scope for no-annotated is clone function itself +// CHECK-DAG: ![[#SZ99_COPY_LOC]] = !DILocation({{.*}}scope: ![[#SZ99_COPY_SCOPE:]] +// CHECK-DAG: ![[#SZ99_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "clone", + +// Clone itself is copy, but return is move. +// CHECK-DAG: ![[#SZ100_COPY_LOC]] = !DILocation({{.*}}scope: ![[#SZ100_COPY_SCOPE:]] +// CHECK-DAG: ![[#SZ100_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" +// CHECK-DAG: ![[#SZ100_RETURN_LOC]] = !DILocation({{.*}}scope: ![[#SZ100_RETURN_SCOPE:]] +// CHECK-DAG: ![[#SZ100_RETURN_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" + +// Assignment is move +// CHECK-DAG: ![[#SZ100_MOVE_LOC]] = !DILocation({{.*}}scope: ![[#SZ100_MOVE_SCOPE:]] +// CHECK-DAG: ![[#SZ100_MOVE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" + +// Clone itself is copy, but return is move. +// CHECK-DAG: ![[#SZ101_COPY_LOC]] = !DILocation({{.*}}scope: ![[#SZ101_COPY_SCOPE:]] +// CHECK-DAG: ![[#SZ101_COPY_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_copy<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" +// CHECK-DAG: ![[#SZ101_RETURN_LOC]] = !DILocation({{.*}}scope: ![[#SZ101_RETURN_SCOPE:]] +// CHECK-DAG: ![[#SZ101_RETURN_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" + +// Assignment is move +// CHECK-DAG: ![[#SZ101_MOVE_LOC]] = !DILocation({{.*}}scope: ![[#SZ101_MOVE_SCOPE:]] +// CHECK-DAG: ![[#SZ101_MOVE_SCOPE]] = {{(distinct )?}}!DISubprogram(name: "compiler_move<{{(array\$<|\[)u8[,;].*}},{{ *[0-9]+}}>" diff --git a/tests/ui/annotate-moves/annotate-moves-basic.rs b/tests/ui/annotate-moves/annotate-moves-basic.rs new file mode 100644 index 000000000000..645122113dab --- /dev/null +++ b/tests/ui/annotate-moves/annotate-moves-basic.rs @@ -0,0 +1,15 @@ +//@ check-pass +//@ compile-flags: -Z annotate-moves=100 + +// Test that valid annotate-moves flags are accepted + +#[derive(Clone)] +struct TestStruct { + data: [u64; 20], // 160 bytes +} + +fn main() { + let s = TestStruct { data: [42; 20] }; + let _copy = s.clone(); + let _moved = s; +} diff --git a/tests/ui/annotate-moves/annotate-moves-invalid-flag.rs b/tests/ui/annotate-moves/annotate-moves-invalid-flag.rs new file mode 100644 index 000000000000..621b7861657e --- /dev/null +++ b/tests/ui/annotate-moves/annotate-moves-invalid-flag.rs @@ -0,0 +1,10 @@ +//@ check-fail +//@ compile-flags: -Z annotate-moves=invalid + +// Test that invalid values for annotate-moves flag are rejected + +fn main() { + // This should fail at compile time due to invalid flag value +} + +//~? ERROR incorrect value `invalid` for unstable option `annotate-moves` diff --git a/tests/ui/annotate-moves/annotate-moves-invalid-flag.stderr b/tests/ui/annotate-moves/annotate-moves-invalid-flag.stderr new file mode 100644 index 000000000000..5a323573a777 --- /dev/null +++ b/tests/ui/annotate-moves/annotate-moves-invalid-flag.stderr @@ -0,0 +1,2 @@ +error: incorrect value `invalid` for unstable option `annotate-moves` - either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes was expected + diff --git a/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.rs b/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.rs new file mode 100644 index 000000000000..50a402102184 --- /dev/null +++ b/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.rs @@ -0,0 +1,10 @@ +//@ check-fail +//@ compile-flags: -Z annotate-moves=-5 + +// Test that negative size limits are rejected + +fn main() { + // This should fail at compile time due to invalid negative size limit +} + +//~? ERROR incorrect value `-5` for unstable option `annotate-moves` diff --git a/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.stderr b/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.stderr new file mode 100644 index 000000000000..24a3659a30a6 --- /dev/null +++ b/tests/ui/annotate-moves/annotate-moves-size-limit-invalid.stderr @@ -0,0 +1,2 @@ +error: incorrect value `-5` for unstable option `annotate-moves` - either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes was expected + From 12cde3091a5d258c2f3e140e47537818680cb58d Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 7 Nov 2025 08:27:23 +0800 Subject: [PATCH 458/525] Add note for identifier with attempted hygiene violation --- .../rustc_resolve/src/late/diagnostics.rs | 24 +++++++++++++++++++ .../macros/macro-hygiene-help-issue-148580.rs | 15 ++++++++++++ .../macro-hygiene-help-issue-148580.stderr | 19 +++++++++++++++ .../macros/macro-hygiene-scope-15167.stderr | 20 ++++++++++++++++ .../metavar-expressions/concat-hygiene.stderr | 5 ++++ .../proc-macro/gen-macro-rules-hygiene.stderr | 5 ++++ tests/ui/proc-macro/mixed-site-span.stderr | 5 ++++ tests/ui/proc-macro/weird-hygiene.stderr | 10 ++++++++ 8 files changed, 103 insertions(+) create mode 100644 tests/ui/macros/macro-hygiene-help-issue-148580.rs create mode 100644 tests/ui/macros/macro-hygiene-help-issue-148580.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 1d00a6b81fab..ad3493d93e80 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1125,6 +1125,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } } + + self.suggest_ident_hidden_by_hygiene(err, path, span); } else if err_code == E0412 { if let Some(correct) = Self::likely_rust_type(path) { err.span_suggestion( @@ -1138,6 +1140,28 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + fn suggest_ident_hidden_by_hygiene(&self, err: &mut Diag<'_>, path: &[Segment], span: Span) { + let [segment] = path else { return }; + + let ident = segment.ident; + let callsite_span = span.source_callsite(); + for rib in self.ribs[ValueNS].iter().rev() { + for (binding_ident, _) in &rib.bindings { + if binding_ident.name == ident.name + && !binding_ident.span.eq_ctxt(span) + && !binding_ident.span.from_expansion() + && binding_ident.span.lo() < callsite_span.lo() + { + err.span_help( + binding_ident.span, + "an identifier with the same name exists, but is not accessible due to macro hygiene", + ); + return; + } + } + } + } + /// Emit special messages for unresolved `Self` and `self`. fn suggest_self_ty( &self, diff --git a/tests/ui/macros/macro-hygiene-help-issue-148580.rs b/tests/ui/macros/macro-hygiene-help-issue-148580.rs new file mode 100644 index 000000000000..8441290b1722 --- /dev/null +++ b/tests/ui/macros/macro-hygiene-help-issue-148580.rs @@ -0,0 +1,15 @@ +macro_rules! print_it { {} => { println!("{:?}", it); } } +//~^ ERROR cannot find value `it` in this scope + +fn main() { + { + let it = "hello"; + } + { + let it = "world"; + { + let it = (); + print_it!(); + } + } +} diff --git a/tests/ui/macros/macro-hygiene-help-issue-148580.stderr b/tests/ui/macros/macro-hygiene-help-issue-148580.stderr new file mode 100644 index 000000000000..f6a4ae7dd1c6 --- /dev/null +++ b/tests/ui/macros/macro-hygiene-help-issue-148580.stderr @@ -0,0 +1,19 @@ +error[E0425]: cannot find value `it` in this scope + --> $DIR/macro-hygiene-help-issue-148580.rs:1:50 + | +LL | macro_rules! print_it { {} => { println!("{:?}", it); } } + | ^^ not found in this scope +... +LL | print_it!(); + | ----------- in this macro invocation + | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/macro-hygiene-help-issue-148580.rs:11:17 + | +LL | let it = (); + | ^^ + = note: this error originates in the macro `print_it` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/macros/macro-hygiene-scope-15167.stderr b/tests/ui/macros/macro-hygiene-scope-15167.stderr index 58112c52df15..332a58467cee 100644 --- a/tests/ui/macros/macro-hygiene-scope-15167.stderr +++ b/tests/ui/macros/macro-hygiene-scope-15167.stderr @@ -7,6 +7,11 @@ LL | macro_rules! f { () => (n) } LL | println!("{}", f!()); | ---- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/macro-hygiene-scope-15167.rs:12:9 + | +LL | for n in 0..1 { + | ^ = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope @@ -18,6 +23,11 @@ LL | macro_rules! f { () => (n) } LL | println!("{}", f!()); | ---- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/macro-hygiene-scope-15167.rs:16:17 + | +LL | if let Some(n) = None { + | ^ = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope @@ -29,6 +39,11 @@ LL | macro_rules! f { () => (n) } LL | println!("{}", f!()); | ---- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/macro-hygiene-scope-15167.rs:21:24 + | +LL | } else if let Some(n) = None { + | ^ = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope @@ -40,6 +55,11 @@ LL | macro_rules! f { () => (n) } LL | println!("{}", f!()); | ---- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/macro-hygiene-scope-15167.rs:25:20 + | +LL | while let Some(n) = None { + | ^ = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/macros/metavar-expressions/concat-hygiene.stderr b/tests/ui/macros/metavar-expressions/concat-hygiene.stderr index f3150d385ee7..9520f5182f4a 100644 --- a/tests/ui/macros/metavar-expressions/concat-hygiene.stderr +++ b/tests/ui/macros/metavar-expressions/concat-hygiene.stderr @@ -7,6 +7,11 @@ LL | ${concat($lhs, $rhs)} LL | let _another = join!(abc, def); | --------------- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/concat-hygiene.rs:11:9 + | +LL | let abcdef = 1; + | ^^^^^^ = note: this error originates in the macro `join` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index e904b43aaae0..17171ad5c5cc 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -18,6 +18,11 @@ LL | gen_macro_rules!(); LL | generated!(); | ------------ in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/gen-macro-rules-hygiene.rs:19:13 + | +LL | let local_use = 1; + | ^^^^^^^^^ = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 2d2d55fe148d..4bb2508416aa 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -594,6 +594,11 @@ error[E0425]: cannot find value `local_use` in this scope LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/mixed-site-span.rs:21:13 + | +LL | let local_use = 1; + | ^^^^^^^^^ = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope diff --git a/tests/ui/proc-macro/weird-hygiene.stderr b/tests/ui/proc-macro/weird-hygiene.stderr index 0cfac3f89a04..aa3ef9556eb1 100644 --- a/tests/ui/proc-macro/weird-hygiene.stderr +++ b/tests/ui/proc-macro/weird-hygiene.stderr @@ -7,6 +7,11 @@ LL | Value = (stringify!($tokens + hidden_ident), 1).1 LL | other!(50); | ---------- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/weird-hygiene.rs:44:9 + | +LL | let hidden_ident = "Hello1"; + | ^^^^^^^^^^^^ = note: this error originates in the macro `inner` which comes from the expansion of the macro `other` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `hidden_ident` in this scope @@ -18,6 +23,11 @@ LL | hidden_ident LL | invoke_it!(25); | -------------- in this macro invocation | +help: an identifier with the same name exists, but is not accessible due to macro hygiene + --> $DIR/weird-hygiene.rs:44:9 + | +LL | let hidden_ident = "Hello1"; + | ^^^^^^^^^^^^ = note: this error originates in the macro `invoke_it` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors From c92ef479343a92212707a4e85c718d4da4a75328 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 6 Nov 2025 10:07:21 +0800 Subject: [PATCH 459/525] Fix suggestion for returning async closures --- compiler/rustc_hir_analysis/src/collect.rs | 15 ++++ ...async-closure-variance-issue-148488.stderr | 6 ++ .../suggest-impl-async-fn-issue-148493.fixed | 64 ++++++++++++++ .../suggest-impl-async-fn-issue-148493.rs | 64 ++++++++++++++ .../suggest-impl-async-fn-issue-148493.stderr | 87 +++++++++++++++++++ 5 files changed, 236 insertions(+) create mode 100644 tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.fixed create mode 100644 tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.rs create mode 100644 tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 6e62e50d3af8..190b57ecea4d 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1263,6 +1263,21 @@ pub fn suggest_impl_trait<'tcx>( infcx.tcx.lang_items().future_output(), format_as_assoc, ), + ( + infcx.tcx.lang_items().async_fn_trait(), + infcx.tcx.lang_items().async_fn_once_output(), + format_as_parenthesized, + ), + ( + infcx.tcx.lang_items().async_fn_mut_trait(), + infcx.tcx.lang_items().async_fn_once_output(), + format_as_parenthesized, + ), + ( + infcx.tcx.lang_items().async_fn_once_trait(), + infcx.tcx.lang_items().async_fn_once_output(), + format_as_parenthesized, + ), ( infcx.tcx.lang_items().fn_trait(), infcx.tcx.lang_items().fn_once_output(), diff --git a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr index ca98d210579f..507b1e895898 100644 --- a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr +++ b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr @@ -11,6 +11,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn ord() -> _ { | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn ord() -> _ { +LL + fn ord() -> impl AsyncFn() { + | error[E0392]: lifetime parameter `'g` is never used --> $DIR/ice-async-closure-variance-issue-148488.rs:3:10 diff --git a/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.fixed b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.fixed new file mode 100644 index 000000000000..db5091f6b7f6 --- /dev/null +++ b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.fixed @@ -0,0 +1,64 @@ +#![allow(dead_code)] +//@ run-rustfix +//@ edition: 2021 + +// The suggestion should be `impl AsyncFn()` instead of something like `{async closure@...}` + +fn test1() -> impl AsyncFn() { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() + async || {} +} + +fn test2() -> impl AsyncFn(i32) -> i32 { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn(i32) -> i32 + async |x: i32| x + 1 +} + +fn test3() -> impl AsyncFn(i32, i32) -> i32 { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn(i32, i32) -> i32 + async |x: i32, y: i32| x + y +} + +fn test4() -> impl AsyncFn() { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() + async || -> () { () } +} + +fn test5() -> impl AsyncFn() -> i32 { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() -> i32 + let z = 42; + async move || z +} + +fn test6() -> impl AsyncFnMut() -> i32 { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFnMut() -> i32 + let mut x = 0; + async move || { + x += 1; + x + } +} + +fn test7() -> impl AsyncFnOnce() { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFnOnce() + let s = String::from("hello"); + async move || { + drop(s); + } +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.rs b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.rs new file mode 100644 index 000000000000..1109904398da --- /dev/null +++ b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.rs @@ -0,0 +1,64 @@ +#![allow(dead_code)] +//@ run-rustfix +//@ edition: 2021 + +// The suggestion should be `impl AsyncFn()` instead of something like `{async closure@...}` + +fn test1() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() + async || {} +} + +fn test2() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn(i32) -> i32 + async |x: i32| x + 1 +} + +fn test3() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn(i32, i32) -> i32 + async |x: i32, y: i32| x + y +} + +fn test4() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() + async || -> () { () } +} + +fn test5() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFn() -> i32 + let z = 42; + async move || z +} + +fn test6() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFnMut() -> i32 + let mut x = 0; + async move || { + x += 1; + x + } +} + +fn test7() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl AsyncFnOnce() + let s = String::from("hello"); + async move || { + drop(s); + } +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.stderr b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.stderr new file mode 100644 index 000000000000..abe775cec082 --- /dev/null +++ b/tests/ui/async-await/async-closures/suggest-impl-async-fn-issue-148493.stderr @@ -0,0 +1,87 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:7:15 + | +LL | fn test1() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test1() -> _ { +LL + fn test1() -> impl AsyncFn() { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:14:15 + | +LL | fn test2() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test2() -> _ { +LL + fn test2() -> impl AsyncFn(i32) -> i32 { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:21:15 + | +LL | fn test3() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test3() -> _ { +LL + fn test3() -> impl AsyncFn(i32, i32) -> i32 { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:28:15 + | +LL | fn test4() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test4() -> _ { +LL + fn test4() -> impl AsyncFn() { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:35:15 + | +LL | fn test5() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test5() -> _ { +LL + fn test5() -> impl AsyncFn() -> i32 { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:43:15 + | +LL | fn test6() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test6() -> _ { +LL + fn test6() -> impl AsyncFnMut() -> i32 { + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-impl-async-fn-issue-148493.rs:54:15 + | +LL | fn test7() -> _ { + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn test7() -> _ { +LL + fn test7() -> impl AsyncFnOnce() { + | + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0121`. From 5ed01e95df9be3accd4d46a9b9c315f602299abd Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 6 Nov 2025 19:40:00 -0600 Subject: [PATCH 460/525] Switch hexagon targets to rust-lld lld is a great choice for a default linker. --- .../src/spec/targets/hexagon_unknown_linux_musl.rs | 1 + .../src/spec/targets/hexagon_unknown_none_elf.rs | 1 + .../src/platform-support/hexagon-unknown-linux-musl.md | 6 ++++++ .../rustc/src/platform-support/hexagon-unknown-none-elf.md | 7 +++++++ 4 files changed, 15 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs index 17b371f05e53..82811cda00ce 100644 --- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs @@ -8,6 +8,7 @@ pub(crate) fn target() -> Target { base.features = "-small-data,+hvx-length128b".into(); base.has_rpath = true; + base.linker = Some("rust-lld".into()); base.linker_flavor = LinkerFlavor::Unix(Cc::Yes); base.c_enum_min_bits = Some(8); diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs index 6379cd30c355..55ec3697a15e 100644 --- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs @@ -27,6 +27,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(32), emit_debug_gdb_scripts: false, c_enum_min_bits: Some(8), + linker: Some("rust-lld".into()), ..Default::default() }, } diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md index be6e17883f4e..d74dd843eb25 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md @@ -39,6 +39,12 @@ dynamically linked executables. # /opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/bin/qemu-hexagon -L /opt/clang+llvm-18.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr/ ./hello ``` +## Linking + +This target selects `rust-lld` by default. Another option to use is +[eld](https://github.com/qualcomm/eld), which is also provided with +the opensource hexagon toolchain and the Hexagon SDK. + ## Building the target Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target. diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md index b07b0bb08d60..a906e895b774 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md @@ -25,6 +25,13 @@ Functions marked `extern "C"` use the [Hexagon architecture calling convention]( This target generates PIC ELF binaries. +## Linking + +This target selects `rust-lld` by default. Another option to use is +[eld](https://github.com/qualcomm/eld), which is also provided with +[the opensource hexagon toolchain](https://github.com/quic/toolchain_for_hexagon) +and the Hexagon SDK. + ## Building the target You can build Rust with support for the target by adding it to the `target` From b827732898bc52912d2428c9d2d004a3a22378f7 Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Fri, 7 Nov 2025 04:36:12 +0000 Subject: [PATCH 461/525] Enable std locking functions on AIX This patch enables the std locking functions on AIX by including AIX on the list of supported targets for the locking functions. Excluding AIX from the std locking functions results to compilation errors such as: ("try_lock() not supported"). --- library/std/src/sys/fs/unix.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 129fccdbf419..cadcfddb0f7f 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1296,6 +1296,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "illumos", + target_os = "aix", target_vendor = "apple", ))] pub fn lock(&self) -> io::Result<()> { @@ -1321,6 +1322,7 @@ impl File { target_os = "cygwin", target_os = "solaris", target_os = "illumos", + target_os = "aix", target_vendor = "apple", )))] pub fn lock(&self) -> io::Result<()> { @@ -1335,6 +1337,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "illumos", + target_os = "aix", target_vendor = "apple", ))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1360,6 +1363,7 @@ impl File { target_os = "cygwin", target_os = "solaris", target_os = "illumos", + target_os = "aix", target_vendor = "apple", )))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1374,6 +1378,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "illumos", + target_os = "aix", target_vendor = "apple", ))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1415,6 +1420,7 @@ impl File { target_os = "cygwin", target_os = "solaris", target_os = "illumos", + target_os = "aix", target_vendor = "apple", )))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1432,6 +1438,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "illumos", + target_os = "aix", target_vendor = "apple", ))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1473,6 +1480,7 @@ impl File { target_os = "cygwin", target_os = "solaris", target_os = "illumos", + target_os = "aix", target_vendor = "apple", )))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1490,6 +1498,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "illumos", + target_os = "aix", target_vendor = "apple", ))] pub fn unlock(&self) -> io::Result<()> { @@ -1515,6 +1524,7 @@ impl File { target_os = "cygwin", target_os = "solaris", target_os = "illumos", + target_os = "aix", target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { From fc20a28776ae6cd9583031c970e1ad2b377ddd9e Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 28 Oct 2025 12:10:18 +0100 Subject: [PATCH 462/525] Modify contributor email entries in .mailmap Updated email addresses for several contributors in the mailmap. --- .mailmap | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.mailmap b/.mailmap index fc8e83d6493c..de7001b77427 100644 --- a/.mailmap +++ b/.mailmap @@ -9,7 +9,7 @@ Aaron Todd Abhishek Chanda Abhishek Chanda Abhijeet Bhagat Abroskin Alexander -Adolfo Ochagavía +Adolfo Ochagavía Adrian Heine né Lang Adrien Tétar Ahmed Charles @@ -36,6 +36,7 @@ Amanda Stjerna Amanda Stjerna Amanieu d'Antras Amos Onn +Amos Wenger Ana-Maria Mihalache Anatoly Ikorsky Andre Bogus @@ -276,7 +277,8 @@ Irina Popa Ivan Ivaschenko ivan tkachenko J. J. Weber -Jack Huey +Jack Huey +Jack Huey <31162821+jackh726@users.noreply.github.com> Jacob Jacob Hoffman-Andrews Jacob Greenfield @@ -292,6 +294,8 @@ Jakub Adam Wieczorek Jakub Adam Wieczorek Jakub Adam Wieczorek Jakub Adam Wieczorek +Jakub Adam Wieczorek +Jakub Adam Wieczorek Jakub Beránek James [Undefined] James Deng @@ -303,6 +307,7 @@ Jamie Hill-Daniel Jana Dönszelmann Jana Dönszelmann Jana Dönszelmann +Jane Lusby Jan-Erik Rediger Jaro Fietz Jason Fager @@ -313,6 +318,7 @@ Jason Toffaletti Jason Toffaletti Jauhien Piatlicki Jauhien Piatlicki Jay True Jeremy Letang +Jeremy Soller Jeremy Sorensen Jeremy Stucki Jeremy Stucki @@ -336,6 +342,7 @@ John Kåre Alsaker John Kåre Alsaker John Talling John Van Enk +Jon Gjengset Jonas Tepe Jonathan Bailey Jonathan Chan Kwan Yin @@ -424,7 +431,7 @@ Malo Jaffré Manish Goregaokar Mara Bos Marcell Pardavi -Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> +Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Marcus Klaas de Vries Margaret Meyerhofer Marijn Schouten @@ -531,6 +538,7 @@ Oliver Scherer Oliver Scherer Oliver Scherer Oliver Scherer +Onur Özkan Onur Özkan Onur Özkan Ömer Sinan Ağacan @@ -591,6 +599,7 @@ Rusty Blitzerr RustyYato Ruud van Asseldonk Ruud van Asseldonk Ryan Leung +Ryan Levick Ryan Scheel Ryan Sullivant Ryan Wiedemann @@ -685,6 +694,8 @@ Weihang Lo Weihang Lo Wesley Wiser whitequark +Will Crichton +Will Crichton William Ting Wim Looman Wim Looman @@ -694,6 +705,8 @@ Xinye Tao Xuefeng Wu Xuefeng Wu Xuefeng Wu XuefengWu York Xiang +Yoshua Wuyts +Yoshua Wuyts <2467194+yoshuawuyts@users.noreply.github.com> Yotam Ofek Youngsoo Son Youngsuk Kim From a7aedeb5c8895c470cb2f693115f10f0961ab40d Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 9 Oct 2025 17:08:17 +0530 Subject: [PATCH 463/525] implement SIMD funnel shifts in const-eval --- .../src/interpret/intrinsics/simd.rs | 54 ++++++++++++++++++- .../intrinsics/simd-funnel_shl-too-far.rs | 12 +++++ .../intrinsics/simd-funnel_shl-too-far.stderr | 13 +++++ .../intrinsics/simd-funnel_shr-too-far.rs | 12 +++++ .../intrinsics/simd-funnel_shr-too-far.stderr | 13 +++++ .../tests/pass/intrinsics/portable-simd.rs | 16 +++++- 6 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.stderr create mode 100644 src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.stderr diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 751674f3f068..bae423840ee1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -3,7 +3,7 @@ use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; -use rustc_middle::ty::{FloatTy, SimdAlign}; +use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; use rustc_span::{Symbol, sym}; use tracing::trace; @@ -744,6 +744,58 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(val, &dest)?; } } + sym::simd_funnel_shl | sym::simd_funnel_shr => { + let (left, _) = self.project_to_simd(&args[0])?; + let (right, _) = self.project_to_simd(&args[1])?; + let (shift, _) = self.project_to_simd(&args[2])?; + let (dest, _) = self.project_to_simd(&dest)?; + + let (len, elem_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx); + let (elem_size, _signed) = elem_ty.int_size_and_signed(*self.tcx); + let elem_size_bits = u128::from(elem_size.bits()); + + let is_left = intrinsic_name == sym::simd_funnel_shl; + + for i in 0..len { + let left = + self.read_scalar(&self.project_index(&left, i)?)?.to_bits(elem_size)?; + let right = + self.read_scalar(&self.project_index(&right, i)?)?.to_bits(elem_size)?; + let shift_bits = + self.read_scalar(&self.project_index(&shift, i)?)?.to_bits(elem_size)?; + + if shift_bits >= elem_size_bits { + throw_ub_format!( + "overflowing shift by {shift_bits} in `{intrinsic_name}` in lane {i}" + ); + } + let inv_shift_bits = u32::try_from(elem_size_bits - shift_bits).unwrap(); + + // A funnel shift left by S can be implemented as `(x << S) | y.unbounded_shr(SIZE - S)`. + // The `unbounded_shr` is needed because otherwise if `S = 0`, it would be `x | y` + // when it should be `x`. + // + // This selects the least-significant `SIZE - S` bits of `x`, followed by the `S` most + // significant bits of `y`. As `left` and `right` both occupy the lower `SIZE` bits, + // we can treat the lower `SIZE` bits as an integer of the right width and use + // the same implementation, but on a zero-extended `x` and `y`. This works because + // `x << S` just pushes the `SIZE-S` MSBs out, and `y >> (SIZE - S)` shifts in + // zeros, as it is zero-extended. To the lower `SIZE` bits, this looks just like a + // funnel shift left. + // + // Note that the `unbounded_sh{l,r}`s are needed only in case we are using this on + // `u128xN` and `inv_shift_bits == 128`. + let result_bits = if is_left { + (left << shift_bits) | right.unbounded_shr(inv_shift_bits) + } else { + left.unbounded_shl(inv_shift_bits) | (right >> shift_bits) + }; + let (result, _overflow) = ScalarInt::truncate_from_uint(result_bits, elem_size); + + let dest = self.project_index(&dest, i)?; + self.write_scalar(result, &dest)?; + } + } // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), diff --git a/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.rs new file mode 100644 index 000000000000..54cecc23f9e7 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.rs @@ -0,0 +1,12 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::simd_funnel_shl; +use std::simd::*; + +fn main() { + unsafe { + let x = i32x2::from_array([1, 1]); + let y = i32x2::from_array([100, 0]); + simd_funnel_shl(x, x, y); //~ERROR: overflowing shift by 100 in `simd_funnel_shl` in lane 0 + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.stderr b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.stderr new file mode 100644 index 000000000000..00c7c39a8856 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shl-too-far.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: overflowing shift by 100 in `simd_funnel_shl` in lane 0 + --> tests/fail/intrinsics/simd-funnel_shl-too-far.rs:LL:CC + | +LL | simd_funnel_shl(x, x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.rs new file mode 100644 index 000000000000..6fb2daa48848 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.rs @@ -0,0 +1,12 @@ +#![feature(core_intrinsics, portable_simd)] + +use std::intrinsics::simd::simd_funnel_shr; +use std::simd::*; + +fn main() { + unsafe { + let x = i32x2::from_array([1, 1]); + let y = i32x2::from_array([20, 40]); + simd_funnel_shr(x, x, y); //~ERROR: overflowing shift by 40 in `simd_funnel_shr` in lane 1 + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.stderr b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.stderr new file mode 100644 index 000000000000..2f6c6cd71ea6 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/simd-funnel_shr-too-far.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: overflowing shift by 40 in `simd_funnel_shr` in lane 1 + --> tests/fail/intrinsics/simd-funnel_shr-too-far.rs:LL:CC + | +LL | simd_funnel_shr(x, x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index 4ecbe167b525..961a4b82a7e9 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -62,7 +62,7 @@ impl PackedSimd { #[rustc_nounwind] pub unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; -pub fn simd_ops_f16() { +fn simd_ops_f16() { use intrinsics::*; // small hack to make type inference better @@ -273,7 +273,7 @@ fn simd_ops_f64() { assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_min(), 0.0); } -pub fn simd_ops_f128() { +fn simd_ops_f128() { use intrinsics::*; // small hack to make type inference better @@ -454,6 +454,18 @@ fn simd_ops_i32() { 0x3fffffffu32 as i32 ]) ); + + // these values are taken from the doctests of `u32::funnel_shl` and `u32::funnel_shr` + let c = u32x4::splat(0x010000b3); + let d = u32x4::splat(0x2fe78e45); + + unsafe { + assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(0)), c); + assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(8)), u32x4::splat(0x0000b32f)); + + assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(0)), d); + assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(8)), u32x4::splat(0xb32fe78e)); + } } fn simd_mask() { From f2794ce6c0742f28e650840bba90df0a7289838e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 6 Nov 2025 15:08:13 +0100 Subject: [PATCH 464/525] Switch clean `print` methods into a function --- src/librustdoc/html/format.rs | 776 ++++++++++----------- src/librustdoc/html/render/mod.rs | 46 +- src/librustdoc/html/render/print_item.rs | 49 +- src/librustdoc/html/render/sidebar.rs | 7 +- src/librustdoc/html/render/write_shared.rs | 5 +- 5 files changed, 445 insertions(+), 438 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 856e637a4587..c2466135a2cd 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -47,71 +47,69 @@ pub(crate) fn print_generic_bounds( bounds .iter() .filter(move |b| bounds_dup.insert(*b)) - .map(|bound| bound.print(cx)) + .map(|bound| print_generic_bound(bound, cx)) .joined(" + ", f) }) } -impl clean::GenericParamDef { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| match &self.kind { - clean::GenericParamDefKind::Lifetime { outlives } => { - write!(f, "{}", self.name)?; +pub(crate) fn print_generic_param_def( + generic_param: &clean::GenericParamDef, + cx: &Context<'_>, +) -> impl Display { + fmt::from_fn(move |f| match &generic_param.kind { + clean::GenericParamDefKind::Lifetime { outlives } => { + write!(f, "{}", generic_param.name)?; - if !outlives.is_empty() { - f.write_str(": ")?; - outlives.iter().map(|lt| lt.print()).joined(" + ", f)?; - } - - Ok(()) + if !outlives.is_empty() { + f.write_str(": ")?; + outlives.iter().map(|lt| print_lifetime(lt)).joined(" + ", f)?; } - clean::GenericParamDefKind::Type { bounds, default, .. } => { - f.write_str(self.name.as_str())?; - if !bounds.is_empty() { - f.write_str(": ")?; - print_generic_bounds(bounds, cx).fmt(f)?; - } + Ok(()) + } + clean::GenericParamDefKind::Type { bounds, default, .. } => { + f.write_str(generic_param.name.as_str())?; - if let Some(ty) = default { - f.write_str(" = ")?; - ty.print(cx).fmt(f)?; - } - - Ok(()) + if !bounds.is_empty() { + f.write_str(": ")?; + print_generic_bounds(bounds, cx).fmt(f)?; } - clean::GenericParamDefKind::Const { ty, default, .. } => { - write!(f, "const {}: ", self.name)?; - ty.print(cx).fmt(f)?; - if let Some(default) = default { - f.write_str(" = ")?; - if f.alternate() { - write!(f, "{default}")?; - } else { - write!(f, "{}", Escape(default))?; - } - } - - Ok(()) + if let Some(ty) = default { + f.write_str(" = ")?; + print_type(ty, cx).fmt(f)?; } - }) - } + + Ok(()) + } + clean::GenericParamDefKind::Const { ty, default, .. } => { + write!(f, "const {}: ", generic_param.name)?; + print_type(ty, cx).fmt(f)?; + + if let Some(default) = default { + f.write_str(" = ")?; + if f.alternate() { + write!(f, "{default}")?; + } else { + write!(f, "{}", Escape(default))?; + } + } + + Ok(()) + } + }) } -impl clean::Generics { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); - if real_params.peek().is_none() { - None - } else { - Some( - Wrapped::with_angle_brackets() - .wrap_fn(move |f| real_params.clone().map(|g| g.print(cx)).joined(", ", f)), - ) - } - .maybe_display() +pub(crate) fn print_generics(generics: &clean::Generics, cx: &Context<'_>) -> impl Display { + let mut real_params = generics.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); + if real_params.peek().is_none() { + None + } else { + Some(Wrapped::with_angle_brackets().wrap_fn(move |f| { + real_params.clone().map(|g| print_generic_param_def(g, cx)).joined(", ", f) + })) } + .maybe_display() } #[derive(Clone, Copy, PartialEq, Eq)] @@ -125,7 +123,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> match predicate { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { print_higher_ranked_params_with_space(bound_params, cx, "for").fmt(f)?; - ty.print(cx).fmt(f)?; + print_type(ty, cx).fmt(f)?; f.write_str(":")?; if !bounds.is_empty() { f.write_str(" ")?; @@ -136,7 +134,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> clean::WherePredicate::RegionPredicate { lifetime, bounds } => { // We don't need to check `alternate` since we can be certain that neither // the lifetime nor the bounds contain any characters which need escaping. - write!(f, "{}:", lifetime.print())?; + write!(f, "{}:", print_lifetime(lifetime))?; if !bounds.is_empty() { write!(f, " {}", print_generic_bounds(bounds, cx))?; } @@ -144,7 +142,12 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> } clean::WherePredicate::EqPredicate { lhs, rhs } => { let opts = WithOpts::from(f); - write!(f, "{} == {}", opts.display(lhs.print(cx)), opts.display(rhs.print(cx))) + write!( + f, + "{} == {}", + opts.display(print_qpath_data(lhs, cx)), + opts.display(print_term(rhs, cx)), + ) } } }) @@ -229,92 +232,91 @@ pub(crate) fn print_where_clause( })) } -impl clean::Lifetime { - pub(crate) fn print(&self) -> impl Display { - self.0.as_str() - } +#[inline] +pub(crate) fn print_lifetime(lt: &clean::Lifetime) -> &str { + lt.0.as_str() } -impl clean::ConstantKind { - pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display { - let expr = self.expr(tcx); - fmt::from_fn(move |f| { +pub(crate) fn print_constant_kind( + constant_kind: &clean::ConstantKind, + tcx: TyCtxt<'_>, +) -> impl Display { + let expr = constant_kind.expr(tcx); + fmt::from_fn( + move |f| { if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } - }) - } + }, + ) } -impl clean::PolyTrait { - fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| { - print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?; - self.trait_.print(cx).fmt(f) - }) - } +fn print_poly_trait(poly_trait: &clean::PolyTrait, cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| { + print_higher_ranked_params_with_space(&poly_trait.generic_params, cx, "for").fmt(f)?; + print_path(&poly_trait.trait_, cx).fmt(f) + }) } -impl clean::GenericBound { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| match self { - clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()), - clean::GenericBound::TraitBound(ty, modifiers) => { - // `const` and `[const]` trait bounds are experimental; don't render them. - let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers; - f.write_str(match polarity { - hir::BoundPolarity::Positive => "", - hir::BoundPolarity::Maybe(_) => "?", - hir::BoundPolarity::Negative(_) => "!", - })?; - ty.print(cx).fmt(f) - } - clean::GenericBound::Use(args) => { - f.write_str("use")?; - Wrapped::with_angle_brackets() - .wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f)) - .fmt(f) - } - }) - } +pub(crate) fn print_generic_bound( + generic_bound: &clean::GenericBound, + cx: &Context<'_>, +) -> impl Display { + fmt::from_fn(move |f| match generic_bound { + clean::GenericBound::Outlives(lt) => f.write_str(print_lifetime(lt)), + clean::GenericBound::TraitBound(ty, modifiers) => { + // `const` and `[const]` trait bounds are experimental; don't render them. + let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers; + f.write_str(match polarity { + hir::BoundPolarity::Positive => "", + hir::BoundPolarity::Maybe(_) => "?", + hir::BoundPolarity::Negative(_) => "!", + })?; + print_poly_trait(ty, cx).fmt(f) + } + clean::GenericBound::Use(args) => { + f.write_str("use")?; + Wrapped::with_angle_brackets() + .wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f)) + .fmt(f) + } + }) } -impl clean::GenericArgs { - fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| { - match self { - clean::GenericArgs::AngleBracketed { args, constraints } => { - if !args.is_empty() || !constraints.is_empty() { - Wrapped::with_angle_brackets() - .wrap_fn(|f| { - [Either::Left(args), Either::Right(constraints)] - .into_iter() - .flat_map(Either::factor_into_iter) - .map(|either| { - either.map_either( - |arg| arg.print(cx), - |constraint| constraint.print(cx), - ) - }) - .joined(", ", f) - }) - .fmt(f)?; - } - } - clean::GenericArgs::Parenthesized { inputs, output } => { - Wrapped::with_parens() - .wrap_fn(|f| inputs.iter().map(|ty| ty.print(cx)).joined(", ", f)) +fn print_generic_args(generic_args: &clean::GenericArgs, cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| { + match generic_args { + clean::GenericArgs::AngleBracketed { args, constraints } => { + if !args.is_empty() || !constraints.is_empty() { + Wrapped::with_angle_brackets() + .wrap_fn(|f| { + [Either::Left(args), Either::Right(constraints)] + .into_iter() + .flat_map(Either::factor_into_iter) + .map(|either| { + either.map_either( + |arg| print_generic_arg(arg, cx), + |constraint| print_assoc_item_constraint(constraint, cx), + ) + }) + .joined(", ", f) + }) .fmt(f)?; - if let Some(ref ty) = *output { - f.write_str(if f.alternate() { " -> " } else { " -> " })?; - ty.print(cx).fmt(f)?; - } - } - clean::GenericArgs::ReturnTypeNotation => { - f.write_str("(..)")?; } } - Ok(()) - }) - } + clean::GenericArgs::Parenthesized { inputs, output } => { + Wrapped::with_parens() + .wrap_fn(|f| inputs.iter().map(|ty| print_type(ty, cx)).joined(", ", f)) + .fmt(f)?; + if let Some(ref ty) = *output { + f.write_str(if f.alternate() { " -> " } else { " -> " })?; + print_type(ty, cx).fmt(f)?; + } + } + clean::GenericArgs::ReturnTypeNotation => { + f.write_str("(..)")?; + } + } + Ok(()) + }) } // Possible errors when computing href link source for a `DefId` @@ -684,7 +686,7 @@ fn resolved_path( } } if w.alternate() { - write!(w, "{}{:#}", last.name, last.args.print(cx))?; + write!(w, "{}{:#}", last.name, print_generic_args(&last.args, cx))?; } else { let path = fmt::from_fn(|f| { if use_absolute { @@ -702,7 +704,7 @@ fn resolved_path( write!(f, "{}", print_anchor(did, last.name, cx)) } }); - write!(w, "{path}{args}", args = last.args.print(cx))?; + write!(w, "{path}{args}", args = print_generic_args(&last.args, cx))?; } Ok(()) } @@ -791,11 +793,11 @@ fn print_tybounds( cx: &Context<'_>, ) -> impl Display { fmt::from_fn(move |f| { - bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?; + bounds.iter().map(|bound| print_poly_trait(bound, cx)).joined(" + ", f)?; if let Some(lt) = lt { // We don't need to check `alternate` since we can be certain that // the lifetime doesn't contain any characters which need escaping. - write!(f, " + {}", lt.print())?; + write!(f, " + {}", print_lifetime(lt))?; } Ok(()) }) @@ -810,7 +812,9 @@ fn print_higher_ranked_params_with_space( if !params.is_empty() { f.write_str(keyword)?; Wrapped::with_angle_brackets() - .wrap_fn(|f| params.iter().map(|lt| lt.print(cx)).joined(", ", f)) + .wrap_fn(|f| { + params.iter().map(|lt| print_generic_param_def(lt, cx)).joined(", ", f) + }) .fmt(f)?; f.write_char(' ')?; } @@ -868,11 +872,11 @@ fn fmt_type( } else { primitive_link(f, PrimitiveType::Fn, format_args!("fn"), cx)?; } - decl.decl.print(cx).fmt(f) + print_fn_decl(&decl.decl, cx).fmt(f) } clean::UnsafeBinder(binder) => { print_higher_ranked_params_with_space(&binder.generic_params, cx, "unsafe").fmt(f)?; - binder.ty.print(cx).fmt(f) + print_type(&binder.ty, cx).fmt(f) } clean::Tuple(typs) => match &typs[..] { &[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx), @@ -881,7 +885,7 @@ fn fmt_type( primitive_link(f, PrimitiveType::Tuple, format_args!("({name},)"), cx) } else { write!(f, "(")?; - one.print(cx).fmt(f)?; + print_type(one, cx).fmt(f)?; write!(f, ",)") } } @@ -907,7 +911,7 @@ fn fmt_type( ) } else { Wrapped::with_parens() - .wrap_fn(|f| many.iter().map(|item| item.print(cx)).joined(", ", f)) + .wrap_fn(|f| many.iter().map(|item| print_type(item, cx)).joined(", ", f)) .fmt(f) } } @@ -915,9 +919,9 @@ fn fmt_type( clean::Slice(box clean::Generic(name)) => { primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx) } - clean::Slice(t) => Wrapped::with_square_brackets().wrap(t.print(cx)).fmt(f), + clean::Slice(t) => Wrapped::with_square_brackets().wrap(print_type(t, cx)).fmt(f), clean::Type::Pat(t, pat) => { - fmt::Display::fmt(&t.print(cx), f)?; + fmt::Display::fmt(&print_type(t, cx), f)?; write!(f, " is {pat}") } clean::Array(box clean::Generic(name), n) if !f.alternate() => primitive_link( @@ -928,7 +932,7 @@ fn fmt_type( ), clean::Array(t, n) => Wrapped::with_square_brackets() .wrap(fmt::from_fn(|f| { - t.print(cx).fmt(f)?; + print_type(t, cx).fmt(f)?; f.write_str("; ")?; if f.alternate() { f.write_str(n) @@ -944,17 +948,17 @@ fn fmt_type( primitive_link( f, clean::PrimitiveType::RawPointer, - format_args!("*{m} {ty}", ty = WithOpts::from(f).display(t.print(cx))), + format_args!("*{m} {ty}", ty = WithOpts::from(f).display(print_type(t, cx))), cx, ) } else { primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?; - t.print(cx).fmt(f) + print_type(t, cx).fmt(f) } } clean::BorrowedRef { lifetime: l, mutability, type_: ty } => { let lt = fmt::from_fn(|f| match l { - Some(l) => write!(f, "{} ", l.print()), + Some(l) => write!(f, "{} ", print_lifetime(l)), _ => Ok(()), }); let m = mutability.print_with_space(); @@ -989,133 +993,133 @@ fn fmt_type( f.write_str("impl ")?; print_generic_bounds(bounds, cx).fmt(f) } - clean::QPath(qpath) => qpath.print(cx).fmt(f), + clean::QPath(qpath) => print_qpath_data(qpath, cx).fmt(f), } } -impl clean::Type { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| fmt_type(self, f, false, cx)) - } +pub(crate) fn print_type(type_: &clean::Type, cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| fmt_type(type_, f, false, cx)) } -impl clean::Path { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) - } +pub(crate) fn print_path(path: &clean::Path, cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| resolved_path(f, path.def_id(), path, false, false, cx)) } -impl clean::QPathData { - fn print(&self, cx: &Context<'_>) -> impl Display { - let Self { ref assoc, ref self_type, should_fully_qualify, ref trait_ } = *self; +fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Display { + let clean::QPathData { ref assoc, ref self_type, should_fully_qualify, ref trait_ } = + *qpath_data; - fmt::from_fn(move |f| { - // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719), - // we need to surround them with angle brackets in some cases (e.g. `::P`). + fmt::from_fn(move |f| { + // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719), + // we need to surround them with angle brackets in some cases (e.g. `::P`). - if let Some(trait_) = trait_ - && should_fully_qualify - { - let opts = WithOpts::from(f); - Wrapped::with_angle_brackets() - .wrap(format_args!( - "{} as {}", - opts.display(self_type.print(cx)), - opts.display(trait_.print(cx)) - )) - .fmt(f)? - } else { - self_type.print(cx).fmt(f)?; - } - f.write_str("::")?; - // It's pretty unsightly to look at `::C` in output, and - // we've got hyperlinking on our side, so try to avoid longer - // notation as much as possible by making `C` a hyperlink to trait - // `B` to disambiguate. - // - // FIXME: this is still a lossy conversion and there should probably - // be a better way of representing this in general? Most of - // the ugliness comes from inlining across crates where - // everything comes in as a fully resolved QPath (hard to - // look at). - if !f.alternate() { - // FIXME(inherent_associated_types): We always link to the very first associated - // type (in respect to source order) that bears the given name (`assoc.name`) and that is - // affiliated with the computed `DefId`. This is obviously incorrect when we have - // multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself - // through here and map it to the corresponding HTML ID that was generated by - // `render::Context::derive_id` when the impl blocks were rendered. - // There is no such mapping unfortunately. - // As a hack, we could badly imitate `derive_id` here by keeping *count* when looking - // for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()` - // considering privacy, `doc(hidden)`, etc. - // I don't feel like that right now :cold_sweat:. + if let Some(trait_) = trait_ + && should_fully_qualify + { + let opts = WithOpts::from(f); + Wrapped::with_angle_brackets() + .wrap(format_args!( + "{} as {}", + opts.display(print_type(self_type, cx)), + opts.display(print_path(trait_, cx)) + )) + .fmt(f)? + } else { + print_type(self_type, cx).fmt(f)?; + } + f.write_str("::")?; + // It's pretty unsightly to look at `::C` in output, and + // we've got hyperlinking on our side, so try to avoid longer + // notation as much as possible by making `C` a hyperlink to trait + // `B` to disambiguate. + // + // FIXME: this is still a lossy conversion and there should probably + // be a better way of representing this in general? Most of + // the ugliness comes from inlining across crates where + // everything comes in as a fully resolved QPath (hard to + // look at). + if !f.alternate() { + // FIXME(inherent_associated_types): We always link to the very first associated + // type (in respect to source order) that bears the given name (`assoc.name`) and that is + // affiliated with the computed `DefId`. This is obviously incorrect when we have + // multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself + // through here and map it to the corresponding HTML ID that was generated by + // `render::Context::derive_id` when the impl blocks were rendered. + // There is no such mapping unfortunately. + // As a hack, we could badly imitate `derive_id` here by keeping *count* when looking + // for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()` + // considering privacy, `doc(hidden)`, etc. + // I don't feel like that right now :cold_sweat:. - let parent_href = match trait_ { - Some(trait_) => href(trait_.def_id(), cx).ok(), - None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()), - }; + let parent_href = match trait_ { + Some(trait_) => href(trait_.def_id(), cx).ok(), + None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()), + }; - if let Some((url, _, path)) = parent_href { - write!( - f, - "{name}", - shortty = ItemType::AssocType, - name = assoc.name, - path = join_path_syms(path), - ) - } else { - write!(f, "{}", assoc.name) - } + if let Some((url, _, path)) = parent_href { + write!( + f, + "{name}", + shortty = ItemType::AssocType, + name = assoc.name, + path = join_path_syms(path), + ) } else { write!(f, "{}", assoc.name) - }?; + } + } else { + write!(f, "{}", assoc.name) + }?; - assoc.args.print(cx).fmt(f) - }) - } + print_generic_args(&assoc.args, cx).fmt(f) + }) +} + +pub(crate) fn print_impl( + impl_: &clean::Impl, + use_absolute: bool, + cx: &Context<'_>, +) -> impl Display { + fmt::from_fn(move |f| { + f.write_str("impl")?; + print_generics(&impl_.generics, cx).fmt(f)?; + f.write_str(" ")?; + + if let Some(ref ty) = impl_.trait_ { + if impl_.is_negative_trait_impl() { + f.write_char('!')?; + } + if impl_.kind.is_fake_variadic() + && let Some(generics) = ty.generics() + && let Ok(inner_type) = generics.exactly_one() + { + let last = ty.last(); + if f.alternate() { + write!(f, "{last}")?; + } else { + write!(f, "{}", print_anchor(ty.def_id(), last, cx))?; + }; + Wrapped::with_angle_brackets() + .wrap_fn(|f| impl_.print_type(inner_type, f, use_absolute, cx)) + .fmt(f)?; + } else { + print_path(ty, cx).fmt(f)?; + } + f.write_str(" for ")?; + } + + if let Some(ty) = impl_.kind.as_blanket_ty() { + fmt_type(ty, f, use_absolute, cx)?; + } else { + impl_.print_type(&impl_.for_, f, use_absolute, cx)?; + } + + print_where_clause(&impl_.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) + }) } impl clean::Impl { - pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| { - f.write_str("impl")?; - self.generics.print(cx).fmt(f)?; - f.write_str(" ")?; - - if let Some(ref ty) = self.trait_ { - if self.is_negative_trait_impl() { - f.write_char('!')?; - } - if self.kind.is_fake_variadic() - && let Some(generics) = ty.generics() - && let Ok(inner_type) = generics.exactly_one() - { - let last = ty.last(); - if f.alternate() { - write!(f, "{last}")?; - } else { - write!(f, "{}", print_anchor(ty.def_id(), last, cx))?; - }; - Wrapped::with_angle_brackets() - .wrap_fn(|f| self.print_type(inner_type, f, use_absolute, cx)) - .fmt(f)?; - } else { - ty.print(cx).fmt(f)?; - } - f.write_str(" for ")?; - } - - if let Some(ty) = self.kind.as_blanket_ty() { - fmt_type(ty, f, use_absolute, cx)?; - } else { - self.print_type(&self.for_, f, use_absolute, cx)?; - } - - print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) - }) - } fn print_type( &self, type_: &clean::Type, @@ -1191,7 +1195,7 @@ pub(crate) fn print_params(params: &[clean::Parameter], cx: &Context<'_>) -> imp if let Some(name) = param.name { write!(f, "{name}: ")?; } - param.type_.print(cx).fmt(f) + print_type(¶m.type_, cx).fmt(f) }) }) .joined(", ", f) @@ -1221,76 +1225,73 @@ impl Display for Indent { } } -impl clean::Parameter { - fn print(&self, cx: &Context<'_>) -> impl fmt::Display { - fmt::from_fn(move |f| { - if let Some(self_ty) = self.to_receiver() { - match self_ty { - clean::SelfTy => f.write_str("self"), - clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => { - f.write_str(if f.alternate() { "&" } else { "&" })?; - if let Some(lt) = lifetime { - write!(f, "{lt} ", lt = lt.print())?; - } - write!(f, "{mutability}self", mutability = mutability.print_with_space()) - } - _ => { - f.write_str("self: ")?; - self_ty.print(cx).fmt(f) +fn print_parameter(parameter: &clean::Parameter, cx: &Context<'_>) -> impl fmt::Display { + fmt::from_fn(move |f| { + if let Some(self_ty) = parameter.to_receiver() { + match self_ty { + clean::SelfTy => f.write_str("self"), + clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => { + f.write_str(if f.alternate() { "&" } else { "&" })?; + if let Some(lt) = lifetime { + write!(f, "{lt} ", lt = print_lifetime(lt))?; } + write!(f, "{mutability}self", mutability = mutability.print_with_space()) } - } else { - if self.is_const { - write!(f, "const ")?; + _ => { + f.write_str("self: ")?; + print_type(self_ty, cx).fmt(f) } - if let Some(name) = self.name { - write!(f, "{name}: ")?; - } - self.type_.print(cx).fmt(f) } - }) - } + } else { + if parameter.is_const { + write!(f, "const ")?; + } + if let Some(name) = parameter.name { + write!(f, "{name}: ")?; + } + print_type(¶meter.type_, cx).fmt(f) + } + }) +} + +fn print_fn_decl(fn_decl: &clean::FnDecl, cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| { + let ellipsis = if fn_decl.c_variadic { ", ..." } else { "" }; + Wrapped::with_parens() + .wrap_fn(|f| { + print_params(&fn_decl.inputs, cx).fmt(f)?; + f.write_str(ellipsis) + }) + .fmt(f)?; + fn_decl.print_output(cx).fmt(f) + }) +} + +/// * `header_len`: The length of the function header and name. In other words, the number of +/// characters in the function declaration up to but not including the parentheses. +/// This is expected to go into a `
`/`code-header` block, so indentation and newlines
+///   are preserved.
+/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
+///   necessary.
+pub(crate) fn full_print_fn_decl(
+    fn_decl: &clean::FnDecl,
+    header_len: usize,
+    indent: usize,
+    cx: &Context<'_>,
+) -> impl Display {
+    fmt::from_fn(move |f| {
+        // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
+        let mut counter = WriteCounter(0);
+        write!(&mut counter, "{:#}", fmt::from_fn(|f| { fn_decl.inner_full_print(None, f, cx) }))?;
+        // If the text form was over 80 characters wide, we will line-wrap our output.
+        let line_wrapping_indent = if header_len + counter.0 > 80 { Some(indent) } else { None };
+        // Generate the final output. This happens to accept `{:#}` formatting to get textual
+        // output but in practice it is only formatted with `{}` to get HTML output.
+        fn_decl.inner_full_print(line_wrapping_indent, f, cx)
+    })
 }
 
 impl clean::FnDecl {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| {
-            let ellipsis = if self.c_variadic { ", ..." } else { "" };
-            Wrapped::with_parens()
-                .wrap_fn(|f| {
-                    print_params(&self.inputs, cx).fmt(f)?;
-                    f.write_str(ellipsis)
-                })
-                .fmt(f)?;
-            self.print_output(cx).fmt(f)
-        })
-    }
-
-    /// * `header_len`: The length of the function header and name. In other words, the number of
-    ///   characters in the function declaration up to but not including the parentheses.
-    ///   This is expected to go into a `
`/`code-header` block, so indentation and newlines
-    ///   are preserved.
-    /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
-    ///   necessary.
-    pub(crate) fn full_print(
-        &self,
-        header_len: usize,
-        indent: usize,
-        cx: &Context<'_>,
-    ) -> impl Display {
-        fmt::from_fn(move |f| {
-            // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
-            let mut counter = WriteCounter(0);
-            write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))?;
-            // If the text form was over 80 characters wide, we will line-wrap our output.
-            let line_wrapping_indent =
-                if header_len + counter.0 > 80 { Some(indent) } else { None };
-            // Generate the final output. This happens to accept `{:#}` formatting to get textual
-            // output but in practice it is only formatted with `{}` to get HTML output.
-            self.inner_full_print(line_wrapping_indent, f, cx)
-        })
-    }
-
     fn inner_full_print(
         &self,
         // For None, the declaration will not be line-wrapped. For Some(n),
@@ -1316,7 +1317,7 @@ impl clean::FnDecl {
                         }
                     });
 
-                    self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
+                    self.inputs.iter().map(|param| print_parameter(param, cx)).joined(sep, f)?;
 
                     if line_wrapping_indent.is_some() {
                         writeln!(f, ",")?
@@ -1348,7 +1349,7 @@ impl clean::FnDecl {
             }
 
             f.write_str(if f.alternate() { " -> " } else { " -> " })?;
-            self.output.print(cx).fmt(f)
+            print_type(&self.output, cx).fmt(f)
         })
     }
 }
@@ -1461,67 +1462,68 @@ pub(crate) fn print_constness_with_space(
     }
 }
 
-impl clean::Import {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| match self.kind {
-            clean::ImportKind::Simple(name) => {
-                if name == self.source.path.last() {
-                    write!(f, "use {};", self.source.print(cx))
-                } else {
-                    write!(f, "use {source} as {name};", source = self.source.print(cx))
-                }
+pub(crate) fn print_import(import: &clean::Import, cx: &Context<'_>) -> impl Display {
+    fmt::from_fn(move |f| match import.kind {
+        clean::ImportKind::Simple(name) => {
+            if name == import.source.path.last() {
+                write!(f, "use {};", print_import_source(&import.source, cx))
+            } else {
+                write!(
+                    f,
+                    "use {source} as {name};",
+                    source = print_import_source(&import.source, cx)
+                )
             }
-            clean::ImportKind::Glob => {
-                if self.source.path.segments.is_empty() {
-                    write!(f, "use *;")
-                } else {
-                    write!(f, "use {}::*;", self.source.print(cx))
-                }
+        }
+        clean::ImportKind::Glob => {
+            if import.source.path.segments.is_empty() {
+                write!(f, "use *;")
+            } else {
+                write!(f, "use {}::*;", print_import_source(&import.source, cx))
             }
-        })
-    }
+        }
+    })
 }
 
-impl clean::ImportSource {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| match self.did {
-            Some(did) => resolved_path(f, did, &self.path, true, false, cx),
-            _ => {
-                for seg in &self.path.segments[..self.path.segments.len() - 1] {
-                    write!(f, "{}::", seg.name)?;
-                }
-                let name = self.path.last();
-                if let hir::def::Res::PrimTy(p) = self.path.res {
-                    primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
-                } else {
-                    f.write_str(name.as_str())?;
-                }
-                Ok(())
+fn print_import_source(import_source: &clean::ImportSource, cx: &Context<'_>) -> impl Display {
+    fmt::from_fn(move |f| match import_source.did {
+        Some(did) => resolved_path(f, did, &import_source.path, true, false, cx),
+        _ => {
+            for seg in &import_source.path.segments[..import_source.path.segments.len() - 1] {
+                write!(f, "{}::", seg.name)?;
             }
-        })
-    }
-}
-
-impl clean::AssocItemConstraint {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| {
-            f.write_str(self.assoc.name.as_str())?;
-            self.assoc.args.print(cx).fmt(f)?;
-            match self.kind {
-                clean::AssocItemConstraintKind::Equality { ref term } => {
-                    f.write_str(" = ")?;
-                    term.print(cx).fmt(f)?;
-                }
-                clean::AssocItemConstraintKind::Bound { ref bounds } => {
-                    if !bounds.is_empty() {
-                        f.write_str(": ")?;
-                        print_generic_bounds(bounds, cx).fmt(f)?;
-                    }
-                }
+            let name = import_source.path.last();
+            if let hir::def::Res::PrimTy(p) = import_source.path.res {
+                primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
+            } else {
+                f.write_str(name.as_str())?;
             }
             Ok(())
-        })
-    }
+        }
+    })
+}
+
+fn print_assoc_item_constraint(
+    assoc_item_constraint: &clean::AssocItemConstraint,
+    cx: &Context<'_>,
+) -> impl Display {
+    fmt::from_fn(move |f| {
+        f.write_str(assoc_item_constraint.assoc.name.as_str())?;
+        print_generic_args(&assoc_item_constraint.assoc.args, cx).fmt(f)?;
+        match assoc_item_constraint.kind {
+            clean::AssocItemConstraintKind::Equality { ref term } => {
+                f.write_str(" = ")?;
+                print_term(term, cx).fmt(f)?;
+            }
+            clean::AssocItemConstraintKind::Bound { ref bounds } => {
+                if !bounds.is_empty() {
+                    f.write_str(": ")?;
+                    print_generic_bounds(bounds, cx).fmt(f)?;
+                }
+            }
+        }
+        Ok(())
+    })
 }
 
 pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
@@ -1538,22 +1540,18 @@ pub(crate) fn print_default_space(v: bool) -> &'static str {
     if v { "default " } else { "" }
 }
 
-impl clean::GenericArg {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| match self {
-            clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
-            clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
-            clean::GenericArg::Const(ct) => ct.print(cx.tcx()).fmt(f),
-            clean::GenericArg::Infer => Display::fmt("_", f),
-        })
-    }
+fn print_generic_arg(generic_arg: &clean::GenericArg, cx: &Context<'_>) -> impl Display {
+    fmt::from_fn(move |f| match generic_arg {
+        clean::GenericArg::Lifetime(lt) => f.write_str(print_lifetime(lt)),
+        clean::GenericArg::Type(ty) => print_type(ty, cx).fmt(f),
+        clean::GenericArg::Const(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
+        clean::GenericArg::Infer => Display::fmt("_", f),
+    })
 }
 
-impl clean::Term {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| match self {
-            clean::Term::Type(ty) => ty.print(cx).fmt(f),
-            clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
-        })
-    }
+fn print_term(term: &clean::Term, cx: &Context<'_>) -> impl Display {
+    fmt::from_fn(move |f| match term {
+        clean::Term::Type(ty) => print_type(ty, cx).fmt(f),
+        clean::Term::Constant(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
+    })
 }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 13178ee4e993..36990332b2fc 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -74,8 +74,9 @@ use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::format::{
-    Ending, HrefError, PrintWithSpace, href, print_abi_with_space, print_constness_with_space,
-    print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
+    Ending, HrefError, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space,
+    print_constness_with_space, print_default_space, print_generic_bounds, print_generics,
+    print_impl, print_path, print_type, print_where_clause, visibility_print_with_space,
 };
 use crate::html::markdown::{
     HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
@@ -1044,8 +1045,8 @@ fn assoc_const(
             vis = visibility_print_with_space(it, cx),
             href = assoc_href_attr(it, link, cx).maybe_display(),
             name = it.name.as_ref().unwrap(),
-            generics = generics.print(cx),
-            ty = ty.print(cx),
+            generics = print_generics(generics, cx),
+            ty = print_type(ty, cx),
         )?;
         if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value {
             // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
@@ -1083,14 +1084,14 @@ fn assoc_type(
             vis = visibility_print_with_space(it, cx),
             href = assoc_href_attr(it, link, cx).maybe_display(),
             name = it.name.as_ref().unwrap(),
-            generics = generics.print(cx),
+            generics = print_generics(generics, cx),
         )?;
         if !bounds.is_empty() {
             write!(w, ": {}", print_generic_bounds(bounds, cx))?;
         }
         // Render the default before the where-clause which aligns with the new recommended style. See #89122.
         if let Some(default) = default {
-            write!(w, " = {}", default.print(cx))?;
+            write!(w, " = {}", print_type(default, cx))?;
         }
         write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display())
     })
@@ -1128,7 +1129,7 @@ fn assoc_method(
         let href = assoc_href_attr(meth, link, cx).maybe_display();
 
         // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
-        let generics_len = format!("{:#}", g.print(cx)).len();
+        let generics_len = format!("{:#}", print_generics(g, cx)).len();
         let mut header_len = "fn ".len()
             + vis.len()
             + defaultness.len()
@@ -1155,8 +1156,8 @@ fn assoc_method(
             "{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \
             {name}{generics}{decl}{notable_traits}{where_clause}",
             indent = indent_str,
-            generics = g.print(cx),
-            decl = d.full_print(header_len, indent, cx),
+            generics = print_generics(g, cx),
+            decl = full_print_fn_decl(d, header_len, indent, cx),
             where_clause = print_where_clause(g, cx, indent, end_newline).maybe_display(),
         )
     })
@@ -1441,8 +1442,10 @@ fn render_assoc_items_inner(
                 Cow::Borrowed("implementations-list"),
             ),
             AssocItemRender::DerefFor { trait_, type_, .. } => {
-                let id =
-                    cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
+                let id = cx.derive_id(small_url_encode(format!(
+                    "deref-methods-{:#}",
+                    print_type(type_, cx)
+                )));
                 // the `impls.get` above only looks at the outermost type,
                 // and the Deref impl may only be implemented for certain
                 // values of generic parameters.
@@ -1466,8 +1469,8 @@ fn render_assoc_items_inner(
                                 fmt::from_fn(|f| write!(
                                     f,
                                     "Methods from {trait_}<Target = {type_}>",
-                                    trait_ = trait_.print(cx),
-                                    type_ = type_.print(cx),
+                                    trait_ = print_path(trait_, cx),
+                                    type_ = print_type(type_, cx),
                                 )),
                                 &id,
                             )
@@ -1645,7 +1648,7 @@ fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Optionⓘ",
-                ty = Escape(&format!("{:#}", ty.print(cx))),
+                ty = Escape(&format!("{:#}", print_type(ty, cx))),
             )
         })
     })
@@ -1683,7 +1686,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
                 f,
                 "

Notable traits for {}

\
",
-                impl_.for_.print(cx)
+                print_type(&impl_.for_, cx),
             )?;
             true
         } else {
@@ -1691,7 +1694,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
         };
 
         for (impl_, trait_did) in notable_impls {
-            write!(f, "
{}
", impl_.print(false, cx))?; + write!(f, "
{}
", print_impl(impl_, false, cx))?; for it in &impl_.items { let clean::AssocTypeItem(tydef, ..) = &it.kind else { continue; @@ -1724,7 +1727,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { }) .to_string(); - (format!("{:#}", ty.print(cx)), out) + (format!("{:#}", print_type(ty, cx)), out) } fn notable_traits_json<'a>(tys: impl Iterator, cx: &Context<'_>) -> String { @@ -2284,7 +2287,7 @@ fn render_impl_summary( )?; if let Some(use_absolute) = use_absolute { - write!(w, "{}", inner_impl.print(use_absolute, cx))?; + write!(w, "{}", print_impl(inner_impl, use_absolute, cx))?; if show_def_docs { for it in &inner_impl.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { @@ -2305,7 +2308,7 @@ fn render_impl_summary( } } } else { - write!(w, "{}", inner_impl.print(false, cx))?; + write!(w, "{}", print_impl(inner_impl, false, cx))?; } w.write_str("")?; @@ -2423,7 +2426,10 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String clean::ItemKind::ImplItem(ref i) if i.trait_.is_some() => { // Alternative format produces no URLs, // so this parameter does nothing. - Some((format!("{:#}", i.for_.print(cx)), get_id_for_impl(cx.tcx(), item.item_id))) + Some(( + format!("{:#}", print_type(&i.for_, cx)), + get_id_for_impl(cx.tcx(), item.item_id), + )) } _ => None, } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6bb8f2043f4b..fa7c9e75fdac 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -31,7 +31,8 @@ use crate::formats::Impl; use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyTextWithWbr}; use crate::html::format::{ - Ending, PrintWithSpace, print_abi_with_space, print_constness_with_space, print_where_clause, + Ending, PrintWithSpace, full_print_fn_decl, print_abi_with_space, print_constness_with_space, + print_generic_bound, print_generics, print_impl, print_import, print_type, print_where_clause, visibility_print_with_space, }; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; @@ -462,7 +463,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i "{vis}{imp}
{stab_tags}\ ", vis = visibility_print_with_space(myitem, cx), - imp = import.print(cx) + imp = print_import(import, cx), )?; } _ => { @@ -611,7 +612,7 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp let visibility = visibility_print_with_space(it, cx).to_string(); let name = it.name.unwrap(); - let generics_len = format!("{:#}", f.generics.print(cx)).len(); + let generics_len = format!("{:#}", print_generics(&f.generics, cx)).len(); let header_len = "fn ".len() + visibility.len() + constness.len() @@ -635,10 +636,10 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp safety = safety, abi = abi, name = name, - generics = f.generics.print(cx), + generics = print_generics(&f.generics, cx), where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline).maybe_display(), - decl = f.decl.full_print(header_len, 0, cx), + decl = full_print_fn_decl(&f.decl, header_len, 0, cx), ) })?; write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) @@ -673,7 +674,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: safety = t.safety(tcx).print_with_space(), is_auto = if t.is_auto(tcx) { "auto " } else { "" }, name = it.name.unwrap(), - generics = t.generics.print(cx), + generics = print_generics(&t.generics, cx), )?; if !t.generics.where_predicates.is_empty() { @@ -1244,7 +1245,7 @@ fn item_trait_alias( w, "trait {name}{generics} = {bounds}{where_clause};", name = it.name.unwrap(), - generics = t.generics.print(cx), + generics = print_generics(&t.generics, cx), bounds = print_bounds(&t.bounds, true, cx), where_clause = print_where_clause(&t.generics, cx, 0, Ending::NoNewline).maybe_display(), @@ -1273,10 +1274,10 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> "{vis}type {name}{generics}{where_clause} = {type_};", vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), - generics = t.generics.print(cx), + generics = print_generics(&t.generics, cx), where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(), - type_ = t.type_.print(cx), + type_ = print_type(&t.type_, cx), ) })?; @@ -1477,7 +1478,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { } fn print_ty(&self, ty: &'a clean::Type) -> impl Display { - ty.print(self.cx) + print_type(ty, self.cx) } // FIXME (GuillaumeGomez): When is implemented, @@ -1523,7 +1524,7 @@ fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Displa .map(|ty| { fmt::from_fn(|f| match ty.kind { clean::StrippedItem(box clean::StructFieldItem(_)) => f.write_str("_"), - clean::StructFieldItem(ref ty) => write!(f, "{}", ty.print(cx)), + clean::StructFieldItem(ref ty) => write!(f, "{}", print_type(ty, cx)), _ => unreachable!(), }) }) @@ -1562,7 +1563,7 @@ impl<'clean> DisplayEnum<'clean> { "{}enum {}{}{}", visibility_print_with_space(it, cx), it.name.unwrap(), - self.generics.print(cx), + print_generics(&self.generics, cx), render_enum_fields( cx, Some(self.generics), @@ -1862,7 +1863,7 @@ fn item_variants( {doc}\ ", f = field.name.unwrap(), - t = ty.print(cx), + t = print_type(ty, cx), doc = document(cx, field, Some(variant), HeadingOffset::H5), )?; } @@ -1956,8 +1957,8 @@ fn item_constant( "{vis}const {name}{generics}: {typ}{where_clause}", vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), - generics = generics.print(cx), - typ = ty.print(cx), + generics = print_generics(generics, cx), + typ = print_type(ty, cx), where_clause = print_where_clause(generics, cx, 0, Ending::NoNewline).maybe_display(), )?; @@ -2102,7 +2103,7 @@ fn item_fields( "{field_name}: {ty}\ \ {doc}", - ty = ty.print(cx), + ty = print_type(ty, cx), doc = document(cx, field, Some(it), HeadingOffset::H3), )?; } @@ -2127,7 +2128,7 @@ fn item_static( safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), - typ = s.type_.print(cx) + typ = print_type(&s.type_, cx) ) })?; @@ -2286,7 +2287,7 @@ fn print_bounds( } } - bounds.iter().map(|p| p.print(cx)).joined(inter_str, f) + bounds.iter().map(|p| print_generic_bound(p, cx)).joined(inter_str, f) })) .maybe_display() } @@ -2307,7 +2308,7 @@ struct ImplString(String); impl ImplString { fn new(i: &Impl, cx: &Context<'_>) -> ImplString { - ImplString(format!("{}", i.inner_impl().print(false, cx))) + ImplString(format!("{}", print_impl(i.inner_impl(), false, cx))) } } @@ -2376,7 +2377,7 @@ fn render_union( write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; let where_displayed = if let Some(generics) = g { - write!(f, "{}", generics.print(cx))?; + write!(f, "{}", print_generics(generics, cx))?; if let Some(where_clause) = print_where_clause(generics, cx, 0, Ending::Newline) { write!(f, "{where_clause}")?; true @@ -2408,7 +2409,7 @@ fn render_union( " {}{}: {},", visibility_print_with_space(field, cx), field.name.unwrap(), - ty.print(cx) + print_type(ty, cx) )?; } } @@ -2442,7 +2443,7 @@ fn render_struct( it.name.unwrap() )?; if let Some(g) = g { - write!(w, "{}", g.print(cx))?; + write!(w, "{}", print_generics(g, cx))?; } write!( w, @@ -2505,7 +2506,7 @@ fn render_struct_fields( "{tab} {vis}{name}: {ty},", vis = visibility_print_with_space(field, cx), name = field.name.unwrap(), - ty = ty.print(cx) + ty = print_type(ty, cx) )?; } } @@ -2548,7 +2549,7 @@ fn render_struct_fields( w, "{}{}", visibility_print_with_space(field, cx), - ty.print(cx) + print_type(ty, cx), )?; } _ => unreachable!(), diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index b9f5ada417c7..df9e8631bbdd 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -13,6 +13,7 @@ use super::{Context, ItemSection, item_ty_to_section}; use crate::clean; use crate::formats::Impl; use crate::formats::item_type::ItemType; +use crate::html::format::{print_path, print_type}; use crate::html::markdown::{IdMap, MarkdownWithToc}; use crate::html::render::print_item::compare_names; @@ -558,8 +559,8 @@ fn sidebar_deref_methods<'a>( }; let title = format!( "Methods from {:#}", - impl_.inner_impl().trait_.as_ref().unwrap().print(cx), - real_target.print(cx), + print_path(impl_.inner_impl().trait_.as_ref().unwrap(), cx), + print_type(real_target, cx), ); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); @@ -690,7 +691,7 @@ fn sidebar_render_assoc_items( ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", ty::ImplPolarity::Negative => "!", }; - let generated = Link::new(encoded, format!("{prefix}{:#}", trait_.print(cx))); + let generated = Link::new(encoded, format!("{prefix}{:#}", print_path(trait_, cx))); if links.insert(generated.clone()) { Some(generated) } else { None } }) .collect::>>(); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 3a1db805d01c..6045b9a77eca 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -44,6 +44,7 @@ use crate::docfs::PathError; use crate::error::Error; use crate::formats::Impl; use crate::formats::item_type::ItemType; +use crate::html::format::{print_impl, print_path}; use crate::html::layout; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; use crate::html::render::search_index::{SerializedSearchIndex, build_index}; @@ -605,7 +606,7 @@ impl TypeAliasPart { .inner_impl() .trait_ .as_ref() - .map(|trait_| format!("{:#}", trait_.print(cx))); + .map(|trait_| format!("{:#}", print_path(trait_, cx))); ret = Some(AliasSerializableImpl { text, trait_, @@ -704,7 +705,7 @@ impl TraitAliasPart { None } else { Some(Implementor { - text: imp.inner_impl().print(false, cx).to_string(), + text: print_impl(imp.inner_impl(), false, cx).to_string(), synthetic: imp.inner_impl().kind.is_auto(), types: collect_paths_for_type(&imp.inner_impl().for_, cache), }) From 0f0342949d241c15aaf7bf2741cc5f63cd3fb6f9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Nov 2025 11:45:29 +0100 Subject: [PATCH 465/525] Replace `Display::fmt` with `write_char` --- src/librustdoc/html/format.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index c2466135a2cd..337429a6248d 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1545,7 +1545,7 @@ fn print_generic_arg(generic_arg: &clean::GenericArg, cx: &Context<'_>) -> impl clean::GenericArg::Lifetime(lt) => f.write_str(print_lifetime(lt)), clean::GenericArg::Type(ty) => print_type(ty, cx).fmt(f), clean::GenericArg::Const(ct) => print_constant_kind(ct, cx.tcx()).fmt(f), - clean::GenericArg::Infer => Display::fmt("_", f), + clean::GenericArg::Infer => f.write_char('_'), }) } From fdced17e1fb1f1cf00486383d5a90f45987c66b6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Nov 2025 12:35:12 +0100 Subject: [PATCH 466/525] [bootstrap] Make `--open` option work with `doc src/tools/error_index_generator` --- src/bootstrap/src/core/build_steps/doc.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 6622aae069d5..d6d6fc67ba5a 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1228,9 +1228,12 @@ impl Step for ErrorIndex { t!(fs::create_dir_all(&out)); tool::ErrorIndex::command(builder, self.compilers) .arg("html") - .arg(out) + .arg(&out) .arg(&builder.version) .run(builder); + + let index = out.join("error-index.html"); + builder.maybe_open_in_browser::(index); } fn metadata(&self) -> Option { From 7711eb9f1e1efae614eee7a044553db53a2daf04 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Nov 2025 08:34:13 +0100 Subject: [PATCH 467/525] lazy_sync: ensure the cookie fits inside the primitive --- src/tools/miri/src/concurrency/sync.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index e4e7fb1d725f..2ac68fa1eeb6 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -246,12 +246,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; alloc_extra.sync.insert(offset, Box::new(data)); // Mark this as "initialized". + let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); + assert!(init_offset + init_cookie.size() <= primitive.layout.size); let init_field = primitive.offset(init_offset, this.machine.layouts.u32, this)?; - this.write_scalar_atomic( - Scalar::from_u32(LAZY_INIT_COOKIE), - &init_field, - AtomicWriteOrd::Relaxed, - )?; + this.write_scalar_atomic(init_cookie, &init_field, AtomicWriteOrd::Relaxed)?; interp_ok(this.get_alloc_extra(alloc)?.get_sync::(offset).unwrap()) } @@ -278,6 +276,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // thread initializing. Needs to be an RMW operation to ensure we read the *latest* value. // So we just try to replace MUTEX_INIT_COOKIE with itself. let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); + assert!(init_offset + init_cookie.size() <= primitive.layout.size); let init_field = primitive.offset(init_offset, this.machine.layouts.u32, this)?; let (_init, success) = this .atomic_compare_exchange_scalar( From bd23d55f298639de1f108507e6b0a6518fae4a84 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 6 Nov 2025 18:51:01 +0300 Subject: [PATCH 468/525] `invalid_atomic_ordering`: also lint `update` & `try_update` --- compiler/rustc_lint/src/types.rs | 13 +- compiler/rustc_span/src/symbol.rs | 2 + ...nt-invalid-atomic-ordering-fetch-update.rs | 49 ---- ...nvalid-atomic-ordering-fetch-update.stderr | 83 ------ .../lint-invalid-atomic-ordering-update.rs | 144 +++++++++++ ...lint-invalid-atomic-ordering-update.stderr | 243 ++++++++++++++++++ 6 files changed, 399 insertions(+), 135 deletions(-) delete mode 100644 tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs delete mode 100644 tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr create mode 100644 tests/ui/lint/lint-invalid-atomic-ordering-update.rs create mode 100644 tests/ui/lint/lint-invalid-atomic-ordering-update.stderr diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 4895e61069e5..f3e6db6f2d8e 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1022,7 +1022,8 @@ declare_lint! { /// /// - Passing `Ordering::Release` or `Ordering::AcqRel` as the failure /// ordering for any of `AtomicType::compare_exchange`, - /// `AtomicType::compare_exchange_weak`, or `AtomicType::fetch_update`. + /// `AtomicType::compare_exchange_weak`, `AtomicType::update`, or + /// `AtomicType::try_update`. INVALID_ATOMIC_ORDERING, Deny, "usage of invalid atomic ordering in atomic operations and memory fences" @@ -1118,13 +1119,19 @@ impl InvalidAtomicOrdering { let Some((method, args)) = Self::inherent_atomic_method_call( cx, expr, - &[sym::fetch_update, sym::compare_exchange, sym::compare_exchange_weak], + &[ + sym::update, + sym::try_update, + sym::fetch_update, + sym::compare_exchange, + sym::compare_exchange_weak, + ], ) else { return; }; let fail_order_arg = match method { - sym::fetch_update => &args[1], + sym::update | sym::try_update | sym::fetch_update => &args[1], sym::compare_exchange | sym::compare_exchange_weak => &args[3], _ => return, }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38718bad9e57..b447239ea85b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2273,6 +2273,7 @@ symbols! { try_from_fn, try_into, try_trait_v2, + try_update, tt, tuple, tuple_indexing, @@ -2390,6 +2391,7 @@ symbols! { unwrap, unwrap_binder, unwrap_or, + update, use_cloned, use_extern_macros, use_nested_groups, diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs deleted file mode 100644 index bdeacac4957b..000000000000 --- a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs +++ /dev/null @@ -1,49 +0,0 @@ -//@ only-x86_64 -use std::sync::atomic::{AtomicIsize, Ordering}; - -fn main() { - // `fetch_update` testing - let x = AtomicIsize::new(0); - - // Allowed ordering combos - let _ = x.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1)); - let _ = x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1)); - - // AcqRel is always forbidden as a failure ordering - let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - - // Release is always forbidden as a failure ordering - let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); - //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` - -} diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr deleted file mode 100644 index 33829d68fd5c..000000000000 --- a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr +++ /dev/null @@ -1,83 +0,0 @@ -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:26:47 - | -LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - = note: `#[deny(invalid_atomic_ordering)]` on by default - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:28:47 - | -LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:30:47 - | -LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:32:46 - | -LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:34:46 - | -LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:38:47 - | -LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:40:47 - | -LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:42:47 - | -LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:44:46 - | -LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:46:46 - | -LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); - | ^^^^^^^^^^^^^^^^^ invalid failure ordering - | - = help: consider using `Acquire` or `Relaxed` failure ordering instead - -error: aborting due to 10 previous errors - diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-update.rs b/tests/ui/lint/lint-invalid-atomic-ordering-update.rs new file mode 100644 index 000000000000..ac41e7cee0c2 --- /dev/null +++ b/tests/ui/lint/lint-invalid-atomic-ordering-update.rs @@ -0,0 +1,144 @@ +//@ only-x86_64 +#![feature(atomic_try_update)] + +use std::sync::atomic::{AtomicIsize, Ordering}; + +fn main() { + // `fetch_update` testing + let x = AtomicIsize::new(0); + + // Allowed ordering combos + let _ = x.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.update(Ordering::Relaxed, Ordering::Relaxed, |old| old + 1); + + let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.update(Ordering::Relaxed, Ordering::Acquire, |old| old + 1); + + let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.update(Ordering::Relaxed, Ordering::SeqCst, |old| old + 1); + + let _ = x.fetch_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.update(Ordering::Acquire, Ordering::Relaxed, |old| old + 1); + + let _ = x.fetch_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.update(Ordering::Acquire, Ordering::Acquire, |old| old + 1); + + let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.update(Ordering::Acquire, Ordering::SeqCst, |old| old + 1); + + let _ = x.fetch_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.update(Ordering::Release, Ordering::Relaxed, |old| old + 1); + + let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.update(Ordering::Release, Ordering::Acquire, |old| old + 1); + + let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.try_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.update(Ordering::Release, Ordering::SeqCst, |old| old + 1); + + let _ = x.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.try_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.update(Ordering::AcqRel, Ordering::Relaxed, |old| old + 1); + + let _ = x.fetch_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.try_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.update(Ordering::AcqRel, Ordering::Acquire, |old| old + 1); + + let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.try_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.update(Ordering::AcqRel, Ordering::SeqCst, |old| old + 1); + + let _ = x.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.try_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1)); + let _ = x.update(Ordering::SeqCst, Ordering::Relaxed, |old| old + 1); + + let _ = x.fetch_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.try_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1)); + let _ = x.update(Ordering::SeqCst, Ordering::Acquire, |old| old + 1); + + let _ = x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.try_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1)); + let _ = x.update(Ordering::SeqCst, Ordering::SeqCst, |old| old + 1); + + // AcqRel is always forbidden as a failure ordering + + let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Relaxed, Ordering::AcqRel, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Acquire, Ordering::AcqRel, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Release, Ordering::AcqRel, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::AcqRel, Ordering::AcqRel, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::SeqCst, Ordering::AcqRel, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + // Release is always forbidden as a failure ordering + + let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Relaxed, Ordering::Release, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Acquire, Ordering::Release, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::Release, Ordering::Release, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::AcqRel, Ordering::Release, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` + + let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.try_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); + //~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel` + let _ = x.update(Ordering::SeqCst, Ordering::Release, |old| old + 1); + //~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel` +} diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr new file mode 100644 index 000000000000..8c266bacf314 --- /dev/null +++ b/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr @@ -0,0 +1,243 @@ +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:73:47 + | +LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + = note: `#[deny(invalid_atomic_ordering)]` on by default + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:75:45 + | +LL | let _ = x.try_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:77:41 + | +LL | let _ = x.update(Ordering::Relaxed, Ordering::AcqRel, |old| old + 1); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:80:47 + | +LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:82:45 + | +LL | let _ = x.try_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:84:41 + | +LL | let _ = x.update(Ordering::Acquire, Ordering::AcqRel, |old| old + 1); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:87:47 + | +LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:89:45 + | +LL | let _ = x.try_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:91:41 + | +LL | let _ = x.update(Ordering::Release, Ordering::AcqRel, |old| old + 1); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:94:46 + | +LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:96:44 + | +LL | let _ = x.try_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:98:40 + | +LL | let _ = x.update(Ordering::AcqRel, Ordering::AcqRel, |old| old + 1); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:101:46 + | +LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:103:44 + | +LL | let _ = x.try_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:105:40 + | +LL | let _ = x.update(Ordering::SeqCst, Ordering::AcqRel, |old| old + 1); + | ^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:110:47 + | +LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:112:45 + | +LL | let _ = x.try_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:114:41 + | +LL | let _ = x.update(Ordering::Relaxed, Ordering::Release, |old| old + 1); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:117:47 + | +LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:119:45 + | +LL | let _ = x.try_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:121:41 + | +LL | let _ = x.update(Ordering::Acquire, Ordering::Release, |old| old + 1); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:124:47 + | +LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:126:45 + | +LL | let _ = x.try_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:128:41 + | +LL | let _ = x.update(Ordering::Release, Ordering::Release, |old| old + 1); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:131:46 + | +LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:133:44 + | +LL | let _ = x.try_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:135:40 + | +LL | let _ = x.update(Ordering::AcqRel, Ordering::Release, |old| old + 1); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:138:46 + | +LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:140:44 + | +LL | let _ = x.try_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write + --> $DIR/lint-invalid-atomic-ordering-update.rs:142:40 + | +LL | let _ = x.update(Ordering::SeqCst, Ordering::Release, |old| old + 1); + | ^^^^^^^^^^^^^^^^^ invalid failure ordering + | + = help: consider using `Acquire` or `Relaxed` failure ordering instead + +error: aborting due to 30 previous errors + From c07f11ac0aa0651dde845fe3b72393867e0527aa Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 7 Nov 2025 14:38:16 +0100 Subject: [PATCH 469/525] don't completely reset `HeadUsages` --- compiler/rustc_type_ir/src/search_graph/mod.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 4f3f140af67d..8e6376b22ce6 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -23,7 +23,7 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir::data_structures::HashMap; -use tracing::{debug, instrument}; +use tracing::{debug, instrument, trace}; mod stack; use stack::{Stack, StackDepth, StackEntry}; @@ -916,6 +916,7 @@ impl, X: Cx> SearchGraph { /// heads from the stack. This may not necessarily mean that we've actually /// reached a fixpoint for that cycle head, which impacts the way we rebase /// provisional cache entries. +#[derive_where(Debug; X: Cx)] enum RebaseReason { NoCycleUsages, Ambiguity(X::AmbiguityInfo), @@ -950,6 +951,7 @@ impl, X: Cx> SearchGraph { /// cache entries to also be ambiguous. This causes some undesirable ambiguity for nested /// goals whose result doesn't actually depend on this cycle head, but that's acceptable /// to me. + #[instrument(level = "trace", skip(self, cx))] fn rebase_provisional_cache_entries( &mut self, cx: X, @@ -969,6 +971,7 @@ impl, X: Cx> SearchGraph { let popped_head = if heads.highest_cycle_head_index() == popped_head_index { heads.remove_highest_cycle_head() } else { + debug_assert!(heads.highest_cycle_head_index() < popped_head_index); return true; }; @@ -1057,6 +1060,8 @@ impl, X: Cx> SearchGraph { new_highest_head_index, )); + trace!(?input, ?entry, "rebased provisional cache entry"); + true }); !entries.is_empty() @@ -1379,7 +1384,8 @@ impl, X: Cx> SearchGraph { } // Clear all provisional cache entries which depend on a previous provisional - // result of this goal and rerun. + // result of this goal and rerun. This does not remove goals which accessed this + // goal without depending on its result. self.clear_dependent_provisional_results_for_rerun(); debug!(?result, "fixpoint changed provisional results"); @@ -1399,7 +1405,12 @@ impl, X: Cx> SearchGraph { // similar to the previous iterations when reevaluating, it's better // for caching if the reevaluation also starts out with `false`. encountered_overflow: false, - usages: None, + // We keep provisional cache entries around if they used this goal + // without depending on its result. + // + // We still need to drop or rebase these cache entries once we've + // finished evaluating this goal. + usages: Some(HeadUsages::default()), candidate_usages: None, }); } From fa8e8649ad521cd9cb823cffa5a250caa9bcf2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Fri, 7 Nov 2025 15:10:04 +0100 Subject: [PATCH 470/525] Stabilise 'as_array' in '[_]' and '*const [_]'; Stabilise 'as_mut_array' in '[_]' and '*mut [_]'; Update feature gate and tracking issue for 'alloc_slice_into_array' items; --- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- library/alloc/src/boxed.rs | 2 +- library/alloc/src/rc.rs | 2 +- library/alloc/src/sync.rs | 2 +- library/core/src/lib.rs | 1 - library/core/src/ptr/const_ptr.rs | 3 ++- library/core/src/ptr/mut_ptr.rs | 3 ++- library/core/src/slice/mod.rs | 6 ++++-- 8 files changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index aaf1f6fbc804..1b65a133d58c 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(slice_as_array))] #![feature(assert_matches)] #![feature(extern_types)] #![feature(file_buffered)] @@ -12,7 +13,6 @@ #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] -#![feature(slice_as_array)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7ad1679b1c82..381eaeb809f2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -850,7 +850,7 @@ impl Box<[T]> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] pub fn into_array(self) -> Option> { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a24ea6e526c4..f0ce6aa03a8b 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1166,7 +1166,7 @@ impl Rc<[T]> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] pub fn into_array(self) -> Option> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 13b5cf23e72d..b85293973fd5 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1314,7 +1314,7 @@ impl Arc<[T]> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] pub fn into_array(self) -> Option> { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f1948fc778ce..1f66c43c73db 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -121,7 +121,6 @@ #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] #![feature(set_ptr_value)] -#![feature(slice_as_array)] #![feature(slice_ptr_get)] #![feature(str_internals)] #![feature(str_split_inclusive_remainder)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 451092709443..84a6982d5680 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1462,7 +1462,8 @@ impl *const [T] { /// Gets a raw pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] #[inline] #[must_use] pub const fn as_array(self) -> Option<*const [T; N]> { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 24ee92bdd6e1..85d54b4d3b9b 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1712,7 +1712,8 @@ impl *mut [T] { /// Gets a raw, mutable pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] #[inline] #[must_use] pub const fn as_mut_array(self) -> Option<*mut [T; N]> { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 96c1034f9735..1d88eb33dce1 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -841,7 +841,8 @@ impl [T] { /// Gets a reference to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] #[inline] #[must_use] pub const fn as_array(&self) -> Option<&[T; N]> { @@ -859,7 +860,8 @@ impl [T] { /// Gets a mutable reference to the slice's underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "slice_as_array", issue = "133508")] + #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] #[inline] #[must_use] pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { From b8eee76769c3f0b2059f222383be7cb5c8d55396 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 20:50:24 +0100 Subject: [PATCH 471/525] ./miri run: verbose by default, add flag to be quiet --- src/tools/miri/miri-script/src/commands.rs | 12 ++++++------ src/tools/miri/miri-script/src/main.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index f1b522931232..5f50598e203b 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -112,8 +112,8 @@ impl Command { Command::Check { features, flags } => Self::check(features, flags), Command::Test { bless, target, coverage, features, flags } => Self::test(bless, target, coverage, features, flags), - Command::Run { dep, verbose, target, edition, features, flags } => - Self::run(dep, verbose, target, edition, features, flags), + Command::Run { dep, quiet, target, edition, features, flags } => + Self::run(dep, quiet, target, edition, features, flags), Command::Doc { features, flags } => Self::doc(features, flags), Command::Fmt { flags } => Self::fmt(flags), Command::Clippy { features, flags } => Self::clippy(features, flags), @@ -458,7 +458,7 @@ impl Command { fn run( dep: bool, - verbose: bool, + quiet: bool, target: Option, edition: Option, features: Vec, @@ -468,7 +468,7 @@ impl Command { // Preparation: get a sysroot, and get the miri binary. let miri_sysroot = - e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref(), &features)?; + e.build_miri_sysroot(/* quiet */ quiet, target.as_deref(), &features)?; let miri_bin = e .build_get_binary(".", &features) .context("failed to get filename of miri executable")?; @@ -492,7 +492,7 @@ impl Command { // Compute flags. let miri_flags = e.sh.var("MIRIFLAGS").unwrap_or_default(); let miri_flags = flagsplit(&miri_flags); - let quiet_flag = if verbose { None } else { Some("--quiet") }; + let quiet_flag = if quiet { Some("--quiet") } else { None }; // Run Miri. // The basic command that executes the Miri driver. @@ -506,7 +506,7 @@ impl Command { } else { cmd!(e.sh, "{miri_bin}") }; - cmd.set_quiet(!verbose); + cmd.set_quiet(quiet); // Add Miri flags let mut cmd = cmd.args(&miri_flags).args(&early_flags).args(&flags); // For `--dep` we also need to set the target in the env var. diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index 761ec5979faf..e30701449688 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs @@ -78,9 +78,9 @@ pub enum Command { /// Build the program with the dependencies declared in `tests/deps/Cargo.toml`. #[arg(long)] dep: bool, - /// Show build progress. + /// Hide build progress. #[arg(long, short)] - verbose: bool, + quiet: bool, /// The cross-interpretation target. #[arg(long)] target: Option, From 384c05f81dafa2b737dece10a1c1e4515e574ed2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Nov 2025 17:20:29 +0100 Subject: [PATCH 472/525] fix 'cargo miri setup' quietness --- src/tools/miri/miri-script/src/commands.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 5f50598e203b..5a8bf76befd6 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -57,7 +57,9 @@ impl MiriEnv { .arg("--") .args(&["miri", "setup", "--print-sysroot"]) .args(target_flag); - cmd.set_quiet(quiet); + if quiet { + cmd = cmd.arg("--quiet"); + } let output = cmd.read()?; self.sh.set_var("MIRI_SYSROOT", &output); Ok(output.into()) From 6419f9a9df24443063d95f90aaecf599e14cc9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 29 Oct 2025 20:25:33 +0100 Subject: [PATCH 473/525] Encode cfg trace, not its early counterpart to fix cross-crate `doc(auto_cfg)` --- compiler/rustc_feature/src/builtin_attrs.rs | 6 +-- tests/rustdoc/doc_auto_cfg.rs | 2 +- .../inline_cross/auxiliary/doc-auto-cfg.rs | 11 ++++ .../auxiliary/u_default_generic_args.rs | 1 - tests/rustdoc/inline_cross/doc-auto-cfg.rs | 53 +++++++++++++++++++ ...ue-113982-doc_auto_cfg-reexport-foreign.rs | 3 -- .../doc_auto_cfg-reexport-foreign-113982.rs | 20 ------- ...b-reexport-attribute-merge-doc-auto-cfg.rs | 2 +- 8 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs delete mode 100644 tests/rustdoc/inline_cross/auxiliary/u_default_generic_args.rs create mode 100644 tests/rustdoc/inline_cross/doc-auto-cfg.rs delete mode 100644 tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs delete mode 100644 tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a2acac8b3045..dddd1be9648b 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -425,7 +425,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ List: &["predicate"], "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute" ), - DuplicatesOk, EncodeCrossCrate::Yes + DuplicatesOk, EncodeCrossCrate::No ), ungated!( cfg_attr, Normal, @@ -433,7 +433,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ List: &["predicate, attr1, attr2, ..."], "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute" ), - DuplicatesOk, EncodeCrossCrate::Yes + DuplicatesOk, EncodeCrossCrate::No ), // Testing: @@ -1100,7 +1100,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // can only be generated by the compiler. ungated!( cfg_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk, - EncodeCrossCrate::No + EncodeCrossCrate::Yes ), ungated!( cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk, diff --git a/tests/rustdoc/doc_auto_cfg.rs b/tests/rustdoc/doc_auto_cfg.rs index 19ef174c1778..a1903e1a0ca3 100644 --- a/tests/rustdoc/doc_auto_cfg.rs +++ b/tests/rustdoc/doc_auto_cfg.rs @@ -1,4 +1,4 @@ -// Test covering RFC 3631 features. +// Basic tests covering RFC 3631 features. #![crate_name = "foo"] #![feature(doc_cfg)] diff --git a/tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs b/tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs new file mode 100644 index 000000000000..b494b701a2ff --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --cfg extension + +#[cfg(extension)] +pub fn compute() {} + +pub struct Type; + +impl Type { + #[cfg(extension)] + pub fn transform(self) -> Self { self } +} diff --git a/tests/rustdoc/inline_cross/auxiliary/u_default_generic_args.rs b/tests/rustdoc/inline_cross/auxiliary/u_default_generic_args.rs deleted file mode 100644 index a742dd7d865f..000000000000 --- a/tests/rustdoc/inline_cross/auxiliary/u_default_generic_args.rs +++ /dev/null @@ -1 +0,0 @@ -pub use default_generic_args::*; diff --git a/tests/rustdoc/inline_cross/doc-auto-cfg.rs b/tests/rustdoc/inline_cross/doc-auto-cfg.rs new file mode 100644 index 000000000000..6e0f6e22f8c7 --- /dev/null +++ b/tests/rustdoc/inline_cross/doc-auto-cfg.rs @@ -0,0 +1,53 @@ +// Test that `doc(auto_cfg)` works with inlined cross-crate re-exports. +//@ compile-flags: --cfg feature="extra" --cfg feature="addon" + +#![feature(doc_cfg)] +#![crate_name = "it"] + +//@ aux-build: doc-auto-cfg.rs +extern crate doc_auto_cfg; + +// The cfg is on the reexported item. +// issue: +pub mod pre { + //@ has 'it/pre/index.html' '//*[@class="stab portability"]' 'extension' + //@ has 'it/pre/fn.compute.html' '//*[@class="stab portability"]' \ + // 'Available on extension only.' + pub use doc_auto_cfg::*; + + // Indeed, this reexport doesn't have a cfg badge! + // That's because this crate (`it`) wouldn't've compiled in the first place + // if `--cfg extension` wasn't passed when compiling the auxiliary crate + // contrary to the glob import above since `compute` wouldn't exist. + // + //@ !has 'it/pre/fn.calculate.html' '//*[@class="stab portability"]' \ + // 'Available on extension only.' + pub use doc_auto_cfg::compute as calculate; + + // FIXME(HtmlDocCk): Ideally I would've used the following XPath here: + // `*[@class="impl-items"][*[@id="method.transform"]]//*[@class="stab portability"]` + // + //@ has 'it/pre/struct.Kind.html' '//*[@id="method.transform"]' '' + //@ has - '//*[@class="impl-items"]//*[@class="stab portability"]' \ + // 'Available on extension only.' + pub use doc_auto_cfg::Type as Kind; +} + +// The cfg is on the reexport. +pub mod post { + // issue: + //@ has 'it/post/index.html' '//*[@class="stab portability"]' 'extra' + //@ has - '//*[@class="stab portability"]' 'extra and extension' + //@ has 'it/post/struct.Type.html' '//*[@class="stab portability"]' \ + // 'Available on crate feature extra only.' + //@ has 'it/post/fn.compute.html' '//*[@class="stab portability"]' \ + // 'Available on crate feature extra and extension only.' + #[cfg(feature = "extra")] + pub use doc_auto_cfg::*; + + //@ has 'it/post/index.html' '//*[@class="stab portability"]' 'addon' + //@ has 'it/post/struct.Addon.html' '//*[@class="stab portability"]' \ + // 'Available on crate feature addon only.' + #[cfg(feature = "addon")] + pub use doc_auto_cfg::Type as Addon; +} diff --git a/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs b/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs deleted file mode 100644 index a1a716f5a41b..000000000000 --- a/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_name = "colors"] - -pub struct Color; diff --git a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs deleted file mode 100644 index f8ec4afc0313..000000000000 --- a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ aux-build: issue-113982-doc_auto_cfg-reexport-foreign.rs - -// https://github.com/rust-lang/rust/issues/113982 -#![feature(no_core, doc_cfg)] -#![no_core] -#![crate_name = "foo"] - -extern crate colors; - -//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-colors' -//@ has 'foo/struct.Color.html' '//*[@class="stab portability"]' \ -// 'Available on non-crate feature colors only.' -#[cfg(not(feature = "colors"))] -pub use colors::*; - -//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-fruits' -//@ has 'foo/struct.Red.html' '//*[@class="stab portability"]' \ -// 'Available on non-crate feature fruits only.' -#[cfg(not(feature = "fruits"))] -pub use colors::Color as Red; diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs index 0aed2b0c4620..b0f7df6f3e2d 100644 --- a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs +++ b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs @@ -1,4 +1,4 @@ -// This test ensures that non-glob reexports don't get their attributes merge with +// This test ensures that non-glob reexports don't get their attributes merged with // the reexported item whereas glob reexports do with the `doc_auto_cfg` feature. #![crate_name = "foo"] From 566a86b02fc81447d922a1bf0a40648466b73dc5 Mon Sep 17 00:00:00 2001 From: 21aslade Date: Mon, 20 Oct 2025 08:42:16 -0600 Subject: [PATCH 474/525] show packed alignment in mir_transform_unaligned_packed_ref --- .../rustc_const_eval/src/util/alignment.rs | 45 +++++++++------- compiler/rustc_const_eval/src/util/mod.rs | 2 +- compiler/rustc_mir_transform/messages.ftl | 7 ++- .../src/add_moves_for_packed_drops.rs | 2 +- .../src/check_packed_ref.rs | 10 +++- .../src/dead_store_elimination.rs | 4 +- compiler/rustc_mir_transform/src/errors.rs | 2 + compiler/rustc_mir_transform/src/validate.rs | 10 ++-- tests/ui/binding/issue-53114-safety-checks.rs | 12 ++--- .../binding/issue-53114-safety-checks.stderr | 24 ++++----- .../diagnostics/repr_packed.rs | 2 +- .../diagnostics/repr_packed.stderr | 4 +- .../lint/unaligned_references.current.stderr | 52 +++++++++---------- .../ui/lint/unaligned_references.next.stderr | 52 +++++++++---------- tests/ui/lint/unaligned_references.rs | 26 +++++----- .../unaligned_references_external_macro.rs | 2 +- ...unaligned_references_external_macro.stderr | 4 +- tests/ui/packed/issue-27060.rs | 8 +-- tests/ui/packed/issue-27060.stderr | 16 +++--- .../packed-struct-borrow-element-64bit.rs | 2 +- .../packed-struct-borrow-element-64bit.stderr | 4 +- .../ui/packed/packed-struct-borrow-element.rs | 4 +- .../packed-struct-borrow-element.stderr | 8 +-- .../ui/packed/packed-union-borrow-element.rs | 26 ++++++++++ .../packed/packed-union-borrow-element.stderr | 23 ++++++++ 25 files changed, 210 insertions(+), 141 deletions(-) create mode 100644 tests/ui/packed/packed-union-borrow-element.rs create mode 100644 tests/ui/packed/packed-union-borrow-element.stderr diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs index 9aafc7efd8a6..0fab4b288d18 100644 --- a/compiler/rustc_const_eval/src/util/alignment.rs +++ b/compiler/rustc_const_eval/src/util/alignment.rs @@ -1,24 +1,24 @@ use rustc_abi::Align; use rustc_middle::mir::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, TyCtxt}; use tracing::debug; -/// Returns `true` if this place is allowed to be less aligned -/// than its containing struct (because it is within a packed -/// struct). -pub fn is_disaligned<'tcx, L>( +/// If the place may be less aligned than its type requires +/// (because it is in a packed type), returns the AdtDef +/// and packed alignment of its most-unaligned projection. +pub fn place_unalignment<'tcx, L>( tcx: TyCtxt<'tcx>, local_decls: &L, typing_env: ty::TypingEnv<'tcx>, place: Place<'tcx>, -) -> bool +) -> Option<(AdtDef<'tcx>, Align)> where L: HasLocalDecls<'tcx>, { - debug!("is_disaligned({:?})", place); - let Some(pack) = is_within_packed(tcx, local_decls, place) else { - debug!("is_disaligned({:?}) - not within packed", place); - return false; + debug!("unalignment({:?})", place); + let Some((descr, pack)) = most_packed_projection(tcx, local_decls, place) else { + debug!("unalignment({:?}) - not within packed", place); + return None; }; let ty = place.ty(local_decls, tcx).ty; @@ -30,31 +30,34 @@ where || matches!(unsized_tail().kind(), ty::Slice(..) | ty::Str)) => { // If the packed alignment is greater or equal to the field alignment, the type won't be - // further disaligned. + // further unaligned. // However we need to ensure the field is sized; for unsized fields, `layout.align` is // just an approximation -- except when the unsized tail is a slice, where the alignment // is fully determined by the type. debug!( - "is_disaligned({:?}) - align = {}, packed = {}; not disaligned", + "unalignment({:?}) - align = {}, packed = {}; not unaligned", place, layout.align.bytes(), pack.bytes() ); - false + None } _ => { - // We cannot figure out the layout. Conservatively assume that this is disaligned. - debug!("is_disaligned({:?}) - true", place); - true + // We cannot figure out the layout. Conservatively assume that this is unaligned. + debug!("unalignment({:?}) - unaligned", place); + Some((descr, pack)) } } } -pub fn is_within_packed<'tcx, L>( +/// If the place includes a projection from a packed struct, +/// returns the AdtDef and packed alignment of the projection +/// with the lowest pack +pub fn most_packed_projection<'tcx, L>( tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>, -) -> Option +) -> Option<(AdtDef<'tcx>, Align)> where L: HasLocalDecls<'tcx>, { @@ -65,9 +68,11 @@ where .take_while(|(_base, elem)| !matches!(elem, ProjectionElem::Deref)) // Consider the packed alignments at play here... .filter_map(|(base, _elem)| { - base.ty(local_decls, tcx).ty.ty_adt_def().and_then(|adt| adt.repr().pack) + let adt = base.ty(local_decls, tcx).ty.ty_adt_def()?; + let pack = adt.repr().pack?; + Some((adt, pack)) }) // ... and compute their minimum. // The overall smallest alignment is what matters. - .min() + .min_by_key(|(_, align)| *align) } diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 5be5ee8d1ae9..39992123882a 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -6,7 +6,7 @@ mod check_validity_requirement; mod compare_types; mod type_name; -pub use self::alignment::{is_disaligned, is_within_packed}; +pub use self::alignment::{most_packed_projection, place_unalignment}; pub use self::check_validity_requirement::check_validity_requirement; pub(crate) use self::check_validity_requirement::validate_scalar_in_layout; pub use self::compare_types::{relate_types, sub_types}; diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index 71ec2db1ef00..cfc9b8edf7a2 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -69,8 +69,11 @@ mir_transform_tail_expr_local = {$is_generated_name -> *[false] `{$name}` calls a custom destructor } -mir_transform_unaligned_packed_ref = reference to packed field is unaligned - .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses +mir_transform_unaligned_packed_ref = reference to field of packed {$ty_descr} is unaligned + .note = this {$ty_descr} is {$align -> + [one] {""} + *[other] {"at most "} + }{$align}-byte aligned, but the type of this field may require higher alignment .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 7ae2ebaf4ff0..9950a94d722e 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -51,7 +51,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops { match terminator.kind { TerminatorKind::Drop { place, .. } - if util::is_disaligned(tcx, body, typing_env, place) => + if util::place_unalignment(tcx, body, typing_env, place).is_some() => { add_move_for_packed_drop( tcx, diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 100104e9de03..9ce244a00fce 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -37,7 +37,9 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.typing_env, *place) + if context.is_borrow() + && let Some((adt, pack)) = + util::place_unalignment(self.tcx, self.body, self.typing_env, *place) { let def_id = self.body.source.instance.def_id(); if let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(def_id) @@ -48,7 +50,11 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { // shouldn't do. span_bug!(self.source_info.span, "builtin derive created an unaligned reference"); } else { - self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); + self.tcx.dcx().emit_err(errors::UnalignedPackedRef { + span: self.source_info.span, + ty_descr: adt.descr(), + align: pack.bytes(), + }); } } } diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 732c3dcd44ab..63ee69322eef 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -23,7 +23,7 @@ use rustc_mir_dataflow::impls::{ }; use crate::simplify::UsedInStmtLocals; -use crate::util::is_within_packed; +use crate::util::most_packed_projection; /// Performs the optimization on the body /// @@ -65,7 +65,7 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { // the move may be codegened as a pointer to that field. // Using that disaligned pointer may trigger UB in the callee, // so do nothing. - && is_within_packed(tcx, body, place).is_none() + && most_packed_projection(tcx, body, place).is_none() { call_operands_to_move.push((bb, index)); } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index a039851681a6..517e4dd69262 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -99,6 +99,8 @@ pub(crate) enum ConstMutate { pub(crate) struct UnalignedPackedRef { #[primary_span] pub span: Span, + pub ty_descr: &'static str, + pub align: u64, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 5a9018a62c57..379af9c442b1 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -20,7 +20,7 @@ use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::debuginfo::debuginfo_locals; use rustc_trait_selection::traits::ObligationCtxt; -use crate::util::{self, is_within_packed}; +use crate::util::{self, most_packed_projection}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -409,7 +409,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { // The call destination place and Operand::Move place used as an argument might // be passed by a reference to the callee. Consequently they cannot be packed. - if is_within_packed(self.tcx, &self.body.local_decls, destination).is_some() { + if most_packed_projection(self.tcx, &self.body.local_decls, destination) + .is_some() + { // This is bad! The callee will expect the memory to be aligned. self.fail( location, @@ -423,7 +425,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { for arg in args { if let Operand::Move(place) = &arg.node { - if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() { + if most_packed_projection(self.tcx, &self.body.local_decls, *place) + .is_some() + { // This is bad! The callee will expect the memory to be aligned. self.fail( location, diff --git a/tests/ui/binding/issue-53114-safety-checks.rs b/tests/ui/binding/issue-53114-safety-checks.rs index f4be2b482a7e..07dfda77622a 100644 --- a/tests/ui/binding/issue-53114-safety-checks.rs +++ b/tests/ui/binding/issue-53114-safety-checks.rs @@ -20,12 +20,12 @@ fn let_wild_gets_unsafe_field() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - let _ = &p.b; //~ ERROR reference to packed field + let _ = &p.b; //~ ERROR reference to field of packed struct let _ = u1.a; //~ ERROR [E0133] let _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure - let (_,) = (&p.b,); //~ ERROR reference to packed field + let (_,) = (&p.b,); //~ ERROR reference to field of packed struct let (_,) = (u1.a,); //~ ERROR [E0133] let (_,) = (&u2.a,); //~ ERROR [E0133] } @@ -34,12 +34,12 @@ fn let_ascribe_gets_unsafe_field() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - let _: _ = &p.b; //~ ERROR reference to packed field + let _: _ = &p.b; //~ ERROR reference to field of packed struct let _: _ = u1.a; //~ ERROR [E0133] let _: _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure - let (_,): _ = (&p.b,); //~ ERROR reference to packed field + let (_,): _ = (&p.b,); //~ ERROR reference to field of packed struct let (_,): _ = (u1.a,); //~ ERROR [E0133] let (_,): _ = (&u2.a,); //~ ERROR [E0133] } @@ -48,12 +48,12 @@ fn match_unsafe_field_to_wild() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - match &p.b { _ => { } } //~ ERROR reference to packed field + match &p.b { _ => { } } //~ ERROR reference to field of packed struct match u1.a { _ => { } } //~ ERROR [E0133] match &u2.a { _ => { } } //~ ERROR [E0133] // variation on above with `_` in substructure - match (&p.b,) { (_,) => { } } //~ ERROR reference to packed field + match (&p.b,) { (_,) => { } } //~ ERROR reference to field of packed struct match (u1.a,) { (_,) => { } } //~ ERROR [E0133] match (&u2.a,) { (_,) => { } } //~ ERROR [E0133] } diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index 9d909e915c21..3e8389b77c53 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -1,20 +1,20 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:23:13 | LL | let _ = &p.b; | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:28:17 | LL | let (_,) = (&p.b,); | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) @@ -50,23 +50,23 @@ LL | let (_,) = (&u2.a,); | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:37:16 | LL | let _: _ = &p.b; | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:42:20 | LL | let (_,): _ = (&p.b,); | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) @@ -102,23 +102,23 @@ LL | let (_,): _ = (&u2.a,); | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:51:11 | LL | match &p.b { _ => { } } | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-53114-safety-checks.rs:56:12 | LL | match (&p.b,) { (_,) => { } } | ^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs index fe5106c57af6..4395b70a922f 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs @@ -19,7 +19,7 @@ fn test_missing_unsafe_warning_on_repr_packed() { let c = || { println!("{}", foo.x); - //~^ ERROR: reference to packed field is unaligned + //~^ ERROR: reference to field of packed struct is unaligned let _z = foo.x; }; diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr index c9972c8e7e34..0e93e033c022 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr @@ -1,10 +1,10 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/repr_packed.rs:21:24 | LL | println!("{}", foo.x); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/unaligned_references.current.stderr b/tests/ui/lint/unaligned_references.current.stderr index 0f980c5301f3..39ca072e848c 100644 --- a/tests/ui/lint/unaligned_references.current.stderr +++ b/tests/ui/lint/unaligned_references.current.stderr @@ -1,130 +1,130 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:32:13 | LL | &self.x; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 2-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:44:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:46:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:51:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:81:17 | LL | let _ = &good.ptr; | ^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:82:17 | LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:84:17 | LL | let _ = &good.data as *const _; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:85:27 | LL | let _: *const _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:87:17 | LL | let _ = good.data.clone(); | ^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:89:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:98:17 | LL | let _ = &packed2.x; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 2-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:137:20 | LL | let _ref = &m1.1.a; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:140:20 | LL | let _ref = &m2.1.a; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/lint/unaligned_references.next.stderr b/tests/ui/lint/unaligned_references.next.stderr index 0f980c5301f3..39ca072e848c 100644 --- a/tests/ui/lint/unaligned_references.next.stderr +++ b/tests/ui/lint/unaligned_references.next.stderr @@ -1,130 +1,130 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:32:13 | LL | &self.x; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 2-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:44:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:46:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:51:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:81:17 | LL | let _ = &good.ptr; | ^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:82:17 | LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:84:17 | LL | let _ = &good.data as *const _; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:85:27 | LL | let _: *const _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:87:17 | LL | let _ = good.data.clone(); | ^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:89:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:98:17 | LL | let _ = &packed2.x; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 2-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:137:20 | LL | let _ref = &m1.1.a; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references.rs:140:20 | LL | let _ref = &m2.1.a; | ^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/lint/unaligned_references.rs b/tests/ui/lint/unaligned_references.rs index 321e3ed135c4..af922a1031ab 100644 --- a/tests/ui/lint/unaligned_references.rs +++ b/tests/ui/lint/unaligned_references.rs @@ -29,7 +29,7 @@ trait Foo { impl Foo for Packed2 { fn evil(&self) { unsafe { - &self.x; //~ ERROR reference to packed field + &self.x; //~ ERROR reference to field of packed struct } } } @@ -41,14 +41,14 @@ fn packed_dyn() { let ref local = Unaligned(ManuallyDrop::new([3, 5, 8u64])); let foo: &Unaligned = &*local; - println!("{:?}", &*foo.0); //~ ERROR reference to packed field + println!("{:?}", &*foo.0); //~ ERROR reference to field of packed struct let foo: &Unaligned<[u64]> = &*local; - println!("{:?}", &*foo.0); //~ ERROR reference to packed field + println!("{:?}", &*foo.0); //~ ERROR reference to field of packed struct // Even if the actual alignment is 1, we cannot know that when looking at `dyn Debug.` let ref local = Unaligned(ManuallyDrop::new([3, 5, 8u8])); let foo: &Unaligned = &*local; - println!("{:?}", &*foo.0); //~ ERROR reference to packed field + println!("{:?}", &*foo.0); //~ ERROR reference to field of packed struct // However, we *can* know the alignment when looking at a slice. let foo: &Unaligned<[u8]> = &*local; println!("{:?}", &*foo.0); // no error! @@ -78,15 +78,15 @@ fn main() { unsafe { let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] }; - let _ = &good.ptr; //~ ERROR reference to packed field - let _ = &good.data; //~ ERROR reference to packed field + let _ = &good.ptr; //~ ERROR reference to field of packed struct + let _ = &good.data; //~ ERROR reference to field of packed struct // Error even when turned into raw pointer immediately. - let _ = &good.data as *const _; //~ ERROR reference to packed field - let _: *const _ = &good.data; //~ ERROR reference to packed field + let _ = &good.data as *const _; //~ ERROR reference to field of packed struct + let _: *const _ = &good.data; //~ ERROR reference to field of packed struct // Error on method call. - let _ = good.data.clone(); //~ ERROR reference to packed field + let _ = good.data.clone(); //~ ERROR reference to field of packed struct // Error for nested fields. - let _ = &good.data2[0]; //~ ERROR reference to packed field + let _ = &good.data2[0]; //~ ERROR reference to field of packed struct let _ = &*good.ptr; // ok, behind a pointer let _ = &good.aligned; // ok, has align 1 @@ -95,7 +95,7 @@ fn main() { unsafe { let packed2 = Packed2 { x: 0, y: 0, z: 0 }; - let _ = &packed2.x; //~ ERROR reference to packed field + let _ = &packed2.x; //~ ERROR reference to field of packed struct let _ = &packed2.y; // ok, has align 2 in packed(2) struct let _ = &packed2.z; // ok, has align 1 packed2.evil(); @@ -134,9 +134,9 @@ fn main() { struct Misalign(u8, T); let m1 = Misalign(0, Wrapper { a: U16(10), b: HasDrop }); - let _ref = &m1.1.a; //~ ERROR reference to packed field + let _ref = &m1.1.a; //~ ERROR reference to field of packed struct let m2 = Misalign(0, Wrapper2 { a: U16(10), b: HasDrop }); - let _ref = &m2.1.a; //~ ERROR reference to packed field + let _ref = &m2.1.a; //~ ERROR reference to field of packed struct } } diff --git a/tests/ui/lint/unaligned_references_external_macro.rs b/tests/ui/lint/unaligned_references_external_macro.rs index 3a97e2112a14..2d6e493dd542 100644 --- a/tests/ui/lint/unaligned_references_external_macro.rs +++ b/tests/ui/lint/unaligned_references_external_macro.rs @@ -2,7 +2,7 @@ extern crate unaligned_references_external_crate; -unaligned_references_external_crate::mac! { //~ERROR reference to packed field is unaligned +unaligned_references_external_crate::mac! { //~ERROR reference to field of packed struct is unaligned #[repr(packed)] pub struct X { pub field: u16 diff --git a/tests/ui/lint/unaligned_references_external_macro.stderr b/tests/ui/lint/unaligned_references_external_macro.stderr index 9945c78e8ba6..dd8788aec4b5 100644 --- a/tests/ui/lint/unaligned_references_external_macro.stderr +++ b/tests/ui/lint/unaligned_references_external_macro.stderr @@ -1,4 +1,4 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/unaligned_references_external_macro.rs:5:1 | LL | / unaligned_references_external_crate::mac! { @@ -9,7 +9,7 @@ LL | | } LL | | } | |_^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/packed/issue-27060.rs b/tests/ui/packed/issue-27060.rs index a0e944caa0b5..7d8be9603b68 100644 --- a/tests/ui/packed/issue-27060.rs +++ b/tests/ui/packed/issue-27060.rs @@ -12,11 +12,11 @@ fn main() { aligned: [0; 32] }; - let _ = &good.data; //~ ERROR reference to packed field - let _ = &good.data2[0]; //~ ERROR reference to packed field + let _ = &good.data; //~ ERROR reference to field of packed struct + let _ = &good.data2[0]; //~ ERROR reference to field of packed struct - let _ = &good.data; //~ ERROR reference to packed field - let _ = &good.data2[0]; //~ ERROR reference to packed field + let _ = &good.data; //~ ERROR reference to field of packed struct + let _ = &good.data2[0]; //~ ERROR reference to field of packed struct let _ = &*good.data; // ok, behind a pointer let _ = &good.aligned; // ok, has align 1 let _ = &good.aligned[2]; // ok, has align 1 diff --git a/tests/ui/packed/issue-27060.stderr b/tests/ui/packed/issue-27060.stderr index 4dc31a283865..3ede68cf9362 100644 --- a/tests/ui/packed/issue-27060.stderr +++ b/tests/ui/packed/issue-27060.stderr @@ -1,40 +1,40 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-27060.rs:15:13 | LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-27060.rs:16:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-27060.rs:18:13 | LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/issue-27060.rs:19:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/packed/packed-struct-borrow-element-64bit.rs b/tests/ui/packed/packed-struct-borrow-element-64bit.rs index 81eac07eaa89..59bd71c80e8c 100644 --- a/tests/ui/packed/packed-struct-borrow-element-64bit.rs +++ b/tests/ui/packed/packed-struct-borrow-element-64bit.rs @@ -10,6 +10,6 @@ struct Foo4C { pub fn main() { let foo = Foo4C { bar: 1, baz: 2 }; - let brw = &foo.baz; //~ERROR reference to packed field is unaligned + let brw = &foo.baz; //~ERROR reference to field of packed struct is unaligned assert_eq!(*brw, 2); } diff --git a/tests/ui/packed/packed-struct-borrow-element-64bit.stderr b/tests/ui/packed/packed-struct-borrow-element-64bit.stderr index a464b1893878..dcf8e7a51f13 100644 --- a/tests/ui/packed/packed-struct-borrow-element-64bit.stderr +++ b/tests/ui/packed/packed-struct-borrow-element-64bit.stderr @@ -1,10 +1,10 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/packed-struct-borrow-element-64bit.rs:13:15 | LL | let brw = &foo.baz; | ^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 4-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/packed/packed-struct-borrow-element.rs b/tests/ui/packed/packed-struct-borrow-element.rs index 24dadbcec7ca..d639746e067b 100644 --- a/tests/ui/packed/packed-struct-borrow-element.rs +++ b/tests/ui/packed/packed-struct-borrow-element.rs @@ -21,10 +21,10 @@ struct Foo4C { pub fn main() { let foo = Foo1 { bar: 1, baz: 2 }; - let brw = &foo.baz; //~ERROR reference to packed field is unaligned + let brw = &foo.baz; //~ERROR reference to field of packed struct is unaligned assert_eq!(*brw, 2); let foo = Foo2 { bar: 1, baz: 2 }; - let brw = &foo.baz; //~ERROR reference to packed field is unaligned + let brw = &foo.baz; //~ERROR reference to field of packed struct is unaligned assert_eq!(*brw, 2); } diff --git a/tests/ui/packed/packed-struct-borrow-element.stderr b/tests/ui/packed/packed-struct-borrow-element.stderr index c1f749d6fbbb..ccdbb3aedc71 100644 --- a/tests/ui/packed/packed-struct-borrow-element.stderr +++ b/tests/ui/packed/packed-struct-borrow-element.stderr @@ -1,20 +1,20 @@ -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/packed-struct-borrow-element.rs:24:15 | LL | let brw = &foo.baz; | ^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error[E0793]: reference to packed field is unaligned +error[E0793]: reference to field of packed struct is unaligned --> $DIR/packed-struct-borrow-element.rs:28:15 | LL | let brw = &foo.baz; | ^^^^^^^^ | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: this struct is at most 2-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/tests/ui/packed/packed-union-borrow-element.rs b/tests/ui/packed/packed-union-borrow-element.rs new file mode 100644 index 000000000000..e39d72b4a45c --- /dev/null +++ b/tests/ui/packed/packed-union-borrow-element.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] +//@ ignore-emscripten weird assertion? + +#[repr(packed)] +#[derive(Clone, Copy)] +struct Foo1(usize); + +#[repr(packed(4))] +#[derive(Clone, Copy)] +struct Foo4(usize); + +#[repr(packed(2))] +union Bar2 { + foo1: Foo1, + foo4: Foo4, +} + +pub fn main() { + let bar = Bar2 { foo1: Foo1(2) }; + let brw = unsafe { &bar.foo1.0 }; //~ERROR reference to field of packed struct is unaligned + assert_eq!(*brw, 2); + + let bar = Bar2 { foo4: Foo4(2) }; + let brw = unsafe { &bar.foo4.0 }; //~ERROR reference to field of packed union is unaligned + assert_eq!(*brw, 2); +} diff --git a/tests/ui/packed/packed-union-borrow-element.stderr b/tests/ui/packed/packed-union-borrow-element.stderr new file mode 100644 index 000000000000..ace7620d97f7 --- /dev/null +++ b/tests/ui/packed/packed-union-borrow-element.stderr @@ -0,0 +1,23 @@ +error[E0793]: reference to field of packed struct is unaligned + --> $DIR/packed-union-borrow-element.rs:20:24 + | +LL | let brw = unsafe { &bar.foo1.0 }; + | ^^^^^^^^^^^ + | + = note: this struct is 1-byte aligned, but the type of this field may require higher alignment + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to field of packed union is unaligned + --> $DIR/packed-union-borrow-element.rs:24:24 + | +LL | let brw = unsafe { &bar.foo4.0 }; + | ^^^^^^^^^^^ + | + = note: this union is at most 2-byte aligned, but the type of this field may require higher alignment + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0793`. From 057127cfee067474de01e4854bc50d1d3e386d9f Mon Sep 17 00:00:00 2001 From: Vrtgs Date: Tue, 14 Oct 2025 18:47:50 +0300 Subject: [PATCH 475/525] update isolate_highest_one for NonZero --- library/core/src/num/nonzero.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fcdb65bd45c9..cb8838f1eece 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -660,12 +660,15 @@ macro_rules! nonzero_integer { without modifying the original"] #[inline(always)] pub const fn isolate_highest_one(self) -> Self { - let n = self.get() & (((1 as $Int) << (<$Int>::BITS - 1)).wrapping_shr(self.leading_zeros())); - // SAFETY: // `self` is non-zero, so masking to preserve only the most // significant set bit will result in a non-zero `n`. - unsafe { NonZero::new_unchecked(n) } + // and self.leading_zeros() is always < $INT::BITS since + // at least one of the bits in the number is not zero + unsafe { + let bit = (((1 as $Uint) << (<$Uint>::BITS - 1)).unchecked_shr(self.leading_zeros())); + NonZero::new_unchecked(bit as $Int) + } } /// Returns `self` with only the least significant bit set. From 2bd3508ed8e7329b097a9f93ffa8b9625feb35cf Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 7 Nov 2025 16:30:54 -0500 Subject: [PATCH 476/525] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 6368002885a0..445fe4a68f46 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 6368002885a04cbeae39a82cf5118f941559a40a +Subproject commit 445fe4a68f469bf936b2fd81de2c503b233a7f4f From eac0c5ac432a50f46a7ae7833a13dde0c962e5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 7 Nov 2025 23:04:25 +0100 Subject: [PATCH 477/525] Remove eslint-js from npm dependencies --- package-lock.json | 32 ++++++++++++++++++++++---------- package.json | 4 +++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0297bf70b63..72129f115845 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,10 @@ "browser-ui-test": "^0.22.2", "es-check": "^6.2.1", "eslint": "^8.57.1", - "eslint-js": "github:eslint/js", "typescript": "^5.8.3" + }, + "devDependencies": { + "@types/node": "^24.10.0" } }, "node_modules/@babel/code-frame": { @@ -57,6 +59,12 @@ "node": ">= 10" } }, + "node_modules/@caporal/core/node_modules/@types/node": { + "version": "13.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.3.tgz", + "integrity": "sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==", + "license": "MIT" + }, "node_modules/@colors/colors": { "version": "1.6.0", "license": "MIT", @@ -225,8 +233,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "13.9.3", - "license": "MIT" + "version": "24.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", + "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } }, "node_modules/@types/table": { "version": "5.0.0", @@ -944,13 +957,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-js": { - "version": "1.0.0", - "resolved": "git+ssh://git@github.com/eslint/js.git#9e5b4fabf073b915abc56d6c14cc24177036d43e", - "workspaces": [ - "packages/*" - ] - }, "node_modules/eslint-scope": { "version": "7.2.2", "license": "BSD-2-Clause", @@ -2575,6 +2581,12 @@ "through": "^2.3.8" } }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, "node_modules/untildify": { "version": "3.0.3", "license": "MIT", diff --git a/package.json b/package.json index 04e0f6af19a0..7420c53fd8cc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "browser-ui-test": "^0.22.2", "es-check": "^6.2.1", "eslint": "^8.57.1", - "eslint-js": "github:eslint/js", "typescript": "^5.8.3" + }, + "devDependencies": { + "@types/node": "^24.10.0" } } From d1052e476b0106a262d05446f5c70bbdaa584552 Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Sat, 8 Nov 2025 04:51:33 +0100 Subject: [PATCH 478/525] Recover `[T: N]` as `[T; N]` --- compiler/rustc_parse/src/parser/ty.rs | 11 ++++----- tests/ui/parser/better-expected.stderr | 5 ++-- .../issues/error-pattern-issue-50571.stderr | 1 - tests/ui/parser/recover/array-type-no-semi.rs | 2 ++ .../parser/recover/array-type-no-semi.stderr | 23 ++++++++++++------- .../removed-syntax-fixed-vec.stderr | 3 +-- 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 55a279f7ee0c..ae2e71a78dd5 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -687,7 +687,6 @@ impl<'a> Parser<'a> { let mut err = self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr)); err.span_label(span, "expected `;` or `]`"); - err.note("you might have meant to write a slice or array type"); // If we cannot recover, return the error immediately. if !self.may_recover() { @@ -696,12 +695,10 @@ impl<'a> Parser<'a> { let snapshot = self.create_snapshot_for_diagnostic(); - let suggestion_span = if self.eat(exp!(Comma)) || self.eat(exp!(Star)) { - // Consume common erroneous separators. - self.prev_token.span - } else { - self.token.span.shrink_to_lo() - }; + // Consume common erroneous separators. + let hi = self.prev_token.span.hi(); + _ = self.eat(exp!(Comma)) || self.eat(exp!(Colon)) || self.eat(exp!(Star)); + let suggestion_span = self.prev_token.span.with_lo(hi); // we first try to parse pattern like `[u8 5]` let length = match self.parse_expr_anon_const() { diff --git a/tests/ui/parser/better-expected.stderr b/tests/ui/parser/better-expected.stderr index 4646ce7eff0e..6b64ec24da48 100644 --- a/tests/ui/parser/better-expected.stderr +++ b/tests/ui/parser/better-expected.stderr @@ -4,11 +4,10 @@ error: expected `;` or `]`, found `3` LL | let x: [isize 3]; | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | -LL | let x: [isize ;3]; - | + +LL | let x: [isize; 3]; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/error-pattern-issue-50571.stderr b/tests/ui/parser/issues/error-pattern-issue-50571.stderr index 47457cff461c..dac4b5309d23 100644 --- a/tests/ui/parser/issues/error-pattern-issue-50571.stderr +++ b/tests/ui/parser/issues/error-pattern-issue-50571.stderr @@ -4,7 +4,6 @@ error: expected `;` or `]`, found `,` LL | fn foo([a, b]: [i32; 2]) {} | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | LL - fn foo([a, b]: [i32; 2]) {} diff --git a/tests/ui/parser/recover/array-type-no-semi.rs b/tests/ui/parser/recover/array-type-no-semi.rs index 2cc5d979604c..499d5719d730 100644 --- a/tests/ui/parser/recover/array-type-no-semi.rs +++ b/tests/ui/parser/recover/array-type-no-semi.rs @@ -14,4 +14,6 @@ fn main() { //~| ERROR attempt to use a non-constant value in a constant [E0435] let e: [i32 5]; //~^ ERROR expected `;` or `]`, found `5` + let f: [i32: 1 - 1]; + //~^ ERROR expected `;` or `]`, found `:` } diff --git a/tests/ui/parser/recover/array-type-no-semi.stderr b/tests/ui/parser/recover/array-type-no-semi.stderr index 82330465144c..45f39fefe5e3 100644 --- a/tests/ui/parser/recover/array-type-no-semi.stderr +++ b/tests/ui/parser/recover/array-type-no-semi.stderr @@ -4,7 +4,6 @@ error: expected `;` or `]`, found `,` LL | let b: [i32, 5]; | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | LL - let b: [i32, 5]; @@ -19,8 +18,6 @@ LL | let a: [i32, ]; | | | while parsing the type for `a` | help: use `=` if you meant to assign - | - = note: you might have meant to write a slice or array type error: expected `;` or `]`, found `,` --> $DIR/array-type-no-semi.rs:12:16 @@ -28,7 +25,6 @@ error: expected `;` or `]`, found `,` LL | let c: [i32, x]; | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | LL - let c: [i32, x]; @@ -41,11 +37,22 @@ error: expected `;` or `]`, found `5` LL | let e: [i32 5]; | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | -LL | let e: [i32 ;5]; - | + +LL | let e: [i32; 5]; + | + + +error: expected `;` or `]`, found `:` + --> $DIR/array-type-no-semi.rs:17:16 + | +LL | let f: [i32: 1 - 1]; + | ^ expected `;` or `]` + | +help: you might have meant to use `;` as the separator + | +LL - let f: [i32: 1 - 1]; +LL + let f: [i32; 1 - 1]; + | error[E0435]: attempt to use a non-constant value in a constant --> $DIR/array-type-no-semi.rs:12:18 @@ -65,7 +72,7 @@ error[E0423]: expected value, found builtin type `i32` LL | let a: [i32, ]; | ^^^ not a value -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0423, E0435. For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr index f584197c98e8..3a5254d16b30 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr @@ -4,11 +4,10 @@ error: expected `;` or `]`, found `*` LL | type v = [isize * 3]; | ^ expected `;` or `]` | - = note: you might have meant to write a slice or array type help: you might have meant to use `;` as the separator | LL - type v = [isize * 3]; -LL + type v = [isize ; 3]; +LL + type v = [isize; 3]; | warning: type `v` should have an upper camel case name From 67802e0494034e1c55205a178b2ee1843e6d39da Mon Sep 17 00:00:00 2001 From: MolecularPilot Date: Thu, 30 Oct 2025 17:36:11 +1100 Subject: [PATCH 479/525] rustc_builtin_macros: rename bench parameter to avoid collisions with user-defined function names --- compiler/rustc_builtin_macros/src/test.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 7a189ee1f4d0..b0155fad139b 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -207,30 +207,30 @@ pub(crate) fn expand_test_or_bench( }; let test_fn = if is_bench { - // A simple ident for a lambda - let b = Ident::from_str_and_span("b", attr_sp); - + // avoid name collisions by using the function name within the identifier, see bug #148275 + let bencher_param = + Ident::from_str_and_span(&format!("__bench_{}", fn_.ident.name), attr_sp); cx.expr_call( sp, cx.expr_path(test_path("StaticBenchFn")), thin_vec![ // #[coverage(off)] - // |b| self::test::assert_test_result( + // |__bench_fn_name| self::test::assert_test_result( coverage_off(cx.lambda1( sp, cx.expr_call( sp, cx.expr_path(test_path("assert_test_result")), thin_vec![ - // super::$test_fn(b) + // super::$test_fn(__bench_fn_name) cx.expr_call( ret_ty_sp, cx.expr_path(cx.path(sp, vec![fn_.ident])), - thin_vec![cx.expr_ident(sp, b)], + thin_vec![cx.expr_ident(sp, bencher_param)], ), ], ), - b, + bencher_param, )), // ) ], ) From f6b751e3dfbb19dd3f80e6a196d4c29595f89d88 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 8 Nov 2025 04:52:53 +0000 Subject: [PATCH 480/525] Prepare for merging from rust-lang/rust This updates the rust-version file to ceb7df7e6f17c92c7d49f7e4f02df0e68bc9b38b. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 5bdb8bd8369f..1ce491a50eae 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -401ae55427522984e4a89c37cff6562a4ddcf6b7 +ceb7df7e6f17c92c7d49f7e4f02df0e68bc9b38b From 8aedbf12f6fb5cc0c585ac8a29de3ea9f64b8f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 8 Nov 2025 06:40:27 +0100 Subject: [PATCH 481/525] Replace `#[const_trait]` with `const` in libcore --- library/core/src/array/equality.rs | 3 +-- library/core/src/cmp/bytewise.rs | 3 +-- library/core/src/ops/range.rs | 9 +++------ library/core/src/slice/cmp.rs | 15 +++++---------- library/core/src/slice/index.rs | 3 +-- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs index c2c7ccf0daa2..ec79a657e58e 100644 --- a/library/core/src/array/equality.rs +++ b/library/core/src/array/equality.rs @@ -132,9 +132,8 @@ where #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const Eq for [T; N] {} -#[const_trait] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] -trait SpecArrayEq: Sized { +const trait SpecArrayEq: Sized { fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool; fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool; } diff --git a/library/core/src/cmp/bytewise.rs b/library/core/src/cmp/bytewise.rs index 2265fa7a3531..f0f5f656405a 100644 --- a/library/core/src/cmp/bytewise.rs +++ b/library/core/src/cmp/bytewise.rs @@ -17,8 +17,7 @@ use crate::num::NonZero; /// - Neither `Self` nor `Rhs` have provenance, so integer comparisons are correct. /// - `>::{eq,ne}` are equivalent to comparing the bytes. #[rustc_specialization_trait] -#[const_trait] // FIXME(const_trait_impl): Migrate to `const unsafe trait` once #146122 is fixed. -pub(crate) unsafe trait BytewiseEq: +pub(crate) const unsafe trait BytewiseEq: [const] PartialEq + Sized { } diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index d781f3f7ace4..a0b74ff383ea 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -816,9 +816,8 @@ impl Bound<&T> { /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] #[rustc_diagnostic_item = "RangeBounds"] -#[const_trait] #[rustc_const_unstable(feature = "const_range", issue = "none")] -pub trait RangeBounds { +pub const trait RangeBounds { /// Start index bound. /// /// Returns the start value as a `Bound`. @@ -954,9 +953,8 @@ pub trait RangeBounds { /// `IntoBounds` is implemented by Rust’s built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[unstable(feature = "range_into_bounds", issue = "136903")] -#[const_trait] #[rustc_const_unstable(feature = "const_range", issue = "none")] -pub trait IntoBounds: [const] RangeBounds { +pub const trait IntoBounds: [const] RangeBounds { /// Convert this range into the start and end bounds. /// Returns `(start_bound, end_bound)`. /// @@ -1319,9 +1317,8 @@ pub enum OneSidedRangeBound { /// Types that implement `OneSidedRange` must return `Bound::Unbounded` /// from one of `RangeBounds::start_bound` or `RangeBounds::end_bound`. #[unstable(feature = "one_sided_range", issue = "69780")] -#[const_trait] #[rustc_const_unstable(feature = "const_range", issue = "none")] -pub trait OneSidedRange: RangeBounds { +pub const trait OneSidedRange: RangeBounds { /// An internal-only helper function for `split_off` and /// `split_off_mut` that returns the bound of the one-sided range. fn bound(self) -> (OneSidedRangeBound, T); diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 103630aba0f7..fd1ca23fb79c 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -155,18 +155,16 @@ where } #[doc(hidden)] -#[const_trait] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's PartialOrd -trait SlicePartialOrd: Sized { +const trait SlicePartialOrd: Sized { fn partial_compare(left: &[Self], right: &[Self]) -> Option; } #[doc(hidden)] -#[const_trait] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's PartialOrd chaining methods -trait SliceChain: Sized { +const trait SliceChain: Sized { fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow; fn chaining_le(left: &[Self], right: &[Self]) -> ControlFlow; fn chaining_gt(left: &[Self], right: &[Self]) -> ControlFlow; @@ -244,9 +242,8 @@ impl const SlicePartialOrd for A { } #[rustc_specialization_trait] -#[const_trait] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] -trait AlwaysApplicableOrd: [const] SliceOrd + [const] Ord {} +const trait AlwaysApplicableOrd: [const] SliceOrd + [const] Ord {} macro_rules! always_applicable_ord { ($([$($p:tt)*] $t:ty,)*) => { @@ -265,10 +262,9 @@ always_applicable_ord! { } #[doc(hidden)] -#[const_trait] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's Ord -trait SliceOrd: Sized { +const trait SliceOrd: Sized { fn compare(left: &[Self], right: &[Self]) -> Ordering; } @@ -292,8 +288,7 @@ impl SliceOrd for A { /// * For every `x` and `y` of this type, `Ord(x, y)` must return the same /// value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`. #[rustc_specialization_trait] -#[const_trait] -unsafe trait UnsignedBytewiseOrd: [const] Ord {} +const unsafe trait UnsignedBytewiseOrd: [const] Ord {} #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] unsafe impl const UnsignedBytewiseOrd for bool {} diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 1a4dcebf3648..d8ed521f4435 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -159,9 +159,8 @@ mod private_slice_index { message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" )] -#[const_trait] // FIXME(const_trait_impl): Migrate to `const unsafe trait` once #146122 is fixed. #[rustc_const_unstable(feature = "const_index", issue = "143775")] -pub unsafe trait SliceIndex: private_slice_index::Sealed { +pub const unsafe trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] type Output: ?Sized; From 474501b672a90799be55d268e74941b0d3379c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 7 Nov 2025 22:17:06 +0100 Subject: [PATCH 482/525] Remove a remnant of `dyn*` from the parser --- compiler/rustc_parse/src/parser/ty.rs | 44 ++++++++++++--------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 65347496599d..f785e1d42f27 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -82,25 +82,24 @@ enum AllowCVariadic { No, } -/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, -/// `IDENT<::AssocTy>`. +/// Determine if the given token can begin a bound assuming it follows Rust 2015 identifier `dyn`. /// -/// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes -/// that `IDENT` is not the ident of a fn trait. -fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { - t == &token::PathSep || t == &token::Lt || t == &token::Shl -} +/// In Rust 2015, `dyn` is a contextual keyword, not a full one. +fn can_begin_dyn_bound_in_edition_2015(t: Token) -> bool { + if t.is_path_start() { + // In `dyn::x`, `dyn` and `dyn<::Y>`, `dyn` should (continue to) denote a regular path + // segment for backward compatibility. We make an exception for `dyn(X)` which used to be + // interpreted as a path with parenthesized generic arguments which can be semantically + // well-formed (consider: `use std::ops::Fn as dyn;`). Instead, we treat it as a trait + // object type whose first bound is parenthesized. + return t != token::PathSep && t != token::Lt && t != token::Shl; + } -fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { - // `!`, `const`, `[`, `async` are deliberately not part of this list to - // contain the number of potential regressions esp. in MBE code. - // `const` and `[` would regress UI test `macro-dyn-const-2015.rs`. - // `!` would regress `dyn!(...)` macro calls in Rust 2015. - t.is_path_start() - || t.is_lifetime() - || t == &TokenKind::Question - || t.is_keyword(kw::For) - || t == &TokenKind::OpenParen + // Contrary to `Parser::can_begin_bound`, `!`, `const`, `[` and `async` are deliberately not + // part of this list to contain the number of potential regressions esp. in MBE code. + // `const` and `[` would regress UI test `macro-dyn-const-2015.rs` and + // `!` would regress `dyn!(...)` macro calls in Rust 2015 for example. + t == token::OpenParen || t == token::Question || t.is_lifetime() || t.is_keyword(kw::For) } impl<'a> Parser<'a> { @@ -930,10 +929,7 @@ impl<'a> Parser<'a> { fn is_explicit_dyn_type(&mut self) -> bool { self.check_keyword(exp!(Dyn)) && (self.token_uninterpolated_span().at_least_rust_2018() - || self.look_ahead(1, |t| { - (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star) - && !can_continue_type_after_non_fn_ident(t) - })) + || self.look_ahead(1, |&t| can_begin_dyn_bound_in_edition_2015(t))) } /// Parses a `dyn B0 + ... + Bn` type. @@ -942,13 +938,11 @@ impl<'a> Parser<'a> { fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { self.bump(); // `dyn` - // We used to parse `*` for `dyn*` here. - let syntax = TraitObjectSyntax::Dyn; - // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus; - Ok(TyKind::TraitObject(bounds, syntax)) + + Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)) } /// Parses a type starting with a path. From c262920059e995b0fd53ff08b26201bc4cce3f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 7 Nov 2025 22:42:31 +0100 Subject: [PATCH 483/525] Remove `#[const_trait]` --- compiler/rustc_ast_passes/messages.ftl | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 23 ++- compiler/rustc_ast_passes/src/errors.rs | 2 +- .../src/attributes/traits.rs | 11 -- compiler/rustc_attr_parsing/src/context.rs | 3 +- .../rustc_const_eval/src/check_consts/ops.rs | 18 ++- compiler/rustc_feature/src/builtin_attrs.rs | 8 -- .../rustc_hir/src/attrs/data_structures.rs | 3 - .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 - compiler/rustc_hir_analysis/src/collect.rs | 30 ++-- compiler/rustc_hir_analysis/src/errors.rs | 18 +-- .../src/hir_ty_lowering/mod.rs | 33 +++-- compiler/rustc_passes/src/check_attr.rs | 1 - compiler/rustc_span/src/symbol.rs | 1 - .../const-super-trait-nightly-disabled.stderr | 15 +- .../const-super-trait-nightly-enabled.stderr | 13 +- tests/rustdoc/constant/const-effect-param.rs | 3 +- .../constant/const-trait-and-impl-methods.rs | 6 +- .../constant/rfc-2632-const-trait-impl.rs | 3 +- .../auxiliary/const-effect-param.rs | 3 +- .../const_trait_fn-issue-88433.rs | 3 +- tests/ui/const-generics/issues/issue-88119.rs | 3 +- .../const-generics/issues/issue-88119.stderr | 28 ++-- tests/ui/const-generics/issues/issue-98629.rs | 3 +- .../const-generics/issues/issue-98629.stderr | 2 +- .../constifconst-call-in-const-position.rs | 3 +- ...constifconst-call-in-const-position.stderr | 4 +- .../ui/delegation/unsupported.current.stderr | 2 +- tests/ui/delegation/unsupported.next.stderr | 2 +- tests/ui/delegation/unsupported.rs | 3 +- .../generic-const-items/const-trait-impl.rs | 5 +- .../impls-nested-within-fns-semantic-1.rs | 3 +- tests/ui/resolve/issue-39559-2.stderr | 14 +- tests/ui/specialization/const_trait_impl.rs | 9 +- .../ui/specialization/const_trait_impl.stderr | 12 +- .../structs/default-field-values/support.rs | 2 +- .../assoc-type-const-bound-usage-0.rs | 3 +- .../assoc-type-const-bound-usage-1.rs | 3 +- ...pe-const-bound-usage-fail-2.current.stderr | 4 +- ...-type-const-bound-usage-fail-2.next.stderr | 4 +- .../assoc-type-const-bound-usage-fail-2.rs | 6 +- ...type-const-bound-usage-fail.current.stderr | 4 +- ...oc-type-const-bound-usage-fail.next.stderr | 4 +- .../assoc-type-const-bound-usage-fail.rs | 3 +- .../const-traits/assoc-type.current.stderr | 4 +- .../const-traits/assoc-type.next.stderr | 4 +- tests/ui/traits/const-traits/assoc-type.rs | 9 +- tests/ui/traits/const-traits/attr-misuse.rs | 10 -- .../ui/traits/const-traits/attr-misuse.stderr | 18 --- .../const-traits/auxiliary/cross-crate.rs | 3 +- .../traits/const-traits/auxiliary/minicore.rs | 51 +++---- .../const-traits/auxiliary/staged-api.rs | 3 +- .../traits/const-traits/call-const-closure.rs | 3 +- .../const-traits/call-const-closure.stderr | 2 +- .../call-const-in-conditionally-const.rs | 2 +- .../call-const-trait-method-fail.rs | 3 +- .../call-const-trait-method-fail.stderr | 2 +- .../call-const-trait-method-pass.rs | 3 +- .../const-traits/call-generic-in-impl.rs | 3 +- .../call-generic-method-nonconst.rs | 3 +- .../call-generic-method-nonconst.stderr | 4 +- .../conditionally-const-and-const-params.rs | 3 +- ...onditionally-const-and-const-params.stderr | 6 +- ...ditionally-const-assoc-fn-in-trait-impl.rs | 6 +- .../conditionally-const-in-anon-const.rs | 3 +- .../conditionally-const-in-anon-const.stderr | 8 +- ...itionally-const-inherent-assoc-const-fn.rs | 3 +- .../conditionally-const-invalid-places.rs | 3 +- .../conditionally-const-invalid-places.stderr | 96 ++++++------- ...nditionally-const-trait-bound-assoc-tys.rs | 6 +- .../const-assoc-bound-in-trait-wc.rs | 3 +- .../const-traits/const-bound-in-host.rs | 2 +- .../const-bound-on-not-const-associated-fn.rs | 3 +- ...st-bound-on-not-const-associated-fn.stderr | 8 +- .../const-bounds-non-const-trait.stderr | 12 +- .../const-check-fns-in-const-impl.rs | 3 +- .../const-check-fns-in-const-impl.stderr | 4 +- .../const-closure-trait-method-fail.rs | 3 +- .../const-closure-trait-method-fail.stderr | 2 +- .../const-closure-trait-method.rs | 3 +- .../const-traits/const-cond-for-rpitit.rs | 6 +- .../const-default-method-bodies.rs | 3 +- .../const-default-method-bodies.stderr | 2 +- .../const-drop-fail-2.precise.stderr | 6 +- .../traits/const-traits/const-drop-fail-2.rs | 3 +- .../const-drop-fail-2.stock.stderr | 6 +- tests/ui/traits/const-traits/const-drop.rs | 3 +- .../const-traits/const-impl-recovery.rs | 6 +- .../const-traits/const-impl-recovery.stderr | 4 +- .../const-impl-requires-const-trait.stderr | 4 +- .../traits/const-traits/const-impl-trait.rs | 6 +- .../traits/const-traits/const-in-closure.rs | 3 +- .../const-traits/const-opaque.no.stderr | 6 +- tests/ui/traits/const-traits/const-opaque.rs | 3 +- .../const-trait-bounds-trait-objects.stderr | 8 +- .../const-trait-impl-parameter-mismatch.rs | 6 +- ...const-trait-impl-parameter-mismatch.stderr | 2 +- .../const-traits/const-via-item-bound.rs | 3 +- .../const-traits/cross-crate.gatednc.stderr | 2 +- ...ault-method-body-is-const-body-checking.rs | 6 +- ...-method-body-is-const-body-checking.stderr | 4 +- ...ault-method-body-is-const-same-trait-ck.rs | 3 +- ...-method-body-is-const-same-trait-ck.stderr | 2 +- ...lt-method-body-is-const-with-staged-api.rs | 3 +- .../do-not-const-check-override.rs | 3 +- .../traits/const-traits/do-not-const-check.rs | 6 +- .../dont-ice-on-const-pred-for-bounds.rs | 3 +- .../traits/const-traits/dont-observe-host.rs | 3 +- ...dont-prefer-param-env-for-infer-self-ty.rs | 3 +- .../double-error-for-unimplemented-trait.rs | 3 +- ...ouble-error-for-unimplemented-trait.stderr | 20 +-- .../traits/const-traits/effect-param-infer.rs | 3 +- .../traits/const-traits/eval-bad-signature.rs | 3 +- .../const-traits/eval-bad-signature.stderr | 4 +- tests/ui/traits/const-traits/feature-gate.rs | 4 +- .../const-traits/feature-gate.stock.stderr | 44 +++--- ...function-pointer-does-not-require-const.rs | 3 +- .../ui/traits/const-traits/hir-const-check.rs | 3 +- .../const-traits/ice-121536-const-method.rs | 3 +- .../ice-121536-const-method.stderr | 2 +- ...-124857-combine-effect-const-infer-vars.rs | 3 +- ...857-combine-effect-const-infer-vars.stderr | 2 +- .../const-traits/impl-with-default-fn-fail.rs | 3 +- .../impl-with-default-fn-fail.stderr | 2 +- .../const-traits/impl-with-default-fn-pass.rs | 3 +- .../traits/const-traits/imply-always-const.rs | 6 +- .../inherent-impl-const-bounds.rs | 6 +- ...nline-incorrect-early-bound-in-ctfe.stderr | 5 +- tests/ui/traits/const-traits/issue-100222.rs | 16 ++- tests/ui/traits/const-traits/issue-79450.rs | 3 +- .../ui/traits/const-traits/issue-79450.stderr | 2 +- .../ui/traits/const-traits/issue-88155.stderr | 5 +- .../issue-92230-wf-super-trait-env.rs | 6 +- .../item-bound-entailment-fails.rs | 4 +- .../const-traits/item-bound-entailment.rs | 4 +- .../traits/const-traits/minicore-drop-fail.rs | 2 +- .../traits/const-traits/minicore-fn-fail.rs | 3 +- .../const-traits/minicore-fn-fail.stderr | 2 +- ...utually-exclusive-trait-bound-modifiers.rs | 3 +- .../const-traits/no-explicit-const-params.rs | 3 +- .../no-explicit-const-params.stderr | 22 +-- .../non-const-op-in-closure-in-const.rs | 3 +- ...verlap-const-with-nonconst.min_spec.stderr | 2 +- .../overlap-const-with-nonconst.rs | 6 +- .../overlap-const-with-nonconst.spec.stderr | 2 +- .../predicate-entailment-fails.rs | 6 +- .../predicate-entailment-passes.rs | 6 +- tests/ui/traits/const-traits/project.rs | 6 +- .../const-traits/spec-effectvar-ice.stderr | 12 +- ...fault-bound-non-const-specialized-bound.rs | 9 +- ...t-bound-non-const-specialized-bound.stderr | 4 +- .../const-default-const-specialized.rs | 3 +- ...non-const-specialized-impl.min_spec.stderr | 2 +- ...default-impl-non-const-specialized-impl.rs | 3 +- ...mpl-non-const-specialized-impl.spec.stderr | 2 +- .../specialization/default-keyword.rs | 3 +- ...87-same-trait-bound-different-constness.rs | 9 +- .../non-const-default-const-specialized.rs | 3 +- .../specialize-on-conditionally-const.rs | 9 +- .../const-traits/specializing-constness-2.rs | 6 +- .../specializing-constness-2.stderr | 2 +- .../const-traits/specializing-constness.rs | 9 +- .../specializing-constness.stderr | 2 +- tests/ui/traits/const-traits/staged-api.rs | 6 +- .../ui/traits/const-traits/staged-api.stderr | 34 ++--- .../super-traits-fail-2.nn.stderr | 59 ++++---- .../super-traits-fail-2.ny.stderr | 67 +++++---- .../const-traits/super-traits-fail-2.rs | 21 +-- .../super-traits-fail-2.yn.stderr | 14 +- .../super-traits-fail-2.yy.stderr | 2 +- .../super-traits-fail-3.nnn.stderr | 113 +++++++++------ .../super-traits-fail-3.nny.stderr | 136 ++++++++++-------- .../super-traits-fail-3.nyn.stderr | 95 ++++++++---- .../super-traits-fail-3.nyy.stderr | 62 ++++---- .../const-traits/super-traits-fail-3.rs | 40 +++--- .../super-traits-fail-3.ynn.stderr | 71 +++++---- .../super-traits-fail-3.yny.stderr | 67 +++++---- .../super-traits-fail-3.yyn.stderr | 26 ++-- .../traits/const-traits/super-traits-fail.rs | 6 +- .../const-traits/super-traits-fail.stderr | 2 +- tests/ui/traits/const-traits/super-traits.rs | 6 +- .../const-traits/syntactical-unstable.rs | 3 +- .../const-traits/syntactical-unstable.stderr | 20 +-- .../trait-default-body-stability.rs | 3 +- .../ui/traits/const-traits/trait-fn-const.rs | 3 +- .../traits/const-traits/trait-fn-const.stderr | 20 ++- .../const-traits/trait-where-clause-const.rs | 6 +- .../trait-where-clause-const.stderr | 8 +- .../const-traits/trait-where-clause-run.rs | 6 +- .../trait-where-clause-self-referential.rs | 3 +- .../traits/const-traits/trait-where-clause.rs | 3 +- .../const-traits/trait-where-clause.stderr | 16 +-- .../unconstrained-var-specialization.rs | 3 +- .../unsatisfied-const-trait-bound.rs | 3 +- .../unsatisfied-const-trait-bound.stderr | 32 ++--- tests/ui/traits/const-traits/variance.rs | 3 +- tests/ui/traits/const-traits/variance.stderr | 2 +- .../next-solver/canonical/effect-var.rs | 3 +- 198 files changed, 945 insertions(+), 1073 deletions(-) delete mode 100644 tests/ui/traits/const-traits/attr-misuse.rs delete mode 100644 tests/ui/traits/const-traits/attr-misuse.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 5e10c5a77d97..7d618f16b26e 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -290,7 +290,7 @@ ast_passes_trait_fn_const = *[false] {""} } .make_impl_const_sugg = ... and declare the impl to be const instead - .make_trait_const_sugg = ... and declare the trait to be a `#[const_trait]` instead + .make_trait_const_sugg = ... and declare the trait to be const instead ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 6b218f34363d..ffd4c770a6d4 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -48,7 +48,7 @@ enum SelfSemantic { } enum TraitOrTraitImpl { - Trait { span: Span, constness: Const }, + Trait { vis: Span, constness: Const }, TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref_span: Span }, } @@ -109,10 +109,10 @@ impl<'a> AstValidator<'a> { self.outer_trait_or_trait_impl = old; } - fn with_in_trait(&mut self, span: Span, constness: Const, f: impl FnOnce(&mut Self)) { + fn with_in_trait(&mut self, vis: Span, constness: Const, f: impl FnOnce(&mut Self)) { let old = mem::replace( &mut self.outer_trait_or_trait_impl, - Some(TraitOrTraitImpl::Trait { span, constness }), + Some(TraitOrTraitImpl::Trait { vis, constness }), ); f(self); self.outer_trait_or_trait_impl = old; @@ -265,10 +265,12 @@ impl<'a> AstValidator<'a> { None }; + let map = self.sess.source_map(); + let make_trait_const_sugg = if const_trait_impl - && let TraitOrTraitImpl::Trait { span, constness: ast::Const::No } = parent + && let &TraitOrTraitImpl::Trait { vis, constness: ast::Const::No } = parent { - Some(span.shrink_to_lo()) + Some(map.span_extend_while_whitespace(vis).shrink_to_hi()) } else { None }; @@ -279,7 +281,7 @@ impl<'a> AstValidator<'a> { in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }), const_context_label: parent_constness, remove_const_sugg: ( - self.sess.source_map().span_extend_while_whitespace(span), + map.span_extend_while_whitespace(span), match parent_constness { Some(_) => rustc_errors::Applicability::MachineApplicable, None => rustc_errors::Applicability::MaybeIncorrect, @@ -1165,13 +1167,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .. }) => { self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident); - // FIXME(const_trait_impl) remove this - let alt_const_trait_span = - attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span); - let constness = match (*constness, alt_const_trait_span) { - (Const::Yes(span), _) | (Const::No, Some(span)) => Const::Yes(span), - (Const::No, None) => Const::No, - }; if *is_auto == IsAuto::Yes { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, ident.span); @@ -1188,7 +1183,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits) }); - self.with_in_trait(item.span, constness, |this| { + self.with_in_trait(item.vis.span, *constness, |this| { walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait); }); } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index fd75e999d138..7c63b8e35999 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -56,7 +56,7 @@ pub(crate) struct TraitFnConst { pub make_impl_const_sugg: Option, #[suggestion( ast_passes_make_trait_const_sugg, - code = "#[const_trait]\n", + code = "const ", applicability = "maybe-incorrect" )] pub make_trait_const_sugg: Option, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index ced3bcad2293..03a517efb1bd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -101,17 +101,6 @@ impl NoArgsAttributeParser for DoNotImplementViaObjectParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; } -// FIXME(const_trait_impl): remove this -// Const traits - -pub(crate) struct ConstTraitParser; -impl NoArgsAttributeParser for ConstTraitParser { - const PATH: &[Symbol] = &[sym::const_trait]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); - const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; -} - // Specialization pub(crate) struct SpecializationTraitParser; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index a3473c675dd5..4789f27785cb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -64,7 +64,7 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser}; use crate::attributes::traits::{ - AllowIncoherentImplParser, CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, + AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser, PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, @@ -218,7 +218,6 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index d81b31b704b3..f606158e4018 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -381,23 +381,21 @@ fn build_error_for_const_call<'tcx>( `{trait_name}` is not const", ), ); - if parent.is_local() && ccx.tcx.sess.is_nightly_build() { + if let Some(parent) = parent.as_local() + && ccx.tcx.sess.is_nightly_build() + { if !ccx.tcx.features().const_trait_impl() { err.help( "add `#![feature(const_trait_impl)]` to the crate attributes to \ - enable `#[const_trait]`", + enable const traits", ); } - let indentation = ccx - .tcx - .sess - .source_map() - .indentation_before(trait_span) - .unwrap_or_default(); + let span = ccx.tcx.hir_expect_item(parent).vis_span; + let span = ccx.tcx.sess.source_map().span_extend_while_whitespace(span); err.span_suggestion_verbose( - trait_span.shrink_to_lo(), + span.shrink_to_hi(), format!("consider making trait `{trait_name}` const"), - format!("#[const_trait]\n{indentation}"), + "const ".to_owned(), Applicability::MaybeIncorrect, ); } else if !ccx.tcx.sess.is_nightly_build() { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5dcb5df55720..fd3974922349 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -846,14 +846,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, experimental!(register_tool), ), - // RFC 2632 - // FIXME(const_trait_impl) remove this - gated!( - const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, const_trait_impl, - "`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \ - `impls` and all default bodies as `const`, which may be removed or renamed in the \ - future." - ), // lang-team MCP 147 gated!( deprecated_safe, Normal, template!(List: &[r#"since = "version", note = "...""#]), ErrorFollowing, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index a5f7debe1787..830096527ab3 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -489,9 +489,6 @@ pub enum AttributeKind { /// Represents `#[rustc_const_stable_indirect]`. ConstStabilityIndirect, - /// Represents `#[const_trait]`. - ConstTrait(Span), - /// Represents `#[coroutine]`. Coroutine(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index d59fccb3f1a0..2ccfdc2ad983 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -32,7 +32,6 @@ impl AttributeKind { ConstContinue(..) => No, ConstStability { .. } => Yes, ConstStabilityIndirect => No, - ConstTrait(..) => No, Coroutine(..) => No, Coverage(..) => No, CrateName { .. } => No, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 6e62e50d3af8..454af28419b0 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -890,15 +890,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { }; let attrs = tcx.get_all_attrs(def_id); - // Only regular traits can be const. - // FIXME(const_trait_impl): remove this - let constness = if constness == hir::Constness::Const - || !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) - { - hir::Constness::Const - } else { - hir::Constness::NotConst - }; let paren_sugar = find_attr!(attrs, AttributeKind::ParenSugar(_)); if paren_sugar && !tcx.features().unboxed_closures() { @@ -1366,22 +1357,27 @@ fn check_impl_constness( } let trait_name = tcx.item_name(trait_def_id).to_string(); - let (local_trait_span, suggestion_pre) = - match (trait_def_id.is_local(), tcx.sess.is_nightly_build()) { - (true, true) => ( - Some(tcx.def_span(trait_def_id).shrink_to_lo()), + let (suggestion, suggestion_pre) = match (trait_def_id.as_local(), tcx.sess.is_nightly_build()) + { + (Some(trait_def_id), true) => { + let span = tcx.hir_expect_item(trait_def_id).vis_span; + let span = tcx.sess.source_map().span_extend_while_whitespace(span); + + ( + Some(span.shrink_to_hi()), if tcx.features().const_trait_impl() { "" } else { "enable `#![feature(const_trait_impl)]` in your crate and " }, - ), - (false, _) | (_, false) => (None, ""), - }; + ) + } + (None, _) | (_, false) => (None, ""), + }; tcx.dcx().emit_err(errors::ConstImplForNonConstTrait { trait_ref_span: hir_trait_ref.path.span, trait_name, - local_trait_span, + suggestion, suggestion_pre, marking: (), adding: (), diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index dbad98fd7952..209b0156de32 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -500,13 +500,8 @@ pub(crate) struct ConstImplForNonConstTrait { #[label] pub trait_ref_span: Span, pub trait_name: String, - #[suggestion( - applicability = "machine-applicable", - // FIXME(const_trait_impl) fix this suggestion - code = "#[const_trait] ", - style = "verbose" - )] - pub local_trait_span: Option, + #[suggestion(applicability = "machine-applicable", code = "const ", style = "verbose")] + pub suggestion: Option, pub suggestion_pre: &'static str, #[note] pub marking: (), @@ -523,14 +518,9 @@ pub(crate) struct ConstBoundForNonConstTrait { pub modifier: &'static str, #[note] pub def_span: Option, - pub suggestion_pre: &'static str, - #[suggestion( - applicability = "machine-applicable", - // FIXME(const_trait_impl) fix this suggestion - code = "#[const_trait] ", - style = "verbose" - )] + #[suggestion(applicability = "machine-applicable", code = "const ", style = "verbose")] pub suggestion: Option, + pub suggestion_pre: &'static str, pub trait_name: String, } 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 c1eb277b1380..1edc96a74d26 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -880,28 +880,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness - && !self.tcx().is_const_trait(trait_def_id) + && !tcx.is_const_trait(trait_def_id) { let (def_span, suggestion, suggestion_pre) = - match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) { - (true, true) => ( - None, - Some(tcx.def_span(trait_def_id).shrink_to_lo()), - if self.tcx().features().const_trait_impl() { - "" - } else { - "enable `#![feature(const_trait_impl)]` in your crate and " - }, - ), - (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""), + match (trait_def_id.as_local(), tcx.sess.is_nightly_build()) { + (Some(trait_def_id), true) => { + let span = tcx.hir_expect_item(trait_def_id).vis_span; + let span = tcx.sess.source_map().span_extend_while_whitespace(span); + + ( + None, + Some(span.shrink_to_hi()), + if self.tcx().features().const_trait_impl() { + "" + } else { + "enable `#![feature(const_trait_impl)]` in your crate and " + }, + ) + } + (None, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""), }; self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { span, modifier: constness.as_str(), def_span, - trait_name: self.tcx().def_path_str(trait_def_id), - suggestion_pre, + trait_name: tcx.def_path_str(trait_def_id), suggestion, + suggestion_pre, }); } else { match predicate_filter { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5944a1e8da5d..30a36d51c796 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -235,7 +235,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Marker(..) | AttributeKind::SkipDuringMethodDispatch { .. } | AttributeKind::Coinductive(..) - | AttributeKind::ConstTrait(..) | AttributeKind::DenyExplicitImpl(..) | AttributeKind::DoNotImplementViaObject(..) | AttributeKind::SpecializationTrait(..) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38718bad9e57..951f556ff366 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -746,7 +746,6 @@ symbols! { const_raw_ptr_to_usize_cast, const_refs_to_cell, const_refs_to_static, - const_trait, const_trait_bound_opt_out, const_trait_impl, const_try, diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr index 646688604674..46b0ce96b1fe 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr @@ -38,8 +38,8 @@ LL | trait Bar: [const] Foo {} | help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | const trait Foo { + | +++++ error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 @@ -49,8 +49,8 @@ LL | const fn foo(x: &T) { | help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | const trait Bar: [const] Foo {} + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 @@ -65,13 +65,12 @@ LL | trait Foo { | ^^^^^^^^^ this trait is not const LL | fn a(&self); | ------------ this method is not const - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable const traits = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | const trait Foo { + | +++++ error: aborting due to 6 previous errors diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr index d0e7edf42cdd..c1b35e733a1f 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr @@ -18,8 +18,8 @@ LL | trait Bar: [const] Foo {} | help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | const trait Foo { + | +++++ error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 @@ -29,8 +29,8 @@ LL | const fn foo(x: &T) { | help: mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | const trait Bar: [const] Foo {} + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions --> const-super-trait.rs:10:7 @@ -48,9 +48,8 @@ LL | fn a(&self); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | const trait Foo { + | +++++ error: aborting due to 4 previous errors diff --git a/tests/rustdoc/constant/const-effect-param.rs b/tests/rustdoc/constant/const-effect-param.rs index 3dc63fb3d30f..28c1a43fa9da 100644 --- a/tests/rustdoc/constant/const-effect-param.rs +++ b/tests/rustdoc/constant/const-effect-param.rs @@ -3,8 +3,7 @@ #![crate_name = "foo"] #![feature(const_trait_impl)] -#[const_trait] -pub trait Tr { +pub const trait Tr { fn f(); } diff --git a/tests/rustdoc/constant/const-trait-and-impl-methods.rs b/tests/rustdoc/constant/const-trait-and-impl-methods.rs index 30fc539e5533..987a816d465b 100644 --- a/tests/rustdoc/constant/const-trait-and-impl-methods.rs +++ b/tests/rustdoc/constant/const-trait-and-impl-methods.rs @@ -1,5 +1,4 @@ -// check that we don't render `#[const_trait]` methods as `const` - even for -// const `trait`s and `impl`s. +// check that we don't render assoc fns as `const` - even for const `trait`s and `impl`s. #![crate_name = "foo"] #![feature(const_trait_impl)] @@ -8,8 +7,7 @@ //@ !has - '//*[@id="tymethod.required"]' 'const' //@ has - '//*[@id="method.defaulted"]' 'fn defaulted()' //@ !has - '//*[@id="method.defaulted"]' 'const' -#[const_trait] -pub trait Tr { +pub const trait Tr { fn required(); fn defaulted() {} } diff --git a/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs index e304eff14e8c..f263410d93af 100644 --- a/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs @@ -19,8 +19,7 @@ pub struct S(T); //@ has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' //@ !has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' '[const]' //@ has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Fn' -#[const_trait] -pub trait Tr { +pub const trait Tr { //@ !has - '//section[@id="method.a"]/h4[@class="code-header"]' '[const]' //@ has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' //@ !has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '[const]' diff --git a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs index d7d7b32e2b8b..6f47091b18bf 100644 --- a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs +++ b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait Resource {} +pub const trait Resource {} pub const fn load() -> i32 { 0 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 2f92a528bf72..51c4fefaf70d 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Func { +const trait Func { type Output; fn call_once(self, arg: T) -> Self::Output; diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index a49b2ab8b03d..d44b5ab985b0 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -3,8 +3,7 @@ #![allow(incomplete_features)] #![feature(const_trait_impl, generic_const_exprs)] -#[const_trait] -trait ConstName { +const trait ConstName { const NAME_BYTES: &'static [u8]; } diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr index 0aabf48011dc..0bdf153468bc 100644 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -7,85 +7,85 @@ LL | #![feature(const_trait_impl, generic_const_exprs)] = help: remove one of these features error[E0275]: overflow evaluating the requirement `&T: [const] ConstName` - --> $DIR/issue-88119.rs:19:49 + --> $DIR/issue-88119.rs:18:49 | LL | impl const ConstName for &T | ^^ error[E0275]: overflow evaluating the requirement `&T: ConstName` - --> $DIR/issue-88119.rs:19:49 + --> $DIR/issue-88119.rs:18:49 | LL | impl const ConstName for &T | ^^ error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:21:5 + --> $DIR/issue-88119.rs:20:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:21:5 + --> $DIR/issue-88119.rs:20:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:21:10 + --> $DIR/issue-88119.rs:20:10 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^ | note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:21:5 + --> $DIR/issue-88119.rs:20:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` error[E0275]: overflow evaluating the requirement `&mut T: [const] ConstName` - --> $DIR/issue-88119.rs:26:49 + --> $DIR/issue-88119.rs:25:49 | LL | impl const ConstName for &mut T | ^^^^^^ error[E0275]: overflow evaluating the requirement `&mut T: ConstName` - --> $DIR/issue-88119.rs:26:49 + --> $DIR/issue-88119.rs:25:49 | LL | impl const ConstName for &mut T | ^^^^^^ error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:28:5 + --> $DIR/issue-88119.rs:27:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:28:5 + --> $DIR/issue-88119.rs:27:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:28:10 + --> $DIR/issue-88119.rs:27:10 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^ | note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:28:5 + --> $DIR/issue-88119.rs:27:5 | LL | [(); name_len::()]:, | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName` - --> $DIR/issue-88119.rs:33:35 + --> $DIR/issue-88119.rs:32:35 | LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES; | ^^^^^^^^ error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName` - --> $DIR/issue-88119.rs:34:35 + --> $DIR/issue-88119.rs:33:35 | LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES; | ^^^^^^^^ diff --git a/tests/ui/const-generics/issues/issue-98629.rs b/tests/ui/const-generics/issues/issue-98629.rs index 1d2d3012a6ee..4d65ce868195 100644 --- a/tests/ui/const-generics/issues/issue-98629.rs +++ b/tests/ui/const-generics/issues/issue-98629.rs @@ -1,7 +1,6 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { const N: usize; } diff --git a/tests/ui/const-generics/issues/issue-98629.stderr b/tests/ui/const-generics/issues/issue-98629.stderr index e7582aaae11a..3e929356d2cd 100644 --- a/tests/ui/const-generics/issues/issue-98629.stderr +++ b/tests/ui/const-generics/issues/issue-98629.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `N` - --> $DIR/issue-98629.rs:8:1 + --> $DIR/issue-98629.rs:7:1 | LL | const N: usize; | -------------- `N` from trait diff --git a/tests/ui/consts/constifconst-call-in-const-position.rs b/tests/ui/consts/constifconst-call-in-const-position.rs index da29030dbc74..3069014088bb 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.rs +++ b/tests/ui/consts/constifconst-call-in-const-position.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl, generic_const_exprs)] #![allow(incomplete_features)] -#[const_trait] -pub trait Tr { +pub const trait Tr { fn a() -> usize; } diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index e84e686251a5..70e8ac988e51 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: const Tr` is not satisfied - --> $DIR/constifconst-call-in-const-position.rs:17:39 + --> $DIR/constifconst-call-in-const-position.rs:16:39 | LL | const fn foo() -> [u8; T::a()] { | ^ error[E0277]: the trait bound `T: const Tr` is not satisfied - --> $DIR/constifconst-call-in-const-position.rs:18:9 + --> $DIR/constifconst-call-in-const-position.rs:17:9 | LL | [0; T::a()] | ^ diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr index 55564e8f231f..5c4115630c00 100644 --- a/tests/ui/delegation/unsupported.current.stderr +++ b/tests/ui/delegation/unsupported.current.stderr @@ -46,7 +46,7 @@ LL | reuse to_reuse1::foo; | ^^^ error[E0283]: type annotations needed - --> $DIR/unsupported.rs:56:18 + --> $DIR/unsupported.rs:55:18 | LL | reuse Trait::foo; | ^^^ cannot infer type diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr index 606a25d4269a..a626da9a1442 100644 --- a/tests/ui/delegation/unsupported.next.stderr +++ b/tests/ui/delegation/unsupported.next.stderr @@ -38,7 +38,7 @@ LL | reuse to_reuse1::foo; | ^^^ error[E0283]: type annotations needed - --> $DIR/unsupported.rs:56:18 + --> $DIR/unsupported.rs:55:18 | LL | reuse Trait::foo; | ^^^ cannot infer type diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index 79bab342da09..5e2bd832a4d8 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -48,8 +48,7 @@ mod recursive { } mod effects { - #[const_trait] - trait Trait { + const trait Trait { fn foo(); } diff --git a/tests/ui/generic-const-items/const-trait-impl.rs b/tests/ui/generic-const-items/const-trait-impl.rs index e11d346b712d..197c97ef9fed 100644 --- a/tests/ui/generic-const-items/const-trait-impl.rs +++ b/tests/ui/generic-const-items/const-trait-impl.rs @@ -11,8 +11,7 @@ const CREATE: T = T::create(); pub const K0: i32 = CREATE::; pub const K1: i32 = CREATE; // arg inferred -#[const_trait] -trait Create { +const trait Create { fn create() -> Self; } @@ -22,7 +21,7 @@ impl const Create for i32 { } } -trait Mod { // doesn't need to be a `#[const_trait]` +trait Mod { // doesn't need to be a const trait const CREATE: T; } 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 f06d19d7f5ec..be8a7ddf2669 100644 --- a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs +++ b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs @@ -4,8 +4,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { fn required(); } diff --git a/tests/ui/resolve/issue-39559-2.stderr b/tests/ui/resolve/issue-39559-2.stderr index 4bfa1d1b1322..27b6020dd1c6 100644 --- a/tests/ui/resolve/issue-39559-2.stderr +++ b/tests/ui/resolve/issue-39559-2.stderr @@ -11,13 +11,12 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable const traits = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | -LL + #[const_trait] -LL | trait Dim { - | +LL | const trait Dim { + | +++++ error[E0015]: cannot call non-const associated function `::dim` in constants --> $DIR/issue-39559-2.rs:16:15 @@ -32,13 +31,12 @@ LL | trait Dim { | ^^^^^^^^^ this trait is not const LL | fn dim() -> usize; | ------------------ this associated function is not const - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable const traits = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: consider making trait `Dim` const | -LL + #[const_trait] -LL | trait Dim { - | +LL | const trait Dim { + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs index e917263d1936..adfef77a15ca 100644 --- a/tests/ui/specialization/const_trait_impl.rs +++ b/tests/ui/specialization/const_trait_impl.rs @@ -5,14 +5,12 @@ use std::fmt::Debug; #[rustc_specialization_trait] -#[const_trait] -pub unsafe trait Sup { +pub const unsafe trait Sup { fn foo() -> u32; } #[rustc_specialization_trait] -#[const_trait] -pub unsafe trait Sub: [const] Sup {} +pub const unsafe trait Sub: [const] Sup {} unsafe impl const Sup for u8 { default fn foo() -> u32 { @@ -28,8 +26,7 @@ unsafe impl const Sup for () { unsafe impl const Sub for () {} -#[const_trait] -pub trait A { +pub const trait A { fn a() -> u32; } diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index a21a48997ee7..93ed7234e563 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,5 +1,5 @@ error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:36:9 + --> $DIR/const_trait_impl.rs:33:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` @@ -8,7 +8,7 @@ note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:42:9 + --> $DIR/const_trait_impl.rs:39:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` @@ -17,7 +17,7 @@ note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:48:9 + --> $DIR/const_trait_impl.rs:45:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` @@ -26,7 +26,7 @@ note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:42:9 + --> $DIR/const_trait_impl.rs:39:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` @@ -36,7 +36,7 @@ note: `Debug` can't be used with `[const]` because it isn't `const` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:36:9 + --> $DIR/const_trait_impl.rs:33:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` @@ -46,7 +46,7 @@ note: `Debug` can't be used with `[const]` because it isn't `const` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:48:9 + --> $DIR/const_trait_impl.rs:45:9 | LL | impl const A for T { | ^^^^^^^ can't be applied to `Debug` diff --git a/tests/ui/structs/default-field-values/support.rs b/tests/ui/structs/default-field-values/support.rs index 8209d6dd4a09..670557e12c11 100644 --- a/tests/ui/structs/default-field-values/support.rs +++ b/tests/ui/structs/default-field-values/support.rs @@ -27,7 +27,7 @@ pub enum Bar { } } -#[const_trait] pub trait ConstDefault { +pub const trait ConstDefault { fn value() -> Self; } diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs index ff1ce949f097..0bda247d5f4e 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs @@ -4,8 +4,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc: [const] Trait; fn func() -> i32; } diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs index 5773f2281c39..2498a1ad03bf 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl, generic_const_exprs)] #![allow(incomplete_features)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc: [const] Trait; fn func() -> i32; } diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr index a0474e65efeb..3976c71899e6 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `U: [const] Other` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5 + --> $DIR/assoc-type-const-bound-usage-fail-2.rs:22:5 | LL | T::Assoc::::func(); | ^^^^^^^^^^^^^ error[E0277]: the trait bound `U: [const] Other` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail-2.rs:26:5 + --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5 | LL | ::Assoc::::func(); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr index a0474e65efeb..3976c71899e6 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `U: [const] Other` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5 + --> $DIR/assoc-type-const-bound-usage-fail-2.rs:22:5 | LL | T::Assoc::::func(); | ^^^^^^^^^^^^^ error[E0277]: the trait bound `U: [const] Other` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail-2.rs:26:5 + --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5 | LL | ::Assoc::::func(); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs index 5338c27bedca..a817fff36fa6 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs @@ -8,8 +8,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc: [const] Trait where U: [const] Other; @@ -17,8 +16,7 @@ trait Trait { fn func(); } -#[const_trait] -trait Other {} +const trait Other {} const fn fails() { T::Assoc::::func(); diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr index 20b01d06e8d5..1f0248365ce6 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: [const] Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail.rs:17:5 + --> $DIR/assoc-type-const-bound-usage-fail.rs:16:5 | LL | T::Assoc::func(); | ^^^^^^^^ error[E0277]: the trait bound `T: [const] Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail.rs:19:5 + --> $DIR/assoc-type-const-bound-usage-fail.rs:18:5 | LL | ::Assoc::func(); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr index 20b01d06e8d5..1f0248365ce6 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: [const] Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail.rs:17:5 + --> $DIR/assoc-type-const-bound-usage-fail.rs:16:5 | LL | T::Assoc::func(); | ^^^^^^^^ error[E0277]: the trait bound `T: [const] Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-fail.rs:19:5 + --> $DIR/assoc-type-const-bound-usage-fail.rs:18:5 | LL | ::Assoc::func(); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs index 4940b3a1aa6c..65c3a06e89c2 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs @@ -7,8 +7,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc: [const] Trait; fn func(); } diff --git a/tests/ui/traits/const-traits/assoc-type.current.stderr b/tests/ui/traits/const-traits/assoc-type.current.stderr index 7fe086550f1c..b730fd8ad366 100644 --- a/tests/ui/traits/const-traits/assoc-type.current.stderr +++ b/tests/ui/traits/const-traits/assoc-type.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied - --> $DIR/assoc-type.rs:37:16 + --> $DIR/assoc-type.rs:35:16 | LL | type Bar = NonConstAdd; | ^^^^^^^^^^^ | note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:33:15 + --> $DIR/assoc-type.rs:31:15 | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` diff --git a/tests/ui/traits/const-traits/assoc-type.next.stderr b/tests/ui/traits/const-traits/assoc-type.next.stderr index 7fe086550f1c..b730fd8ad366 100644 --- a/tests/ui/traits/const-traits/assoc-type.next.stderr +++ b/tests/ui/traits/const-traits/assoc-type.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied - --> $DIR/assoc-type.rs:37:16 + --> $DIR/assoc-type.rs:35:16 | LL | type Bar = NonConstAdd; | ^^^^^^^^^^^ | note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:33:15 + --> $DIR/assoc-type.rs:31:15 | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` diff --git a/tests/ui/traits/const-traits/assoc-type.rs b/tests/ui/traits/const-traits/assoc-type.rs index 1faef1b0a325..3fb6f679a193 100644 --- a/tests/ui/traits/const-traits/assoc-type.rs +++ b/tests/ui/traits/const-traits/assoc-type.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Add { +const trait Add { type Output; fn add(self, other: Rhs) -> Self::Output; @@ -28,8 +27,7 @@ impl Add for NonConstAdd { } } -#[const_trait] -trait Foo { +const trait Foo { type Bar: [const] Add; } @@ -38,8 +36,7 @@ impl const Foo for NonConstAdd { //~^ ERROR the trait bound `NonConstAdd: [const] Add` is not satisfied } -#[const_trait] -trait Baz { +const trait Baz { type Qux: Add; } diff --git a/tests/ui/traits/const-traits/attr-misuse.rs b/tests/ui/traits/const-traits/attr-misuse.rs deleted file mode 100644 index 70dfcbf47d28..000000000000 --- a/tests/ui/traits/const-traits/attr-misuse.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(const_trait_impl)] - -#[const_trait] -trait A { - #[const_trait] //~ ERROR attribute cannot be used on - fn foo(self); -} - -#[const_trait] //~ ERROR attribute cannot be used on -fn main() {} diff --git a/tests/ui/traits/const-traits/attr-misuse.stderr b/tests/ui/traits/const-traits/attr-misuse.stderr deleted file mode 100644 index 2f86efac4c92..000000000000 --- a/tests/ui/traits/const-traits/attr-misuse.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: `#[const_trait]` attribute cannot be used on required trait methods - --> $DIR/attr-misuse.rs:5:5 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ - | - = help: `#[const_trait]` can only be applied to traits - -error: `#[const_trait]` attribute cannot be used on functions - --> $DIR/attr-misuse.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ - | - = help: `#[const_trait]` can only be applied to traits - -error: aborting due to 2 previous errors - diff --git a/tests/ui/traits/const-traits/auxiliary/cross-crate.rs b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs index 01921c140cbc..7d464d57c365 100644 --- a/tests/ui/traits/const-traits/auxiliary/cross-crate.rs +++ b/tests/ui/traits/const-traits/auxiliary/cross-crate.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait MyTrait { +pub const trait MyTrait { fn defaulted_func(&self) {} fn func(self); } diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index d2133bbbcaea..2e5df13d021d 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -35,8 +35,7 @@ impl Copy for u8 {} impl Copy for &T {} #[lang = "add"] -#[const_trait] -pub trait Add { +pub const trait Add { type Output; fn add(self, rhs: Rhs) -> Self::Output; @@ -58,8 +57,7 @@ const fn bar() { } #[lang = "Try"] -#[const_trait] -pub trait Try: FromResidual { +pub const trait Try: FromResidual { type Output; type Residual; @@ -70,8 +68,7 @@ pub trait Try: FromResidual { fn branch(self) -> ControlFlow; } -#[const_trait] -pub trait FromResidual::Residual> { +pub const trait FromResidual::Residual> { #[lang = "from_residual"] fn from_residual(residual: R) -> Self; } @@ -83,24 +80,21 @@ enum ControlFlow { Break(B), } -#[const_trait] #[lang = "fn"] #[rustc_paren_sugar] -pub trait Fn: [const] FnMut { +pub const trait Fn: [const] FnMut { extern "rust-call" fn call(&self, args: Args) -> Self::Output; } -#[const_trait] #[lang = "fn_mut"] #[rustc_paren_sugar] -pub trait FnMut: [const] FnOnce { +pub const trait FnMut: [const] FnOnce { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; } -#[const_trait] #[lang = "fn_once"] #[rustc_paren_sugar] -pub trait FnOnce { +pub const trait FnOnce { #[lang = "fn_once_output"] type Output; @@ -128,20 +122,17 @@ impl Receiver for T { } #[lang = "destruct"] -#[const_trait] -pub trait Destruct {} +pub const trait Destruct {} #[lang = "freeze"] pub unsafe auto trait Freeze {} #[lang = "drop"] -#[const_trait] -pub trait Drop { +pub const trait Drop { fn drop(&mut self); } -#[const_trait] -pub trait Residual { +pub const trait Residual { type TryType: [const] Try + Try; } @@ -168,15 +159,13 @@ const fn panic_display() { fn panic_fmt() {} #[lang = "index"] -#[const_trait] -pub trait Index { +pub const trait Index { type Output: MetaSized; fn index(&self, index: Idx) -> &Self::Output; } -#[const_trait] -pub unsafe trait SliceIndex { +pub const unsafe trait SliceIndex { type Output: MetaSized; fn index(self, slice: &T) -> &Self::Output; } @@ -214,8 +203,7 @@ pub trait CoerceUnsized {} impl<'a, 'b: 'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} #[lang = "deref"] -#[const_trait] -pub trait Deref { +pub const trait Deref { #[lang = "deref_target"] type Target: MetaSized; @@ -273,13 +261,11 @@ where } } -#[const_trait] -pub trait Into: Sized { +pub const trait Into: Sized { fn into(self) -> T; } -#[const_trait] -pub trait From: Sized { +pub const trait From: Sized { fn from(value: T) -> Self; } @@ -313,8 +299,7 @@ fn from_str(s: &str) -> Result { } #[lang = "eq"] -#[const_trait] -pub trait PartialEq: PointeeSized { +pub const trait PartialEq: PointeeSized { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { !self.eq(other) @@ -337,8 +322,7 @@ impl PartialEq for str { } #[lang = "not"] -#[const_trait] -pub trait Not { +pub const trait Not { type Output; fn not(self) -> Self::Output; } @@ -462,8 +446,7 @@ impl Deref for Ref<'_, T> { #[lang = "clone"] #[rustc_trivial_field_reads] -#[const_trait] -pub trait Clone: Sized { +pub const trait Clone: Sized { fn clone(&self) -> Self; fn clone_from(&mut self, source: &Self) where diff --git a/tests/ui/traits/const-traits/auxiliary/staged-api.rs b/tests/ui/traits/const-traits/auxiliary/staged-api.rs index 933a25769dca..b2b1e0615c37 100644 --- a/tests/ui/traits/const-traits/auxiliary/staged-api.rs +++ b/tests/ui/traits/const-traits/auxiliary/staged-api.rs @@ -5,8 +5,7 @@ #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "unstable", issue = "none")] -#[const_trait] -pub trait MyTrait { +pub const trait MyTrait { #[stable(feature = "rust1", since = "1.0.0")] fn func(); } diff --git a/tests/ui/traits/const-traits/call-const-closure.rs b/tests/ui/traits/const-traits/call-const-closure.rs index 70dfaf724c9b..c4293579aea8 100644 --- a/tests/ui/traits/const-traits/call-const-closure.rs +++ b/tests/ui/traits/const-traits/call-const-closure.rs @@ -4,8 +4,7 @@ #![feature(const_trait_impl, const_closures)] #![allow(incomplete_features)] -#[const_trait] -trait Bar { +const trait Bar { fn foo(&self); } diff --git a/tests/ui/traits/const-traits/call-const-closure.stderr b/tests/ui/traits/const-traits/call-const-closure.stderr index 9de22759c200..9a851a97f186 100644 --- a/tests/ui/traits/const-traits/call-const-closure.stderr +++ b/tests/ui/traits/const-traits/call-const-closure.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): [const] Bar` is not satisfied - --> $DIR/call-const-closure.rs:17:18 + --> $DIR/call-const-closure.rs:16:18 | LL | (const || ().foo())(); | ^^^ diff --git a/tests/ui/traits/const-traits/call-const-in-conditionally-const.rs b/tests/ui/traits/const-traits/call-const-in-conditionally-const.rs index 4e8c2cd171e6..52d25b85c01d 100644 --- a/tests/ui/traits/const-traits/call-const-in-conditionally-const.rs +++ b/tests/ui/traits/const-traits/call-const-in-conditionally-const.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] trait Foo { +const trait Foo { fn foo(); } diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.rs b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs index c03d3e950b0b..bb481d0d9ea9 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-fail.rs +++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait Plus { +pub const trait Plus { fn plus(self, rhs: Self) -> Self; } diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr index c6f93629379a..6e235d9cb6f0 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `u32: [const] Plus` is not satisfied - --> $DIR/call-const-trait-method-fail.rs:26:5 + --> $DIR/call-const-trait-method-fail.rs:25:5 | LL | a.plus(b) | ^ diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs index 2d9c2ca08617..b12e7e82664b 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs +++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs @@ -20,8 +20,7 @@ impl const PartialEq for Int { } } -#[const_trait] -pub trait Plus { +pub const trait Plus { fn plus(self, rhs: Self) -> Self; } diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.rs b/tests/ui/traits/const-traits/call-generic-in-impl.rs index 72fc80c50e02..4ed937eacaca 100644 --- a/tests/ui/traits/const-traits/call-generic-in-impl.rs +++ b/tests/ui/traits/const-traits/call-generic-in-impl.rs @@ -1,8 +1,7 @@ //@ check-pass #![feature(const_trait_impl, const_cmp)] -#[const_trait] -trait MyPartialEq { +const trait MyPartialEq { fn eq(&self, other: &Self) -> bool; } diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.rs b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs index 0efc8a954ded..e23c4d646b7c 100644 --- a/tests/ui/traits/const-traits/call-generic-method-nonconst.rs +++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.rs @@ -3,8 +3,7 @@ struct S; -#[const_trait] -trait Foo { +const trait Foo { fn eq(&self, _: &Self) -> bool; } diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr index b2ec41182a83..91d391837260 100644 --- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `S: const Foo` is not satisfied - --> $DIR/call-generic-method-nonconst.rs:24:34 + --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); | ----------- ^^ @@ -7,7 +7,7 @@ LL | pub const EQ: bool = equals_self(&S); | required by a bound introduced by this call | note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:17:25 + --> $DIR/call-generic-method-nonconst.rs:16:25 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^^^ required by this bound in `equals_self` diff --git a/tests/ui/traits/const-traits/conditionally-const-and-const-params.rs b/tests/ui/traits/const-traits/conditionally-const-and-const-params.rs index 29553884b21c..2241f70cf21e 100644 --- a/tests/ui/traits/const-traits/conditionally-const-and-const-params.rs +++ b/tests/ui/traits/const-traits/conditionally-const-and-const-params.rs @@ -12,8 +12,7 @@ impl Foo { } } -#[const_trait] -trait Add42 { +const trait Add42 { fn add(a: usize) -> usize; } diff --git a/tests/ui/traits/const-traits/conditionally-const-and-const-params.stderr b/tests/ui/traits/const-traits/conditionally-const-and-const-params.stderr index ebd816ac9a54..81eff253d717 100644 --- a/tests/ui/traits/const-traits/conditionally-const-and-const-params.stderr +++ b/tests/ui/traits/const-traits/conditionally-const-and-const-params.stderr @@ -11,19 +11,19 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { | ^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-and-const-params.rs:26:11 + --> $DIR/conditionally-const-and-const-params.rs:25:11 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-and-const-params.rs:26:4 + --> $DIR/conditionally-const-and-const-params.rs:25:4 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ error[E0277]: the trait bound `A: const Add42` is not satisfied - --> $DIR/conditionally-const-and-const-params.rs:26:62 + --> $DIR/conditionally-const-and-const-params.rs:25:62 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^ diff --git a/tests/ui/traits/const-traits/conditionally-const-assoc-fn-in-trait-impl.rs b/tests/ui/traits/const-traits/conditionally-const-assoc-fn-in-trait-impl.rs index 7f01c0b7a5c9..11ff1ddb7953 100644 --- a/tests/ui/traits/const-traits/conditionally-const-assoc-fn-in-trait-impl.rs +++ b/tests/ui/traits/const-traits/conditionally-const-assoc-fn-in-trait-impl.rs @@ -3,8 +3,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Main { +const trait Main { fn compute() -> u32; } @@ -14,8 +13,7 @@ impl const Main for () { } } -#[const_trait] -trait Aux { +const trait Aux { fn generate() -> u32; } diff --git a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs index 5aebcceb7c75..21419be29591 100644 --- a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs +++ b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.rs @@ -1,8 +1,7 @@ #![feature(const_trait_impl, impl_trait_in_bindings)] struct S; -#[const_trait] -trait Trait {} +const trait Trait {} impl const Trait<0> for () {} diff --git a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr index c6be249b95a2..94b8ea0970dd 100644 --- a/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr +++ b/tests/ui/traits/const-traits/conditionally-const-in-anon-const.stderr @@ -1,23 +1,23 @@ error: `[const]` is not allowed here - --> $DIR/conditionally-const-in-anon-const.rs:14:25 + --> $DIR/conditionally-const-in-anon-const.rs:13:25 | LL | struct I>(U); | ^^^^^^^ | note: structs cannot have `[const]` trait bounds - --> $DIR/conditionally-const-in-anon-const.rs:14:13 + --> $DIR/conditionally-const-in-anon-const.rs:13:13 | LL | struct I>(U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-in-anon-const.rs:17:26 + --> $DIR/conditionally-const-in-anon-const.rs:16:26 | LL | let x: &impl [const] Trait<0> = &(); | ^^^^^^^ | note: anonymous constants cannot have `[const]` trait bounds - --> $DIR/conditionally-const-in-anon-const.rs:11:9 + --> $DIR/conditionally-const-in-anon-const.rs:10:9 | LL | / { LL | | const fn g>() {} diff --git a/tests/ui/traits/const-traits/conditionally-const-inherent-assoc-const-fn.rs b/tests/ui/traits/const-traits/conditionally-const-inherent-assoc-const-fn.rs index 56478a6674b0..083885837cff 100644 --- a/tests/ui/traits/const-traits/conditionally-const-inherent-assoc-const-fn.rs +++ b/tests/ui/traits/const-traits/conditionally-const-inherent-assoc-const-fn.rs @@ -2,8 +2,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn foo(&self) {} } diff --git a/tests/ui/traits/const-traits/conditionally-const-invalid-places.rs b/tests/ui/traits/const-traits/conditionally-const-invalid-places.rs index 52627004fb24..5e13097b3fa2 100644 --- a/tests/ui/traits/const-traits/conditionally-const-invalid-places.rs +++ b/tests/ui/traits/const-traits/conditionally-const-invalid-places.rs @@ -1,7 +1,6 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait {} +const trait Trait {} // Regression test for issue #90052. fn non_const_function() {} //~ ERROR `[const]` is not allowed diff --git a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr index 5c3bb2369675..52b62e7aaccc 100644 --- a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr +++ b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr @@ -1,77 +1,77 @@ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:7:26 + --> $DIR/conditionally-const-invalid-places.rs:6:26 | LL | fn non_const_function() {} | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:7:4 + --> $DIR/conditionally-const-invalid-places.rs:6:4 | LL | fn non_const_function() {} | ^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:9:18 + --> $DIR/conditionally-const-invalid-places.rs:8:18 | LL | struct Struct { field: T } | ^^^^^^^ | note: structs cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:9:1 + --> $DIR/conditionally-const-invalid-places.rs:8:1 | LL | struct Struct { field: T } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:10:23 + --> $DIR/conditionally-const-invalid-places.rs:9:23 | LL | struct TupleStruct(T); | ^^^^^^^ | note: structs cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:10:1 + --> $DIR/conditionally-const-invalid-places.rs:9:1 | LL | struct TupleStruct(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:11:22 + --> $DIR/conditionally-const-invalid-places.rs:10:22 | LL | struct UnitStruct; | ^^^^^^^ | note: structs cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:11:1 + --> $DIR/conditionally-const-invalid-places.rs:10:1 | LL | struct UnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:14:14 + --> $DIR/conditionally-const-invalid-places.rs:13:14 | LL | enum Enum { Variant(T) } | ^^^^^^^ | note: enums cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:14:1 + --> $DIR/conditionally-const-invalid-places.rs:13:1 | LL | enum Enum { Variant(T) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:16:16 + --> $DIR/conditionally-const-invalid-places.rs:15:16 | LL | union Union { field: T } | ^^^^^^^ | note: unions cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:16:1 + --> $DIR/conditionally-const-invalid-places.rs:15:1 | LL | union Union { field: T } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:19:14 + --> $DIR/conditionally-const-invalid-places.rs:18:14 | LL | type Type = T; | ^^^^^^^ @@ -79,7 +79,7 @@ LL | type Type = T; = note: this item cannot have `[const]` trait bounds error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:21:19 + --> $DIR/conditionally-const-invalid-places.rs:20:19 | LL | const CONSTANT: () = (); | ^^^^^^^ @@ -87,43 +87,43 @@ LL | const CONSTANT: () = (); = note: this item cannot have `[const]` trait bounds error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:25:18 + --> $DIR/conditionally-const-invalid-places.rs:24:18 | LL | type Type: [const] Trait; | ^^^^^^^ | note: associated types in non-`const` traits cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:25:5 + --> $DIR/conditionally-const-invalid-places.rs:24:5 | LL | type Type: [const] Trait; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:25:34 + --> $DIR/conditionally-const-invalid-places.rs:24:34 | LL | type Type: [const] Trait; | ^^^^^^^ | note: associated types in non-`const` traits cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:25:5 + --> $DIR/conditionally-const-invalid-places.rs:24:5 | LL | type Type: [const] Trait; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:28:30 + --> $DIR/conditionally-const-invalid-places.rs:27:30 | LL | fn non_const_function(); | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:28:8 + --> $DIR/conditionally-const-invalid-places.rs:27:8 | LL | fn non_const_function(); | ^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:29:23 + --> $DIR/conditionally-const-invalid-places.rs:28:23 | LL | const CONSTANT: (); | ^^^^^^^ @@ -131,31 +131,31 @@ LL | const CONSTANT: (); = note: this item cannot have `[const]` trait bounds error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:34:18 + --> $DIR/conditionally-const-invalid-places.rs:33:18 | LL | type Type = (); | ^^^^^^^ | note: associated types in non-const impls cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:34:5 + --> $DIR/conditionally-const-invalid-places.rs:33:5 | LL | type Type = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:36:30 + --> $DIR/conditionally-const-invalid-places.rs:35:30 | LL | fn non_const_function() {} | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:36:8 + --> $DIR/conditionally-const-invalid-places.rs:35:8 | LL | fn non_const_function() {} | ^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:37:23 + --> $DIR/conditionally-const-invalid-places.rs:36:23 | LL | const CONSTANT: () = (); | ^^^^^^^ @@ -163,31 +163,31 @@ LL | const CONSTANT: () = (); = note: this item cannot have `[const]` trait bounds error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:44:18 + --> $DIR/conditionally-const-invalid-places.rs:43:18 | LL | type Type = (); | ^^^^^^^ | note: inherent associated types cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:44:5 + --> $DIR/conditionally-const-invalid-places.rs:43:5 | LL | type Type = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:46:30 + --> $DIR/conditionally-const-invalid-places.rs:45:30 | LL | fn non_const_function() {} | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:46:8 + --> $DIR/conditionally-const-invalid-places.rs:45:8 | LL | fn non_const_function() {} | ^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:47:23 + --> $DIR/conditionally-const-invalid-places.rs:46:23 | LL | const CONSTANT: () = (); | ^^^^^^^ @@ -195,55 +195,55 @@ LL | const CONSTANT: () = (); = note: this item cannot have `[const]` trait bounds error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:52:15 + --> $DIR/conditionally-const-invalid-places.rs:51:15 | LL | trait Child0: [const] Trait {} | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:52:1 + --> $DIR/conditionally-const-invalid-places.rs:51:1 | LL | trait Child0: [const] Trait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:53:26 + --> $DIR/conditionally-const-invalid-places.rs:52:26 | LL | trait Child1 where Self: [const] Trait {} | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:53:1 + --> $DIR/conditionally-const-invalid-places.rs:52:1 | LL | trait Child1 where Self: [const] Trait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:56:9 + --> $DIR/conditionally-const-invalid-places.rs:55:9 | LL | impl Trait for T {} | ^^^^^^^ | note: this impl is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:56:1 + --> $DIR/conditionally-const-invalid-places.rs:55:1 | LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/conditionally-const-invalid-places.rs:59:9 + --> $DIR/conditionally-const-invalid-places.rs:58:9 | LL | impl Struct {} | ^^^^^^^ | note: inherent impls cannot have `[const]` trait bounds - --> $DIR/conditionally-const-invalid-places.rs:59:1 + --> $DIR/conditionally-const-invalid-places.rs:58:1 | LL | impl Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: generic const items are experimental - --> $DIR/conditionally-const-invalid-places.rs:21:15 + --> $DIR/conditionally-const-invalid-places.rs:20:15 | LL | const CONSTANT: () = (); | ^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | const CONSTANT: () = (); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: generic const items are experimental - --> $DIR/conditionally-const-invalid-places.rs:29:19 + --> $DIR/conditionally-const-invalid-places.rs:28:19 | LL | const CONSTANT: (); | ^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | const CONSTANT: (); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: generic const items are experimental - --> $DIR/conditionally-const-invalid-places.rs:37:19 + --> $DIR/conditionally-const-invalid-places.rs:36:19 | LL | const CONSTANT: () = (); | ^^^^^^^^^^^^^^^^^^ @@ -273,7 +273,7 @@ LL | const CONSTANT: () = (); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: generic const items are experimental - --> $DIR/conditionally-const-invalid-places.rs:47:19 + --> $DIR/conditionally-const-invalid-places.rs:46:19 | LL | const CONSTANT: () = (); | ^^^^^^^^^^^^^^^^^^ @@ -283,7 +283,7 @@ LL | const CONSTANT: () = (); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0392]: type parameter `T` is never used - --> $DIR/conditionally-const-invalid-places.rs:11:19 + --> $DIR/conditionally-const-invalid-places.rs:10:19 | LL | struct UnitStruct; | ^ unused type parameter @@ -291,7 +291,7 @@ LL | struct UnitStruct; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union - --> $DIR/conditionally-const-invalid-places.rs:16:33 + --> $DIR/conditionally-const-invalid-places.rs:15:33 | LL | union Union { field: T } | ^^^^^^^^ @@ -303,19 +303,19 @@ LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + error[E0275]: overflow evaluating the requirement `(): Trait` - --> $DIR/conditionally-const-invalid-places.rs:34:35 + --> $DIR/conditionally-const-invalid-places.rs:33:35 | LL | type Type = (); | ^^ | note: required by a bound in `NonConstTrait::Type` - --> $DIR/conditionally-const-invalid-places.rs:25:34 + --> $DIR/conditionally-const-invalid-places.rs:24:34 | LL | type Type: [const] Trait; | ^^^^^^^^^^^^^ required by this bound in `NonConstTrait::Type` error[E0658]: inherent associated types are unstable - --> $DIR/conditionally-const-invalid-places.rs:44:5 + --> $DIR/conditionally-const-invalid-places.rs:43:5 | LL | type Type = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/conditionally-const-trait-bound-assoc-tys.rs b/tests/ui/traits/const-traits/conditionally-const-trait-bound-assoc-tys.rs index b0bd8466f66b..dfb828623ee6 100644 --- a/tests/ui/traits/const-traits/conditionally-const-trait-bound-assoc-tys.rs +++ b/tests/ui/traits/const-traits/conditionally-const-trait-bound-assoc-tys.rs @@ -2,8 +2,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc; } @@ -11,7 +10,6 @@ impl const Trait for () { type Assoc = T; } -#[const_trait] -trait Bound {} +const trait Bound {} fn main() {} diff --git a/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs b/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs index 81acce65f2a9..ccc6e0e4d51d 100644 --- a/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs +++ b/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs @@ -3,8 +3,7 @@ #![feature(const_clone)] #![feature(const_trait_impl)] -#[const_trait] -trait A where Self::Target: [const] Clone { +const trait A where Self::Target: [const] Clone { type Target; } diff --git a/tests/ui/traits/const-traits/const-bound-in-host.rs b/tests/ui/traits/const-traits/const-bound-in-host.rs index b4c4f5a6de1d..a6f607617f15 100644 --- a/tests/ui/traits/const-traits/const-bound-in-host.rs +++ b/tests/ui/traits/const-traits/const-bound-in-host.rs @@ -3,7 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] trait Foo { +const trait Foo { fn foo(); } diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs index 941112727083..9b2e93fa0ded 100644 --- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs +++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait MyTrait { +const trait MyTrait { fn do_something(&self); } diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr index 901c2cbd8a71..55106cf43115 100644 --- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/traits/const-traits/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:11: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:11: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:22: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:22: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/traits/const-traits/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr index 304d81bb9171..9990d1b3b9e5 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr @@ -6,8 +6,8 @@ LL | const fn perform() {} | help: mark `NonConst` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait NonConst {} - | ++++++++++++++ +LL | const trait NonConst {} + | +++++ error: `[const]` can only be applied to `const` traits --> $DIR/const-bounds-non-const-trait.rs:6:21 @@ -18,8 +18,8 @@ LL | const fn perform() {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `NonConst` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait NonConst {} - | ++++++++++++++ +LL | const trait NonConst {} + | +++++ error: `const` can only be applied to `const` traits --> $DIR/const-bounds-non-const-trait.rs:10:15 @@ -29,8 +29,8 @@ LL | fn operate() {} | help: mark `NonConst` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait NonConst {} - | ++++++++++++++ +LL | const trait NonConst {} + | +++++ error: aborting due to 3 previous errors diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs index f7686ea6139b..f80e379a1317 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] struct S; -#[const_trait] -trait T { +const trait T { fn foo(); } diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr index 1a7ec35f3ddb..04da8f730e20 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr @@ -1,11 +1,11 @@ error[E0015]: cannot call non-const function `non_const` in constant functions - --> $DIR/const-check-fns-in-const-impl.rs:14:16 + --> $DIR/const-check-fns-in-const-impl.rs:13:16 | LL | fn foo() { non_const() } | ^^^^^^^^^^^ | note: function `non_const` is not const - --> $DIR/const-check-fns-in-const-impl.rs:11:1 + --> $DIR/const-check-fns-in-const-impl.rs:10:1 | LL | fn non_const() {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs index cbcc4aa7c3cd..da9327226f77 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs +++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { fn a(self) -> i32; } diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr index faacc8651244..93563dd12f95 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): const Tr` is not satisfied - --> $DIR/const-closure-trait-method-fail.rs:18:23 + --> $DIR/const-closure-trait-method-fail.rs:17:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.rs b/tests/ui/traits/const-traits/const-closure-trait-method.rs index 6477aa63c680..62de7c533ffb 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method.rs +++ b/tests/ui/traits/const-traits/const-closure-trait-method.rs @@ -3,8 +3,7 @@ //@[next] compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { fn a(self) -> i32; } diff --git a/tests/ui/traits/const-traits/const-cond-for-rpitit.rs b/tests/ui/traits/const-traits/const-cond-for-rpitit.rs index da83e054dd9b..0d010fe0de97 100644 --- a/tests/ui/traits/const-traits/const-cond-for-rpitit.rs +++ b/tests/ui/traits/const-traits/const-cond-for-rpitit.rs @@ -4,13 +4,11 @@ #![feature(const_trait_impl)] #![allow(refining_impl_trait)] -#[const_trait] -pub trait Foo { +pub const trait Foo { fn method(self) -> impl [const] Bar; } -#[const_trait] -pub trait Bar {} +pub const trait Bar {} struct A(T); impl const Foo for A where A: [const] Bar { diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.rs b/tests/ui/traits/const-traits/const-default-method-bodies.rs index 27e828c7ab91..b2ddf1ba541e 100644 --- a/tests/ui/traits/const-traits/const-default-method-bodies.rs +++ b/tests/ui/traits/const-traits/const-default-method-bodies.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait ConstDefaultFn: Sized { +const trait ConstDefaultFn: Sized { fn b(self); fn a(self) { diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr index 22b6a9b5613a..55a12f95a6d1 100644 --- a/tests/ui/traits/const-traits/const-default-method-bodies.stderr +++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NonConstImpl: [const] ConstDefaultFn` is not satisfied - --> $DIR/const-default-method-bodies.rs:25:18 + --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); | ^ diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr index 48c8852a7b8d..b4603f4882cc 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr @@ -1,18 +1,18 @@ error[E0277]: the trait bound `NonTrivialDrop: const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 + --> $DIR/const-drop-fail-2.rs:30:23 | LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: required for `ConstDropImplWithBounds` to implement `const Drop` - --> $DIR/const-drop-fail-2.rs:25:26 + --> $DIR/const-drop-fail-2.rs:24:26 | LL | impl const Drop for ConstDropImplWithBounds { | --------- ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | unsatisfied trait bound introduced here note: required by a bound in `check` - --> $DIR/const-drop-fail-2.rs:21:19 + --> $DIR/const-drop-fail-2.rs:20:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.rs b/tests/ui/traits/const-traits/const-drop-fail-2.rs index 3f98a9f715e8..f5e5793b95c1 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.rs +++ b/tests/ui/traits/const-traits/const-drop-fail-2.rs @@ -13,8 +13,7 @@ impl Drop for NonTrivialDrop { } } -#[const_trait] -trait A { fn a() { } } +const trait A { fn a() { } } impl A for NonTrivialDrop {} diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr index 48c8852a7b8d..b4603f4882cc 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr @@ -1,18 +1,18 @@ error[E0277]: the trait bound `NonTrivialDrop: const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 + --> $DIR/const-drop-fail-2.rs:30:23 | LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: required for `ConstDropImplWithBounds` to implement `const Drop` - --> $DIR/const-drop-fail-2.rs:25:26 + --> $DIR/const-drop-fail-2.rs:24:26 | LL | impl const Drop for ConstDropImplWithBounds { | --------- ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | unsatisfied trait bound introduced here note: required by a bound in `check` - --> $DIR/const-drop-fail-2.rs:21:19 + --> $DIR/const-drop-fail-2.rs:20:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs index dc985a8f6207..f7c3ec9be331 100644 --- a/tests/ui/traits/const-traits/const-drop.rs +++ b/tests/ui/traits/const-traits/const-drop.rs @@ -49,8 +49,7 @@ mod t { pub struct HasConstDrop(pub ConstDrop); pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize); - #[const_trait] - pub trait SomeTrait { + pub const trait SomeTrait { fn foo(); } impl const SomeTrait for () { diff --git a/tests/ui/traits/const-traits/const-impl-recovery.rs b/tests/ui/traits/const-traits/const-impl-recovery.rs index 837124db04e2..0f1c6225d8f0 100644 --- a/tests/ui/traits/const-traits/const-impl-recovery.rs +++ b/tests/ui/traits/const-traits/const-impl-recovery.rs @@ -1,12 +1,10 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo {} +const trait Foo {} const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword -#[const_trait] -trait Bar {} +const trait Bar {} const impl Bar for T {} //~ ERROR: expected identifier, found keyword diff --git a/tests/ui/traits/const-traits/const-impl-recovery.stderr b/tests/ui/traits/const-traits/const-impl-recovery.stderr index 7217fc855435..709084c86e0a 100644 --- a/tests/ui/traits/const-traits/const-impl-recovery.stderr +++ b/tests/ui/traits/const-traits/const-impl-recovery.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `impl` - --> $DIR/const-impl-recovery.rs:6:7 + --> $DIR/const-impl-recovery.rs:5:7 | LL | const impl Foo for i32 {} | ^^^^ expected identifier, found keyword @@ -11,7 +11,7 @@ LL + impl const Foo for i32 {} | error: expected identifier, found keyword `impl` - --> $DIR/const-impl-recovery.rs:11:7 + --> $DIR/const-impl-recovery.rs:9:7 | LL | const impl Bar for T {} | ^^^^ expected identifier, found keyword diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr index bf73436b78d3..705ade389436 100644 --- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr @@ -8,8 +8,8 @@ LL | impl const A for () {} = note: adding a non-const method body in the future would be a breaking change help: mark `A` as `const` to allow it to have `const` implementations | -LL | #[const_trait] pub trait A {} - | ++++++++++++++ +LL | pub const trait A {} + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs index c89aaa62d992..e3fcf540643a 100644 --- a/tests/ui/traits/const-traits/const-impl-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-trait.rs @@ -16,8 +16,7 @@ const fn wrap( x } -#[const_trait] -trait Foo { +const trait Foo { fn huh() -> impl [const] PartialEq + [const] Destruct + Copy; } @@ -36,8 +35,7 @@ const _: () = { assert!(x == x); }; -#[const_trait] -trait T {} +const trait T {} struct S; impl const T for S {} diff --git a/tests/ui/traits/const-traits/const-in-closure.rs b/tests/ui/traits/const-traits/const-in-closure.rs index 0657c5af5883..73e348d022ae 100644 --- a/tests/ui/traits/const-traits/const-in-closure.rs +++ b/tests/ui/traits/const-traits/const-in-closure.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { fn method(); } diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr index 591b81f97674..9f17b0d4354d 100644 --- a/tests/ui/traits/const-traits/const-opaque.no.stderr +++ b/tests/ui/traits/const-traits/const-opaque.no.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): const Foo` is not satisfied - --> $DIR/const-opaque.rs:31:22 + --> $DIR/const-opaque.rs:30:22 | LL | let opaque = bar(()); | --- ^^ @@ -7,7 +7,7 @@ LL | let opaque = bar(()); | required by a bound introduced by this call | note: required by a bound in `bar` - --> $DIR/const-opaque.rs:26:17 + --> $DIR/const-opaque.rs:25:17 | LL | const fn bar(t: T) -> impl [const] Foo { | ^^^^^^^^^^^ required by this bound in `bar` @@ -17,7 +17,7 @@ LL | impl const Foo for () { | +++++ error[E0277]: the trait bound `(): const Foo` is not satisfied - --> $DIR/const-opaque.rs:33:12 + --> $DIR/const-opaque.rs:32:12 | LL | opaque.method(); | ^^^^^^ diff --git a/tests/ui/traits/const-traits/const-opaque.rs b/tests/ui/traits/const-traits/const-opaque.rs index 56ebf0aefccf..9b24cfa69a86 100644 --- a/tests/ui/traits/const-traits/const-opaque.rs +++ b/tests/ui/traits/const-traits/const-opaque.rs @@ -4,8 +4,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn method(&self); } diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr index 3ba5da39106d..b78dc0e98abe 100644 --- a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr +++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr @@ -34,8 +34,8 @@ LL | const fn handle(_: &dyn const NonConst) {} | help: mark `NonConst` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait NonConst {} - | ++++++++++++++ +LL | const trait NonConst {} + | +++++ error: `[const]` can only be applied to `const` traits --> $DIR/const-trait-bounds-trait-objects.rs:16:23 @@ -45,8 +45,8 @@ LL | const fn take(_: &dyn [const] NonConst) {} | help: mark `NonConst` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait NonConst {} - | ++++++++++++++ +LL | const trait NonConst {} + | +++++ error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs index 5376baf15e0f..fcc23fbb6510 100644 --- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs +++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs @@ -10,8 +10,7 @@ #![feature(const_trait_impl, effects)] //~^ ERROR feature has been removed -#[const_trait] -trait Main { +const trait Main { fn compute() -> u32; } @@ -22,8 +21,7 @@ impl const Main for () { } } -#[const_trait] -trait Aux {} +const trait Aux {} impl const Aux for () {} diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr index 736fde33ce3a..70add14c3712 100644 --- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr +++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)] = note: removed, redundant with `#![feature(const_trait_impl)]` error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/const-trait-impl-parameter-mismatch.rs:19:16 + --> $DIR/const-trait-impl-parameter-mismatch.rs:18:16 | LL | fn compute() -> u32; | - expected 1 type parameter diff --git a/tests/ui/traits/const-traits/const-via-item-bound.rs b/tests/ui/traits/const-traits/const-via-item-bound.rs index 23f122b74130..c927e1f73ce7 100644 --- a/tests/ui/traits/const-traits/const-via-item-bound.rs +++ b/tests/ui/traits/const-traits/const-via-item-bound.rs @@ -5,8 +5,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Bar {} +const trait Bar {} trait Baz: const Bar {} diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr index fe45ff188efb..45e06c78cfb2 100644 --- a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr @@ -5,7 +5,7 @@ LL | NonConst.func(); | ^^^^ | note: trait `MyTrait` is implemented but not `const` - --> $DIR/auxiliary/cross-crate.rs:12:1 + --> $DIR/auxiliary/cross-crate.rs:11:1 | LL | impl MyTrait for NonConst { | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs index ea97f755d55c..3de92f571e70 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs +++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs @@ -1,13 +1,11 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Tr {} +const trait Tr {} impl Tr for () {} const fn foo() where T: [const] Tr {} -#[const_trait] -pub trait Foo { +pub const trait Foo { fn foo() { foo::<()>(); //~^ ERROR the trait bound `(): [const] Tr` is not satisfied diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr index 3ce646ec5027..a436221d7541 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr +++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): [const] Tr` is not satisfied - --> $DIR/default-method-body-is-const-body-checking.rs:12:15 + --> $DIR/default-method-body-is-const-body-checking.rs:10:15 | LL | foo::<()>(); | ^^ | note: required by a bound in `foo` - --> $DIR/default-method-body-is-const-body-checking.rs:7:28 + --> $DIR/default-method-body-is-const-body-checking.rs:6:28 | LL | const fn foo() where T: [const] Tr {} | ^^^^^^^^^^ required by this bound in `foo` diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs index eb2c472e3bf7..6de82edfbedc 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs +++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait Tr { +pub const trait Tr { fn a(&self) {} fn b(&self) { diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr index f473a687efcb..f93e57d5fd6b 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): [const] Tr` is not satisfied - --> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() | ^ diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs index 8b264ebd0e42..9fccef759bb9 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs +++ b/tests/ui/traits/const-traits/default-method-body-is-const-with-staged-api.rs @@ -9,8 +9,7 @@ #![feature(const_trait_impl)] #![stable(feature = "foo", since = "3.3.3")] -#[const_trait] -trait Tr { +const trait Tr { fn a() {} } diff --git a/tests/ui/traits/const-traits/do-not-const-check-override.rs b/tests/ui/traits/const-traits/do-not-const-check-override.rs index 2b8e1d38ac99..caa3e192e71f 100644 --- a/tests/ui/traits/const-traits/do-not-const-check-override.rs +++ b/tests/ui/traits/const-traits/do-not-const-check-override.rs @@ -3,8 +3,7 @@ #![allow(incomplete_features)] #![feature(const_trait_impl, rustc_attrs)] -#[const_trait] -trait Foo { +const trait Foo { #[rustc_do_not_const_check] fn into_iter(&self) { println!("FEAR ME!") } } diff --git a/tests/ui/traits/const-traits/do-not-const-check.rs b/tests/ui/traits/const-traits/do-not-const-check.rs index 443b63857357..fecbfea8467b 100644 --- a/tests/ui/traits/const-traits/do-not-const-check.rs +++ b/tests/ui/traits/const-traits/do-not-const-check.rs @@ -1,13 +1,11 @@ //@ check-pass #![feature(const_trait_impl, rustc_attrs)] -#[const_trait] -trait IntoIter { +const trait IntoIter { fn into_iter(self); } -#[const_trait] -trait Hmm: Sized { +const trait Hmm: Sized { #[rustc_do_not_const_check] fn chain(self, other: U) where U: IntoIter, { diff --git a/tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs b/tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs index d39e661ed920..ae87d1c4e9c2 100644 --- a/tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs +++ b/tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs @@ -8,8 +8,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Assoc: const Trait; } diff --git a/tests/ui/traits/const-traits/dont-observe-host.rs b/tests/ui/traits/const-traits/dont-observe-host.rs index 06050385f916..f8477a3e5ea8 100644 --- a/tests/ui/traits/const-traits/dont-observe-host.rs +++ b/tests/ui/traits/const-traits/dont-observe-host.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { fn method() {} } diff --git a/tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs b/tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs index f1fc98d72a54..f45265c2cc75 100644 --- a/tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs +++ b/tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo {} +const trait Foo {} impl const Foo for (T,) where T: [const] Foo {} diff --git a/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.rs b/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.rs index 414b80ca0daa..062853635f28 100644 --- a/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.rs +++ b/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { type Out; } diff --git a/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.stderr b/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.stderr index 740a05be06ba..1ae376c8b6b2 100644 --- a/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.stderr +++ b/tests/ui/traits/const-traits/double-error-for-unimplemented-trait.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Trait` is not satisfied - --> $DIR/double-error-for-unimplemented-trait.rs:13:15 + --> $DIR/double-error-for-unimplemented-trait.rs:12:15 | LL | needs_const(&()); | ----------- ^^^ the trait `Trait` is not implemented for `()` @@ -7,18 +7,18 @@ LL | needs_const(&()); | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/double-error-for-unimplemented-trait.rs:6:1 + --> $DIR/double-error-for-unimplemented-trait.rs:5:1 | -LL | trait Trait { - | ^^^^^^^^^^^ +LL | const trait Trait { + | ^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_const` - --> $DIR/double-error-for-unimplemented-trait.rs:10:25 + --> $DIR/double-error-for-unimplemented-trait.rs:9:25 | LL | const fn needs_const(_: &T) {} | ^^^^^^^^^^^^^ required by this bound in `needs_const` error[E0277]: the trait bound `(): Trait` is not satisfied - --> $DIR/double-error-for-unimplemented-trait.rs:18:15 + --> $DIR/double-error-for-unimplemented-trait.rs:17:15 | LL | needs_const(&()); | ----------- ^^^ the trait `Trait` is not implemented for `()` @@ -26,12 +26,12 @@ LL | needs_const(&()); | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/double-error-for-unimplemented-trait.rs:6:1 + --> $DIR/double-error-for-unimplemented-trait.rs:5:1 | -LL | trait Trait { - | ^^^^^^^^^^^ +LL | const trait Trait { + | ^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_const` - --> $DIR/double-error-for-unimplemented-trait.rs:10:25 + --> $DIR/double-error-for-unimplemented-trait.rs:9:25 | LL | const fn needs_const(_: &T) {} | ^^^^^^^^^^^^^ required by this bound in `needs_const` diff --git a/tests/ui/traits/const-traits/effect-param-infer.rs b/tests/ui/traits/const-traits/effect-param-infer.rs index fcacf458a9fa..4ff2406ed15f 100644 --- a/tests/ui/traits/const-traits/effect-param-infer.rs +++ b/tests/ui/traits/const-traits/effect-param-infer.rs @@ -5,8 +5,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait Foo { +pub const trait Foo { /* stuff */ } diff --git a/tests/ui/traits/const-traits/eval-bad-signature.rs b/tests/ui/traits/const-traits/eval-bad-signature.rs index 66e296d43880..02afdb93d240 100644 --- a/tests/ui/traits/const-traits/eval-bad-signature.rs +++ b/tests/ui/traits/const-traits/eval-bad-signature.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Value { +const trait Value { fn value() -> u32; } diff --git a/tests/ui/traits/const-traits/eval-bad-signature.stderr b/tests/ui/traits/const-traits/eval-bad-signature.stderr index 52de5283f7fd..db5f434ee0e9 100644 --- a/tests/ui/traits/const-traits/eval-bad-signature.stderr +++ b/tests/ui/traits/const-traits/eval-bad-signature.stderr @@ -1,11 +1,11 @@ error[E0053]: method `value` has an incompatible type for trait - --> $DIR/eval-bad-signature.rs:17:19 + --> $DIR/eval-bad-signature.rs:16:19 | LL | fn value() -> i64 { | ^^^ expected `u32`, found `i64` | note: type in trait - --> $DIR/eval-bad-signature.rs:7:19 + --> $DIR/eval-bad-signature.rs:6:19 | LL | fn value() -> u32; | ^^^ diff --git a/tests/ui/traits/const-traits/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs index c2918f0249b9..46f0e92021a1 100644 --- a/tests/ui/traits/const-traits/feature-gate.rs +++ b/tests/ui/traits/const-traits/feature-gate.rs @@ -5,15 +5,13 @@ #![cfg_attr(gated, feature(const_trait_impl))] struct S; -#[const_trait] //[stock]~ ERROR `const_trait` is a temporary placeholder -trait T {} +const trait T {} //[stock]~ ERROR const trait impls are experimental impl const T for S {} //[stock]~^ ERROR const trait impls are experimental const fn f() {} //[stock]~ ERROR const trait impls are experimental fn g() {} //[stock]~ ERROR const trait impls are experimental -const trait Trait {} //[stock]~ ERROR const trait impls are experimental #[cfg(false)] const trait Trait {} //[stock]~ ERROR const trait impls are experimental macro_rules! discard { ($ty:ty) => {} } diff --git a/tests/ui/traits/const-traits/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr index 551c7ced7c1f..b5e031094600 100644 --- a/tests/ui/traits/const-traits/feature-gate.stock.stderr +++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr @@ -1,5 +1,15 @@ error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:10:6 + --> $DIR/feature-gate.rs:8:1 + | +LL | const trait T {} + | ^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:9:6 | LL | impl const T for S {} | ^^^^^ @@ -9,7 +19,7 @@ LL | impl const T for S {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:13:15 + --> $DIR/feature-gate.rs:12:15 | LL | const fn f() {} | ^^^^^^^ @@ -19,7 +29,7 @@ LL | const fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:14:9 + --> $DIR/feature-gate.rs:13:9 | LL | fn g() {} | ^^^^^ @@ -29,17 +39,7 @@ LL | fn g() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:16:1 - | -LL | const trait Trait {} - | ^^^^^ - | - = note: see issue #143874 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 - -error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:17:15 + --> $DIR/feature-gate.rs:15:15 | LL | #[cfg(false)] const trait Trait {} | ^^^^^ @@ -49,7 +49,7 @@ LL | #[cfg(false)] const trait Trait {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:21:17 + --> $DIR/feature-gate.rs:19:17 | LL | discard! { impl [const] T } | ^^^^^^^ @@ -59,7 +59,7 @@ LL | discard! { impl [const] T } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:22:17 + --> $DIR/feature-gate.rs:20:17 | LL | discard! { impl const T } | ^^^^^ @@ -68,16 +68,6 @@ LL | discard! { impl const T } = 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 -error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. - --> $DIR/feature-gate.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ - | - = note: see issue #143874 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 - -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs index 8acd195e546b..faa4b51d6685 100644 --- a/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs +++ b/tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs @@ -1,8 +1,7 @@ //@ check-pass #![feature(const_trait_impl)] -#[const_trait] -pub trait Test {} +pub const trait Test {} impl Test for () {} diff --git a/tests/ui/traits/const-traits/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs index 1b6fa1afab9f..5473cdd04075 100644 --- a/tests/ui/traits/const-traits/hir-const-check.rs +++ b/tests/ui/traits/const-traits/hir-const-check.rs @@ -6,8 +6,7 @@ #![feature(const_trait_impl)] #![feature(const_try)] -#[const_trait] -pub trait MyTrait { +pub const trait MyTrait { fn method(&self) -> Option<()>; } diff --git a/tests/ui/traits/const-traits/ice-121536-const-method.rs b/tests/ui/traits/const-traits/ice-121536-const-method.rs index b89786bfd933..a1dbd7551b7b 100644 --- a/tests/ui/traits/const-traits/ice-121536-const-method.rs +++ b/tests/ui/traits/const-traits/ice-121536-const-method.rs @@ -2,8 +2,7 @@ pub struct Vec3; -#[const_trait] -pub trait Add { +pub const trait Add { fn add(self) -> Vec3; } diff --git a/tests/ui/traits/const-traits/ice-121536-const-method.stderr b/tests/ui/traits/const-traits/ice-121536-const-method.stderr index 408958abf630..55f158b3ddec 100644 --- a/tests/ui/traits/const-traits/ice-121536-const-method.stderr +++ b/tests/ui/traits/const-traits/ice-121536-const-method.stderr @@ -1,5 +1,5 @@ error[E0379]: functions in trait impls cannot be declared const - --> $DIR/ice-121536-const-method.rs:11:5 + --> $DIR/ice-121536-const-method.rs:10:5 | LL | const fn add(self) -> Vec3 { | ^^^^^ functions in trait impls cannot be const diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs index ea4db0515cd4..617c28cc3401 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs @@ -2,8 +2,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo {} +const trait Foo {} impl const Foo for i32 {} diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr index 5b417dcfe2cb..082e7a141358 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `i32` - --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:10:1 + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:9:1 | LL | impl const Foo for i32 {} | ---------------------- first implementation here diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs index 6df9696f2cbd..7becb01027d7 100644 --- a/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs +++ b/tests/ui/traits/const-traits/impl-with-default-fn-fail.rs @@ -1,7 +1,6 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { fn req(&self); fn default() {} diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr b/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr index 36c8163f1c56..61f989810bf3 100644 --- a/tests/ui/traits/const-traits/impl-with-default-fn-fail.stderr +++ b/tests/ui/traits/const-traits/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:11:1 | LL | fn req(&self); | -------------- `req` from trait diff --git a/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs index c776a29716ff..f6888f5e997b 100644 --- a/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs +++ b/tests/ui/traits/const-traits/impl-with-default-fn-pass.rs @@ -2,8 +2,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { fn req(&self); fn default() {} diff --git a/tests/ui/traits/const-traits/imply-always-const.rs b/tests/ui/traits/const-traits/imply-always-const.rs index f6cab0681ec2..44391b2753ec 100644 --- a/tests/ui/traits/const-traits/imply-always-const.rs +++ b/tests/ui/traits/const-traits/imply-always-const.rs @@ -2,13 +2,11 @@ #![feature(const_trait_impl)] -#[const_trait] -trait A where Self::Assoc: const B { +const trait A where Self::Assoc: const B { type Assoc; } -#[const_trait] -trait B {} +const trait B {} fn needs_b() {} diff --git a/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs index 941f05428037..67701461b389 100644 --- a/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs +++ b/tests/ui/traits/const-traits/inherent-impl-const-bounds.rs @@ -3,10 +3,8 @@ struct S; -#[const_trait] -trait A {} -#[const_trait] -trait B {} +const trait A {} +const trait B {} impl const A for S {} impl const B for S {} diff --git a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr index ca73ae845550..541a2000c287 100644 --- a/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr +++ b/tests/ui/traits/const-traits/inline-incorrect-early-bound-in-ctfe.stderr @@ -23,9 +23,8 @@ LL | fn foo(self); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Trait` const | -LL + #[const_trait] -LL | trait Trait { - | +LL | const trait Trait { + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/issue-100222.rs b/tests/ui/traits/const-traits/issue-100222.rs index 4c93272b224f..aebcb625cfd7 100644 --- a/tests/ui/traits/const-traits/issue-100222.rs +++ b/tests/ui/traits/const-traits/issue-100222.rs @@ -5,12 +5,20 @@ #![allow(incomplete_features)] #![feature(const_trait_impl, associated_type_defaults)] -#[cfg_attr(any(yn, yy), const_trait)] -pub trait Index { - type Output; +#[cfg(any(yn, yy))] pub const trait Index { type Output; } +#[cfg(not(any(yn, yy)))] pub trait Index { type Output; } + +#[cfg(any(ny, yy))] +pub const trait IndexMut +where + Self: Index, +{ + const C: ::Output; + type Assoc = ::Output; + fn foo(&mut self, x: ::Output) -> ::Output; } -#[cfg_attr(any(ny, yy), const_trait)] +#[cfg(not(any(ny, yy)))] pub trait IndexMut where Self: Index, diff --git a/tests/ui/traits/const-traits/issue-79450.rs b/tests/ui/traits/const-traits/issue-79450.rs index 5ba5036ce277..e74da811fc80 100644 --- a/tests/ui/traits/const-traits/issue-79450.rs +++ b/tests/ui/traits/const-traits/issue-79450.rs @@ -1,8 +1,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { fn req(&self); fn prov(&self) { diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index d8a9e1898068..c10023e9f0ef 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const function `_print` in constant functions - --> $DIR/issue-79450.rs:9:9 + --> $DIR/issue-79450.rs:8:9 | LL | println!("lul"); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr index 4a912cc8274a..514f1fed947e 100644 --- a/tests/ui/traits/const-traits/issue-88155.stderr +++ b/tests/ui/traits/const-traits/issue-88155.stderr @@ -14,9 +14,8 @@ LL | fn assoc() -> bool; = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `A` const | -LL + #[const_trait] -LL | pub trait A { - | +LL | pub const trait A { + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs index 0eb7f54d596f..0663e23f5170 100644 --- a/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs +++ b/tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs @@ -5,10 +5,8 @@ #![feature(const_trait_impl)] -#[const_trait] -pub trait Super {} -#[const_trait] -pub trait Sub: Super {} +pub const trait Super {} +pub const trait Sub: Super {} impl const Super for &A where A: [const] Super {} impl const Sub for &A where A: [const] Sub {} diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.rs b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs index 029597ea1f03..047da4cc938d 100644 --- a/tests/ui/traits/const-traits/item-bound-entailment-fails.rs +++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs @@ -1,13 +1,13 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] trait Foo { +const trait Foo { type Assoc: [const] Bar where T: [const] Bar; } -#[const_trait] trait Bar {} +const trait Bar {} struct N(T); impl Bar for N where T: Bar {} struct C(T); diff --git a/tests/ui/traits/const-traits/item-bound-entailment.rs b/tests/ui/traits/const-traits/item-bound-entailment.rs index 6e053adb3850..facd222e5aaf 100644 --- a/tests/ui/traits/const-traits/item-bound-entailment.rs +++ b/tests/ui/traits/const-traits/item-bound-entailment.rs @@ -3,13 +3,13 @@ #![feature(const_trait_impl)] -#[const_trait] trait Foo { +const trait Foo { type Assoc: [const] Bar where T: [const] Bar; } -#[const_trait] trait Bar {} +const trait Bar {} struct N(T); impl Bar for N where T: Bar {} struct C(T); diff --git a/tests/ui/traits/const-traits/minicore-drop-fail.rs b/tests/ui/traits/const-traits/minicore-drop-fail.rs index f3e7c7df4d41..d01d259040c6 100644 --- a/tests/ui/traits/const-traits/minicore-drop-fail.rs +++ b/tests/ui/traits/const-traits/minicore-drop-fail.rs @@ -15,7 +15,7 @@ impl Drop for NotDropImpl { fn drop(&mut self) {} } -#[const_trait] trait Foo {} +const trait Foo {} impl Foo for () {} struct Conditional(T); diff --git a/tests/ui/traits/const-traits/minicore-fn-fail.rs b/tests/ui/traits/const-traits/minicore-fn-fail.rs index d4cd41a51ca5..e0ce235e72a2 100644 --- a/tests/ui/traits/const-traits/minicore-fn-fail.rs +++ b/tests/ui/traits/const-traits/minicore-fn-fail.rs @@ -10,8 +10,7 @@ use minicore::*; const fn call_indirect(t: &T) { t() } -#[const_trait] -trait Foo {} +const trait Foo {} impl Foo for () {} const fn foo() {} diff --git a/tests/ui/traits/const-traits/minicore-fn-fail.stderr b/tests/ui/traits/const-traits/minicore-fn-fail.stderr index eb840d421f48..0c260f7f33a7 100644 --- a/tests/ui/traits/const-traits/minicore-fn-fail.stderr +++ b/tests/ui/traits/const-traits/minicore-fn-fail.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): [const] Foo` is not satisfied - --> $DIR/minicore-fn-fail.rs:19:19 + --> $DIR/minicore-fn-fail.rs:18:19 | LL | call_indirect(&foo::<()>); | ------------- ^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs index 8d1d3a4c7907..7cb83ecfb0b6 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs @@ -17,7 +17,6 @@ fn const_negative() {} //~^ ERROR `const` trait not allowed with `!` trait polarity modifier //~| ERROR negative bounds are not supported -#[const_trait] -trait Trait {} +const trait Trait {} fn main() {} diff --git a/tests/ui/traits/const-traits/no-explicit-const-params.rs b/tests/ui/traits/const-traits/no-explicit-const-params.rs index 76663292223b..cf641db0a8ce 100644 --- a/tests/ui/traits/const-traits/no-explicit-const-params.rs +++ b/tests/ui/traits/const-traits/no-explicit-const-params.rs @@ -2,8 +2,7 @@ const fn foo() {} -#[const_trait] -trait Bar { +const trait Bar { fn bar(); } diff --git a/tests/ui/traits/const-traits/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/no-explicit-const-params.stderr index 47fa65b2479b..efd90482f774 100644 --- a/tests/ui/traits/const-traits/no-explicit-const-params.stderr +++ b/tests/ui/traits/const-traits/no-explicit-const-params.stderr @@ -1,5 +1,5 @@ error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/no-explicit-const-params.rs:15:5 + --> $DIR/no-explicit-const-params.rs:14:5 | LL | foo::(); | ^^^-------- help: remove the unnecessary generics @@ -13,7 +13,7 @@ LL | const fn foo() {} | ^^^ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/no-explicit-const-params.rs:17:12 + --> $DIR/no-explicit-const-params.rs:16:12 | LL | <() as Bar>::bar(); | ^^^------ help: remove the unnecessary generics @@ -21,13 +21,13 @@ LL | <() as Bar>::bar(); | expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/no-explicit-const-params.rs:6:7 + --> $DIR/no-explicit-const-params.rs:5:13 | -LL | trait Bar { - | ^^^ +LL | const trait Bar { + | ^^^ error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/no-explicit-const-params.rs:22:5 + --> $DIR/no-explicit-const-params.rs:21:5 | LL | foo::(); | ^^^--------- help: remove the unnecessary generics @@ -41,7 +41,7 @@ LL | const fn foo() {} | ^^^ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/no-explicit-const-params.rs:24:12 + --> $DIR/no-explicit-const-params.rs:23:12 | LL | <() as Bar>::bar(); | ^^^------- help: remove the unnecessary generics @@ -49,13 +49,13 @@ LL | <() as Bar>::bar(); | expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/no-explicit-const-params.rs:6:7 + --> $DIR/no-explicit-const-params.rs:5:13 | -LL | trait Bar { - | ^^^ +LL | const trait Bar { + | ^^^ error[E0277]: the trait bound `(): const Bar` is not satisfied - --> $DIR/no-explicit-const-params.rs:24:6 + --> $DIR/no-explicit-const-params.rs:23:6 | LL | <() as Bar>::bar(); | ^^ diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs index 50c985096d12..c0051c62b6d6 100644 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs +++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs @@ -2,8 +2,7 @@ //@ check-pass -#[const_trait] -trait Convert { +const trait Convert { fn to(self) -> T; } diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr index ed671bee63ab..a6bd8615d36d 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` - --> $DIR/overlap-const-with-nonconst.rs:23:1 + --> $DIR/overlap-const-with-nonconst.rs:21:1 | LL | / impl const Foo for T LL | | where diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs index f45690b2f78b..10dfb200c643 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs @@ -5,12 +5,10 @@ //[spec]~^ WARN the feature `specialization` is incomplete #![cfg_attr(min_spec, feature(min_specialization))] -#[const_trait] -trait Bar {} +const trait Bar {} impl const Bar for T {} -#[const_trait] -trait Foo { +const trait Foo { fn method(&self); } impl const Foo for T diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr index 35f4d9184cf5..91628f65fdcd 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr @@ -9,7 +9,7 @@ LL | #![cfg_attr(spec, feature(specialization))] = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` - --> $DIR/overlap-const-with-nonconst.rs:23:1 + --> $DIR/overlap-const-with-nonconst.rs:21:1 | LL | / impl const Foo for T LL | | where diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.rs b/tests/ui/traits/const-traits/predicate-entailment-fails.rs index 0e6c277fd822..d1a8c35442cf 100644 --- a/tests/ui/traits/const-traits/predicate-entailment-fails.rs +++ b/tests/ui/traits/const-traits/predicate-entailment-fails.rs @@ -1,11 +1,11 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] trait Bar {} +const trait Bar {} impl const Bar for () {} -#[const_trait] trait TildeConst { +const trait TildeConst { type Bar where T: [const] Bar; fn foo() where T: [const] Bar; @@ -19,7 +19,7 @@ impl TildeConst for () { } -#[const_trait] trait NeverConst { +const trait NeverConst { type Bar where T: Bar; fn foo() where T: Bar; diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.rs b/tests/ui/traits/const-traits/predicate-entailment-passes.rs index fe8714831866..c2bac51024f3 100644 --- a/tests/ui/traits/const-traits/predicate-entailment-passes.rs +++ b/tests/ui/traits/const-traits/predicate-entailment-passes.rs @@ -3,10 +3,10 @@ #![feature(const_trait_impl)] -#[const_trait] trait Bar {} +const trait Bar {} impl const Bar for () {} -#[const_trait] trait TildeConst { +const trait TildeConst { fn foo() where T: [const] Bar; } impl TildeConst for () { @@ -14,7 +14,7 @@ impl TildeConst for () { } -#[const_trait] trait AlwaysConst { +const trait AlwaysConst { fn foo() where T: const Bar; } impl AlwaysConst for i32 { diff --git a/tests/ui/traits/const-traits/project.rs b/tests/ui/traits/const-traits/project.rs index 139299753e5c..4750591b2bab 100644 --- a/tests/ui/traits/const-traits/project.rs +++ b/tests/ui/traits/const-traits/project.rs @@ -2,11 +2,9 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -pub trait Owo::T> {} +pub const trait Owo::T> {} -#[const_trait] -pub trait Uwu: Owo { +pub const trait Uwu: Owo { type T; } diff --git a/tests/ui/traits/const-traits/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/spec-effectvar-ice.stderr index ef5e58e1c3df..8dbbd302c655 100644 --- a/tests/ui/traits/const-traits/spec-effectvar-ice.stderr +++ b/tests/ui/traits/const-traits/spec-effectvar-ice.stderr @@ -8,8 +8,8 @@ LL | impl const Foo for T {} = note: adding a non-const method body in the future would be a breaking change help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo {} - | ++++++++++++++ +LL | const trait Foo {} + | +++++ error: const `impl` for trait `Foo` which is not `const` --> $DIR/spec-effectvar-ice.rs:13:15 @@ -21,8 +21,8 @@ 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 help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo {} - | ++++++++++++++ +LL | const trait Foo {} + | +++++ error: `const` can only be applied to `const` traits --> $DIR/spec-effectvar-ice.rs:13:34 @@ -32,8 +32,8 @@ LL | impl const Foo for T where T: const Specialize {} | help: mark `Specialize` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Specialize {} - | ++++++++++++++ +LL | const trait Specialize {} + | +++++ error: specialization impl does not specialize any associated items --> $DIR/spec-effectvar-ice.rs:13:1 diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs index 212d869d94d3..5125d2580238 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs @@ -10,11 +10,9 @@ #[rustc_specialization_trait] trait Specialize {} -#[const_trait] -trait Foo {} +const trait Foo {} -#[const_trait] -trait Bar { +const trait Bar { fn bar(); } @@ -33,8 +31,7 @@ where fn bar() {} } -#[const_trait] -trait Baz { +const trait Baz { fn baz(); } diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index 074e6237cc20..85e9fda5c2a3 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Bar` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:26:1 | LL | / impl const Bar for T LL | | where @@ -13,7 +13,7 @@ LL | | T: Specialize, | |__________________^ conflicting implementation error[E0119]: conflicting implementations of trait `Baz` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:48:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:45:1 | LL | / impl const Baz for T LL | | where diff --git a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs index 6991b7deda31..3be2ff4ee611 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs @@ -6,8 +6,7 @@ #![feature(const_trait_impl)] #![feature(min_specialization)] -#[const_trait] -trait Value { +const trait Value { fn value() -> u32; } diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr index 38fc5ddfbef5..520a6833f5a5 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/const-default-impl-non-const-specialized-impl.rs:22:1 + --> $DIR/const-default-impl-non-const-specialized-impl.rs:21:1 | LL | impl const Value for T { | ------------------------- first implementation here diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs index acf0a967a884..f7cd4599561c 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs @@ -6,8 +6,7 @@ //[spec]~^ WARN the feature `specialization` is incomplete #![cfg_attr(min_spec, feature(min_specialization))] -#[const_trait] -trait Value { +const trait Value { fn value() -> u32; } diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr index b59c42f51893..397d67855945 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr @@ -9,7 +9,7 @@ LL | #![cfg_attr(spec, feature(specialization))] = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/const-default-impl-non-const-specialized-impl.rs:22:1 + --> $DIR/const-default-impl-non-const-specialized-impl.rs:21:1 | LL | impl const Value for T { | ------------------------- first implementation here diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs index bc45a70777ca..5b074015d199 100644 --- a/tests/ui/traits/const-traits/specialization/default-keyword.rs +++ b/tests/ui/traits/const-traits/specialization/default-keyword.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] #![feature(min_specialization)] -#[const_trait] -trait Foo { +const trait Foo { fn foo(); } diff --git a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs index 754f1c6d09d5..dbdbf5918556 100644 --- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -11,11 +11,9 @@ #[rustc_specialization_trait] trait Specialize {} -#[const_trait] -trait Foo {} +const trait Foo {} -#[const_trait] -trait Bar { +const trait Bar { fn bar(); } @@ -34,8 +32,7 @@ where fn bar() {} } -#[const_trait] -trait Baz { +const trait Baz { fn baz(); } diff --git a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs index b1a1b4a23995..c68f80dfc728 100644 --- a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs +++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs @@ -6,8 +6,7 @@ #![feature(const_trait_impl)] #![feature(min_specialization)] -#[const_trait] -trait Value { +const trait Value { fn value() -> u32; } diff --git a/tests/ui/traits/const-traits/specialization/specialize-on-conditionally-const.rs b/tests/ui/traits/const-traits/specialization/specialize-on-conditionally-const.rs index 0106bb13875a..a0630d1a8062 100644 --- a/tests/ui/traits/const-traits/specialization/specialize-on-conditionally-const.rs +++ b/tests/ui/traits/const-traits/specialization/specialize-on-conditionally-const.rs @@ -7,12 +7,10 @@ #![feature(rustc_attrs)] #![feature(min_specialization)] -#[const_trait] #[rustc_specialization_trait] -trait Specialize {} +const trait Specialize {} -#[const_trait] -trait Foo { +const trait Foo { fn foo(); } @@ -27,8 +25,7 @@ where fn foo() {} } -#[const_trait] -trait Bar { +const trait Bar { fn bar() {} } diff --git a/tests/ui/traits/const-traits/specializing-constness-2.rs b/tests/ui/traits/const-traits/specializing-constness-2.rs index 86c2cee9fedb..455dd111603d 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.rs +++ b/tests/ui/traits/const-traits/specializing-constness-2.rs @@ -1,13 +1,11 @@ #![feature(const_trait_impl, min_specialization, rustc_attrs)] //@ known-bug: #110395 #[rustc_specialization_trait] -#[const_trait] -pub trait Sup {} +pub const trait Sup {} impl const Sup for () {} -#[const_trait] -pub trait A { +pub const trait A { fn a() -> u32; } diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr index 2a34cd1c4f82..bd6ffa544d0e 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: [const] A` is not satisfied - --> $DIR/specializing-constness-2.rs:27:6 + --> $DIR/specializing-constness-2.rs:25:6 | LL | ::a(); | ^ diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs index b64d8b21b24b..6e9931e8a740 100644 --- a/tests/ui/traits/const-traits/specializing-constness.rs +++ b/tests/ui/traits/const-traits/specializing-constness.rs @@ -1,18 +1,15 @@ #![feature(const_trait_impl, min_specialization, rustc_attrs)] #[rustc_specialization_trait] -#[const_trait] -pub trait Sup {} +pub const trait Sup {} impl const Sup for () {} -#[const_trait] -pub trait A { +pub const trait A { fn a() -> u32; } -#[const_trait] -pub trait Spec {} +pub const trait Spec {} impl const A for T { default fn a() -> u32 { diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr index f411ebcdfcac..e55b24f6f4fd 100644 --- a/tests/ui/traits/const-traits/specializing-constness.stderr +++ b/tests/ui/traits/const-traits/specializing-constness.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `A` - --> $DIR/specializing-constness.rs:23:1 + --> $DIR/specializing-constness.rs:20:1 | LL | impl const A for T { | ----------------------------------- first implementation here diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs index d24b26be569c..6d0a84797ea2 100644 --- a/tests/ui/traits/const-traits/staged-api.rs +++ b/tests/ui/traits/const-traits/staged-api.rs @@ -86,13 +86,11 @@ const fn implicitly_stable_const_context() { } // check that const stability of impls and traits must match -#[const_trait] #[rustc_const_unstable(feature = "beef", issue = "none")] -trait U {} +const trait U {} -#[const_trait] #[rustc_const_stable(since = "0.0.0", feature = "beef2")] -trait S {} +const trait S {} // implied stable impl const U for u8 {} diff --git a/tests/ui/traits/const-traits/staged-api.stderr b/tests/ui/traits/const-traits/staged-api.stderr index 3e85834eb94a..15328ae3b455 100644 --- a/tests/ui/traits/const-traits/staged-api.stderr +++ b/tests/ui/traits/const-traits/staged-api.stderr @@ -1,22 +1,22 @@ error: const stability on the impl does not match the const stability on the trait - --> $DIR/staged-api.rs:98:1 + --> $DIR/staged-api.rs:96:1 | LL | impl const U for u8 {} | ^^^^^^^^^^^^^^^^^^^^^^ | note: this impl is (implicitly) stable... - --> $DIR/staged-api.rs:98:1 + --> $DIR/staged-api.rs:96:1 | LL | impl const U for u8 {} | ^^^^^^^^^^^^^^^^^^^^^^ note: ...but the trait is unstable - --> $DIR/staged-api.rs:91:7 + --> $DIR/staged-api.rs:90:13 | -LL | trait U {} - | ^ +LL | const trait U {} + | ^ error: trait implementations cannot be const stable yet - --> $DIR/staged-api.rs:102:1 + --> $DIR/staged-api.rs:100:1 | LL | impl const U for u16 {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,24 +24,24 @@ LL | impl const U for u16 {} = note: see issue #143874 for more information error: const stability on the impl does not match the const stability on the trait - --> $DIR/staged-api.rs:102:1 + --> $DIR/staged-api.rs:100:1 | LL | impl const U for u16 {} | ^^^^^^^^^^^^^^^^^^^^^^^ | note: this impl is (implicitly) stable... - --> $DIR/staged-api.rs:102:1 + --> $DIR/staged-api.rs:100:1 | LL | impl const U for u16 {} | ^^^^^^^^^^^^^^^^^^^^^^^ note: ...but the trait is unstable - --> $DIR/staged-api.rs:91:7 + --> $DIR/staged-api.rs:90:13 | -LL | trait U {} - | ^ +LL | const trait U {} + | ^ error: trait implementations cannot be const stable yet - --> $DIR/staged-api.rs:113:1 + --> $DIR/staged-api.rs:111:1 | LL | impl const S for u16 {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,21 +49,21 @@ LL | impl const S for u16 {} = note: see issue #143874 for more information error: const stability on the impl does not match the const stability on the trait - --> $DIR/staged-api.rs:117:1 + --> $DIR/staged-api.rs:115:1 | LL | impl const S for u32 {} | ^^^^^^^^^^^^^^^^^^^^^^^ | note: this impl is unstable... - --> $DIR/staged-api.rs:117:1 + --> $DIR/staged-api.rs:115:1 | LL | impl const S for u32 {} | ^^^^^^^^^^^^^^^^^^^^^^^ note: ...but the trait is stable - --> $DIR/staged-api.rs:95:7 + --> $DIR/staged-api.rs:93:13 | -LL | trait S {} - | ^ +LL | const trait S {} + | ^ error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]` --> $DIR/staged-api.rs:38:5 diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr index c9dc239bef33..39fea4cbbf1c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr @@ -1,69 +1,68 @@ error: `[const]` is not allowed here - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:14:32 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-2.rs:11:1 + --> $DIR/super-traits-fail-2.rs:14:21 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:14:32 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:14:32 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:14:32 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-2.rs:20:7 + --> $DIR/super-traits-fail-2.rs:21:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-2.rs:6:1 + --> $DIR/super-traits-fail-2.rs:6:21 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const +LL | #[cfg(any(ny, nn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index bfbf6980ab83..652bcb66e8d5 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -1,81 +1,80 @@ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:8:38 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yy, ny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:8:38 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yy, ny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:8:38 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yy, ny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:8:38 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yy, ny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:8:38 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yy, ny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-2.rs:20:7 + --> $DIR/super-traits-fail-2.rs:21:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-2.rs:6:1 + --> $DIR/super-traits-fail-2.rs:6:21 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const +LL | #[cfg(any(ny, nn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(ny, nn))] const trait Foo { fn a(&self); } + | +++++ error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs index 36e7c1c4e4ac..7dd888b87b0c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs @@ -2,19 +2,20 @@ #![feature(const_trait_impl)] //@ revisions: yy yn ny nn -#[cfg_attr(any(yy, yn), const_trait)] -trait Foo { - fn a(&self); -} +#[cfg(any(yy, yn))] const trait Foo { fn a(&self); } +#[cfg(any(ny, nn))] trait Foo { fn a(&self); } -#[cfg_attr(any(yy, ny), const_trait)] -trait Bar: [const] Foo {} -//[ny,nn]~^ ERROR: `[const]` can only be applied to `const` traits -//[ny,nn]~| ERROR: `[const]` can only be applied to `const` traits -//[ny,nn]~| ERROR: `[const]` can only be applied to `const` traits +#[cfg(any(yy, ny))] const trait Bar: [const] Foo {} +//[ny]~^ ERROR: `[const]` can only be applied to `const` traits //[ny]~| ERROR: `[const]` can only be applied to `const` traits //[ny]~| ERROR: `[const]` can only be applied to `const` traits -//[yn,nn]~^^^^^^ ERROR: `[const]` is not allowed here +//[ny]~| ERROR: `[const]` can only be applied to `const` traits +//[ny]~| ERROR: `[const]` can only be applied to `const` traits +#[cfg(any(yn, nn))] trait Bar: [const] Foo {} +//[yn,nn]~^ ERROR: `[const]` is not allowed here +//[nn]~^^ ERROR: `[const]` can only be applied to `const` traits +//[nn]~| ERROR: `[const]` can only be applied to `const` traits +//[nn]~| ERROR: `[const]` can only be applied to `const` traits const fn foo(x: &T) { x.a(); diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr index 657e8ee82e32..65c6f833ccea 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr @@ -1,17 +1,17 @@ error: `[const]` is not allowed here - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:14:32 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-2.rs:11:1 + --> $DIR/super-traits-fail-2.rs:14:21 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(any(yn, nn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: [const] Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:20:7 + --> $DIR/super-traits-fail-2.rs:21:7 | LL | x.a(); | ^ diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr index 4ae4bbde99bb..c17a67132116 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: [const] Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:20:7 + --> $DIR/super-traits-fail-2.rs:21:7 | LL | x.a(); | ^ diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index ea487cbd563f..b31d7eab53ea 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -1,27 +1,57 @@ error: `[const]` is not allowed here - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-3.rs:23:1 + --> $DIR/super-traits-fail-3.rs:27:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:15:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyy, yyn, nyy, nyn))] const trait Foo { fn a(&self); } + | ^^^^^ | = note: see issue #143874 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 error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:19:33 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:19:50 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:27:44 + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ @@ -31,53 +61,53 @@ LL | const fn foo(x: &T) { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` | help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` @@ -85,31 +115,30 @@ LL | const fn foo(x: &T) { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-3.rs:17:1 + --> $DIR/super-traits-fail-3.rs:17:33 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` +LL | #[cfg(any(yny, ynn, nny, nnn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable const traits = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ -error: aborting due to 9 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index ea487cbd563f..ee43dd9d5fc5 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -1,27 +1,45 @@ -error: `[const]` is not allowed here - --> $DIR/super-traits-fail-3.rs:23:12 - | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ - | -note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-3.rs:23:1 - | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:15:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyy, yyn, nyy, nyn))] const trait Foo { fn a(&self); } + | ^^^^^ | = note: see issue #143874 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 error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:19:33 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:19:50 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:27:44 + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ @@ -31,85 +49,85 @@ LL | const fn foo(x: &T) { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | const fn foo(x: &T) { - | ^^^^^^^ can't be applied to `Bar` - | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations - | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ - -error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 - | -LL | const fn foo(x: &T) { - | ^^^^^^^ can't be applied to `Bar` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ + +error: `[const]` can only be applied to `const` traits + --> $DIR/super-traits-fail-3.rs:19:50 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations + | +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-3.rs:17:1 + --> $DIR/super-traits-fail-3.rs:17:33 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable `#[const_trait]` +LL | #[cfg(any(yny, ynn, nny, nnn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable const traits = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr index b00ad706a5fa..1c56aa129794 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr @@ -1,15 +1,57 @@ -error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:23:12 +error: `[const]` is not allowed here + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ + | +note: this trait is not `const`, so it cannot have `[const]` trait bounds + --> $DIR/super-traits-fail-3.rs:27:33 + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:15:33 + | +LL | #[cfg(any(yyy, yyn, nyy, nyn))] const trait Foo { fn a(&self); } + | ^^^^^ | = note: see issue #143874 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 error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:19:33 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:19:50 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:27:44 + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ @@ -18,37 +60,38 @@ LL | const fn foo(x: &T) { = 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 -error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. - --> $DIR/super-traits-fail-3.rs:15:37 +error: `[const]` can only be applied to `const` traits + --> $DIR/super-traits-fail-3.rs:34:17 | -LL | #[cfg_attr(any(yyy, yyn, nyy, nyn), const_trait)] - | ^^^^^^^^^^^ +LL | const fn foo(x: &T) { + | ^^^^^^^ can't be applied to `Bar` | - = note: see issue #143874 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 +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ -error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. - --> $DIR/super-traits-fail-3.rs:21:37 +error: `[const]` can only be applied to `const` traits + --> $DIR/super-traits-fail-3.rs:34:17 | -LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] - | ^^^^^^^^^^^ +LL | const fn foo(x: &T) { + | ^^^^^^^ can't be applied to `Bar` | - = note: see issue #143874 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 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ -error[E0658]: cannot call conditionally-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 +error[E0015]: cannot call non-const method `::a` in constant functions + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: see issue #143874 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 -error: aborting due to 5 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0015, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr index b00ad706a5fa..692e84176a78 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr @@ -1,15 +1,45 @@ error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:15:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyy, yyn, nyy, nyn))] const trait Foo { fn a(&self); } + | ^^^^^ | = note: see issue #143874 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 error[E0658]: const trait impls are experimental - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:19:33 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:19:50 + | +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:27:44 + | +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ + | + = note: see issue #143874 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 + +error[E0658]: const trait impls are experimental + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ @@ -18,28 +48,8 @@ LL | const fn foo(x: &T) { = 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 -error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. - --> $DIR/super-traits-fail-3.rs:15:37 - | -LL | #[cfg_attr(any(yyy, yyn, nyy, nyn), const_trait)] - | ^^^^^^^^^^^ - | - = note: see issue #143874 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 - -error[E0658]: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future. - --> $DIR/super-traits-fail-3.rs:21:37 - | -LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] - | ^^^^^^^^^^^ - | - = note: see issue #143874 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 - error[E0658]: cannot call conditionally-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ @@ -49,6 +59,6 @@ LL | x.a(); = 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 -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs index d74bd3467840..7dd434c528d0 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs @@ -12,31 +12,33 @@ /// nny: feature not enabled, Foo is not const, Bar is const /// nnn: feature not enabled, Foo is not const, Bar is not const -#[cfg_attr(any(yyy, yyn, nyy, nyn), const_trait)] -//[nyy,nyn]~^ ERROR: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future -trait Foo { - fn a(&self); -} +#[cfg(any(yyy, yyn, nyy, nyn))] const trait Foo { fn a(&self); } +//[nyy,nyn,nny,nnn]~^ ERROR: const trait impls are experimental +#[cfg(any(yny, ynn, nny, nnn))] trait Foo { fn a(&self); } -#[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] -//[nyy,nyn]~^ ERROR: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future -trait Bar: [const] Foo {} -//[yny,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `const` traits -//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits -//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits -//[yny]~^^^^ ERROR: `[const]` can only be applied to `const` traits -//[yny]~| ERROR: `[const]` can only be applied to `const` traits -//[yyn,ynn,nny,nnn]~^^^^^^ ERROR: `[const]` is not allowed here -//[nyy,nyn,nny,nnn]~^^^^^^^ ERROR: const trait impls are experimental +#[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} +//[nyy,nyn,nny,nnn]~^ ERROR: const trait impls are experimental +//[nyy,nyn,nny,nnn]~| ERROR: const trait impls are experimental +//[yny,nny]~^^^ ERROR: `[const]` can only be applied to `const` traits +//[yny,nny]~| ERROR: `[const]` can only be applied to `const` traits +//[yny,nny]~| ERROR: `[const]` can only be applied to `const` traits +//[yny,nny]~| ERROR: `[const]` can only be applied to `const` traits +//[yny,nny]~| ERROR: `[const]` can only be applied to `const` traits +#[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} +//[yyn,ynn,nyn,nnn]~^ ERROR: `[const]` is not allowed here +//[nyy,nyn,nny,nnn]~^^ ERROR: const trait impls are experimental +//[ynn,nnn]~^^^ ERROR: `[const]` can only be applied to `const` traits +//[ynn,nnn]~| ERROR: `[const]` can only be applied to `const` traits +//[ynn,nnn]~| ERROR: `[const]` can only be applied to `const` traits const fn foo(x: &T) { - //[yyn,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `const` traits - //[yyn,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits + //[yyn,ynn,nyn,nnn]~^ ERROR: `[const]` can only be applied to `const` traits + //[yyn,ynn,nyn,nnn]~| ERROR: `[const]` can only be applied to `const` traits //[nyy,nyn,nny,nnn]~^^^ ERROR: const trait impls are experimental x.a(); //[yyn]~^ ERROR: the trait bound `T: [const] Foo` is not satisfied - //[ynn,yny,nny,nnn]~^^ ERROR: cannot call non-const method `::a` in constant functions - //[nyy,nyn]~^^^ ERROR: cannot call conditionally-const method `::a` in constant functions + //[ynn,yny,nny,nnn,nyn]~^^ ERROR: cannot call non-const method `::a` in constant functions + //[nyy]~^^^ ERROR: cannot call conditionally-const method `::a` in constant functions } fn main() {} diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr index 5951caebe733..4b02310d75fa 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr @@ -1,63 +1,63 @@ error: `[const]` is not allowed here - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-3.rs:23:1 + --> $DIR/super-traits-fail-3.rs:27:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` | help: mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` @@ -65,28 +65,27 @@ LL | const fn foo(x: &T) { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-3.rs:17:1 + --> $DIR/super-traits-fail-3.rs:17:33 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const +LL | #[cfg(any(yny, ynn, nny, nnn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: aborting due to 7 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr index 563495204ad7..cf86cbbd0e25 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr @@ -1,81 +1,80 @@ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:19:50 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ can't be applied to `Foo` +LL | #[cfg(any(yyy, yny, nyy, nny))] const trait Bar: [const] Foo {} + | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Foo` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Foo { - | ++++++++++++++ +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error[E0015]: cannot call non-const method `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^^^ | note: method `a` is not const because trait `Foo` is not const - --> $DIR/super-traits-fail-3.rs:17:1 + --> $DIR/super-traits-fail-3.rs:17:33 | -LL | trait Foo { - | ^^^^^^^^^ this trait is not const -LL | fn a(&self); - | ------------ this method is not const +LL | #[cfg(any(yny, ynn, nny, nnn))] trait Foo { fn a(&self); } + | ^^^^^^^^^ ------------ this method is not const + | | + | this trait is not const = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider making trait `Foo` const | -LL + #[const_trait] -LL | trait Foo { - | +LL | #[cfg(any(yny, ynn, nny, nnn))] const trait Foo { fn a(&self); } + | +++++ error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr index de3664dae841..7b5a1f7a6a23 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr @@ -1,28 +1,28 @@ error: `[const]` is not allowed here - --> $DIR/super-traits-fail-3.rs:23:12 + --> $DIR/super-traits-fail-3.rs:27:44 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^ | note: this trait is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/super-traits-fail-3.rs:23:1 + --> $DIR/super-traits-fail-3.rs:27:33 | -LL | trait Bar: [const] Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] trait Bar: [const] Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` | help: mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error: `[const]` can only be applied to `const` traits - --> $DIR/super-traits-fail-3.rs:32:17 + --> $DIR/super-traits-fail-3.rs:34:17 | LL | const fn foo(x: &T) { | ^^^^^^^ can't be applied to `Bar` @@ -30,11 +30,11 @@ LL | const fn foo(x: &T) { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: mark `Bar` as `const` to allow it to have `const` implementations | -LL | #[const_trait] trait Bar: [const] Foo {} - | ++++++++++++++ +LL | #[cfg(any(yyn, ynn, nyn, nnn))] const trait Bar: [const] Foo {} + | +++++ error[E0277]: the trait bound `T: [const] Foo` is not satisfied - --> $DIR/super-traits-fail-3.rs:36:7 + --> $DIR/super-traits-fail-3.rs:38:7 | LL | x.a(); | ^ diff --git a/tests/ui/traits/const-traits/super-traits-fail.rs b/tests/ui/traits/const-traits/super-traits-fail.rs index 15e05be4d862..4f835fd4191c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.rs +++ b/tests/ui/traits/const-traits/super-traits-fail.rs @@ -2,12 +2,10 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn a(&self); } -#[const_trait] -trait Bar: [const] Foo {} +const trait Bar: [const] Foo {} struct S; impl Foo for S { diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr index 3010a5df0c31..37ce0586deb4 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `S: [const] Foo` is not satisfied - --> $DIR/super-traits-fail.rs:17:20 + --> $DIR/super-traits-fail.rs:15:20 | LL | impl const Bar for S {} | ^ diff --git a/tests/ui/traits/const-traits/super-traits.rs b/tests/ui/traits/const-traits/super-traits.rs index b5fd985ae439..169627149a30 100644 --- a/tests/ui/traits/const-traits/super-traits.rs +++ b/tests/ui/traits/const-traits/super-traits.rs @@ -2,13 +2,11 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn a(&self); } -#[const_trait] -trait Bar: [const] Foo {} +const trait Bar: [const] Foo {} struct S; impl const Foo for S { diff --git a/tests/ui/traits/const-traits/syntactical-unstable.rs b/tests/ui/traits/const-traits/syntactical-unstable.rs index 5c542d327f15..6518dd0ac4bb 100644 --- a/tests/ui/traits/const-traits/syntactical-unstable.rs +++ b/tests/ui/traits/const-traits/syntactical-unstable.rs @@ -9,8 +9,7 @@ use std::ops::Deref; extern crate staged_api; use staged_api::MyTrait; -#[const_trait] -trait Foo: [const] MyTrait { +const trait Foo: [const] MyTrait { //~^ ERROR use of unstable const library feature `unstable` type Item: [const] MyTrait; //~^ ERROR use of unstable const library feature `unstable` diff --git a/tests/ui/traits/const-traits/syntactical-unstable.stderr b/tests/ui/traits/const-traits/syntactical-unstable.stderr index b8cc8e69f75b..e2a65c724438 100644 --- a/tests/ui/traits/const-traits/syntactical-unstable.stderr +++ b/tests/ui/traits/const-traits/syntactical-unstable.stderr @@ -1,16 +1,16 @@ error[E0658]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:13:20 + --> $DIR/syntactical-unstable.rs:12:26 | -LL | trait Foo: [const] MyTrait { - | ------- ^^^^^^^ - | | - | trait is not stable as const yet +LL | const trait Foo: [const] MyTrait { + | ------- ^^^^^^^ + | | + | trait is not stable as const yet | = help: add `#![feature(unstable)]` 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]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:19:45 + --> $DIR/syntactical-unstable.rs:18:45 | LL | const fn where_clause() where T: [const] MyTrait {} | ------- ^^^^^^^ @@ -21,7 +21,7 @@ LL | const fn where_clause() where T: [const] MyTrait {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:22:53 + --> $DIR/syntactical-unstable.rs:21:53 | LL | const fn nested() where T: Deref {} | ------- ^^^^^^^ @@ -32,7 +32,7 @@ LL | const fn nested() where T: Deref {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:25:33 + --> $DIR/syntactical-unstable.rs:24:33 | LL | const fn rpit() -> impl [const] MyTrait { Local } | ------- ^^^^^^^ @@ -43,7 +43,7 @@ LL | const fn rpit() -> impl [const] MyTrait { Local } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:29:12 + --> $DIR/syntactical-unstable.rs:28:12 | LL | impl const MyTrait for Local { | ^^^^^^^ trait is not stable as const yet @@ -52,7 +52,7 @@ LL | impl const MyTrait for Local { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable const library feature `unstable` - --> $DIR/syntactical-unstable.rs:15:24 + --> $DIR/syntactical-unstable.rs:14:24 | LL | type Item: [const] MyTrait; | ------- ^^^^^^^ diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.rs b/tests/ui/traits/const-traits/trait-default-body-stability.rs index a8157d37ce3f..1053f54aa6fc 100644 --- a/tests/ui/traits/const-traits/trait-default-body-stability.rs +++ b/tests/ui/traits/const-traits/trait-default-body-stability.rs @@ -39,8 +39,7 @@ impl const FromResidual for T { #[stable(feature = "foo", since = "1.0")] #[rustc_const_unstable(feature = "const_tr", issue = "none")] -#[const_trait] -pub trait Tr { +pub const trait Tr { #[stable(feature = "foo", since = "1.0")] fn bar() -> T { T? diff --git a/tests/ui/traits/const-traits/trait-fn-const.rs b/tests/ui/traits/const-traits/trait-fn-const.rs index 07eac032a82a..b8ad7b867a5a 100644 --- a/tests/ui/traits/const-traits/trait-fn-const.rs +++ b/tests/ui/traits/const-traits/trait-fn-const.rs @@ -1,8 +1,7 @@ // Regression test for issue #113378. #![feature(const_trait_impl)] -#[const_trait] -trait Trait { +const trait Trait { const fn fun(); //~ ERROR functions in traits cannot be declared const } diff --git a/tests/ui/traits/const-traits/trait-fn-const.stderr b/tests/ui/traits/const-traits/trait-fn-const.stderr index 4d0b03046d27..6e1ad29a3c2c 100644 --- a/tests/ui/traits/const-traits/trait-fn-const.stderr +++ b/tests/ui/traits/const-traits/trait-fn-const.stderr @@ -1,9 +1,8 @@ error[E0379]: functions in traits cannot be declared const - --> $DIR/trait-fn-const.rs:6:5 + --> $DIR/trait-fn-const.rs:5:5 | -LL | #[const_trait] - | -------------- this declares all associated functions implicitly const -LL | trait Trait { +LL | const trait Trait { + | ----- this declares all associated functions implicitly const LL | const fn fun(); | ^^^^^- | | @@ -11,7 +10,7 @@ LL | const fn fun(); | help: remove the `const` error[E0379]: functions in trait impls cannot be declared const - --> $DIR/trait-fn-const.rs:10:5 + --> $DIR/trait-fn-const.rs:9:5 | LL | impl const Trait for () { | ----- this declares all associated functions implicitly const @@ -22,7 +21,7 @@ LL | const fn fun() {} | help: remove the `const` error[E0379]: functions in trait impls cannot be declared const - --> $DIR/trait-fn-const.rs:14:5 + --> $DIR/trait-fn-const.rs:13:5 | LL | const fn fun() {} | ^^^^^ functions in trait impls cannot be const @@ -38,7 +37,7 @@ LL | impl const Trait for u32 { | +++++ error[E0379]: functions in traits cannot be declared const - --> $DIR/trait-fn-const.rs:18:5 + --> $DIR/trait-fn-const.rs:17:5 | LL | const fn fun(); | ^^^^^ functions in traits cannot be const @@ -48,11 +47,10 @@ help: remove the `const` ... LL - const fn fun(); LL + fn fun(); | -help: ... and declare the trait to be a `#[const_trait]` instead - | -LL + #[const_trait] -LL | trait NonConst { +help: ... and declare the trait to be const instead | +LL | const trait NonConst { + | +++++ error: aborting due to 4 previous errors diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs index ccb514086cc8..548c5529945d 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.rs +++ b/tests/ui/traits/const-traits/trait-where-clause-const.rs @@ -6,11 +6,9 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Bar {} +const trait Bar {} -#[const_trait] -trait Foo { +const trait Foo { fn a(); fn b() where Self: [const] Bar; fn c(); diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr index 71f9bdff8786..20dd395b820b 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr +++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `T: [const] Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:21:5 + --> $DIR/trait-where-clause-const.rs:19:5 | LL | T::b(); | ^ | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:15:24 + --> $DIR/trait-where-clause-const.rs:13:24 | LL | fn b() where Self: [const] Bar; | ^^^^^^^^^^^ required by this bound in `Foo::b` error[E0277]: the trait bound `T: [const] Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:23:12 + --> $DIR/trait-where-clause-const.rs:21:12 | LL | T::c::(); | ^ | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:16:13 + --> $DIR/trait-where-clause-const.rs:14:13 | LL | fn c(); | ^^^^^^^^^^^ required by this bound in `Foo::c` diff --git a/tests/ui/traits/const-traits/trait-where-clause-run.rs b/tests/ui/traits/const-traits/trait-where-clause-run.rs index c40f071f4572..d24a2abb1783 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-run.rs +++ b/tests/ui/traits/const-traits/trait-where-clause-run.rs @@ -3,13 +3,11 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Bar { +const trait Bar { fn bar() -> u8; } -#[const_trait] -trait Foo { +const trait Foo { fn foo() -> u8 where Self: [const] Bar { ::bar() * 6 } diff --git a/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs index 3a5350cd4ea3..39829adbaf4b 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs +++ b/tests/ui/traits/const-traits/trait-where-clause-self-referential.rs @@ -2,8 +2,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn bar() where Self: [const] Foo; } diff --git a/tests/ui/traits/const-traits/trait-where-clause.rs b/tests/ui/traits/const-traits/trait-where-clause.rs index 6aebab79090a..3ff53f590f81 100644 --- a/tests/ui/traits/const-traits/trait-where-clause.rs +++ b/tests/ui/traits/const-traits/trait-where-clause.rs @@ -1,7 +1,6 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Bar {} +const trait Bar {} trait Foo { fn a(); diff --git a/tests/ui/traits/const-traits/trait-where-clause.stderr b/tests/ui/traits/const-traits/trait-where-clause.stderr index dda91e6bca1e..57d87f74565e 100644 --- a/tests/ui/traits/const-traits/trait-where-clause.stderr +++ b/tests/ui/traits/const-traits/trait-where-clause.stderr @@ -1,35 +1,35 @@ error: `[const]` is not allowed here - --> $DIR/trait-where-clause.rs:8:24 + --> $DIR/trait-where-clause.rs:7:24 | LL | fn b() where Self: [const] Bar; | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/trait-where-clause.rs:8:8 + --> $DIR/trait-where-clause.rs:7:8 | LL | fn b() where Self: [const] Bar; | ^ error: `[const]` is not allowed here - --> $DIR/trait-where-clause.rs:10:13 + --> $DIR/trait-where-clause.rs:9:13 | LL | fn c(); | ^^^^^^^ | note: this function is not `const`, so it cannot have `[const]` trait bounds - --> $DIR/trait-where-clause.rs:10:8 + --> $DIR/trait-where-clause.rs:9:8 | LL | fn c(); | ^ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:16:5 + --> $DIR/trait-where-clause.rs:15:5 | LL | T::b(); | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause.rs:8:24 + --> $DIR/trait-where-clause.rs:7:24 | LL | fn b() where Self: [const] Bar; | ^^^^^^^^^^^ required by this bound in `Foo::b` @@ -39,13 +39,13 @@ LL | fn test1() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:18:12 + --> $DIR/trait-where-clause.rs:17:12 | LL | T::c::(); | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause.rs:10:13 + --> $DIR/trait-where-clause.rs:9:13 | LL | fn c(); | ^^^^^^^^^^^ required by this bound in `Foo::c` diff --git a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs index 43a331144501..4330e0aead1a 100644 --- a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs +++ b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs @@ -7,8 +7,7 @@ // In the default impl below, `A` is constrained by the projection predicate, and if the host effect // predicate for `const Foo` doesn't resolve vars, then specialization will fail. -#[const_trait] -trait Foo {} +const trait Foo {} pub trait Iterator { type Item; diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs index c82b44275009..57641423643e 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs @@ -7,8 +7,7 @@ fn require() {} -#[const_trait] -trait Trait { +const trait Trait { fn make() -> u32; } diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr index 9750d806ce97..1a2bc6c2c5f5 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr @@ -7,88 +7,88 @@ LL | #![feature(const_trait_impl, generic_const_exprs)] = help: remove one of these features error[E0391]: cycle detected when evaluating type-level constant - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ | note: ...which requires const-evaluating + checking `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires checking if `accept0::{constant#0}` is a trivial const... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires building MIR for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires building an abstract representation for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires building THIR for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires type-checking `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ = note: ...which again requires evaluating type-level constant, completing the cycle note: cycle used when checking that `accept0` is well-formed - --> $DIR/unsatisfied-const-trait-bound.rs:29:35 + --> $DIR/unsatisfied-const-trait-bound.rs:28:35 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ = 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[E0391]: cycle detected when checking if `accept1::{constant#0}` is a trivial const - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ | note: ...which requires building MIR for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires building an abstract representation for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires building THIR for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires type-checking `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires evaluating type-level constant... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ = note: ...which again requires checking if `accept1::{constant#0}` is a trivial const, completing the cycle note: cycle used when const-evaluating + checking `accept1::{constant#0}` - --> $DIR/unsatisfied-const-trait-bound.rs:33:49 + --> $DIR/unsatisfied-const-trait-bound.rs:32:49 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/variance.rs b/tests/ui/traits/const-traits/variance.rs index 90b5c50161d5..73014703adc0 100644 --- a/tests/ui/traits/const-traits/variance.rs +++ b/tests/ui/traits/const-traits/variance.rs @@ -2,8 +2,7 @@ #![allow(internal_features)] #![rustc_variance_of_opaques] -#[const_trait] -trait Foo {} +const trait Foo {} impl const Foo for () {} diff --git a/tests/ui/traits/const-traits/variance.stderr b/tests/ui/traits/const-traits/variance.stderr index f55069311848..1367ec6929a5 100644 --- a/tests/ui/traits/const-traits/variance.stderr +++ b/tests/ui/traits/const-traits/variance.stderr @@ -1,5 +1,5 @@ error: ['a: *] - --> $DIR/variance.rs:10:21 + --> $DIR/variance.rs:9:21 | LL | fn foo<'a: 'a>() -> impl const Foo {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/next-solver/canonical/effect-var.rs b/tests/ui/traits/next-solver/canonical/effect-var.rs index 82dbde0413c4..872a70417f48 100644 --- a/tests/ui/traits/next-solver/canonical/effect-var.rs +++ b/tests/ui/traits/next-solver/canonical/effect-var.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Foo { +const trait Foo { fn foo(); } From 52fd48c34f032028c9b1535b3d6cb0e74095f3f9 Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 8 Nov 2025 09:27:30 +0100 Subject: [PATCH 484/525] std: use a non-poisoning `RwLock` for the panic hook --- library/std/src/panicking.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 9af3e5f63ffb..7efb7ad8ee8b 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -22,7 +22,7 @@ use crate::io::try_set_output_capture; use crate::mem::{self, ManuallyDrop}; use crate::panic::{BacktraceStyle, PanicHookInfo}; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; -use crate::sync::{PoisonError, RwLock}; +use crate::sync::nonpoison::RwLock; use crate::sys::backtrace; use crate::sys::stdio::panic_output; use crate::{fmt, intrinsics, process, thread}; @@ -144,13 +144,9 @@ pub fn set_hook(hook: Box) + 'static + Sync + Send>) { panic!("cannot modify the panic hook from a panicking thread"); } - let new = Hook::Custom(hook); - let mut hook = HOOK.write().unwrap_or_else(PoisonError::into_inner); - let old = mem::replace(&mut *hook, new); - drop(hook); - // Only drop the old hook after releasing the lock to avoid deadlocking - // if its destructor panics. - drop(old); + // Drop the old hook after changing the hook to avoid deadlocking if its + // destructor panics. + drop(HOOK.replace(Hook::Custom(hook))); } /// Unregisters the current panic hook and returns it, registering the default hook @@ -188,11 +184,7 @@ pub fn take_hook() -> Box) + 'static + Sync + Send> { panic!("cannot modify the panic hook from a panicking thread"); } - let mut hook = HOOK.write().unwrap_or_else(PoisonError::into_inner); - let old_hook = mem::take(&mut *hook); - drop(hook); - - old_hook.into_box() + HOOK.replace(Hook::Default).into_box() } /// Atomic combination of [`take_hook`] and [`set_hook`]. Use this to replace the panic handler with @@ -238,7 +230,7 @@ where panic!("cannot modify the panic hook from a panicking thread"); } - let mut hook = HOOK.write().unwrap_or_else(PoisonError::into_inner); + let mut hook = HOOK.write(); let prev = mem::take(&mut *hook).into_box(); *hook = Hook::Custom(Box::new(move |info| hook_fn(&prev, info))); } @@ -822,7 +814,7 @@ fn panic_with_hook( crate::process::abort(); } - match *HOOK.read().unwrap_or_else(PoisonError::into_inner) { + match *HOOK.read() { // Some platforms (like wasm) know that printing to stderr won't ever actually // print anything, and if that's the case we can skip the default // hook. Since string formatting happens lazily when calling `payload` From c52b7036c03f05ed62a68ae3a23ef249c129f053 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 8 Nov 2025 10:48:08 +0100 Subject: [PATCH 485/525] Remove unused argument `features` from `eval_config_entry` Signed-off-by: Jonathan Brouwer --- compiler/rustc_attr_parsing/src/attributes/cfg.rs | 7 +++---- compiler/rustc_builtin_macros/src/cfg.rs | 1 - compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_expand/src/config.rs | 3 +-- compiler/rustc_metadata/src/native_libs.rs | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 47b46cd69d84..631c2f1be4fd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -199,14 +199,13 @@ pub fn eval_config_entry( sess: &Session, cfg_entry: &CfgEntry, id: NodeId, - features: Option<&Features>, emit_lints: ShouldEmit, ) -> EvalConfigResult { match cfg_entry { CfgEntry::All(subs, ..) => { let mut all = None; for sub in subs { - let res = eval_config_entry(sess, sub, id, features, emit_lints); + let res = eval_config_entry(sess, sub, id, emit_lints); // We cannot short-circuit because `eval_config_entry` emits some lints if !res.as_bool() { all.get_or_insert(res); @@ -217,7 +216,7 @@ pub fn eval_config_entry( CfgEntry::Any(subs, span) => { let mut any = None; for sub in subs { - let res = eval_config_entry(sess, sub, id, features, emit_lints); + let res = eval_config_entry(sess, sub, id, emit_lints); // We cannot short-circuit because `eval_config_entry` emits some lints if res.as_bool() { any.get_or_insert(res); @@ -229,7 +228,7 @@ pub fn eval_config_entry( }) } CfgEntry::Not(sub, span) => { - if eval_config_entry(sess, sub, id, features, emit_lints).as_bool() { + if eval_config_entry(sess, sub, id, emit_lints).as_bool() { EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } } else { EvalConfigResult::True diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 387399668111..4737e2747e4c 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -30,7 +30,6 @@ pub(crate) fn expand_cfg( cx.sess, &cfg, cx.current_expansion.lint_node_id, - Some(cx.ecfg.features), ShouldEmit::ErrorsAndLints, ) .as_bool(); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index fa730bae610c..85788ba5e3b8 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3033,7 +3033,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, None, ShouldEmit::ErrorsAndLints).as_bool() + eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() } None => true, } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 8278c29570b7..e93d9702774e 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -322,7 +322,6 @@ impl<'a> StripUnconfigured<'a> { self.sess, &cfg_predicate, ast::CRATE_NODE_ID, - self.features, ShouldEmit::ErrorsAndLints, ) .as_bool() @@ -443,7 +442,7 @@ impl<'a> StripUnconfigured<'a> { return EvalConfigResult::True; }; - eval_config_entry(self.sess, &cfg, self.lint_node_id, self.features, emit_errors) + eval_config_entry(self.sess, &cfg, self.lint_node_id, emit_errors) } /// If attributes are not allowed on expressions, emit an error for `attr` diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 2d2eedd2ba5a..291f5c65dfa2 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -189,7 +189,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, None, ShouldEmit::ErrorsAndLints).as_bool() + eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() } None => true, } From 18882dd5478c38429ebc0e1519b6836c11a85788 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 13:25:51 +0000 Subject: [PATCH 486/525] Rustup to rustc 1.93.0-nightly (843f8ce2e 2025-11-07) --- rust-toolchain | 2 +- src/inline_asm.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 0e770c49340f..17c2cc5ac660 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-05" +channel = "nightly-2025-11-08" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 5a29961f7d71..08cabe9d695c 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -7,6 +7,7 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; +use rustc_target::spec::Arch; use target_lexicon::BinaryFormat; use crate::prelude::*; @@ -51,7 +52,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( return; } - if fx.tcx.sess.target.arch == "s390x" + if fx.tcx.sess.target.arch == Arch::S390x && template.len() == 3 && template[0] == InlineAsmTemplatePiece::String("stfle 0(".into()) && let InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ } = From a0b865dc8782500efe9623859017dd5e16f85407 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 13:35:51 +0000 Subject: [PATCH 487/525] Fix simd_gather intrinsic --- src/intrinsics/simd.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 59f46cbefe2d..1504869b89e0 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -1006,15 +1006,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); - - let memflags = match alignment { - SimdAlign::Unaligned => MemFlags::new().with_notrap(), - _ => MemFlags::trusted(), - }; - for lane_idx in 0..ptr_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx); @@ -1030,7 +1021,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.seal_block(if_disabled); fx.bcx.switch_to_block(if_enabled); - let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0); + let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); @@ -1059,6 +1050,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let ret_lane_layout = fx.layout_of(ret_lane_ty); let ptr_val = ptr.load_scalar(fx); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..ret_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); @@ -1074,12 +1074,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.switch_to_block(if_enabled); let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; - let res = fx.bcx.ins().load( - lane_clif_ty, - MemFlags::trusted(), - ptr_val, - Offset32::new(offset), - ); + let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_val, Offset32::new(offset)); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); From 7298174cd5905e73b60900110b8cd5e015e45d4f Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sun, 7 Sep 2025 17:07:25 +0000 Subject: [PATCH 488/525] add parser check for multi-reference self --- compiler/rustc_ast/src/ast.rs | 9 ++ .../rustc_parse/src/parser/diagnostics.rs | 39 ++++++++- tests/ui/self/lot-of-references-self.rs | 28 ++++++ tests/ui/self/lot-of-references-self.stderr | 86 +++++++++++++++++++ 4 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 tests/ui/self/lot-of-references-self.rs create mode 100644 tests/ui/self/lot-of-references-self.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 802a6fa32498..422fcabe41b0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -715,6 +715,15 @@ impl Pat { } } + /// Strip off all reference patterns (`&`, `&mut`) and return the inner pattern. + pub fn peel_refs(&self) -> &Pat { + let mut current = self; + while let PatKind::Ref(inner, _) = ¤t.kind { + current = inner; + } + current + } + /// Is this a `..` pattern? pub fn is_rest(&self) -> bool { matches!(self.kind, PatKind::Rest) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a28af7833c38..300b543381de 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2,13 +2,12 @@ use std::mem::take; use std::ops::{Deref, DerefMut}; use ast::token::IdentIsRaw; -use rustc_ast as ast; use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast::{ - AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block, - BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind, - Path, PathSegment, QSelf, Recovered, Ty, TyKind, + self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, + Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, + PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -2290,6 +2289,38 @@ impl<'a> Parser<'a> { pat.span.shrink_to_hi(), pat.span.shrink_to_lo(), ), + PatKind::Ref(ref inner_pat, _) + // Fix suggestions for multi-reference `self` parameters (e.g. `&&&self`) + // cc: https://github.com/rust-lang/rust/pull/146305 + if let PatKind::Ref(_, _) = &inner_pat.kind + && let PatKind::Path(_, path) = &pat.peel_refs().kind + && let [a, ..] = path.segments.as_slice() + && a.ident.name == kw::SelfLower => + { + let mut inner = inner_pat; + let mut span_vec = vec![pat.span]; + + while let PatKind::Ref(ref inner_type, _) = inner.kind { + inner = inner_type; + span_vec.push(inner.span.shrink_to_lo()); + } + + let span = match span_vec.len() { + // Should be unreachable: match guard ensures at least 2 references + 0 | 1 => unreachable!(), + 2 => span_vec[0].until(inner_pat.span.shrink_to_lo()), + _ => span_vec[0].until(span_vec[span_vec.len() - 2].shrink_to_lo()), + }; + + err.span_suggestion_verbose( + span, + "`self` should be `self`, `&self` or `&mut self`, consider removing extra references", + "".to_string(), + Applicability::MachineApplicable, + ); + + return None; + } // Also catches `fn foo(&a)`. PatKind::Ref(ref inner_pat, mutab) if let PatKind::Ident(_, ident, _) = inner_pat.clone().kind => diff --git a/tests/ui/self/lot-of-references-self.rs b/tests/ui/self/lot-of-references-self.rs new file mode 100644 index 000000000000..8f3e1a30616b --- /dev/null +++ b/tests/ui/self/lot-of-references-self.rs @@ -0,0 +1,28 @@ +struct A ; + +impl A { + fn a(&&self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn b(&&&&&&self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn c(&self) {} + fn d(&mut &self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn e(&mut &&&self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn f(&mut &mut &mut self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn g(&mut & &mut self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references + fn h(&mut & & & && & & self) {} + //~^ ERROR expected one of + //~| HELP `self` should be `self`, `&self` or `&mut self`, consider removing extra references +} + +fn main() {} diff --git a/tests/ui/self/lot-of-references-self.stderr b/tests/ui/self/lot-of-references-self.stderr new file mode 100644 index 000000000000..41a401eb1310 --- /dev/null +++ b/tests/ui/self/lot-of-references-self.stderr @@ -0,0 +1,86 @@ +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:4:16 + | +LL | fn a(&&self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn a(&&self) {} +LL + fn a(&self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:7:20 + | +LL | fn b(&&&&&&self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn b(&&&&&&self) {} +LL + fn b(&self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:11:20 + | +LL | fn d(&mut &self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn d(&mut &self) {} +LL + fn d(&self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:14:22 + | +LL | fn e(&mut &&&self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn e(&mut &&&self) {} +LL + fn e(&self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:17:29 + | +LL | fn f(&mut &mut &mut self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn f(&mut &mut &mut self) {} +LL + fn f(&mut self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:20:26 + | +LL | fn g(&mut & &mut self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn g(&mut & &mut self) {} +LL + fn g(&mut self) {} + | + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` + --> $DIR/lot-of-references-self.rs:23:39 + | +LL | fn h(&mut & & & && & & self) {} + | ^ expected one of 9 possible tokens + | +help: `self` should be `self`, `&self` or `&mut self`, consider removing extra references + | +LL - fn h(&mut & & & && & & self) {} +LL + fn h(& self) {} + | + +error: aborting due to 7 previous errors + From edc13e6b8e1d3da87ce0e71459f27de816715163 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Nov 2025 12:59:50 +0100 Subject: [PATCH 489/525] pthread: replace INIT_COOKIE by sync object metadata that gets cleared on writes --- src/tools/miri/src/concurrency/sync.rs | 157 +++++++++++++++--- src/tools/miri/src/machine.rs | 28 +++- src/tools/miri/src/shims/unix/freebsd/sync.rs | 4 +- .../miri/src/shims/unix/linux_like/sync.rs | 4 +- src/tools/miri/src/shims/unix/macos/sync.rs | 6 +- src/tools/miri/src/shims/unix/sync.rs | 144 +++++++++------- src/tools/miri/src/shims/windows/sync.rs | 6 +- .../libc_pthread_cond_double_destroy.rs | 2 +- .../libc_pthread_cond_move.init.stderr | 2 +- .../concurrency/libc_pthread_cond_move.rs | 4 +- ...thread_cond_move.static_initializer.stderr | 2 +- .../libc_pthread_mutex_double_destroy.rs | 2 +- .../libc_pthread_mutex_move.init.stderr | 2 +- .../concurrency/libc_pthread_mutex_move.rs | 4 +- ...hread_mutex_move.static_initializer.stderr | 2 +- .../libc_pthread_mutex_overwrite.rs | 14 ++ .../libc_pthread_mutex_overwrite.stderr | 13 ++ .../libc_pthread_rwlock_double_destroy.rs | 2 +- .../concurrency/libx_pthread_rwlock_moved.rs | 2 +- .../libx_pthread_rwlock_moved.stderr | 2 +- .../miri/tests/pass-dep/libc/pthread-sync.rs | 53 +++--- 21 files changed, 326 insertions(+), 129 deletions(-) create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.stderr diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 2ac68fa1eeb6..9197fe2756da 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -1,3 +1,4 @@ +use std::any::Any; use std::cell::RefCell; use std::collections::VecDeque; use std::collections::hash_map::Entry; @@ -5,6 +6,7 @@ use std::default::Default; use std::ops::Not; use std::rc::Rc; use std::time::Duration; +use std::{fmt, iter}; use rustc_abi::Size; use rustc_data_structures::fx::FxHashMap; @@ -12,6 +14,29 @@ use rustc_data_structures::fx::FxHashMap; use super::vector_clock::VClock; use crate::*; +/// A trait for the synchronization metadata that can be attached to a memory location. +pub trait SyncObj: Any { + /// Determines whether this object's metadata shall be deleted when a write to its + /// location occurs. + fn delete_on_write(&self) -> bool { + false + } +} + +impl dyn SyncObj { + #[inline(always)] + pub fn downcast_ref(&self) -> Option<&T> { + let x: &dyn Any = self; + x.downcast_ref() + } +} + +impl fmt::Debug for dyn SyncObj { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SyncObj").finish_non_exhaustive() + } +} + /// The mutex state. #[derive(Default, Debug)] struct Mutex { @@ -214,15 +239,15 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { impl<'tcx> AllocExtra<'tcx> { fn get_sync(&self, offset: Size) -> Option<&T> { - self.sync.get(&offset).and_then(|s| s.downcast_ref::()) + self.sync_objs.get(&offset).and_then(|s| s.downcast_ref::()) } } -/// We designate an `init`` field in all primitives. -/// If `init` is set to this, we consider the primitive initialized. +/// We designate an `init`` field in all synchronization objects. +/// If `init` is set to this, we consider the object initialized. pub const LAZY_INIT_COOKIE: u32 = 0xcafe_affe; -// Public interface to synchronization primitives. Please note that in most +// Public interface to synchronization objects. Please note that in most // cases, the function calls are infallible and it is the client's (shim // implementation's) responsibility to detect and deal with erroneous // situations. @@ -231,9 +256,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper for lazily initialized `alloc_extra.sync` data: /// this forces an immediate init. /// Return a reference to the data in the machine state. - fn lazy_sync_init<'a, T: 'static>( + fn lazy_sync_init<'a, T: SyncObj>( &'a mut self, - primitive: &MPlaceTy<'tcx>, + obj: &MPlaceTy<'tcx>, init_offset: Size, data: T, ) -> InterpResult<'tcx, &'a T> @@ -242,27 +267,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { { let this = self.eval_context_mut(); - let (alloc, offset, _) = this.ptr_get_alloc_id(primitive.ptr(), 0)?; - let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; - alloc_extra.sync.insert(offset, Box::new(data)); + let (alloc, offset, _) = this.ptr_get_alloc_id(obj.ptr(), 0)?; // Mark this as "initialized". let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); - assert!(init_offset + init_cookie.size() <= primitive.layout.size); - let init_field = primitive.offset(init_offset, this.machine.layouts.u32, this)?; + assert!(init_offset + init_cookie.size() <= obj.layout.size); + let init_field = obj.offset(init_offset, this.machine.layouts.u32, this)?; this.write_scalar_atomic(init_cookie, &init_field, AtomicWriteOrd::Relaxed)?; + // Insert sync obj, and return reference to it. + let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; + alloc_extra.sync_objs.insert(offset, Box::new(data)); interp_ok(this.get_alloc_extra(alloc)?.get_sync::(offset).unwrap()) } /// Helper for lazily initialized `alloc_extra.sync` data: - /// Checks if the primitive is initialized: + /// Checks if the synchronization object is initialized: /// - If yes, fetches the data from `alloc_extra.sync`, or calls `missing_data` if that fails /// and stores that in `alloc_extra.sync`. - /// - Otherwise, calls `new_data` to initialize the primitive. + /// - Otherwise, calls `new_data` to initialize the object. /// /// Return a reference to the data in the machine state. - fn lazy_sync_get_data<'a, T: 'static>( + fn lazy_sync_get_data<'a, T: SyncObj>( &'a mut self, - primitive: &MPlaceTy<'tcx>, + obj: &MPlaceTy<'tcx>, init_offset: Size, missing_data: impl FnOnce() -> InterpResult<'tcx, T>, new_data: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, T>, @@ -276,8 +302,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // thread initializing. Needs to be an RMW operation to ensure we read the *latest* value. // So we just try to replace MUTEX_INIT_COOKIE with itself. let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); - assert!(init_offset + init_cookie.size() <= primitive.layout.size); - let init_field = primitive.offset(init_offset, this.machine.layouts.u32, this)?; + assert!(init_offset + init_cookie.size() <= obj.layout.size); + let init_field = obj.offset(init_offset, this.machine.layouts.u32, this)?; let (_init, success) = this .atomic_compare_exchange_scalar( &init_field, @@ -290,27 +316,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { .to_scalar_pair(); if success.to_bool()? { - // If it is initialized, it must be found in the "sync primitive" table, + // If it is initialized, it must be found in the "sync obj" table, // or else it has been moved illegally. - let (alloc, offset, _) = this.ptr_get_alloc_id(primitive.ptr(), 0)?; + let (alloc, offset, _) = this.ptr_get_alloc_id(obj.ptr(), 0)?; let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; // Due to borrow checker reasons, we have to do the lookup twice. if alloc_extra.get_sync::(offset).is_none() { let data = missing_data()?; - alloc_extra.sync.insert(offset, Box::new(data)); + alloc_extra.sync_objs.insert(offset, Box::new(data)); } interp_ok(alloc_extra.get_sync::(offset).unwrap()) } else { let data = new_data(this)?; - this.lazy_sync_init(primitive, init_offset, data) + this.lazy_sync_init(obj, init_offset, data) } } - /// Get the synchronization primitive associated with the given pointer, + /// Get the synchronization object associated with the given pointer, /// or initialize a new one. /// /// Return `None` if this pointer does not point to at least 1 byte of mutable memory. - fn get_sync_or_init<'a, T: 'static>( + fn get_sync_or_init<'a, T: SyncObj>( &'a mut self, ptr: Pointer, new: impl FnOnce(&'a mut MiriMachine<'tcx>) -> T, @@ -331,11 +357,94 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Due to borrow checker reasons, we have to do the lookup twice. if alloc_extra.get_sync::(offset).is_none() { let new = new(machine); - alloc_extra.sync.insert(offset, Box::new(new)); + alloc_extra.sync_objs.insert(offset, Box::new(new)); } Some(alloc_extra.get_sync::(offset).unwrap()) } + /// Helper for "immovable" synchronization objects: the expected protocol for these objects is + /// that they use a static initializer of `uninit_val`, and we set them to `init_val` upon + /// initialization. At that point we also register a synchronization object, which is expected + /// to have `delete_on_write() == true`. So in the future, if we still see the object, we know + /// the location must still contain `init_val`. If the object is copied somewhere, that will + /// show up as a non-`init_val` value without a synchronization object, which we can then use to + /// error. + /// + /// `new_meta_obj` gets invoked when there is not yet an initialization object. + /// It has to ensure that the in-memory representation indeed matches `uninit_val`. + fn get_immovable_sync_with_static_init<'a, T: SyncObj>( + &'a mut self, + obj: &MPlaceTy<'tcx>, + init_offset: Size, + uninit_val: u8, + init_val: u8, + new_meta_obj: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, T>, + ) -> InterpResult<'tcx, &'a T> + where + 'tcx: 'a, + { + let this = self.eval_context_mut(); + this.check_ptr_access(obj.ptr(), obj.layout.size, CheckInAllocMsg::Dereferenceable)?; + assert!(init_offset < obj.layout.size); // ensure our 1-byte flag fits + let init_field = obj.offset(init_offset, this.machine.layouts.u8, this)?; + + let (alloc, offset, _) = this.ptr_get_alloc_id(init_field.ptr(), 0)?; + let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; + // Due to borrow checker reasons, we have to do the lookup twice. + if alloc_extra.get_sync::(offset).is_some() { + let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc).unwrap(); + return interp_ok(alloc_extra.get_sync::(offset).unwrap()); + } + + // There's no sync object there yet. Create one, and try a CAS for uninit_val to init_val. + let meta_obj = new_meta_obj(this)?; + let (_init, success) = this + .atomic_compare_exchange_scalar( + &init_field, + &ImmTy::from_scalar(Scalar::from_u8(uninit_val), this.machine.layouts.u8), + Scalar::from_u8(init_val), + AtomicRwOrd::Relaxed, + AtomicReadOrd::Relaxed, + /* can_fail_spuriously */ false, + )? + .to_scalar_pair(); + assert!(success.to_bool()?, "`new_meta_obj` should have ensured that this CAS succeeds."); + + let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc).unwrap(); + assert!(meta_obj.delete_on_write()); + alloc_extra.sync_objs.insert(offset, Box::new(meta_obj)); + interp_ok(alloc_extra.get_sync::(offset).unwrap()) + } + + /// Explicitly initializes an object that would usually be implicitly initialized with + /// `get_immovable_sync_with_static_init`. + fn init_immovable_sync<'a, T: SyncObj>( + &'a mut self, + obj: &MPlaceTy<'tcx>, + init_offset: Size, + init_val: u8, + new_meta_obj: T, + ) -> InterpResult<'tcx, Option<&'a T>> + where + 'tcx: 'a, + { + let this = self.eval_context_mut(); + this.check_ptr_access(obj.ptr(), obj.layout.size, CheckInAllocMsg::Dereferenceable)?; + assert!(init_offset < obj.layout.size); // ensure our 1-byte flag fits + let init_field = obj.offset(init_offset, this.machine.layouts.u8, this)?; + + // Zero the entire object, and then store `init_val` directly. + this.write_bytes_ptr(obj.ptr(), iter::repeat_n(0, obj.layout.size.bytes_usize()))?; + this.write_scalar(Scalar::from_u8(init_val), &init_field)?; + + // Create meta-level initialization object. + let (alloc, offset, _) = this.ptr_get_alloc_id(init_field.ptr(), 0)?; + let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc).unwrap(); + assert!(new_meta_obj.delete_on_write()); + alloc_extra.sync_objs.insert(offset, Box::new(new_meta_obj)); + interp_ok(Some(alloc_extra.get_sync::(offset).unwrap())) + } + /// Lock by setting the mutex owner and increasing the lock count. fn mutex_lock(&mut self, mutex_ref: &MutexRef) -> InterpResult<'tcx> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index e91b8d97ef72..07a9e497161c 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1,9 +1,9 @@ //! Global machine state as well as implementation of the interpreter engine //! `Machine` trait. -use std::any::Any; use std::borrow::Cow; use std::cell::{Cell, RefCell}; +use std::collections::BTreeMap; use std::path::Path; use std::rc::Rc; use std::{fmt, process}; @@ -36,6 +36,7 @@ use rustc_target::spec::Arch; use crate::alloc_addresses::EvalContextExt; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; use crate::concurrency::data_race::{self, NaReadType, NaWriteType}; +use crate::concurrency::sync::SyncObj; use crate::concurrency::{ AllocDataRaceHandler, GenmcCtx, GenmcEvalContextExt as _, GlobalDataRaceHandler, weak_memory, }; @@ -399,11 +400,11 @@ pub struct AllocExtra<'tcx> { /// if this allocation is leakable. The backtrace is not /// pruned yet; that should be done before printing it. pub backtrace: Option>>, - /// Synchronization primitives like to attach extra data to particular addresses. We store that + /// Synchronization objects like to attach extra data to particular addresses. We store that /// inside the relevant allocation, to ensure that everything is removed when the allocation is /// freed. /// This maps offsets to synchronization-primitive-specific data. - pub sync: FxHashMap>, + pub sync_objs: BTreeMap>, } // We need a `Clone` impl because the machine passes `Allocation` through `Cow`... @@ -416,7 +417,7 @@ impl<'tcx> Clone for AllocExtra<'tcx> { impl VisitProvenance for AllocExtra<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { - let AllocExtra { borrow_tracker, data_race, backtrace: _, sync: _ } = self; + let AllocExtra { borrow_tracker, data_race, backtrace: _, sync_objs: _ } = self; borrow_tracker.visit_provenance(visit); data_race.visit_provenance(visit); @@ -991,7 +992,12 @@ impl<'tcx> MiriMachine<'tcx> { .insert(id, (ecx.machine.current_user_relevant_span(), None)); } - interp_ok(AllocExtra { borrow_tracker, data_race, backtrace, sync: FxHashMap::default() }) + interp_ok(AllocExtra { + borrow_tracker, + data_race, + backtrace, + sync_objs: BTreeMap::default(), + }) } } @@ -1581,6 +1587,18 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if let Some(borrow_tracker) = &mut alloc_extra.borrow_tracker { borrow_tracker.before_memory_write(alloc_id, prov_extra, range, machine)?; } + // Delete sync objects that don't like writes. + // Most of the time, we can just skip this. + if !alloc_extra.sync_objs.is_empty() { + let to_delete = alloc_extra + .sync_objs + .range(range.start..range.end()) + .filter_map(|(offset, obj)| obj.delete_on_write().then_some(*offset)) + .collect::>(); + for offset in to_delete { + alloc_extra.sync_objs.remove(&offset); + } + } interp_ok(()) } diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs index 13d30e05573a..bd1ee3155372 100644 --- a/src/tools/miri/src/shims/unix/freebsd/sync.rs +++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs @@ -4,13 +4,15 @@ use core::time::Duration; use rustc_abi::FieldIdx; -use crate::concurrency::sync::FutexRef; +use crate::concurrency::sync::{FutexRef, SyncObj}; use crate::*; pub struct FreeBsdFutex { futex: FutexRef, } +impl SyncObj for FreeBsdFutex {} + /// Extended variant of the `timespec` struct. pub struct UmtxTime { timeout: Duration, diff --git a/src/tools/miri/src/shims/unix/linux_like/sync.rs b/src/tools/miri/src/shims/unix/linux_like/sync.rs index 5f032c52deeb..8ff7fe0a4563 100644 --- a/src/tools/miri/src/shims/unix/linux_like/sync.rs +++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs @@ -1,4 +1,4 @@ -use crate::concurrency::sync::FutexRef; +use crate::concurrency::sync::{FutexRef, SyncObj}; use crate::shims::sig::check_min_vararg_count; use crate::*; @@ -6,6 +6,8 @@ struct LinuxFutex { futex: FutexRef, } +impl SyncObj for LinuxFutex {} + /// Implementation of the SYS_futex syscall. /// `args` is the arguments *including* the syscall number. pub fn futex<'tcx>( diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index c4ddff7805ed..33af86937392 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -15,7 +15,7 @@ use std::time::Duration; use rustc_abi::Size; -use crate::concurrency::sync::FutexRef; +use crate::concurrency::sync::{FutexRef, SyncObj}; use crate::*; #[derive(Clone)] @@ -24,6 +24,8 @@ enum MacOsUnfairLock { Active { mutex_ref: MutexRef }, } +impl SyncObj for MacOsUnfairLock {} + pub enum MacOsFutexTimeout<'a, 'tcx> { None, Relative { clock_op: &'a OpTy<'tcx>, timeout_op: &'a OpTy<'tcx> }, @@ -44,6 +46,8 @@ struct MacOsFutex { shared: Cell, } +impl SyncObj for MacOsFutex {} + impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn os_unfair_lock_get_data<'a>( diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index a712279d5762..bb1b97ff8ad1 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -1,13 +1,11 @@ use rustc_abi::Size; -use crate::concurrency::sync::LAZY_INIT_COOKIE; +use crate::concurrency::sync::SyncObj; use crate::*; -/// Do a bytewise comparison of the two places, using relaxed atomic reads. This is used to check if +/// Do a bytewise comparison of the two places. This is used to check if /// a synchronization primitive matches its static initializer value. -/// -/// The reads happen in chunks of 4, so all racing accesses must also use that access size. -fn bytewise_equal_atomic_relaxed<'tcx>( +fn bytewise_equal<'tcx>( ecx: &MiriInterpCx<'tcx>, left: &MPlaceTy<'tcx>, right: &MPlaceTy<'tcx>, @@ -15,25 +13,16 @@ fn bytewise_equal_atomic_relaxed<'tcx>( let size = left.layout.size; assert_eq!(size, right.layout.size); - // We do this in chunks of 4, so that we are okay to race with (sufficiently aligned) - // 4-byte atomic accesses. - assert!(size.bytes().is_multiple_of(4)); - for i in 0..(size.bytes() / 4) { - let offset = Size::from_bytes(i.strict_mul(4)); - let load = |place: &MPlaceTy<'tcx>| { - let byte = place.offset(offset, ecx.machine.layouts.u32, ecx)?; - ecx.read_scalar_atomic(&byte, AtomicReadOrd::Relaxed)?.to_u32() - }; - let left = load(left)?; - let right = load(right)?; - if left != right { - return interp_ok(false); - } - } + let left_bytes = ecx.read_bytes_ptr_strip_provenance(left.ptr(), size)?; + let right_bytes = ecx.read_bytes_ptr_strip_provenance(right.ptr(), size)?; - interp_ok(true) + interp_ok(left_bytes == right_bytes) } +// The in-memory marker values we use to indicate whether objects have been initialized. +const PTHREAD_UNINIT: u8 = 0; +const PTHREAD_INIT: u8 = 1; + // # pthread_mutexattr_t // We store some data directly inside the type, ignoring the platform layout: // - kind: i32 @@ -103,7 +92,7 @@ fn mutexattr_translate_kind<'tcx>( // # pthread_mutex_t // We store some data directly inside the type, ignoring the platform layout: -// - init: u32 +// - init: u8 /// The mutex kind. #[derive(Debug, Clone, Copy)] @@ -120,6 +109,12 @@ struct PthreadMutex { kind: MutexKind, } +impl SyncObj for PthreadMutex { + fn delete_on_write(&self) -> bool { + true + } +} + /// To ensure an initialized mutex that was moved somewhere else can be distinguished from /// a statically initialized mutex that is used the first time, we pick some offset within /// `pthread_mutex_t` and use it as an "initialized" flag. @@ -138,11 +133,11 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> let check_static_initializer = |name| { let static_initializer = ecx.eval_path(&["libc", name]); let init_field = - static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap(); - let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap(); - assert_ne!( - init, LAZY_INIT_COOKIE, - "{name} is incompatible with our initialization cookie" + static_initializer.offset(offset, ecx.machine.layouts.u8, ecx).unwrap(); + let init = ecx.read_scalar(&init_field).unwrap().to_u8().unwrap(); + assert_eq!( + init, PTHREAD_UNINIT, + "{name} is incompatible with our initialization logic" ); }; @@ -172,7 +167,7 @@ fn mutex_create<'tcx>( ) -> InterpResult<'tcx, PthreadMutex> { let mutex = ecx.deref_pointer_as(mutex_ptr, ecx.libc_ty_layout("pthread_mutex_t"))?; let data = PthreadMutex { mutex_ref: MutexRef::new(), kind }; - ecx.lazy_sync_init(&mutex, mutex_init_offset(ecx)?, data.clone())?; + ecx.init_immovable_sync(&mutex, mutex_init_offset(ecx)?, PTHREAD_INIT, data.clone())?; interp_ok(data) } @@ -186,10 +181,11 @@ where 'tcx: 'a, { let mutex = ecx.deref_pointer_as(mutex_ptr, ecx.libc_ty_layout("pthread_mutex_t"))?; - ecx.lazy_sync_get_data( + ecx.get_immovable_sync_with_static_init( &mutex, mutex_init_offset(ecx)?, - || throw_ub_format!("`pthread_mutex_t` can't be moved after first use"), + PTHREAD_UNINIT, + PTHREAD_INIT, |ecx| { let kind = mutex_kind_from_static_initializer(ecx, &mutex)?; interp_ok(PthreadMutex { mutex_ref: MutexRef::new(), kind }) @@ -203,8 +199,7 @@ fn mutex_kind_from_static_initializer<'tcx>( mutex: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, MutexKind> { // All the static initializers recognized here *must* be checked in `mutex_init_offset`! - let is_initializer = - |name| bytewise_equal_atomic_relaxed(ecx, mutex, &ecx.eval_path(&["libc", name])); + let is_initializer = |name| bytewise_equal(ecx, mutex, &ecx.eval_path(&["libc", name])); // PTHREAD_MUTEX_INITIALIZER is recognized on all targets. if is_initializer("PTHREAD_MUTEX_INITIALIZER")? { @@ -220,18 +215,26 @@ fn mutex_kind_from_static_initializer<'tcx>( }, _ => {} } - throw_unsup_format!("unsupported static initializer used for `pthread_mutex_t`"); + throw_ub_format!( + "`pthread_mutex_t` was not properly initialized at this location, or it got overwritten" + ); } // # pthread_rwlock_t // We store some data directly inside the type, ignoring the platform layout: -// - init: u32 +// - init: u8 #[derive(Debug, Clone)] struct PthreadRwLock { rwlock_ref: RwLockRef, } +impl SyncObj for PthreadRwLock { + fn delete_on_write(&self) -> bool { + true + } +} + fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { let offset = match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0, @@ -245,11 +248,11 @@ fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size // the `init` field must start out not equal to LAZY_INIT_COOKIE. if !ecx.machine.pthread_rwlock_sanity.replace(true) { let static_initializer = ecx.eval_path(&["libc", "PTHREAD_RWLOCK_INITIALIZER"]); - let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap(); - let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap(); - assert_ne!( - init, LAZY_INIT_COOKIE, - "PTHREAD_RWLOCK_INITIALIZER is incompatible with our initialization cookie" + let init_field = static_initializer.offset(offset, ecx.machine.layouts.u8, ecx).unwrap(); + let init = ecx.read_scalar(&init_field).unwrap().to_u8().unwrap(); + assert_eq!( + init, PTHREAD_UNINIT, + "PTHREAD_RWLOCK_INITIALIZER is incompatible with our initialization logic" ); } @@ -264,17 +267,20 @@ where 'tcx: 'a, { let rwlock = ecx.deref_pointer_as(rwlock_ptr, ecx.libc_ty_layout("pthread_rwlock_t"))?; - ecx.lazy_sync_get_data( + ecx.get_immovable_sync_with_static_init( &rwlock, rwlock_init_offset(ecx)?, - || throw_ub_format!("`pthread_rwlock_t` can't be moved after first use"), + PTHREAD_UNINIT, + PTHREAD_INIT, |ecx| { - if !bytewise_equal_atomic_relaxed( + if !bytewise_equal( ecx, &rwlock, &ecx.eval_path(&["libc", "PTHREAD_RWLOCK_INITIALIZER"]), )? { - throw_unsup_format!("unsupported static initializer used for `pthread_rwlock_t`"); + throw_ub_format!( + "`pthread_rwlock_t` was not properly initialized at this location, or it got overwritten" + ); } interp_ok(PthreadRwLock { rwlock_ref: RwLockRef::new() }) }, @@ -322,7 +328,7 @@ fn condattr_set_clock_id<'tcx>( // # pthread_cond_t // We store some data directly inside the type, ignoring the platform layout: -// - init: u32 +// - init: u8 fn cond_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { let offset = match &*ecx.tcx.sess.target.os { @@ -337,11 +343,11 @@ fn cond_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> // the `init` field must start out not equal to LAZY_INIT_COOKIE. if !ecx.machine.pthread_condvar_sanity.replace(true) { let static_initializer = ecx.eval_path(&["libc", "PTHREAD_COND_INITIALIZER"]); - let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap(); - let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap(); - assert_ne!( - init, LAZY_INIT_COOKIE, - "PTHREAD_COND_INITIALIZER is incompatible with our initialization cookie" + let init_field = static_initializer.offset(offset, ecx.machine.layouts.u8, ecx).unwrap(); + let init = ecx.read_scalar(&init_field).unwrap().to_u8().unwrap(); + assert_eq!( + init, PTHREAD_UNINIT, + "PTHREAD_COND_INITIALIZER is incompatible with our initialization logic" ); } @@ -354,6 +360,12 @@ struct PthreadCondvar { clock: TimeoutClock, } +impl SyncObj for PthreadCondvar { + fn delete_on_write(&self) -> bool { + true + } +} + fn cond_create<'tcx>( ecx: &mut MiriInterpCx<'tcx>, cond_ptr: &OpTy<'tcx>, @@ -361,7 +373,7 @@ fn cond_create<'tcx>( ) -> InterpResult<'tcx, PthreadCondvar> { let cond = ecx.deref_pointer_as(cond_ptr, ecx.libc_ty_layout("pthread_cond_t"))?; let data = PthreadCondvar { condvar_ref: CondvarRef::new(), clock }; - ecx.lazy_sync_init(&cond, cond_init_offset(ecx)?, data.clone())?; + ecx.init_immovable_sync(&cond, cond_init_offset(ecx)?, PTHREAD_INIT, data.clone())?; interp_ok(data) } @@ -373,17 +385,20 @@ where 'tcx: 'a, { let cond = ecx.deref_pointer_as(cond_ptr, ecx.libc_ty_layout("pthread_cond_t"))?; - ecx.lazy_sync_get_data( + ecx.get_immovable_sync_with_static_init( &cond, cond_init_offset(ecx)?, - || throw_ub_format!("`pthread_cond_t` can't be moved after first use"), + PTHREAD_UNINIT, + PTHREAD_INIT, |ecx| { - if !bytewise_equal_atomic_relaxed( + if !bytewise_equal( ecx, &cond, &ecx.eval_path(&["libc", "PTHREAD_COND_INITIALIZER"]), )? { - throw_unsup_format!("unsupported static initializer used for `pthread_cond_t`"); + throw_ub_format!( + "`pthread_cond_t` was not properly initialized at this location, or it got overwritten" + ); } // This used the static initializer. The clock there is always CLOCK_REALTIME. interp_ok(PthreadCondvar { @@ -575,11 +590,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_ub_format!("destroyed a locked mutex"); } + // This write also deletes the interpreter state for this mutex. // This might lead to false positives, see comment in pthread_mutexattr_destroy - this.write_uninit( - &this.deref_pointer_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?, - )?; - // FIXME: delete interpreter state associated with this mutex. + let mutex_place = + this.deref_pointer_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?; + this.write_uninit(&mutex_place)?; interp_ok(()) } @@ -693,11 +708,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_ub_format!("destroyed a locked rwlock"); } + // This write also deletes the interpreter state for this rwlock. // This might lead to false positives, see comment in pthread_mutexattr_destroy - this.write_uninit( - &this.deref_pointer_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?, - )?; - // FIXME: delete interpreter state associated with this rwlock. + let rwlock_place = + this.deref_pointer_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?; + this.write_uninit(&rwlock_place)?; interp_ok(()) } @@ -889,9 +904,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_ub_format!("destroying an awaited conditional variable"); } + // This write also deletes the interpreter state for this mutex. // This might lead to false positives, see comment in pthread_mutexattr_destroy - this.write_uninit(&this.deref_pointer_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?)?; - // FIXME: delete interpreter state associated with this condvar. + let cond_place = this.deref_pointer_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?; + this.write_uninit(&cond_place)?; interp_ok(()) } diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index a893999ef8e5..72080c92b7cd 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -3,7 +3,7 @@ use std::time::Duration; use rustc_abi::Size; use crate::concurrency::init_once::{EvalContextExt as _, InitOnceStatus}; -use crate::concurrency::sync::FutexRef; +use crate::concurrency::sync::{FutexRef, SyncObj}; use crate::*; #[derive(Clone)] @@ -11,10 +11,14 @@ struct WindowsInitOnce { init_once: InitOnceRef, } +impl SyncObj for WindowsInitOnce {} + struct WindowsFutex { futex: FutexRef, } +impl SyncObj for WindowsFutex {} + impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Windows sync primitives are pointer sized. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs index 5778765589de..5d5ffded5c5c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs @@ -1,6 +1,6 @@ //@ignore-target: windows # No pthreads on Windows //@ normalize-stderr-test: "(\n)ALLOC \(.*\) \{\n(.*\n)*\}(\n)" -> "${1}ALLOC DUMP${3}" -//@ normalize-stderr-test: "\[0x[0-9a-z]..0x[0-9a-z]\]" -> "[0xX..0xY]" +//@ normalize-stderr-test: "\[0x[0-9a-z]+..0x[0-9a-z]+\]" -> "[0xX..0xY]" /// Test that destroying a pthread_cond twice fails, even without a check for number validity diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr index 9a7f0bb79e5f..f3f64a60a89b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: `pthread_cond_t` can't be moved after first use +error: Undefined Behavior: `pthread_cond_t` was not properly initialized at this location, or it got overwritten --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC | LL | libc::pthread_cond_destroy(cond2.as_mut_ptr()); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.rs index 4db904ab5e22..ef20a53dd2f1 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.rs @@ -18,7 +18,7 @@ fn check() { // move pthread_cond_t let mut cond2 = cond; - libc::pthread_cond_destroy(cond2.as_mut_ptr()); //~[init] ERROR: can't be moved after first use + libc::pthread_cond_destroy(cond2.as_mut_ptr()); //~[init] ERROR: not properly initialized } } @@ -32,6 +32,6 @@ fn check() { // move pthread_cond_t let mut cond2 = cond; - libc::pthread_cond_destroy(&mut cond2 as *mut _); //~[static_initializer] ERROR: can't be moved after first use + libc::pthread_cond_destroy(&mut cond2 as *mut _); //~[static_initializer] ERROR: not properly initialized } } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr index ee1fafcf7cb1..4056f7d9d41b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: `pthread_cond_t` can't be moved after first use +error: Undefined Behavior: `pthread_cond_t` was not properly initialized at this location, or it got overwritten --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC | LL | libc::pthread_cond_destroy(&mut cond2 as *mut _); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs index f04fe8be6b38..45d16e173d9a 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs @@ -1,6 +1,6 @@ //@ignore-target: windows # No pthreads on Windows //@ normalize-stderr-test: "(\n)ALLOC \(.*\) \{\n(.*\n)*\}(\n)" -> "${1}ALLOC DUMP${3}" -//@ normalize-stderr-test: "\[0x[0-9a-z]..0x[0-9a-z]\]" -> "[0xX..0xY]" +//@ normalize-stderr-test: "\[0x[0-9a-z]+..0x[0-9a-z]+\]" -> "[0xX..0xY]" /// Test that destroying a pthread_mutex twice fails, even without a check for number validity diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr index 2e8e411e186a..a7cba0f00fe9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: `pthread_mutex_t` can't be moved after first use +error: Undefined Behavior: `pthread_mutex_t` was not properly initialized at this location, or it got overwritten --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC | LL | libc::pthread_mutex_lock(&mut m2 as *mut _); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.rs index 6c1f967b2b03..028c6ec34dc9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.rs @@ -12,7 +12,7 @@ fn check() { assert_eq!(libc::pthread_mutex_init(&mut m as *mut _, std::ptr::null()), 0); let mut m2 = m; // move the mutex - libc::pthread_mutex_lock(&mut m2 as *mut _); //~[init] ERROR: can't be moved after first use + libc::pthread_mutex_lock(&mut m2 as *mut _); //~[init] ERROR: not properly initialized } } @@ -23,6 +23,6 @@ fn check() { libc::pthread_mutex_lock(&mut m as *mut _); let mut m2 = m; // move the mutex - libc::pthread_mutex_unlock(&mut m2 as *mut _); //~[static_initializer] ERROR: can't be moved after first use + libc::pthread_mutex_unlock(&mut m2 as *mut _); //~[static_initializer] ERROR: not properly initialized } } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr index 4fd3bd52ae12..71f71efa0d96 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: `pthread_mutex_t` can't be moved after first use +error: Undefined Behavior: `pthread_mutex_t` was not properly initialized at this location, or it got overwritten --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC | LL | libc::pthread_mutex_unlock(&mut m2 as *mut _); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.rs new file mode 100644 index 000000000000..95b934ab1b72 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.rs @@ -0,0 +1,14 @@ +//@ignore-target: windows # No pthreads on Windows + +fn main() { + unsafe { + let mut m: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; + libc::pthread_mutex_lock(&mut m as *mut _); + + // Overwrite the mutex with itself. This de-initializes it. + let copy = m; + m = copy; + + libc::pthread_mutex_unlock(&mut m as *mut _); //~ERROR: not properly initialized + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.stderr new file mode 100644 index 000000000000..b44792285421 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: `pthread_mutex_t` was not properly initialized at this location, or it got overwritten + --> tests/fail-dep/concurrency/libc_pthread_mutex_overwrite.rs:LL:CC + | +LL | libc::pthread_mutex_unlock(&mut m as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs index 720ba71d2383..3d59d8e39937 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs @@ -1,6 +1,6 @@ //@ignore-target: windows # No pthreads on Windows //@ normalize-stderr-test: "(\n)ALLOC \(.*\) \{\n(.*\n)*\}(\n)" -> "${1}ALLOC DUMP${3}" -//@ normalize-stderr-test: "\[0x[0-9a-z]..0x[0-9a-z]\]" -> "[0xX..0xY]" +//@ normalize-stderr-test: "\[0x[0-9a-z]+..0x[0-9a-z]+\]" -> "[0xX..0xY]" /// Test that destroying a pthread_rwlock twice fails, even without a check for number validity diff --git a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs index 6af19b7df9b5..fe507f63ec4e 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs @@ -9,6 +9,6 @@ fn main() { // Move rwlock let mut rw2 = rw; - libc::pthread_rwlock_unlock(&mut rw2 as *mut _); //~ ERROR: can't be moved after first use + libc::pthread_rwlock_unlock(&mut rw2 as *mut _); //~ ERROR: not properly initialized } } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr index e69da4de99dd..0625708c256b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libx_pthread_rwlock_moved.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: `pthread_rwlock_t` can't be moved after first use +error: Undefined Behavior: `pthread_rwlock_t` was not properly initialized at this location, or it got overwritten --> tests/fail-dep/concurrency/libx_pthread_rwlock_moved.rs:LL:CC | LL | libc::pthread_rwlock_unlock(&mut rw2 as *mut _); diff --git a/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs index 255944662940..a79d0656d85c 100644 --- a/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs +++ b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs @@ -8,18 +8,21 @@ use std::mem::MaybeUninit; use std::{mem, ptr, thread}; fn main() { + test_mutex(); test_mutex_libc_init_recursive(); test_mutex_libc_init_normal(); test_mutex_libc_init_errorcheck(); - test_rwlock_libc_static_initializer(); #[cfg(target_os = "linux")] test_mutex_libc_static_initializer_recursive(); + #[cfg(target_os = "linux")] + test_mutex_libc_static_initializer_errorcheck(); - check_mutex(); - check_rwlock_write(); - check_rwlock_read_no_deadlock(); - check_cond(); - check_condattr(); + test_cond(); + test_condattr(); + + test_rwlock(); + test_rwlock_write(); + test_rwlock_read_no_deadlock(); } // We want to only use pthread APIs here for easier testing. @@ -107,8 +110,7 @@ fn test_mutex_libc_init_errorcheck() { } } -// Only linux provides PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, -// libc for macOS just has the default PTHREAD_MUTEX_INITIALIZER. +// Only linux provides PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP. #[cfg(target_os = "linux")] fn test_mutex_libc_static_initializer_recursive() { let mutex = std::cell::UnsafeCell::new(libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); @@ -126,6 +128,22 @@ fn test_mutex_libc_static_initializer_recursive() { } } +// Only linux provides PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP. +#[cfg(target_os = "linux")] +fn test_mutex_libc_static_initializer_errorcheck() { + let mutex = std::cell::UnsafeCell::new(libc::PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP); + unsafe { + assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_trylock(mutex.get()), libc::EBUSY); + assert_eq!(libc::pthread_mutex_lock(mutex.get()), libc::EDEADLK); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), libc::EPERM); + assert_eq!(libc::pthread_mutex_destroy(mutex.get()), 0); + } +} + struct SendPtr { ptr: *mut T, } @@ -137,7 +155,7 @@ impl Clone for SendPtr { } } -fn check_mutex() { +fn test_mutex() { let bomb = AbortOnDrop; // Specifically *not* using `Arc` to make sure there is no synchronization apart from the mutex. unsafe { @@ -168,7 +186,7 @@ fn check_mutex() { bomb.defuse(); } -fn check_rwlock_write() { +fn test_rwlock_write() { let bomb = AbortOnDrop; unsafe { let data = SyncUnsafeCell::new((libc::PTHREAD_RWLOCK_INITIALIZER, 0)); @@ -209,7 +227,7 @@ fn check_rwlock_write() { bomb.defuse(); } -fn check_rwlock_read_no_deadlock() { +fn test_rwlock_read_no_deadlock() { let bomb = AbortOnDrop; unsafe { let l1 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); @@ -237,12 +255,11 @@ fn check_rwlock_read_no_deadlock() { bomb.defuse(); } -fn check_cond() { +fn test_cond() { let bomb = AbortOnDrop; unsafe { - let mut cond: MaybeUninit = MaybeUninit::uninit(); - assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), ptr::null()), 0); - let cond = SendPtr { ptr: cond.as_mut_ptr() }; + let mut cond: libc::pthread_cond_t = libc::PTHREAD_COND_INITIALIZER; + let cond = SendPtr { ptr: &mut cond }; let mut mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; let mutex = SendPtr { ptr: &mut mutex }; @@ -286,7 +303,7 @@ fn check_cond() { bomb.defuse(); } -fn check_condattr() { +fn test_condattr() { unsafe { // Just smoke-testing that these functions can be called. let mut attr: MaybeUninit = MaybeUninit::uninit(); @@ -311,9 +328,7 @@ fn check_condattr() { } } -// std::sync::RwLock does not even used pthread_rwlock any more. -// Do some smoke testing of the API surface. -fn test_rwlock_libc_static_initializer() { +fn test_rwlock() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); From ba789c6eb54a655bb8aa3e40ff7fba397aa33d7b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Nov 2025 13:58:02 +0100 Subject: [PATCH 490/525] also use new sync obj metadata scheme for INIT_ONCE and os_unfair_lock --- src/tools/miri/src/concurrency/sync.rs | 18 ++++++- src/tools/miri/src/shims/unix/macos/sync.rs | 51 ++++++++++++------- src/tools/miri/src/shims/windows/sync.rs | 26 +++++++--- .../concurrency/apple-os-unfair-lock.rs | 12 ++--- 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 9197fe2756da..81c81b02de9b 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -372,6 +372,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// /// `new_meta_obj` gets invoked when there is not yet an initialization object. /// It has to ensure that the in-memory representation indeed matches `uninit_val`. + /// + /// The point of storing an `init_val` is so that if this memory gets copied somewhere else, + /// it does not look like the static initializer (i.e., `uninit_val`) any more. For some + /// objects we could just entirely forbid reading their bytes to ensure they don't get copied, + /// but that does not work for objects without a destructor (Windows `InitOnce`, macOS + /// `os_unfair_lock`). fn get_immovable_sync_with_static_init<'a, T: SyncObj>( &'a mut self, obj: &MPlaceTy<'tcx>, @@ -383,6 +389,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { where 'tcx: 'a, { + assert!(init_val != uninit_val); let this = self.eval_context_mut(); this.check_ptr_access(obj.ptr(), obj.layout.size, CheckInAllocMsg::Dereferenceable)?; assert!(init_offset < obj.layout.size); // ensure our 1-byte flag fits @@ -398,7 +405,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // There's no sync object there yet. Create one, and try a CAS for uninit_val to init_val. let meta_obj = new_meta_obj(this)?; - let (_init, success) = this + let (old_init, success) = this .atomic_compare_exchange_scalar( &init_field, &ImmTy::from_scalar(Scalar::from_u8(uninit_val), this.machine.layouts.u8), @@ -408,7 +415,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /* can_fail_spuriously */ false, )? .to_scalar_pair(); - assert!(success.to_bool()?, "`new_meta_obj` should have ensured that this CAS succeeds."); + if !success.to_bool()? { + // This can happen for the macOS lock if it is already marked as initialized. + assert_eq!( + old_init.to_u8()?, + init_val, + "`new_meta_obj` should have ensured that this CAS succeeds" + ); + } let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc).unwrap(); assert!(meta_obj.delete_on_write()); diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index 33af86937392..4024ddc09731 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -13,18 +13,22 @@ use std::cell::Cell; use std::time::Duration; -use rustc_abi::Size; +use rustc_abi::{Endian, FieldIdx, Size}; use crate::concurrency::sync::{FutexRef, SyncObj}; use crate::*; #[derive(Clone)] enum MacOsUnfairLock { - Poisoned, Active { mutex_ref: MutexRef }, + PermanentlyLocked, } -impl SyncObj for MacOsUnfairLock {} +impl SyncObj for MacOsUnfairLock { + fn delete_on_write(&self) -> bool { + true + } +} pub enum MacOsFutexTimeout<'a, 'tcx> { None, @@ -57,22 +61,35 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { where 'tcx: 'a, { + // `os_unfair_lock_s` wraps a single `u32` field. We use the first byte to store the "init" + // flag. Due to macOS always being little endian, that's the least significant byte. let this = self.eval_context_mut(); + assert!(this.tcx.data_layout.endian == Endian::Little); + let lock = this.deref_pointer_as(lock_ptr, this.libc_ty_layout("os_unfair_lock_s"))?; - this.lazy_sync_get_data( + this.get_immovable_sync_with_static_init( &lock, Size::ZERO, // offset for init tracking - || { - // If we get here, due to how we reset things to zero in `os_unfair_lock_unlock`, - // this means the lock was moved while locked. This can happen with a `std` lock, - // but then any future attempt to unlock will just deadlock. In practice, terrible - // things can probably happen if you swap two locked locks, since they'd wake up - // from the wrong queue... we just won't catch all UB of this library API then (we - // would need to store some unique identifer in-memory for this, instead of a static - // LAZY_INIT_COOKIE). This can't be hit via `std::sync::Mutex`. - interp_ok(MacOsUnfairLock::Poisoned) + /* uninit_val */ 0, + /* init_val */ 1, + |this| { + let field = this.project_field(&lock, FieldIdx::from_u32(0))?; + let val = this.read_scalar(&field)?.to_u32()?; + if val == 0 { + interp_ok(MacOsUnfairLock::Active { mutex_ref: MutexRef::new() }) + } else if val == 1 { + // This is a lock that got copied while it is initialized. We de-initialize + // locks when they get released, so it got copied while locked. Unfortunately + // that is something `std` needs to support (the guard could have been leaked). + // So we behave like a futex-based lock whose wait queue got pruned: any attempt + // to acquire the lock will just wait forever. + // In practice there actually could be a wait queue there, if someone moves a + // lock *while threads are queued*; this is UB we will not detect. + interp_ok(MacOsUnfairLock::PermanentlyLocked) + } else { + throw_ub_format!("`os_unfair_lock` was not properly initialized at this location, or it got overwritten"); + } }, - |_| interp_ok(MacOsUnfairLock::Active { mutex_ref: MutexRef::new() }), ) } } @@ -336,7 +353,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { - // The lock is poisoned, who knows who owns it... we'll pretend: someone else. + // A perma-locked lock is definitely not held by us. throw_machine_stop!(TerminationInfo::Abort( "attempted to unlock an os_unfair_lock not owned by the current thread".to_owned() )); @@ -365,7 +382,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { - // The lock is poisoned, who knows who owns it... we'll pretend: someone else. + // A perma-locked lock is definitely not held by us. throw_machine_stop!(TerminationInfo::Abort( "called os_unfair_lock_assert_owner on an os_unfair_lock not owned by the current thread".to_owned() )); @@ -387,7 +404,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let MacOsUnfairLock::Active { mutex_ref } = this.os_unfair_lock_get_data(lock_op)? else { - // The lock is poisoned, who knows who owns it... we'll pretend: someone else. + // A perma-locked lock is definitely not held by us. return interp_ok(()); }; let mutex_ref = mutex_ref.clone(); diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 72080c92b7cd..43d9ba0043a3 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use rustc_abi::Size; +use rustc_abi::{FieldIdx, Size}; use crate::concurrency::init_once::{EvalContextExt as _, InitOnceStatus}; use crate::concurrency::sync::{FutexRef, SyncObj}; @@ -11,7 +11,11 @@ struct WindowsInitOnce { init_once: InitOnceRef, } -impl SyncObj for WindowsInitOnce {} +impl SyncObj for WindowsInitOnce { + fn delete_on_write(&self) -> bool { + true + } +} struct WindowsFutex { futex: FutexRef, @@ -22,7 +26,7 @@ impl SyncObj for WindowsFutex {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Windows sync primitives are pointer sized. - // We only use the first 4 bytes for the id. + // We only use the first byte for the "init" flag. fn init_once_get_data<'a>( &'a mut self, @@ -37,13 +41,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.deref_pointer_as(init_once_ptr, this.windows_ty_layout("INIT_ONCE"))?; let init_offset = Size::ZERO; - this.lazy_sync_get_data( + this.get_immovable_sync_with_static_init( &init_once, init_offset, - || throw_ub_format!("`INIT_ONCE` can't be moved after first use"), - |_| { - // TODO: check that this is still all-zero. - interp_ok(WindowsInitOnce { init_once: InitOnceRef::new() }) + /* uninit_val */ 0, + /* init_val */ 1, + |this| { + let ptr_field = this.project_field(&init_once, FieldIdx::from_u32(0))?; + let val = this.read_target_usize(&ptr_field)?; + if val == 0 { + interp_ok(WindowsInitOnce { init_once: InitOnceRef::new() }) + } else { + throw_ub_format!("`INIT_ONCE` was not properly initialized at this location, or it got overwritten"); + } }, ) } diff --git a/src/tools/miri/tests/pass-dep/concurrency/apple-os-unfair-lock.rs b/src/tools/miri/tests/pass-dep/concurrency/apple-os-unfair-lock.rs index f5b64474f83b..05765fc3f30d 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/apple-os-unfair-lock.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/apple-os-unfair-lock.rs @@ -14,12 +14,10 @@ fn main() { libc::os_unfair_lock_assert_not_owner(lock.get()); } - // `os_unfair_lock`s can be moved and leaked. - // In the real implementation, even moving it while locked is possible - // (and "forks" the lock, i.e. old and new location have independent wait queues). - // We only test the somewhat sane case of moving while unlocked that `std` plans to rely on. + // `os_unfair_lock`s can be moved, and even acquired again then. let lock = lock; - let locked = unsafe { libc::os_unfair_lock_trylock(lock.get()) }; - assert!(locked); - let _lock = lock; + assert!(unsafe { libc::os_unfair_lock_trylock(lock.get()) }); + // We can even move it while locked, but then we cannot acquire it any more. + let lock = lock; + assert!(!unsafe { libc::os_unfair_lock_trylock(lock.get()) }); } From 155b09f2b4f97e810b7063b6ced1ac02dc6370c9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Nov 2025 14:34:23 +0100 Subject: [PATCH 491/525] throw an error if a synchronization object is read/written while threads are queued --- src/tools/miri/src/borrow_tracker/mod.rs | 9 ---- src/tools/miri/src/concurrency/init_once.rs | 4 ++ src/tools/miri/src/concurrency/sync.rs | 18 +++++++- src/tools/miri/src/helpers.rs | 11 ++++- src/tools/miri/src/machine.rs | 17 +++++--- src/tools/miri/src/shims/unix/macos/sync.rs | 19 +++++++-- src/tools/miri/src/shims/unix/sync.rs | 29 ++++++++++++- src/tools/miri/src/shims/windows/sync.rs | 9 ++++ .../apple_os_unfair_lock_move_with_queue.rs | 29 +++++++++++++ ...pple_os_unfair_lock_move_with_queue.stderr | 13 ++++++ .../libc_pthread_mutex_read_while_queued.rs | 41 +++++++++++++++++++ ...ibc_pthread_mutex_read_while_queued.stderr | 13 ++++++ .../libc_pthread_mutex_write_while_queued.rs | 41 +++++++++++++++++++ ...bc_pthread_mutex_write_while_queued.stderr | 13 ++++++ 14 files changed, 244 insertions(+), 22 deletions(-) create mode 100644 src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 89bd93edae12..ef137349abb1 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -115,15 +115,6 @@ impl VisitProvenance for GlobalStateInner { /// We need interior mutable access to the global state. pub type GlobalState = RefCell; -impl fmt::Display for AccessKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - AccessKind::Read => write!(f, "read access"), - AccessKind::Write => write!(f, "write access"), - } - } -} - /// Policy on whether to recurse into fields to retag #[derive(Copy, Clone, Debug)] pub enum RetagFields { diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index daea20b3779b..5c3541ffbe4c 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -57,6 +57,10 @@ impl InitOnceRef { pub fn begin(&self) { self.0.borrow_mut().begin(); } + + pub fn queue_is_empty(&self) -> bool { + self.0.borrow().waiters.is_empty() + } } impl VisitProvenance for InitOnceRef { diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 81c81b02de9b..ac3ee3f91c5d 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -16,6 +16,11 @@ use crate::*; /// A trait for the synchronization metadata that can be attached to a memory location. pub trait SyncObj: Any { + /// Determines whether reads/writes to this object's location are currently permitted. + fn on_access<'tcx>(&self, _access_kind: AccessKind) -> InterpResult<'tcx> { + interp_ok(()) + } + /// Determines whether this object's metadata shall be deleted when a write to its /// location occurs. fn delete_on_write(&self) -> bool { @@ -62,6 +67,10 @@ impl MutexRef { pub fn owner(&self) -> Option { self.0.borrow().owner } + + pub fn queue_is_empty(&self) -> bool { + self.0.borrow().queue.is_empty() + } } impl VisitProvenance for MutexRef { @@ -138,6 +147,11 @@ impl RwLockRef { pub fn is_write_locked(&self) -> bool { self.0.borrow().is_write_locked() } + + pub fn queue_is_empty(&self) -> bool { + let inner = self.0.borrow(); + inner.reader_queue.is_empty() && inner.writer_queue.is_empty() + } } impl VisitProvenance for RwLockRef { @@ -165,8 +179,8 @@ impl CondvarRef { Self(Default::default()) } - pub fn is_awaited(&self) -> bool { - !self.0.borrow().waiters.is_empty() + pub fn queue_is_empty(&self) -> bool { + self.0.borrow().waiters.is_empty() } } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 7e1fdfa8cdf2..d6cef032b4e7 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1,7 +1,7 @@ use std::num::NonZero; use std::sync::Mutex; use std::time::Duration; -use std::{cmp, iter}; +use std::{cmp, fmt, iter}; use rand::RngCore; use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants}; @@ -29,6 +29,15 @@ pub enum AccessKind { Write, } +impl fmt::Display for AccessKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + AccessKind::Read => write!(f, "read access"), + AccessKind::Write => write!(f, "write access"), + } + } +} + /// Gets an instance for a path. /// /// A `None` namespace indicates we are looking for a module. diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 07a9e497161c..7eff006f418d 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1547,6 +1547,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if let Some(borrow_tracker) = &alloc_extra.borrow_tracker { borrow_tracker.before_memory_read(alloc_id, prov_extra, range, machine)?; } + // Check if there are any sync objects that would like to prevent reading this memory. + for (_offset, obj) in alloc_extra.sync_objs.range(range.start..range.end()) { + obj.on_access(AccessKind::Read)?; + } + interp_ok(()) } @@ -1590,11 +1595,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { // Delete sync objects that don't like writes. // Most of the time, we can just skip this. if !alloc_extra.sync_objs.is_empty() { - let to_delete = alloc_extra - .sync_objs - .range(range.start..range.end()) - .filter_map(|(offset, obj)| obj.delete_on_write().then_some(*offset)) - .collect::>(); + let mut to_delete = vec![]; + for (offset, obj) in alloc_extra.sync_objs.range(range.start..range.end()) { + obj.on_access(AccessKind::Write)?; + if obj.delete_on_write() { + to_delete.push(*offset); + } + } for offset in to_delete { alloc_extra.sync_objs.remove(&offset); } diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index 4024ddc09731..da87244118a5 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -25,6 +25,17 @@ enum MacOsUnfairLock { } impl SyncObj for MacOsUnfairLock { + fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { + if let MacOsUnfairLock::Active { mutex_ref } = self + && !mutex_ref.queue_is_empty() + { + throw_ub_format!( + "{access_kind} to `os_unfair_lock` is forbidden while the queue is non-empty" + ); + } + interp_ok(()) + } + fn delete_on_write(&self) -> bool { true } @@ -81,10 +92,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a lock that got copied while it is initialized. We de-initialize // locks when they get released, so it got copied while locked. Unfortunately // that is something `std` needs to support (the guard could have been leaked). - // So we behave like a futex-based lock whose wait queue got pruned: any attempt - // to acquire the lock will just wait forever. - // In practice there actually could be a wait queue there, if someone moves a - // lock *while threads are queued*; this is UB we will not detect. + // On the plus side, we know nobody was queued for the lock while it got copied; + // that would have been rejected by our `on_access`. So we behave like a + // futex-based lock would in this case: any attempt to acquire the lock will + // just wait forever, since there's nobody to wake us up. interp_ok(MacOsUnfairLock::PermanentlyLocked) } else { throw_ub_format!("`os_unfair_lock` was not properly initialized at this location, or it got overwritten"); diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index bb1b97ff8ad1..189b475ad897 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -110,6 +110,15 @@ struct PthreadMutex { } impl SyncObj for PthreadMutex { + fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { + if !self.mutex_ref.queue_is_empty() { + throw_ub_format!( + "{access_kind} to `pthread_mutex_t` is forbidden while the queue is non-empty" + ); + } + interp_ok(()) + } + fn delete_on_write(&self) -> bool { true } @@ -230,6 +239,15 @@ struct PthreadRwLock { } impl SyncObj for PthreadRwLock { + fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { + if !self.rwlock_ref.queue_is_empty() { + throw_ub_format!( + "{access_kind} to `pthread_rwlock_t` is forbidden while the queue is non-empty" + ); + } + interp_ok(()) + } + fn delete_on_write(&self) -> bool { true } @@ -361,6 +379,15 @@ struct PthreadCondvar { } impl SyncObj for PthreadCondvar { + fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { + if !self.condvar_ref.queue_is_empty() { + throw_ub_format!( + "{access_kind} to `pthread_cond_t` is forbidden while the queue is non-empty" + ); + } + interp_ok(()) + } + fn delete_on_write(&self) -> bool { true } @@ -900,7 +927,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Reading the field also has the side-effect that we detect double-`destroy` // since we make the field uninit below. let condvar = &cond_get_data(this, cond_op)?.condvar_ref; - if condvar.is_awaited() { + if !condvar.queue_is_empty() { throw_ub_format!("destroying an awaited conditional variable"); } diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 43d9ba0043a3..c079045908ca 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -12,6 +12,15 @@ struct WindowsInitOnce { } impl SyncObj for WindowsInitOnce { + fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { + if !self.init_once.queue_is_empty() { + throw_ub_format!( + "{access_kind} to `INIT_ONCE` is forbidden while the queue is non-empty" + ); + } + interp_ok(()) + } + fn delete_on_write(&self) -> bool { true } diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs new file mode 100644 index 000000000000..b0718d3874aa --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs @@ -0,0 +1,29 @@ +//@only-target: darwin +#![feature(sync_unsafe_cell)] + +use std::cell::SyncUnsafeCell; +use std::sync::atomic::*; +use std::thread; + +fn main() { + let lock = SyncUnsafeCell::new(libc::OS_UNFAIR_LOCK_INIT); + + thread::scope(|s| { + // First thread: grabs the lock. + s.spawn(|| { + unsafe { libc::os_unfair_lock_lock(lock.get()) }; + thread::yield_now(); + unreachable!(); + }); + // Second thread: queues for the lock. + s.spawn(|| { + unsafe { libc::os_unfair_lock_lock(lock.get()) }; + unreachable!(); + }); + // Third thread: tries to read the lock while second thread is queued. + s.spawn(|| { + let atomic_ref = unsafe { &*lock.get().cast::() }; + let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read access to `os_unfair_lock` is forbidden while the queue is non-empty + }); + }); +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr new file mode 100644 index 000000000000..72ce13ac9907 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: read access to `os_unfair_lock` is forbidden while the queue is non-empty + --> tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs:LL:CC + | +LL | ... let _val = atomic_ref.load(Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs new file mode 100644 index 000000000000..e1d801ee4868 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs @@ -0,0 +1,41 @@ +//@ignore-target: windows # No pthreads on Windows +//@compile-flags: -Zmiri-fixed-schedule + +use std::cell::UnsafeCell; +use std::sync::atomic::*; +use std::thread; + +struct Mutex(UnsafeCell); +impl Mutex { + fn get(&self) -> *mut libc::pthread_mutex_t { + self.0.get() + } +} + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +// The offset to the "sensitive" part of the mutex (that Miri attaches the metadata to). +const OFFSET: usize = if cfg!(target_os = "macos") { 4 } else { 0 }; + +fn main() { + let m = Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)); + thread::scope(|s| { + // First thread: grabs the lock. + s.spawn(|| { + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + thread::yield_now(); + unreachable!(); + }); + // Second thread: queues for the lock. + s.spawn(|| { + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + unreachable!(); + }); + // Third thread: tries to read the lock while second thread is queued. + s.spawn(|| { + let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; + let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read access to `pthread_mutex_t` is forbidden while the queue is non-empty + }); + }); +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr new file mode 100644 index 000000000000..b20426ec5973 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: read access to `pthread_mutex_t` is forbidden while the queue is non-empty + --> tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs:LL:CC + | +LL | ... let _val = atomic_ref.load(Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs new file mode 100644 index 000000000000..6d136a8a87c2 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs @@ -0,0 +1,41 @@ +//@ignore-target: windows # No pthreads on Windows +//@compile-flags: -Zmiri-fixed-schedule + +use std::cell::UnsafeCell; +use std::sync::atomic::*; +use std::thread; + +struct Mutex(UnsafeCell); +impl Mutex { + fn get(&self) -> *mut libc::pthread_mutex_t { + self.0.get() + } +} + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +// The offset to the "sensitive" part of the mutex (that Miri attaches the metadata to). +const OFFSET: usize = if cfg!(target_os = "macos") { 4 } else { 0 }; + +fn main() { + let m = Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)); + thread::scope(|s| { + // First thread: grabs the lock. + s.spawn(|| { + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + thread::yield_now(); + unreachable!(); + }); + // Second thread: queues for the lock. + s.spawn(|| { + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + unreachable!(); + }); + // Third thread: tries to overwrite the lock while second thread is queued. + s.spawn(|| { + let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; + atomic_ref.store(0, Ordering::Relaxed); //~ERROR: write access to `pthread_mutex_t` is forbidden while the queue is non-empty + }); + }); +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr new file mode 100644 index 000000000000..28a79099a6b7 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: write access to `pthread_mutex_t` is forbidden while the queue is non-empty + --> tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs:LL:CC + | +LL | ... atomic_ref.store(0, Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 3c4b29c874390c72080ace392bcc9216d973df10 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Nov 2025 14:37:25 +0100 Subject: [PATCH 492/525] remove dead code --- src/tools/miri/src/concurrency/sync.rs | 83 -------------------------- 1 file changed, 83 deletions(-) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index ac3ee3f91c5d..ad8f43624e9b 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -257,95 +257,12 @@ impl<'tcx> AllocExtra<'tcx> { } } -/// We designate an `init`` field in all synchronization objects. -/// If `init` is set to this, we consider the object initialized. -pub const LAZY_INIT_COOKIE: u32 = 0xcafe_affe; - // Public interface to synchronization objects. Please note that in most // cases, the function calls are infallible and it is the client's (shim // implementation's) responsibility to detect and deal with erroneous // situations. impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { - /// Helper for lazily initialized `alloc_extra.sync` data: - /// this forces an immediate init. - /// Return a reference to the data in the machine state. - fn lazy_sync_init<'a, T: SyncObj>( - &'a mut self, - obj: &MPlaceTy<'tcx>, - init_offset: Size, - data: T, - ) -> InterpResult<'tcx, &'a T> - where - 'tcx: 'a, - { - let this = self.eval_context_mut(); - - let (alloc, offset, _) = this.ptr_get_alloc_id(obj.ptr(), 0)?; - // Mark this as "initialized". - let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); - assert!(init_offset + init_cookie.size() <= obj.layout.size); - let init_field = obj.offset(init_offset, this.machine.layouts.u32, this)?; - this.write_scalar_atomic(init_cookie, &init_field, AtomicWriteOrd::Relaxed)?; - // Insert sync obj, and return reference to it. - let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; - alloc_extra.sync_objs.insert(offset, Box::new(data)); - interp_ok(this.get_alloc_extra(alloc)?.get_sync::(offset).unwrap()) - } - - /// Helper for lazily initialized `alloc_extra.sync` data: - /// Checks if the synchronization object is initialized: - /// - If yes, fetches the data from `alloc_extra.sync`, or calls `missing_data` if that fails - /// and stores that in `alloc_extra.sync`. - /// - Otherwise, calls `new_data` to initialize the object. - /// - /// Return a reference to the data in the machine state. - fn lazy_sync_get_data<'a, T: SyncObj>( - &'a mut self, - obj: &MPlaceTy<'tcx>, - init_offset: Size, - missing_data: impl FnOnce() -> InterpResult<'tcx, T>, - new_data: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, T>, - ) -> InterpResult<'tcx, &'a T> - where - 'tcx: 'a, - { - let this = self.eval_context_mut(); - - // Check if this is already initialized. Needs to be atomic because we can race with another - // thread initializing. Needs to be an RMW operation to ensure we read the *latest* value. - // So we just try to replace MUTEX_INIT_COOKIE with itself. - let init_cookie = Scalar::from_u32(LAZY_INIT_COOKIE); - assert!(init_offset + init_cookie.size() <= obj.layout.size); - let init_field = obj.offset(init_offset, this.machine.layouts.u32, this)?; - let (_init, success) = this - .atomic_compare_exchange_scalar( - &init_field, - &ImmTy::from_scalar(init_cookie, this.machine.layouts.u32), - init_cookie, - AtomicRwOrd::Relaxed, - AtomicReadOrd::Relaxed, - /* can_fail_spuriously */ false, - )? - .to_scalar_pair(); - - if success.to_bool()? { - // If it is initialized, it must be found in the "sync obj" table, - // or else it has been moved illegally. - let (alloc, offset, _) = this.ptr_get_alloc_id(obj.ptr(), 0)?; - let (alloc_extra, _machine) = this.get_alloc_extra_mut(alloc)?; - // Due to borrow checker reasons, we have to do the lookup twice. - if alloc_extra.get_sync::(offset).is_none() { - let data = missing_data()?; - alloc_extra.sync_objs.insert(offset, Box::new(data)); - } - interp_ok(alloc_extra.get_sync::(offset).unwrap()) - } else { - let data = new_data(this)?; - this.lazy_sync_init(obj, init_offset, data) - } - } - /// Get the synchronization object associated with the given pointer, /// or initialize a new one. /// From d6b01abd4d5aebadf8b4af42bd023dcedfb59e3a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Nov 2025 12:32:36 +0100 Subject: [PATCH 493/525] also inform sync objcts about deallocation; needs separate AccessKind type --- src/tools/miri/src/borrow_tracker/mod.rs | 16 +++++++ .../stacked_borrows/diagnostics.rs | 2 +- .../src/borrow_tracker/stacked_borrows/mod.rs | 2 +- .../tree_borrows/diagnostics.rs | 2 +- .../src/borrow_tracker/tree_borrows/mod.rs | 2 +- .../src/borrow_tracker/tree_borrows/perms.rs | 2 +- .../src/borrow_tracker/tree_borrows/tree.rs | 2 +- src/tools/miri/src/concurrency/sync.rs | 18 +++++++ src/tools/miri/src/diagnostics.rs | 2 +- src/tools/miri/src/helpers.rs | 18 +------ src/tools/miri/src/lib.rs | 2 +- src/tools/miri/src/machine.rs | 13 +++-- src/tools/miri/src/shims/unix/macos/sync.rs | 4 +- src/tools/miri/src/shims/unix/sync.rs | 8 ++-- src/tools/miri/src/shims/windows/sync.rs | 4 +- .../apple_os_unfair_lock_move_with_queue.rs | 2 +- ...pple_os_unfair_lock_move_with_queue.stderr | 6 +-- .../libc_pthread_mutex_free_while_queued.rs | 48 +++++++++++++++++++ ...ibc_pthread_mutex_free_while_queued.stderr | 22 +++++++++ .../libc_pthread_mutex_read_while_queued.rs | 2 +- ...ibc_pthread_mutex_read_while_queued.stderr | 2 +- .../libc_pthread_mutex_write_while_queued.rs | 2 +- ...bc_pthread_mutex_write_while_queued.stderr | 6 +-- 23 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index ef137349abb1..ebca7377fdbc 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -11,6 +11,22 @@ use crate::*; pub mod stacked_borrows; pub mod tree_borrows; +/// Indicates which kind of access is being performed. +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub enum AccessKind { + Read, + Write, +} + +impl fmt::Display for AccessKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + AccessKind::Read => write!(f, "read access"), + AccessKind::Write => write!(f, "write access"), + } + } +} + /// Tracking pointer provenance #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct BorTag(NonZero); diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 997d7799a5f1..36e574c8e57f 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_span::{Span, SpanData}; use smallvec::SmallVec; -use crate::borrow_tracker::{GlobalStateInner, ProtectorKind}; +use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind}; use crate::*; /// Error reporting diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 76ede552baa2..fa60f27185f8 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -21,7 +21,7 @@ pub use self::stack::Stack; use crate::borrow_tracker::stacked_borrows::diagnostics::{ AllocHistory, DiagnosticCx, DiagnosticCxBuilder, }; -use crate::borrow_tracker::{GlobalStateInner, ProtectorKind}; +use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind}; use crate::concurrency::data_race::{NaReadType, NaWriteType}; use crate::*; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index 00f921b0f8af..f2410a08625d 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -4,10 +4,10 @@ use std::ops::Range; use rustc_data_structures::fx::FxHashMap; use rustc_span::{Span, SpanData}; -use crate::borrow_tracker::ProtectorKind; use crate::borrow_tracker::tree_borrows::perms::{PermTransition, Permission}; use crate::borrow_tracker::tree_borrows::tree::LocationState; use crate::borrow_tracker::tree_borrows::unimap::UniIndex; +use crate::borrow_tracker::{AccessKind, ProtectorKind}; use crate::*; /// Cause of an access: either a real access or one diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 5c905fc161f0..720c5b239495 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -5,7 +5,7 @@ use rustc_middle::ty::{self, Ty}; use self::foreign_access_skipping::IdempotentForeignAccess; use self::tree::LocationState; -use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind}; +use crate::borrow_tracker::{AccessKind, GlobalState, GlobalStateInner, ProtectorKind}; use crate::concurrency::data_race::NaReadType; use crate::*; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index 968e4961a635..b84ebd51656c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -1,7 +1,7 @@ use std::cmp::{Ordering, PartialOrd}; use std::fmt; -use crate::AccessKind; +use crate::borrow_tracker::AccessKind; use crate::borrow_tracker::tree_borrows::diagnostics::TransitionError; use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 740483844e79..e337fe05e135 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -25,7 +25,7 @@ use crate::borrow_tracker::tree_borrows::diagnostics::{ use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess; use crate::borrow_tracker::tree_borrows::perms::PermTransition; use crate::borrow_tracker::tree_borrows::unimap::{UniIndex, UniKeyMap, UniValMap}; -use crate::borrow_tracker::{GlobalState, ProtectorKind}; +use crate::borrow_tracker::{AccessKind, GlobalState, ProtectorKind}; use crate::*; mod tests; diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index ad8f43624e9b..c529ed5145ed 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -14,6 +14,24 @@ use rustc_data_structures::fx::FxHashMap; use super::vector_clock::VClock; use crate::*; +/// Indicates which kind of access is being performed. +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub enum AccessKind { + Read, + Write, + Dealloc, +} + +impl fmt::Display for AccessKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + AccessKind::Read => write!(f, "read"), + AccessKind::Write => write!(f, "write"), + AccessKind::Dealloc => write!(f, "deallocation"), + } + } +} + /// A trait for the synchronization metadata that can be attached to a memory location. pub trait SyncObj: Any { /// Determines whether reads/writes to this object's location are currently permitted. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index d0cfb9c805e1..2ddb3ff49d85 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -128,7 +128,7 @@ pub enum NonHaltingDiagnostic { PoppedPointerTag(Item, String), TrackingAlloc(AllocId, Size, Align), FreedAlloc(AllocId), - AccessedAlloc(AllocId, AllocRange, AccessKind), + AccessedAlloc(AllocId, AllocRange, borrow_tracker::AccessKind), RejectedIsolatedOp(String), ProgressReport { block_count: u64, // how many basic blocks have been run so far diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index d6cef032b4e7..18e16ddf1a5d 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1,7 +1,7 @@ use std::num::NonZero; use std::sync::Mutex; use std::time::Duration; -use std::{cmp, fmt, iter}; +use std::{cmp, iter}; use rand::RngCore; use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants}; @@ -22,22 +22,6 @@ use rustc_symbol_mangling::mangle_internal_symbol; use crate::*; -/// Indicates which kind of access is being performed. -#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] -pub enum AccessKind { - Read, - Write, -} - -impl fmt::Display for AccessKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - AccessKind::Read => write!(f, "read access"), - AccessKind::Write => write!(f, "write access"), - } - } -} - /// Gets an instance for a path. /// /// A `None` namespace indicates we are looking for a module. diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index b756fbb901bc..8f732adeb6ef 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -139,7 +139,7 @@ pub use crate::diagnostics::{ EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo, report_error, }; pub use crate::eval::{MiriConfig, MiriEntryFnType, create_ecx, eval_entry}; -pub use crate::helpers::{AccessKind, EvalContextExt as _, ToU64 as _, ToUsize as _}; +pub use crate::helpers::{EvalContextExt as _, ToU64 as _, ToUsize as _}; pub use crate::intrinsics::EvalContextExt as _; pub use crate::machine::{ AlignmentCheck, AllocExtra, BacktraceStyle, DynMachineCallback, FloatRoundingErrorMode, diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 7eff006f418d..7cfde667f8b9 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1527,7 +1527,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { machine.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc( alloc_id, range, - AccessKind::Read, + borrow_tracker::AccessKind::Read, )); } // The order of checks is deliberate, to prefer reporting a data race over a borrow tracker error. @@ -1549,7 +1549,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } // Check if there are any sync objects that would like to prevent reading this memory. for (_offset, obj) in alloc_extra.sync_objs.range(range.start..range.end()) { - obj.on_access(AccessKind::Read)?; + obj.on_access(concurrency::sync::AccessKind::Read)?; } interp_ok(()) @@ -1568,7 +1568,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { machine.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc( alloc_id, range, - AccessKind::Write, + borrow_tracker::AccessKind::Write, )); } match &machine.data_race { @@ -1597,7 +1597,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if !alloc_extra.sync_objs.is_empty() { let mut to_delete = vec![]; for (offset, obj) in alloc_extra.sync_objs.range(range.start..range.end()) { - obj.on_access(AccessKind::Write)?; + obj.on_access(concurrency::sync::AccessKind::Write)?; if obj.delete_on_write() { to_delete.push(*offset); } @@ -1642,6 +1642,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if let Some(borrow_tracker) = &mut alloc_extra.borrow_tracker { borrow_tracker.before_memory_deallocation(alloc_id, prove_extra, size, machine)?; } + // Check if there are any sync objects that would like to prevent freeing this memory. + for obj in alloc_extra.sync_objs.values() { + obj.on_access(concurrency::sync::AccessKind::Dealloc)?; + } + if let Some((_, deallocated_at)) = machine.allocation_spans.borrow_mut().get_mut(&alloc_id) { *deallocated_at = Some(machine.current_user_relevant_span()); diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index da87244118a5..d69d373b572b 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -15,7 +15,7 @@ use std::time::Duration; use rustc_abi::{Endian, FieldIdx, Size}; -use crate::concurrency::sync::{FutexRef, SyncObj}; +use crate::concurrency::sync::{AccessKind, FutexRef, SyncObj}; use crate::*; #[derive(Clone)] @@ -30,7 +30,7 @@ impl SyncObj for MacOsUnfairLock { && !mutex_ref.queue_is_empty() { throw_ub_format!( - "{access_kind} to `os_unfair_lock` is forbidden while the queue is non-empty" + "{access_kind} of `os_unfair_lock` is forbidden while the queue is non-empty" ); } interp_ok(()) diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 189b475ad897..57dbe2cd333b 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -1,6 +1,6 @@ use rustc_abi::Size; -use crate::concurrency::sync::SyncObj; +use crate::concurrency::sync::{AccessKind, SyncObj}; use crate::*; /// Do a bytewise comparison of the two places. This is used to check if @@ -113,7 +113,7 @@ impl SyncObj for PthreadMutex { fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { if !self.mutex_ref.queue_is_empty() { throw_ub_format!( - "{access_kind} to `pthread_mutex_t` is forbidden while the queue is non-empty" + "{access_kind} of `pthread_mutex_t` is forbidden while the queue is non-empty" ); } interp_ok(()) @@ -242,7 +242,7 @@ impl SyncObj for PthreadRwLock { fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { if !self.rwlock_ref.queue_is_empty() { throw_ub_format!( - "{access_kind} to `pthread_rwlock_t` is forbidden while the queue is non-empty" + "{access_kind} of `pthread_rwlock_t` is forbidden while the queue is non-empty" ); } interp_ok(()) @@ -382,7 +382,7 @@ impl SyncObj for PthreadCondvar { fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { if !self.condvar_ref.queue_is_empty() { throw_ub_format!( - "{access_kind} to `pthread_cond_t` is forbidden while the queue is non-empty" + "{access_kind} of `pthread_cond_t` is forbidden while the queue is non-empty" ); } interp_ok(()) diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index c079045908ca..db1860bdfd30 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -3,7 +3,7 @@ use std::time::Duration; use rustc_abi::{FieldIdx, Size}; use crate::concurrency::init_once::{EvalContextExt as _, InitOnceStatus}; -use crate::concurrency::sync::{FutexRef, SyncObj}; +use crate::concurrency::sync::{AccessKind, FutexRef, SyncObj}; use crate::*; #[derive(Clone)] @@ -15,7 +15,7 @@ impl SyncObj for WindowsInitOnce { fn on_access<'tcx>(&self, access_kind: AccessKind) -> InterpResult<'tcx> { if !self.init_once.queue_is_empty() { throw_ub_format!( - "{access_kind} to `INIT_ONCE` is forbidden while the queue is non-empty" + "{access_kind} of `INIT_ONCE` is forbidden while the queue is non-empty" ); } interp_ok(()) diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs index b0718d3874aa..1c31236a2f80 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs @@ -23,7 +23,7 @@ fn main() { // Third thread: tries to read the lock while second thread is queued. s.spawn(|| { let atomic_ref = unsafe { &*lock.get().cast::() }; - let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read access to `os_unfair_lock` is forbidden while the queue is non-empty + let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read of `os_unfair_lock` is forbidden while the queue is non-empty }); }); } diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr index 72ce13ac9907..003ddb9b287d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: read access to `os_unfair_lock` is forbidden while the queue is non-empty +error: Undefined Behavior: read of `os_unfair_lock` is forbidden while the queue is non-empty --> tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs:LL:CC | -LL | ... let _val = atomic_ref.load(Ordering::Relaxed); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | let _val = atomic_ref.load(Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs new file mode 100644 index 000000000000..55fcb4c61d48 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs @@ -0,0 +1,48 @@ +//@ignore-target: windows # No pthreads on Windows +//@compile-flags: -Zmiri-deterministic-concurrency +//@error-in-other-file: deallocation of `pthread_mutex_t` is forbidden while the queue is non-empty + +use std::cell::UnsafeCell; +use std::sync::atomic::*; +use std::thread; + +struct Mutex(UnsafeCell); +impl Mutex { + fn get(&self) -> *mut libc::pthread_mutex_t { + self.0.get() + } +} + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +fn main() { + let m = Box::new(Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))); + let initialized = AtomicBool::new(false); + thread::scope(|s| { + // First thread: initializes the lock, and then grabs it. + s.spawn(|| { + // Initialize (so the third thread can happens-after the write that occurs here). + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + assert_eq!(unsafe { libc::pthread_mutex_unlock(m.get()) }, 0); + initialized.store(true, Ordering::Release); + // Grab and hold. + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + thread::yield_now(); + unreachable!(); + }); + // Second thread: queues for the lock. + s.spawn(|| { + assert_eq!(unsafe { libc::pthread_mutex_lock(m.get()) }, 0); + unreachable!(); + }); + // Third thread: tries to free the lock while second thread is queued. + s.spawn(|| { + // Ensure we happen-after the initialization write. + assert!(initialized.load(Ordering::Acquire)); + // Now drop it. + drop(unsafe { Box::from_raw(m.get().cast::()) }); + }); + }); + unreachable!(); +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr new file mode 100644 index 000000000000..7b6e05828cea --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr @@ -0,0 +1,22 @@ +error: Undefined Behavior: deallocation of `pthread_mutex_t` is forbidden while the queue is non-empty + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside closure + --> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(m.get().cast::()) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs index e1d801ee4868..555d765d24ba 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs @@ -35,7 +35,7 @@ fn main() { // Third thread: tries to read the lock while second thread is queued. s.spawn(|| { let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; - let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read access to `pthread_mutex_t` is forbidden while the queue is non-empty + let _val = atomic_ref.load(Ordering::Relaxed); //~ERROR: read of `pthread_mutex_t` is forbidden while the queue is non-empty }); }); } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr index b20426ec5973..42dbd5f02cb3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: read access to `pthread_mutex_t` is forbidden while the queue is non-empty +error: Undefined Behavior: read of `pthread_mutex_t` is forbidden while the queue is non-empty --> tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs:LL:CC | LL | ... let _val = atomic_ref.load(Ordering::Relaxed); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs index 6d136a8a87c2..00274f7080f3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs @@ -35,7 +35,7 @@ fn main() { // Third thread: tries to overwrite the lock while second thread is queued. s.spawn(|| { let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; - atomic_ref.store(0, Ordering::Relaxed); //~ERROR: write access to `pthread_mutex_t` is forbidden while the queue is non-empty + atomic_ref.store(0, Ordering::Relaxed); //~ERROR: write of `pthread_mutex_t` is forbidden while the queue is non-empty }); }); } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr index 28a79099a6b7..4705f9a1b5f0 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: write access to `pthread_mutex_t` is forbidden while the queue is non-empty +error: Undefined Behavior: write of `pthread_mutex_t` is forbidden while the queue is non-empty --> tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs:LL:CC | -LL | ... atomic_ref.store(0, Ordering::Relaxed); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | atomic_ref.store(0, Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information From b2a66027fe57cff63a76a66518f8eaffb0921561 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 14:26:36 +0000 Subject: [PATCH 494/525] Update tidy allowed dependencies --- src/tools/tidy/src/deps.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 6a1721df1642..c8bd215a1cb4 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -576,6 +576,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "foldhash", "gimli", "hashbrown", + "heck", "indexmap", "libc", "libloading", @@ -596,8 +597,9 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "syn", "target-lexicon", "unicode-ident", - "wasmtime-jit-icache-coherence", - "wasmtime-math", + "wasmtime-internal-jit-icache-coherence", + "wasmtime-internal-math", + "windows-link", "windows-sys", "windows-targets", "windows_aarch64_gnullvm", From 61c3458105ebf1cd119059aa0a97b816831841b4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 15:04:45 +0000 Subject: [PATCH 495/525] Add missing --check-cfg --- compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index 72140c651a9a..70504ee8007d 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs @@ -52,7 +52,8 @@ pub(crate) fn build_sysroot( .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs"))) .arg("-o") .arg(&wrapper_path) - .arg("-Cstrip=debuginfo"); + .arg("-Cstrip=debuginfo") + .arg("--check-cfg=cfg(support_panic_unwind)"); if panic_unwind_support { build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind"); } From cc8b95cc5490552e7080ec4e98c19249b47dac3a Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 3 Aug 2024 22:57:10 -0600 Subject: [PATCH 496/525] add `overflow_checks` intrinsic --- .../src/check_consts/check.rs | 5 +--- .../rustc_hir_analysis/src/check/intrinsic.rs | 3 +- compiler/rustc_middle/src/mir/pretty.rs | 3 ++ compiler/rustc_middle/src/mir/syntax.rs | 4 +++ .../src/move_paths/builder.rs | 5 +--- .../src/lower_intrinsics.rs | 3 +- compiler/rustc_public/src/mir/body.rs | 2 ++ .../src/unstable/convert/stable/mir.rs | 1 + library/core/src/intrinsics/mod.rs | 18 ++++++++++++ .../auxiliary/overflow_checks_add.rs | 10 +++++++ tests/codegen-llvm/overflow-checks.rs | 29 +++++++++++++++++++ tests/ui/consts/const-eval/overflow_checks.rs | 8 +++++ 12 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 tests/codegen-llvm/auxiliary/overflow_checks_add.rs create mode 100644 tests/codegen-llvm/overflow-checks.rs create mode 100644 tests/ui/consts/const-eval/overflow_checks.rs diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index c0a9bd187c14..f515f5d751bc 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -645,10 +645,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} - Rvalue::NullaryOp( - NullOp::OffsetOf(_) | NullOp::RuntimeChecks(_), - _, - ) => {} + Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::RuntimeChecks(_), _) => {} Rvalue::ShallowInitBox(_, _) => {} Rvalue::UnaryOp(op, operand) => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index a6659912e3fb..39c26f4ea40d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -163,6 +163,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::minnumf128 | sym::mul_with_overflow | sym::needs_drop + | sym::overflow_checks | sym::powf16 | sym::powf32 | sym::powf64 @@ -643,7 +644,7 @@ pub(crate) fn check_intrinsic_type( sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)), sym::ptr_metadata => (2, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)), - sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool), + sym::ub_checks | sym::overflow_checks => (0, 0, Vec::new(), tcx.types.bool), sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))), diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a7941290de2e..f881ff1067d9 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1097,6 +1097,9 @@ impl<'tcx> Debug for Rvalue<'tcx> { NullOp::RuntimeChecks(RuntimeChecks::ContractChecks) => { write!(fmt, "ContractChecks()") } + NullOp::RuntimeChecks(RuntimeChecks::OverflowChecks) => { + write!(fmt, "OverflowChecks()") + } } } ThreadLocalRef(did) => ty::tls::with(|tcx| { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 865b91817b3c..3b48a68df126 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1577,6 +1577,9 @@ pub enum RuntimeChecks { /// Returns whether we should perform contract-checking at runtime. /// See the `contract_checks` intrinsic docs for details. ContractChecks, + /// Returns whether we should perform some overflow-checking at runtime. + /// See the `overflow_checks` intrinsic docs for details. + OverflowChecks, } impl RuntimeChecks { @@ -1584,6 +1587,7 @@ impl RuntimeChecks { match self { Self::UbChecks => sess.ub_checks(), Self::ContractChecks => sess.contract_checks(), + Self::OverflowChecks => sess.overflow_checks(), } } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 8801fa8d9fd3..b4ffeb782b59 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -451,10 +451,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { Rvalue::Ref(..) | Rvalue::RawPtr(..) | Rvalue::Discriminant(..) - | Rvalue::NullaryOp( - NullOp::OffsetOf(..) | NullOp::RuntimeChecks(_), - _, - ) => {} + | Rvalue::NullaryOp(NullOp::OffsetOf(..) | NullOp::RuntimeChecks(_), _) => {} } } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index e6fa30a72b9b..1e874300e25e 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -23,10 +23,11 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { sym::unreachable => { terminator.kind = TerminatorKind::Unreachable; } - sym::ub_checks | sym::contract_checks => { + sym::ub_checks | sym::overflow_checks | sym::contract_checks => { let op = match intrinsic.name { sym::ub_checks => RuntimeChecks::UbChecks, sym::contract_checks => RuntimeChecks::ContractChecks, + sym::overflow_checks => RuntimeChecks::OverflowChecks, _ => unreachable!(), }; let target = target.unwrap(); diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index 551f666023b0..5f41b1063280 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -1033,6 +1033,8 @@ pub enum RuntimeChecks { UbChecks, /// cfg!(contract_checks), but at codegen time ContractChecks, + /// cfg!(overflow_checks), but at codegen time + OverflowChecks, } impl Operand { diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index 1de5a2b32779..d5896474d009 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -330,6 +330,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { RuntimeChecks(op) => crate::mir::NullOp::RuntimeChecks(match op { UbChecks => crate::mir::RuntimeChecks::UbChecks, ContractChecks => crate::mir::RuntimeChecks::ContractChecks, + OverflowChecks => crate::mir::RuntimeChecks::OverflowChecks, }), } } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c397e762d558..41afb3694b91 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2585,6 +2585,24 @@ pub const fn ub_checks() -> bool { cfg!(ub_checks) } +/// Returns whether we should perform some overflow-checking at runtime. This eventually evaluates to +/// `cfg!(overflow_checks)`, but behaves different from `cfg!` when mixing crates built with different +/// flags: if the crate has overflow checks enabled or carries the `#[rustc_inherit_overflow_checks]` +/// attribute, evaluation is delayed until monomorphization (or until the call gets inlined into +/// a crate that does not delay evaluation further); otherwise it can happen any time. +/// +/// The common case here is a user program built with overflow_checks linked against the distributed +/// sysroot which is built without overflow_checks but with `#[rustc_inherit_overflow_checks]`. +/// For code that gets monomorphized in the user crate (i.e., generic functions and functions with +/// `#[inline]`), gating assertions on `overflow_checks()` rather than `cfg!(overflow_checks)` means that +/// assertions are enabled whenever the *user crate* has overflow checks enabled. However if the +/// user has overflow checks disabled, the checks will still get optimized out. +#[inline(always)] +#[rustc_intrinsic] +pub const fn overflow_checks() -> bool { + cfg!(debug_assertions) +} + /// Allocates a block of memory at compile time. /// At runtime, just returns a null pointer. /// diff --git a/tests/codegen-llvm/auxiliary/overflow_checks_add.rs b/tests/codegen-llvm/auxiliary/overflow_checks_add.rs new file mode 100644 index 000000000000..ea9db1e9837e --- /dev/null +++ b/tests/codegen-llvm/auxiliary/overflow_checks_add.rs @@ -0,0 +1,10 @@ +//@ compile-flags: -Cdebug-assertions=yes + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +/// Emulates the default behavior of `+` using `intrinsics::overflow_checks()`. +#[inline] +pub fn add(a: u8, b: u8) -> u8 { + if core::intrinsics::overflow_checks() { a.strict_add(b) } else { a.wrapping_add(b) } +} diff --git a/tests/codegen-llvm/overflow-checks.rs b/tests/codegen-llvm/overflow-checks.rs new file mode 100644 index 000000000000..c8b10df507b0 --- /dev/null +++ b/tests/codegen-llvm/overflow-checks.rs @@ -0,0 +1,29 @@ +// With -Coverflow-checks=yes (enabled by default by -Cdebug-assertions=yes) we will produce a +// runtime check that panics when an operation would result in integer overflow. +// +// This test ensures that such a runtime check is *not* emitted when debug-assertions are enabled, +// but overflow-checks are explicitly disabled. It also ensures that even if a dependency is +// compiled with overflow checks, `intrinsics::overflow_checks()` will be treated with the +// overflow-checks setting of the current crate (when `#[rustc_inherit_overflow_checks]`) is used. + +//@ aux-build:overflow_checks_add.rs +//@ revisions: DEBUG NOCHECKS +//@ compile-flags: -O -Cdebug-assertions=yes +//@ [NOCHECKS] compile-flags: -Coverflow-checks=no + +#![crate_type = "lib"] + +extern crate overflow_checks_add; + +// CHECK-LABEL: @add( +#[no_mangle] +pub unsafe fn add(a: u8, b: u8) -> u8 { + // CHECK: i8 noundef %a, i8 noundef %b + // CHECK: add i8 %b, %a + // DEBUG: icmp ult i8 [[zero:[^,]+]], %a + // DEBUG: call core::num::overflow_panic::add + // DEBUG: unreachable + // NOCHECKS-NOT: unreachable + // NOCHECKS: ret i8 %0 + overflow_checks_add::add(a, b) +} diff --git a/tests/ui/consts/const-eval/overflow_checks.rs b/tests/ui/consts/const-eval/overflow_checks.rs new file mode 100644 index 000000000000..7f6915777990 --- /dev/null +++ b/tests/ui/consts/const-eval/overflow_checks.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ compile-flags: -O -C overflow-checks=no + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +// Always returns true during CTFE, even if overflow checks are disabled. +const _: () = assert!(core::intrinsics::overflow_checks()); From 9864a2fbca8128be72e6489e782cc56c5c6f023b Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 14 Oct 2025 02:15:16 +0100 Subject: [PATCH 497/525] add `const_of_item` query and use it in normalization --- compiler/rustc_hir_analysis/src/collect.rs | 36 ++++++++ .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 18 ++++ compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 13 +++ compiler/rustc_middle/src/ty/context.rs | 3 + .../src/solve/normalizes_to/free_alias.rs | 8 +- .../src/solve/normalizes_to/inherent.rs | 3 +- .../src/solve/normalizes_to/mod.rs | 14 +-- .../src/traits/normalize.rs | 89 +++++++++---------- .../src/traits/project.rs | 23 +---- .../src/normalize_projection_ty.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 1 + .../duplicate-bound-err.rs | 12 ++- .../duplicate-bound-err.stderr | 64 ++++++------- .../associated-type-bounds/duplicate-bound.rs | 5 +- 16 files changed, 171 insertions(+), 122 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index d6ce5d80c045..302847eca115 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -96,6 +96,7 @@ pub(crate) fn provide(providers: &mut Providers) { rendered_precise_capturing_args, const_param_default, anon_const_kind, + const_of_item, ..*providers }; } @@ -1543,3 +1544,38 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin _ => ty::AnonConstKind::NonTypeSystem, } } + +#[instrument(level = "debug", skip(tcx), ret)] +fn const_of_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ty::EarlyBinder<'tcx, Const<'tcx>> { + let ct_rhs = match tcx.hir_node_by_def_id(def_id) { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => *ct, + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Const(.., ct), .. + }) => ct.expect("no default value for trait assoc const"), + hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => *ct, + _ => { + span_bug!(tcx.def_span(def_id), "`const_of_item` expected a const or assoc const item") + } + }; + let ct_arg = match ct_rhs { + hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg, + hir::ConstItemRhs::Body(body_id) => { + bug!("cannot call const_of_item on a non-type_const {body_id:?}") + } + }; + let icx = ItemCtxt::new(tcx, def_id); + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let ct = icx + .lowerer() + .lower_const_arg(ct_arg, FeedConstTy::Param(def_id.to_def_id(), identity_args)); + if let Err(e) = icx.check_tainted_by_errors() + && !ct.references_error() + { + ty::EarlyBinder::bind(Const::new_error(tcx, e)) + } else { + ty::EarlyBinder::bind(ct) + } +} diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index d20df618b38b..4831395f3164 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -403,6 +403,7 @@ provide! { tcx, def_id, other, cdata, tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(def_id.index)) } anon_const_kind => { table } + const_of_item => { table } } pub(in crate::rmeta) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index fd73dbde14c5..2c256ee9b702 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1383,6 +1383,21 @@ fn should_encode_const(def_kind: DefKind) -> bool { } } +fn should_encode_const_of_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: DefKind) -> bool { + matches!(def_kind, DefKind::Const | DefKind::AssocConst) + && find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) + // AssocConst ==> assoc item has value + && (!matches!(def_kind, DefKind::AssocConst) || assoc_item_has_value(tcx, def_id)) +} + +fn assoc_item_has_value<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { + let assoc_item = tcx.associated_item(def_id); + match assoc_item.container { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true, + ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(), + } +} + impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_attrs(&mut self, def_id: LocalDefId) { let tcx = self.tcx; @@ -1604,6 +1619,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::AnonConst = def_kind { record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); } + if should_encode_const_of_item(self.tcx, def_id, def_kind) { + record!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); + } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8f1c7bbb3968..c20c45ae5812 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -471,6 +471,7 @@ define_tables! { assumed_wf_types_for_rpitit: Table, Span)>>, opaque_ty_origin: Table>>, anon_const_kind: Table>, + const_of_item: Table>>>, associated_types_for_impl_traits_in_trait_or_impl: Table>>>, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4dae00c02ccf..53f25ae0840b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -293,6 +293,19 @@ rustc_queries! { separate_provide_extern } + /// Returns the const of the RHS of a (free or assoc) const item, if it is a `#[type_const]`. + /// + /// When a const item is used in a type-level expression, like in equality for an assoc const + /// projection, this allows us to retrieve the typesystem-appropriate representation of the + /// const value. + /// + /// This query will ICE if given a const that is not marked with `#[type_const]`. + query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { + desc { |tcx| "computing the type-level value for `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + /// Returns the *type* of the definition given by `DefId`. /// /// For type aliases (whether eager or lazy) and associated types, this returns diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 60effa13406b..25562999646b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -242,6 +242,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { self.type_of_opaque_hir_typeck(def_id) } + fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { + self.const_of_item(def_id) + } type AdtDef = ty::AdtDef<'tcx>; fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs index 8aa6e4a3d711..8777f84957a7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -30,14 +30,12 @@ where ); let actual = if free_alias.kind(cx).is_type() { - cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args) + cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args).into() } else { - // FIXME(mgca): once const items are actual aliases defined as equal to type system consts - // this should instead return that. - panic!("normalizing free const aliases in the type system is unsupported"); + cx.const_of_item(free_alias.def_id).instantiate(cx, free_alias.args).into() }; - self.instantiate_normalizes_to_term(goal, actual.into()); + self.instantiate_normalizes_to_term(goal, actual); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 2bb1ac8f7426..42aa237762d9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -54,8 +54,7 @@ where let normalized = if inherent.kind(cx).is_type() { cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into() } else { - // FIXME(mgca): Properly handle IACs in the type system - panic!("normalizing inherent associated consts in the type system is unsupported"); + cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).into() }; self.instantiate_normalizes_to_term(goal, normalized); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) 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 0674b3d42ab4..110cc30e740b 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 @@ -366,19 +366,7 @@ where cx.type_of(target_item_def_id).map_bound(|ty| ty.into()) } ty::AliasTermKind::ProjectionConst => { - // FIXME(mgca): once const items are actual aliases defined as equal to type system consts - // this should instead return that. - if cx.features().associated_const_equality() { - panic!("associated const projection is not supported yet") - } else { - ty::EarlyBinder::bind( - Const::new_error_with_message( - cx, - "associated const projection is not supported yet", - ) - .into(), - ) - } + cx.const_of_item(target_item_def_id).map_bound(|ct| ct.into()) } kind => panic!("expected projection, found {kind:?}"), }; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 800a599be789..71e9914f93fa 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -333,10 +333,11 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { let res = if free.kind(infcx.tcx).is_type() { infcx.tcx.type_of(free.def_id).instantiate(infcx.tcx, free.args).fold_with(self).into() } else { - // FIXME(mgca): once const items are actual aliases defined as equal to type system consts - // this should instead use that rather than evaluating. - super::evaluate_const(infcx, free.to_term(infcx.tcx).expect_const(), self.param_env) - .super_fold_with(self) + infcx + .tcx + .const_of_item(free.def_id) + .instantiate(infcx.tcx, free.args) + .fold_with(self) .into() }; self.depth -= 1; @@ -436,51 +437,47 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx return ct; } - // Doing "proper" normalization of const aliases is inherently cyclic until const items - // are real aliases instead of having bodies. We gate proper const alias handling behind - // mgca to avoid breaking stable code, though this should become the "main" codepath long - // before mgca is stabilized. + let uv = match ct.kind() { + ty::ConstKind::Unevaluated(uv) => uv, + _ => return ct.super_fold_with(self), + }; + + // Note that the AssocConst and Const cases are unreachable on stable, + // unless a `min_generic_const_args` feature gate error has already + // been emitted earlier in compilation. // - // FIXME(BoxyUwU): Enabling this by default is blocked on a refactoring to how const items - // are represented. - if tcx.features().min_generic_const_args() { - let uv = match ct.kind() { - ty::ConstKind::Unevaluated(uv) => uv, - _ => return ct.super_fold_with(self), - }; - - let ct = match tcx.def_kind(uv.def) { - DefKind::AssocConst => match tcx.def_kind(tcx.parent(uv.def)) { - DefKind::Trait => self.normalize_trait_projection(uv.into()), - DefKind::Impl { of_trait: false } => { - self.normalize_inherent_projection(uv.into()) - } - kind => unreachable!( - "unexpected `DefKind` for const alias' resolution's parent def: {:?}", - kind - ), - }, - DefKind::Const | DefKind::AnonConst => self.normalize_free_alias(uv.into()), - kind => { - unreachable!("unexpected `DefKind` for const alias to resolve to: {:?}", kind) + // That's because we can only end up with an Unevaluated ty::Const for a const item + // if it was marked with `#[type_const]`. Using this attribute without the mgca + // feature gate causes a parse error. + let ct = match tcx.def_kind(uv.def) { + DefKind::AssocConst => match tcx.def_kind(tcx.parent(uv.def)) { + DefKind::Trait => self.normalize_trait_projection(uv.into()).expect_const(), + DefKind::Impl { of_trait: false } => { + self.normalize_inherent_projection(uv.into()).expect_const() } - }; + kind => unreachable!( + "unexpected `DefKind` for const alias' resolution's parent def: {:?}", + kind + ), + }, + DefKind::Const => self.normalize_free_alias(uv.into()).expect_const(), + DefKind::AnonConst => { + let ct = ct.super_fold_with(self); + super::with_replaced_escaping_bound_vars( + self.selcx.infcx, + &mut self.universes, + ct, + |ct| super::evaluate_const(self.selcx.infcx, ct, self.param_env), + ) + } + kind => { + unreachable!("unexpected `DefKind` for const alias to resolve to: {:?}", kind) + } + }; - // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be - // unnormalized after const evaluation returns. - ct.expect_const().super_fold_with(self) - } else { - let ct = ct.super_fold_with(self); - return super::with_replaced_escaping_bound_vars( - self.selcx.infcx, - &mut self.universes, - ct, - |ct| super::evaluate_const(self.selcx.infcx, ct, self.param_env), - ) - .super_fold_with(self); - // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be - // unnormalized after const evaluation returns. - } + // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be + // unnormalized after const evaluation returns. + ct.super_fold_with(self) } #[inline] diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index fea4b7cec62b..0906284e7019 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -546,7 +546,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( let term: Term<'tcx> = if alias_term.kind(tcx).is_type() { tcx.type_of(alias_term.def_id).instantiate(tcx, args).into() } else { - get_associated_const_value(selcx, alias_term.to_term(tcx).expect_const(), param_env).into() + tcx.const_of_item(alias_term.def_id).instantiate(tcx, args).into() }; let mut term = selcx.infcx.resolve_vars_if_possible(term); @@ -2034,14 +2034,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let term = if obligation.predicate.kind(tcx).is_type() { tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into()) } else { - ty::EarlyBinder::bind( - get_associated_const_value( - selcx, - obligation.predicate.to_term(tcx).expect_const(), - param_env, - ) - .into(), - ) + tcx.const_of_item(assoc_term.item.def_id).map_bound(|ct| ct.into()) }; let progress = if !tcx.check_args_compatible(assoc_term.item.def_id, args) { @@ -2133,15 +2126,3 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> { }) } } - -fn get_associated_const_value<'tcx>( - selcx: &mut SelectionContext<'_, 'tcx>, - alias_ct: ty::Const<'tcx>, - param_env: ty::ParamEnv<'tcx>, -) -> ty::Const<'tcx> { - // FIXME(mgca): We shouldn't be invoking ctfe here, instead const items should be aliases to type - // system consts that we can retrieve with some `query const_arg_of_alias` query. Evaluating the - // constant is "close enough" to getting the actual rhs of the const item for now even if it might - // lead to some cycles - super::evaluate_const(selcx.infcx, alias_ct, param_env) -} diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index fd5795c0fbcc..1d7ea9fe00a3 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -89,7 +89,7 @@ fn normalize_canonicalized_free_alias<'tcx>( let normalized_term = if goal.kind(tcx).is_type() { tcx.type_of(goal.def_id).instantiate(tcx, goal.args).into() } else { - todo!() + tcx.const_of_item(goal.def_id).instantiate(tcx, goal.args).into() }; Ok(NormalizationResult { normalized_term }) }, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index cc56201eb086..3884f29a4fc8 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -205,6 +205,7 @@ pub trait Interner: fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder; fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> ty::EarlyBinder; + fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder; type AdtDef: AdtDef; fn adt_def(self, adt_def_id: Self::AdtId) -> Self::AdtDef; diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs index 01cc05f2545f..72c1ab559bdf 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -1,6 +1,12 @@ //@ edition: 2024 -#![feature(associated_const_equality, type_alias_impl_trait, return_type_notation)] +#![feature( + associated_const_equality, + min_generic_const_args, + type_alias_impl_trait, + return_type_notation +)] +#![expect(incomplete_features)] #![allow(refining_impl_trait_internal)] use std::iter; @@ -45,6 +51,7 @@ fn mismatch_2() -> impl Iterator { trait Trait { type Gat; + #[type_const] const ASSOC: i32; fn foo() -> impl Sized; @@ -53,6 +60,7 @@ trait Trait { impl Trait for () { type Gat = (); + #[type_const] const ASSOC: i32 = 3; fn foo() {} @@ -61,6 +69,7 @@ impl Trait for () { impl Trait for u32 { type Gat = (); + #[type_const] const ASSOC: i32 = 4; fn foo() -> u32 { @@ -79,6 +88,7 @@ type MustFail = dyn Iterator; //~| ERROR conflicting associated type bounds trait Trait2 { + #[type_const] const ASSOC: u32; } diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index 1737d0dc5a38..a54425c3a295 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:9:5 + --> $DIR/duplicate-bound-err.rs:15:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -10,7 +10,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:13:5 + --> $DIR/duplicate-bound-err.rs:19:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -21,7 +21,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:17:5 + --> $DIR/duplicate-bound-err.rs:23:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -32,7 +32,7 @@ LL | iter::empty::() | +++++ error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:21:51 + --> $DIR/duplicate-bound-err.rs:27:51 | LL | type Tait1> = impl Copy; | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | type Tait1> = impl Copy; = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:23:51 + --> $DIR/duplicate-bound-err.rs:29:51 | LL | type Tait2> = impl Copy; | ^^^^^^^^^ @@ -48,7 +48,7 @@ LL | type Tait2> = impl Copy; = note: `Tait2` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:25:57 + --> $DIR/duplicate-bound-err.rs:31:57 | LL | type Tait3> = impl Copy; | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | type Tait3> = impl Copy; = note: `Tait3` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:28:14 + --> $DIR/duplicate-bound-err.rs:34:14 | LL | type Tait4 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | type Tait4 = impl Iterator; = note: `Tait4` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:30:14 + --> $DIR/duplicate-bound-err.rs:36:14 | LL | type Tait5 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | type Tait5 = impl Iterator; = note: `Tait5` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:32:14 + --> $DIR/duplicate-bound-err.rs:38:14 | LL | type Tait6 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | type Tait6 = impl Iterator; = note: `Tait6` must be used in combination with a concrete type within the same crate error[E0277]: `*const ()` cannot be sent between threads safely - --> $DIR/duplicate-bound-err.rs:35:18 + --> $DIR/duplicate-bound-err.rs:41:18 | LL | fn mismatch() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely @@ -91,7 +91,7 @@ LL | iter::empty::<*const ()>() = help: the trait `Send` is not implemented for `*const ()` error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/duplicate-bound-err.rs:40:20 + --> $DIR/duplicate-bound-err.rs:46:20 | LL | fn mismatch_2() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` @@ -100,7 +100,7 @@ LL | iter::empty::() | ----------------------- return type was inferred to be `std::iter::Empty` here error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:100:17 + --> $DIR/duplicate-bound-err.rs:110:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -109,7 +109,7 @@ LL | [2u32].into_iter() | ------------------ return type was inferred to be `std::array::IntoIter` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:77:42 + --> $DIR/duplicate-bound-err.rs:86:42 | LL | type MustFail = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -117,7 +117,7 @@ LL | type MustFail = dyn Iterator; | `Item` bound here first error: conflicting associated type bounds for `Item` - --> $DIR/duplicate-bound-err.rs:77:17 + --> $DIR/duplicate-bound-err.rs:86:17 | LL | type MustFail = dyn Iterator; | ^^^^^^^^^^^^^----------^^----------^ @@ -126,7 +126,7 @@ LL | type MustFail = dyn Iterator; | `Item` is specified to be `i32` here error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:85:43 + --> $DIR/duplicate-bound-err.rs:95:43 | LL | type MustFail2 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -134,7 +134,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` bound here first error: conflicting associated type bounds for `ASSOC` - --> $DIR/duplicate-bound-err.rs:85:18 + --> $DIR/duplicate-bound-err.rs:95:18 | LL | type MustFail2 = dyn Trait2; | ^^^^^^^^^^^------------^^------------^ @@ -143,7 +143,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` is specified to be `3` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:89:43 + --> $DIR/duplicate-bound-err.rs:99:43 | LL | type MustFail3 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -151,7 +151,7 @@ LL | type MustFail3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:92:43 + --> $DIR/duplicate-bound-err.rs:102:43 | LL | type MustFail4 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -159,19 +159,19 @@ LL | type MustFail4 = dyn Trait2; | `ASSOC` bound here first error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:100:17 + --> $DIR/duplicate-bound-err.rs:110:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | note: required by a bound in `Trait3::foo::{anon_assoc#0}` - --> $DIR/duplicate-bound-err.rs:96:31 + --> $DIR/duplicate-bound-err.rs:106:31 | LL | fn foo() -> impl Iterator; | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:108:16 + --> $DIR/duplicate-bound-err.rs:118:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -179,13 +179,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:71:32 + --> $DIR/duplicate-bound-err.rs:80:32 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` - --> $DIR/duplicate-bound-err.rs:109:16 + --> $DIR/duplicate-bound-err.rs:119:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` @@ -193,13 +193,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:71:44 + --> $DIR/duplicate-bound-err.rs:80:44 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:110:22 + --> $DIR/duplicate-bound-err.rs:120:22 | LL | uncallable_const(()); | ---------------- ^^ expected `4`, found `3` @@ -209,13 +209,13 @@ LL | uncallable_const(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:73:46 + --> $DIR/duplicate-bound-err.rs:82:46 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:111:22 + --> $DIR/duplicate-bound-err.rs:121:22 | LL | uncallable_const(4u32); | ---------------- ^^^^ expected `3`, found `4` @@ -225,13 +225,13 @@ LL | uncallable_const(4u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:73:35 + --> $DIR/duplicate-bound-err.rs:82:35 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:112:20 + --> $DIR/duplicate-bound-err.rs:122:20 | LL | uncallable_rtn(()); | -------------- ^^ expected `4`, found `3` @@ -241,13 +241,13 @@ LL | uncallable_rtn(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:75:75 + --> $DIR/duplicate-bound-err.rs:84:75 | LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} | ^^^^^^^^^ required by this bound in `uncallable_rtn` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:113:20 + --> $DIR/duplicate-bound-err.rs:123:20 | LL | uncallable_rtn(17u32); | -------------- ^^^^^ expected `3`, found `4` @@ -257,7 +257,7 @@ LL | uncallable_rtn(17u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:75:48 + --> $DIR/duplicate-bound-err.rs:84:48 | LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} | ^^^^^^^^^ required by this bound in `uncallable_rtn` diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs index 696710d76f6d..3f40e429260f 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -1,7 +1,8 @@ //@ edition: 2024 //@ run-pass -#![feature(associated_const_equality, return_type_notation)] +#![feature(associated_const_equality, min_generic_const_args, return_type_notation)] +#![expect(incomplete_features)] #![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)] use std::iter; @@ -188,6 +189,7 @@ trait Tra3 { trait Trait { type Gat; + #[type_const] const ASSOC: i32; fn foo() -> impl Sized; @@ -196,6 +198,7 @@ trait Trait { impl Trait for () { type Gat = (); + #[type_const] const ASSOC: i32 = 3; fn foo() {} From a7626dc9963040634fb56277c0252da72c795d9a Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 14 Oct 2025 02:25:13 +0100 Subject: [PATCH 498/525] Fix const qualifs under mgca --- .../rustc_const_eval/src/check_consts/qualifs.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 5b65f1726f6c..f50c6af53bf1 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -6,7 +6,9 @@ // having basically only two use-cases that act in different ways. use rustc_errors::ErrorGuaranteed; -use rustc_hir::LangItem; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::def::DefKind; +use rustc_hir::{LangItem, find_attr}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; use rustc_middle::ty::{self, AdtDef, Ty}; @@ -365,8 +367,14 @@ where // check performed after the promotion. Verify that with an assertion. assert!(promoted.is_none() || Q::ALLOW_PROMOTED); - // Don't peek inside trait associated constants. - if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() { + // Avoid looking at attrs of anon consts as that will ICE + let is_type_const_item = + matches!(cx.tcx.def_kind(def), DefKind::Const | DefKind::AssocConst) + && find_attr!(cx.tcx.get_all_attrs(def), AttributeKind::TypeConst(_)); + + // Don't peak inside trait associated constants, also `#[type_const] const` items + // don't have bodies so there's nothing to look at + if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !is_type_const_item { let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { From 0a355170c0ad0b057b072f76fdb35245d3bba009 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 13 Oct 2025 21:58:36 +0100 Subject: [PATCH 499/525] fix associated_const_equality tests --- .../src/hir_ty_lowering/bounds.rs | 30 +++++++++++++++++-- .../src/hir_ty_lowering/mod.rs | 14 +++++++-- compiler/rustc_middle/src/ty/assoc.rs | 20 ------------- compiler/rustc_passes/src/check_attr.rs | 13 ++------ .../assoc-const-eq-ambiguity.rs | 18 ++++++++--- .../assoc-const-eq-ambiguity.stderr | 27 +++++++++-------- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 4 ++- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 6 ++-- .../assoc-const-eq-bound-var-in-ty.rs | 4 ++- ...oc-const-eq-const_evaluatable_unchecked.rs | 8 +++-- .../assoc-const-eq-esc-bound-var-in-ty.rs | 4 ++- .../assoc-const-eq-esc-bound-var-in-ty.stderr | 2 +- .../assoc-const-eq-param-in-ty.rs | 5 +++- .../assoc-const-eq-param-in-ty.stderr | 22 +++++++------- .../assoc-const-eq-supertraits.rs | 4 ++- .../assoc-const-eq-ty-alias-noninteracting.rs | 5 +++- tests/ui/associated-consts/assoc-const.rs | 6 ++-- .../equality-unused-issue-126729.rs | 11 ++++++- .../associated-consts/issue-102335-const.rs | 4 ++- .../issue-102335-const.stderr | 4 +-- tests/ui/associated-consts/issue-110933.rs | 4 ++- .../projection-unspecified-but-bounded.rs | 4 ++- .../projection-unspecified-but-bounded.stderr | 4 +-- .../const-projection-err.gce.stderr | 15 ++-------- .../const-projection-err.rs | 6 ++-- .../const-projection-err.stock.stderr | 8 ++--- .../equality_bound_with_infer.rs | 11 ++++--- .../equality_bound_with_infer.stderr | 17 ----------- .../unconstrained_impl_param.rs | 2 +- .../unconstrained_impl_param.stderr | 19 ++---------- .../mgca/bad-type_const-syntax.rs | 3 +- .../mgca/bad-type_const-syntax.stderr | 8 +---- .../const-generics/mgca/projection-error.rs | 1 + .../mgca/projection-error.stderr | 4 +-- .../assoc-const-no-infer-ice-115806.rs | 3 +- .../assoc-const-no-infer-ice-115806.stderr | 2 +- .../associated-const-equality.rs | 11 +++++-- .../overlap-due-to-unsatisfied-const-bound.rs | 5 +++- ...rlap-due-to-unsatisfied-const-bound.stderr | 20 +++++++++---- 39 files changed, 194 insertions(+), 164 deletions(-) delete mode 100644 tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 1832e6e890b9..555ef5c45e12 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -4,9 +4,10 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; -use rustc_hir::PolyTraitRef; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::{PolyTraitRef, find_attr}; use rustc_middle::bug; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -602,7 +603,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { term, }) }); - bounds.push((bound.upcast(tcx), constraint.span)); + + if let ty::AssocTag::Const = assoc_tag + && !find_attr!( + self.tcx().get_all_attrs(assoc_item.def_id), + AttributeKind::TypeConst(_) + ) + { + if tcx.features().min_generic_const_args() + || tcx.features().associated_const_equality() + { + let mut err = self.dcx().struct_span_err( + constraint.span, + "use of trait associated const without `#[type_const]`", + ); + err.note("the declaration in the trait must be marked with `#[type_const]`"); + return Err(err.emit()); + } else { + let err = self.dcx().span_delayed_bug( + constraint.span, + "use of trait associated const without `#[type_const]`", + ); + return Err(err); + } + } else { + bounds.push((bound.upcast(tcx), constraint.span)); + } } // SelfTraitThatDefines is only interested in trait predicates. PredicateFilter::SelfTraitThatDefines(_) => {} 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 8ea4af9e1761..de65e4c6addf 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -27,9 +27,10 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err, }; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; +use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId, find_attr}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::DynCompatibilityViolation; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -1278,7 +1279,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { LowerTypeRelativePathMode::Const, )? { TypeRelativePath::AssocItem(def_id, args) => { - if !tcx.associated_item(def_id).is_type_const_capable(tcx) { + if !find_attr!(self.tcx().get_all_attrs(def_id), AttributeKind::TypeConst(_)) { let mut err = self.dcx().struct_span_err( span, "use of trait associated const without `#[type_const]`", @@ -1716,6 +1717,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::AssocTag::Const, ) { Ok((item_def_id, item_args)) => { + if !find_attr!(self.tcx().get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) { + let mut err = self.dcx().struct_span_err( + span, + "use of `const` in the type system without `#[type_const]`", + ); + err.note("the declaration must be marked with `#[type_const]`"); + return Const::new_error(self.tcx(), err.emit()); + } + let uv = ty::UnevaluatedConst::new(item_def_id, item_args); Const::new_unevaluated(self.tcx(), uv) } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 768646c76302..5e20bc142ffe 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -1,9 +1,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; -use rustc_hir::find_attr; use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{ErrorGuaranteed, Ident, Symbol}; @@ -173,24 +171,6 @@ impl AssocItem { pub fn is_impl_trait_in_trait(&self) -> bool { matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) }) } - - /// Returns true if: - /// - This trait associated item has the `#[type_const]` attribute, - /// - If it is in a trait impl, the item from the original trait has this attribute, or - /// - It is an inherent assoc const. - pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool { - if !matches!(self.kind, ty::AssocKind::Const { .. }) { - return false; - } - - let def_id = match self.container { - AssocContainer::Trait => self.def_id, - AssocContainer::TraitImpl(Ok(trait_item_did)) => trait_item_did, - AssocContainer::TraitImpl(Err(_)) => return false, - AssocContainer::InherentImpl => return true, - }; - find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) - } } #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ef42c42f68b3..91453e0c1d42 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2102,19 +2102,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { - let tcx = self.tcx; - if target == Target::AssocConst - && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) - && self.tcx.def_kind(parent) == DefKind::Trait - { + fn check_type_const(&self, _hir_id: HirId, attr_span: Span, target: Target) { + if matches!(target, Target::AssocConst | Target::Const) { return; } else { self.dcx() - .struct_span_err( - attr_span, - "`#[type_const]` must only be applied to trait associated constants", - ) + .struct_span_err(attr_span, "`#[type_const]` must only be applied to const items") .emit(); } } diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs index ac085864ff09..d433af6bdd57 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs @@ -1,17 +1,27 @@ // We used to say "ambiguous associated type" on ambiguous associated consts. // Ensure that we now use the correct label. -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait0: Parent0 + Parent0 {} -trait Parent0 { const K: (); } +trait Parent0 { + #[type_const] + const K: (); +} fn take0(_: impl Trait0) {} //~^ ERROR ambiguous associated constant `K` in bounds of `Trait0` trait Trait1: Parent1 + Parent2 {} -trait Parent1 { const C: i32; } -trait Parent2 { const C: &'static str; } +trait Parent1 { + #[type_const] + const C: i32; +} +trait Parent2 { + #[type_const] + const C: &'static str; +} fn take1(_: impl Trait1) {} //~^ ERROR ambiguous associated constant `C` in bounds of `Trait1` diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr index aa1db4cb032e..3541664d1c6a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr @@ -1,12 +1,12 @@ error[E0222]: ambiguous associated constant `K` in bounds of `Trait0` - --> $DIR/assoc-const-eq-ambiguity.rs:9:25 + --> $DIR/assoc-const-eq-ambiguity.rs:13:25 | -LL | trait Parent0 { const K: (); } - | ----------- - | | - | ambiguous `K` from `Parent0` - | ambiguous `K` from `Parent0` -LL | +LL | const K: (); + | ----------- + | | + | ambiguous `K` from `Parent0` + | ambiguous `K` from `Parent0` +... LL | fn take0(_: impl Trait0) {} | ^^^^^^^^^^ ambiguous associated constant `K` | @@ -17,13 +17,14 @@ LL | fn take0(_: impl Trait0) {} T: Parent0::K = { () } error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` - --> $DIR/assoc-const-eq-ambiguity.rs:16:25 + --> $DIR/assoc-const-eq-ambiguity.rs:26:25 | -LL | trait Parent1 { const C: i32; } - | ------------ ambiguous `C` from `Parent1` -LL | trait Parent2 { const C: &'static str; } - | --------------------- ambiguous `C` from `Parent2` -LL | +LL | const C: i32; + | ------------ ambiguous `C` from `Parent1` +... +LL | const C: &'static str; + | --------------------- ambiguous `C` from `Parent2` +... LL | fn take1(_: impl Trait1) {} | ^^^^^^^ ambiguous associated constant `C` diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index e583b12b1d70..f6240ead0b9b 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -1,8 +1,10 @@ // Check that we eventually catch types of assoc const bounds // (containing late-bound vars) that are ill-formed. -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait { + #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 42e084f39c01..b629bb4d3f8c 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 | LL | K = { () } | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 | LL | K = { () } | ^^^^^^ @@ -13,7 +13,7 @@ LL | K = { () } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:10:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 | LL | _: impl Trait< | _____________^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index 7fc6d564ca44..36b3d8a648fd 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -3,9 +3,11 @@ // //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait { + #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs b/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs index 4b6de6f56d55..22a03e47b2f7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs +++ b/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs @@ -4,9 +4,13 @@ // // issue: //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] -pub trait TraitA { const K: u8 = 0; } +pub trait TraitA { + #[type_const] + const K: u8 = 0; +} pub trait TraitB {} impl TraitA for () {} diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 6db1e85ccfa6..3f48b3bfbb6d 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -1,8 +1,10 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait<'a> { + #[type_const] const K: &'a (); } diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index 349fddcafe8b..d6a7eb6cfc7d 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:9:35 + --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:11:35 | LL | fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 06fd0a024f00..5b0438e95695 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -1,8 +1,10 @@ // Regression test for issue #108271. // Detect and reject generic params in the type of assoc consts used in an equality bound. -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait<'a, T: 'a, const N: usize> { + #[type_const] const K: &'a [T; N]; } @@ -21,6 +23,7 @@ fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~| NOTE `K` has type `&'r [A; Q]` trait Project { + #[type_const] const SELF: Self; } diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index 6b7b714fff10..7ba1d638baa8 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:9:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 | LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` @@ -7,7 +7,7 @@ LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} } = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:9:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 | LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` @@ -15,7 +15,7 @@ LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} } = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:9:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 | LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} | - ^ its type must not depend on the const parameter `Q` @@ -25,7 +25,7 @@ LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} } = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:27:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:30:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------ @@ -34,7 +34,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:32:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:35:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -44,7 +44,7 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | trait Iface<'r> { | -- the lifetime parameter `'r` is defined here @@ -55,7 +55,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -63,7 +63,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -73,7 +73,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | trait Iface<'r> { | -- the lifetime parameter `'r` is defined here @@ -85,7 +85,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -94,7 +94,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:41:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index d5d724c9b153..301ddf2d0104 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -3,11 +3,13 @@ //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait: SuperTrait {} trait SuperTrait: SuperSuperTrait {} trait SuperSuperTrait { + #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs index 76df014ccd9b..febd838e2c2e 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs @@ -5,16 +5,19 @@ //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait Trait: SuperTrait { type N; type Q; + #[type_const] const N: usize; } trait SuperTrait { + #[type_const] const Q: &'static str; } diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/associated-consts/assoc-const.rs index 5b272cfeb0c2..4eed8bba53b1 100644 --- a/tests/ui/associated-consts/assoc-const.rs +++ b/tests/ui/associated-consts/assoc-const.rs @@ -1,14 +1,16 @@ //@ run-pass -#![feature(associated_const_equality)] -#![allow(unused)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(unused, incomplete_features)] pub trait Foo { + #[type_const] const N: usize; } pub struct Bar; impl Foo for Bar { + #[type_const] const N: usize = 3; } diff --git a/tests/ui/associated-consts/equality-unused-issue-126729.rs b/tests/ui/associated-consts/equality-unused-issue-126729.rs index 1482b874b9d6..35b49314b5f5 100644 --- a/tests/ui/associated-consts/equality-unused-issue-126729.rs +++ b/tests/ui/associated-consts/equality-unused-issue-126729.rs @@ -1,25 +1,32 @@ //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] #![deny(dead_code)] trait Tr { + #[type_const] const I: i32; } impl Tr for () { + #[type_const] const I: i32 = 1; } fn foo() -> impl Tr {} trait Tr2 { + #[type_const] const J: i32; + #[type_const] const K: i32; } impl Tr2 for () { + #[type_const] const J: i32 = 1; + #[type_const] const K: i32 = 1; } @@ -27,10 +34,12 @@ fn foo2() -> impl Tr2 {} mod t { pub trait Tr3 { + #[type_const] const L: i32; } impl Tr3 for () { + #[type_const] const L: i32 = 1; } } diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs index fd922cd0f1d8..f9b816fd3bc9 100644 --- a/tests/ui/associated-consts/issue-102335-const.rs +++ b/tests/ui/associated-consts/issue-102335-const.rs @@ -1,4 +1,5 @@ -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] trait T { type A: S = 34>; @@ -7,6 +8,7 @@ trait T { } trait S { + #[type_const] const C: i32; } diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/associated-consts/issue-102335-const.stderr index cf96c8cf8eb9..536e39e5522d 100644 --- a/tests/ui/associated-consts/issue-102335-const.stderr +++ b/tests/ui/associated-consts/issue-102335-const.stderr @@ -1,5 +1,5 @@ error[E0229]: associated item constraints are not allowed here - --> $DIR/issue-102335-const.rs:4:17 + --> $DIR/issue-102335-const.rs:5:17 | LL | type A: S = 34>; | ^^^^^^^^ associated item constraint not allowed here @@ -11,7 +11,7 @@ LL + type A: S; | error[E0229]: associated item constraints are not allowed here - --> $DIR/issue-102335-const.rs:4:17 + --> $DIR/issue-102335-const.rs:5:17 | LL | type A: S = 34>; | ^^^^^^^^ associated item constraint not allowed here diff --git a/tests/ui/associated-consts/issue-110933.rs b/tests/ui/associated-consts/issue-110933.rs index efd7e13e4bcd..0284369f4d65 100644 --- a/tests/ui/associated-consts/issue-110933.rs +++ b/tests/ui/associated-consts/issue-110933.rs @@ -1,8 +1,10 @@ //@ check-pass -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] pub trait Trait { + #[type_const] const ASSOC: usize; } diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs index b1a0f39962b6..7f3304f07656 100644 --- a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -1,8 +1,10 @@ -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] // Issue 110549 pub trait TraitWAssocConst { + #[type_const] const A: usize; } diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr index 91bfcf29cb37..232b15b7e981 100644 --- a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/projection-unspecified-but-bounded.rs:12:11 + --> $DIR/projection-unspecified-but-bounded.rs:14:11 | LL | foo::(); | ^ expected `32`, found `::A` @@ -7,7 +7,7 @@ LL | foo::(); = note: expected constant `32` found constant `::A` note: required by a bound in `foo` - --> $DIR/projection-unspecified-but-bounded.rs:9:28 + --> $DIR/projection-unspecified-but-bounded.rs:11:28 | LL | fn foo>() {} | ^^^^^^ required by this bound in `foo` diff --git a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr b/tests/ui/associated-type-bounds/const-projection-err.gce.stderr index 0b6207074979..9ad851d188d3 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr +++ b/tests/ui/associated-type-bounds/const-projection-err.gce.stderr @@ -1,24 +1,15 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-projection-err.rs:4:26 - | -LL | #![cfg_attr(gce, feature(generic_const_exprs))] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:14:11 + --> $DIR/const-projection-err.rs:16:11 | LL | foo::(); | ^ expected `0`, found `1` | note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:11:28 + --> $DIR/const-projection-err.rs:13:28 | LL | fn foo>() {} | ^^^^^ required by this bound in `foo` -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 E0271`. diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/associated-type-bounds/const-projection-err.rs index 22f1897c07f1..80845ec3ee86 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.rs +++ b/tests/ui/associated-type-bounds/const-projection-err.rs @@ -1,10 +1,12 @@ //@ revisions: stock gce -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] +#![allow(incomplete_features)] + #![cfg_attr(gce, feature(generic_const_exprs))] -//[gce]~^ WARN the feature `generic_const_exprs` is incomplete trait TraitWAssocConst { + #[type_const] const A: usize; } diff --git a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr index e782571c7dea..0cacec26aaee 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr +++ b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr @@ -1,13 +1,13 @@ error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:14:11 + --> $DIR/const-projection-err.rs:16:11 | LL | foo::(); - | ^ expected `1`, found `::A` + | ^ expected `1`, found `0` | = note: expected constant `1` - found constant `::A` + found constant `0` note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:11:28 + --> $DIR/const-projection-err.rs:13:28 | LL | fn foo>() {} | ^^^^^ required by this bound in `foo` diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs index dc42e00c2e83..3973c7af15b4 100644 --- a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs +++ b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs @@ -1,14 +1,18 @@ -#![feature(associated_const_equality, generic_const_items)] +//@ check-pass + +#![feature(associated_const_equality, min_generic_const_args, generic_const_items)] #![expect(incomplete_features)] // Regression test for #133066 where we would try to evaluate `<() as Foo>::ASSOC<_>` even // though it contained inference variables, which would cause ICEs. trait Foo { + #[type_const] const ASSOC: u32; } impl Foo for () { + #[type_const] const ASSOC: u32 = N; } @@ -16,9 +20,4 @@ fn bar = 10>>() {} fn main() { bar::<_, ()>(); - //~^ ERROR: type mismatch resolving `<() as Foo>::ASSOC<_> == 10` - - // FIXME(mgca): - // FIXME(associated_const_equality): - // This ought to start compiling once const items are aliases rather than bodies } diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr deleted file mode 100644 index 00741c901e4c..000000000000 --- a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0271]: type mismatch resolving `<() as Foo>::ASSOC<_> == 10` - --> $DIR/equality_bound_with_infer.rs:18:14 - | -LL | bar::<_, ()>(); - | ^^ expected `10`, found `<() as Foo>::ASSOC::<_>` - | - = note: expected constant `10` - found constant `<() as Foo>::ASSOC::<_>` -note: required by a bound in `bar` - --> $DIR/equality_bound_with_infer.rs:15:29 - | -LL | fn bar = 10>>() {} - | ^^^^^^^^^^^^^ required by this bound in `bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs index 99318ef75984..edadcd7c80ed 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs +++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs @@ -19,7 +19,7 @@ impl Trait for () where (U,): AssocConst {} fn foo() where (): Trait, - //~^ ERROR type mismatch resolving + //~^ ERROR type annotations needed { } diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr index e6799ec5c3aa..4106c500215b 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr @@ -14,26 +14,13 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self LL | impl Trait for () where (U,): AssocConst {} | ^ unconstrained type parameter -error[E0271]: type mismatch resolving `<(_,) as AssocConst>::A == 0` +error[E0282]: type annotations needed --> $DIR/unconstrained_impl_param.rs:21:5 | LL | (): Trait, - | ^^^^^^^^^ expected `0`, found `<(_,) as AssocConst>::A` - | - = note: expected constant `0` - found constant `<(_,) as AssocConst>::A` -note: required for `()` to implement `Trait` - --> $DIR/unconstrained_impl_param.rs:15:9 - | -LL | impl Trait for () where (U,): AssocConst {} - | ^^^^^ ^^ --------- unsatisfied trait bound introduced here - = help: see issue #48214 -help: add `#![feature(trivial_bounds)]` to the crate attributes to enable - | -LL + #![feature(trivial_bounds)] - | + | ^^^^^^^^^ cannot infer type for type parameter `U` error: aborting due to 3 previous errors -Some errors have detailed explanations: E0207, E0271, E0658. +Some errors have detailed explanations: E0207, E0282, E0658. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs index 1e9673a56b56..bb5bdb8d7c4c 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs @@ -9,8 +9,7 @@ struct S; impl Tr for S { #[type_const] - //~^ ERROR must only be applied to trait associated constants - //~| ERROR experimental + //~^ ERROR experimental const N: usize = 0; } diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index 125c778ef1cd..df442c22241b 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -27,13 +27,7 @@ LL | #[type_const()] | | didn't expect any arguments here | help: must be of the form: `#[type_const]` -error: `#[type_const]` must only be applied to trait associated constants - --> $DIR/bad-type_const-syntax.rs:11:5 - | -LL | #[type_const] - | ^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0565, E0658. For more information about an error, try `rustc --explain E0565`. diff --git a/tests/ui/const-generics/mgca/projection-error.rs b/tests/ui/const-generics/mgca/projection-error.rs index d1c4fa8a492d..edb6db098084 100644 --- a/tests/ui/const-generics/mgca/projection-error.rs +++ b/tests/ui/const-generics/mgca/projection-error.rs @@ -7,6 +7,7 @@ pub trait Tr { + #[type_const] const SIZE: usize; } diff --git a/tests/ui/const-generics/mgca/projection-error.stderr b/tests/ui/const-generics/mgca/projection-error.stderr index e6888351da13..e60acf9144b5 100644 --- a/tests/ui/const-generics/mgca/projection-error.stderr +++ b/tests/ui/const-generics/mgca/projection-error.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:13:17 + --> $DIR/projection-error.rs:14:17 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here @@ -17,7 +17,7 @@ LL | fn mk_array(_x: T) -> [(); >::SIZE] {} | +++ error[E0412]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:13:29 + --> $DIR/projection-error.rs:14:29 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 2607013ec633..57b748a6b475 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] #![allow(incomplete_features)] pub struct NoPin; @@ -8,6 +8,7 @@ pub struct NoPin; impl Pins for NoPin {} pub trait PinA { + #[type_const] const A: &'static () = &(); } diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index 9a9baaddcba3..34546349592f 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` - --> $DIR/assoc-const-no-infer-ice-115806.rs:16:1 + --> $DIR/assoc-const-no-infer-ice-115806.rs:17:1 | LL | impl Pins for NoPin {} | --------------------------- first implementation here diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs index c0179f02fd2e..0620998188b2 100644 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ b/tests/ui/generic-const-items/associated-const-equality.rs @@ -1,17 +1,24 @@ //@ check-pass -#![feature(generic_const_items, associated_const_equality, adt_const_params)] +#![feature(generic_const_items, min_generic_const_args)] +#![feature(associated_const_equality, adt_const_params)] #![allow(incomplete_features)] trait Owner { + #[type_const] const C: u32; + #[type_const] const K: u32; + #[type_const] const Q: Maybe; } impl Owner for () { + #[type_const] const C: u32 = N; - const K: u32 = N + 1; + #[type_const] + const K: u32 = 99 + 1; + #[type_const] const Q: Maybe = Maybe::Nothing; } diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs index f4cde1d62b2c..edea6f75444f 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs @@ -1,12 +1,15 @@ // Regression test for #140571. The compiler used to ICE -#![feature(associated_const_equality, specialization)] +#![feature(associated_const_equality, min_generic_const_args, specialization)] //~^ WARN the feature `specialization` is incomplete +//~| WARN the feature `min_generic_const_args` is incomplete pub trait IsVoid { + #[type_const] const IS_VOID: bool; } impl IsVoid for T { + #[type_const] default const IS_VOID: bool = false; } diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr index a26b30fbb633..bf15d0fae4e5 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr @@ -1,21 +1,29 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39 | -LL | #![feature(associated_const_equality, specialization)] - | ^^^^^^^^^^^^^^ +LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:63 + | +LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^ | = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()` - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:18:1 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:21:1 | LL | impl Maybe for T {} | ---------------------- first implementation here LL | impl Maybe for () where T: NotVoid + ?Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0119`. From d663152fa700d33d951f55c0a20c26f8f5e94787 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 14 Oct 2025 03:46:25 +0100 Subject: [PATCH 500/525] use right span for inferrable ret ty --- compiler/rustc_hir/src/hir.rs | 7 ++++++ .../rustc_hir_analysis/src/collect/type_of.rs | 23 +++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 870c5de47acc..58fb3798d17d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -416,6 +416,13 @@ impl<'hir> ConstItemRhs<'hir> { ConstItemRhs::TypeConst(ct_arg) => ct_arg.hir_id, } } + + pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span { + match self { + ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span, + ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(), + } + } } /// A constant that enters the type system, used for arguments to const generics (e.g. array lengths). diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f44899a323d8..f9aae54bbcdb 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -166,6 +166,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ def_id, ct_arg.hir_id(), ty.span, + ct_arg.span(tcx), item.ident, "associated constant", ) @@ -190,6 +191,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ def_id, ct_arg.hir_id(), ty.span, + ct_arg.span(tcx), item.ident, "associated constant", ) @@ -214,6 +216,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ def_id, body_id.hir_id, ty.span, + tcx.hir_body(body_id).value.span, ident, "static variable", ) @@ -236,6 +239,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ def_id, body.hir_id(), ty.span, + body.span(tcx), ident, "constant", ) @@ -426,7 +430,8 @@ fn infer_placeholder_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, hir_id: HirId, - span: Span, + ty_span: Span, + body_span: Span, item_ident: Ident, kind: &'static str, ) -> Ty<'tcx> { @@ -439,10 +444,10 @@ fn infer_placeholder_type<'tcx>( // us to improve in typeck so we do that now. let guar = cx .dcx() - .try_steal_modify_and_emit_err(span, StashKey::ItemNoType, |err| { + .try_steal_modify_and_emit_err(ty_span, StashKey::ItemNoType, |err| { if !ty.references_error() { // Only suggest adding `:` if it was missing (and suggested by parsing diagnostic). - let colon = if span == item_ident.span.shrink_to_hi() { ":" } else { "" }; + let colon = if ty_span == item_ident.span.shrink_to_hi() { ":" } else { "" }; // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type. // We are typeck and have the real type, so remove that and suggest the actual type. @@ -452,14 +457,14 @@ fn infer_placeholder_type<'tcx>( if let Some(ty) = ty.make_suggestable(tcx, false, None) { err.span_suggestion( - span, + ty_span, format!("provide a type for the {kind}"), format!("{colon} {ty}"), Applicability::MachineApplicable, ); } else { with_forced_trimmed_paths!(err.span_note( - tcx.hir_span(hir_id), + body_span, format!("however, the inferred type `{ty}` cannot be named"), )); } @@ -473,7 +478,7 @@ fn infer_placeholder_type<'tcx>( } // If we didn't find any infer tys, then just fallback to `span`. if visitor.spans.is_empty() { - visitor.spans.push(span); + visitor.spans.push(ty_span); } let mut diag = bad_placeholder(cx, visitor.spans, kind); @@ -482,20 +487,20 @@ fn infer_placeholder_type<'tcx>( // same span. If this happens, we will fall through to this arm, so // we need to suppress the suggestion since it's invalid. Ideally we // would suppress the duplicated error too, but that's really hard. - if span.is_empty() && span.from_expansion() { + if ty_span.is_empty() && ty_span.from_expansion() { // An approximately better primary message + no suggestion... diag.primary_message("missing type for item"); } else if !ty.references_error() { if let Some(ty) = ty.make_suggestable(tcx, false, None) { diag.span_suggestion_verbose( - span, + ty_span, "replace this with a fully-specified type", ty, Applicability::MachineApplicable, ); } else { with_forced_trimmed_paths!(diag.span_note( - tcx.hir_span(hir_id), + body_span, format!("however, the inferred type `{ty}` cannot be named"), )); } From f532622aa8cf6e5a16654e25770e53a796489af3 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 31 Oct 2025 17:25:45 -0400 Subject: [PATCH 501/525] Fix rustdoc --- src/librustdoc/clean/mod.rs | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 33247fa855d9..eed75b0a5240 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -306,24 +306,23 @@ pub(crate) fn clean_precise_capturing_arg( } } -pub(crate) fn clean_const<'tcx>( - constant: &hir::ConstArg<'tcx>, - // Used for mgca representation of const item bodies. - parent_if_item_body: Option, - _cx: &mut DocContext<'tcx>, +pub(crate) fn clean_const_item_rhs<'tcx>( + ct_rhs: hir::ConstItemRhs<'tcx>, + parent: DefId, ) -> ConstantKind { + match ct_rhs { + hir::ConstItemRhs::Body(body) => ConstantKind::Local { def_id: parent, body }, + hir::ConstItemRhs::TypeConst(ct) => clean_const(ct), + } +} + +pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind { match &constant.kind { hir::ConstArgKind::Path(qpath) => { ConstantKind::Path { path: qpath_to_string(qpath).into() } } - hir::ConstArgKind::Anon(anon) => { - if let Some(def_id) = parent_if_item_body { - ConstantKind::Local { def_id, body: anon.body } - } else { - ConstantKind::Anonymous { body: anon.body } - } - } - hir::ConstArgKind::Infer(..) => ConstantKind::Infer, + hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, + hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, } } @@ -1202,7 +1201,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Const(ty, Some(default)) => { ProvidedAssocConstItem(Box::new(Constant { generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), - kind: clean_const(default, Some(local_did), cx), + kind: clean_const_item_rhs(default, local_did), type_: clean_ty(ty, cx), })) } @@ -1252,7 +1251,7 @@ pub(crate) fn clean_impl_item<'tcx>( let inner = match impl_.kind { hir::ImplItemKind::Const(ty, expr) => ImplAssocConstItem(Box::new(Constant { generics: clean_generics(impl_.generics, cx), - kind: clean_const(expr, Some(local_did), cx), + kind: clean_const_item_rhs(expr, local_did), type_: clean_ty(ty, cx), })), hir::ImplItemKind::Fn(ref sig, body) => { @@ -1807,7 +1806,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T // results in an ICE while manually constructing the constant and using `eval` // does nothing for `ConstKind::Param`. let length = match const_arg.kind { - hir::ConstArgKind::Infer(..) => "_".to_string(), + hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => "_".to_string(), hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); @@ -2524,7 +2523,7 @@ fn clean_generic_args<'tcx>( hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)), hir::GenericArg::Const(ct) => { - GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), None, cx))) + GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct()))) } hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) @@ -2796,7 +2795,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Const(_, generics, ty, body) => ConstantItem(Box::new(Constant { generics: clean_generics(generics, cx), type_: clean_ty(ty, cx), - kind: clean_const(body, Some(def_id), cx), + kind: clean_const_item_rhs(body, def_id), })), ItemKind::TyAlias(_, generics, ty) => { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; From 91054e80426fe00d8c7d2de51a2b259170abe97e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 1 Nov 2025 13:52:11 -0400 Subject: [PATCH 502/525] Fix clippy When mgca is enabled, const rhs's that are paths may have false negatives with the lints in non_copy_const.rs. But these should probably be using the trait solver anyway, and it only happens under mgca. --- .../clippy/clippy_lints/src/non_copy_const.rs | 73 +++++++++++-------- .../src/undocumented_unsafe_blocks.rs | 29 +++++++- .../clippy/clippy_lints/src/utils/author.rs | 1 + .../clippy/clippy_utils/src/ast_utils/mod.rs | 13 +++- src/tools/clippy/clippy_utils/src/consts.rs | 16 +++- .../clippy/clippy_utils/src/hir_utils.rs | 6 +- src/tools/clippy/clippy_utils/src/msrvs.rs | 16 ++-- .../clippy/tests/ui/needless_doc_main.rs | 6 +- .../ui/trait_duplication_in_bounds.fixed | 11 +-- .../tests/ui/trait_duplication_in_bounds.rs | 11 +-- .../ui/trait_duplication_in_bounds.stderr | 8 +- ...duplication_in_bounds_assoc_const_eq.fixed | 14 ++++ ...it_duplication_in_bounds_assoc_const_eq.rs | 14 ++++ ...uplication_in_bounds_assoc_const_eq.stderr | 14 ++++ 14 files changed, 157 insertions(+), 75 deletions(-) create mode 100644 src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed create mode 100644 src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs create mode 100644 src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 2fffc4244a73..3c3e5fea4970 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ // definitely contains interior mutability. use clippy_config::Conf; -use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::consts::{ConstEvalCtxt, Constant, const_item_rhs_to_expr}; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::is_in_const_context; use clippy_utils::macros::macro_backtrace; @@ -28,7 +28,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ - Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, StructTailExpr, TraitItem, TraitItemKind, UnOp, + ConstArgKind, ConstItemRhs, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, StructTailExpr, + TraitItem, TraitItemKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::mir::{ConstValue, UnevaluatedConst}; @@ -272,6 +273,7 @@ impl<'tcx> NonCopyConst<'tcx> { /// Checks if a value of the given type is `Freeze`, or may be depending on the value. fn is_ty_freeze(&mut self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>) -> IsFreeze { + // FIXME: this should probably be using the trait solver let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); match self.freeze_tys.entry(ty) { Entry::Occupied(e) => *e.get(), @@ -695,7 +697,7 @@ impl<'tcx> NonCopyConst<'tcx> { impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Const(ident, .., body_id) = item.kind + if let ItemKind::Const(ident, .., ct_rhs) = item.kind && !ident.is_special() && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { @@ -703,13 +705,14 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { IsFreeze::Yes => false, IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze, - _ => !self.is_init_expr_freeze( + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).map_or(false, |e| !self.is_init_expr_freeze( cx.tcx, cx.typing_env(), cx.tcx.typeck(item.owner_id), GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + e + )), }, } && !item.span.in_external_macro(cx.sess().source_map()) @@ -736,22 +739,25 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Const(_, body_id_opt) = item.kind + if let TraitItemKind::Const(_, ct_rhs_opt) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, - IsFreeze::Maybe if let Some(body_id) = body_id_opt => { + IsFreeze::Maybe if let Some(ct_rhs) = ct_rhs_opt => { match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => { !is_freeze }, - _ => !self.is_init_expr_freeze( - cx.tcx, - cx.typing_env(), - cx.tcx.typeck(item.owner_id), - GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).map_or(false, |e| { + !self.is_init_expr_freeze( + cx.tcx, + cx.typing_env(), + cx.tcx.typeck(item.owner_id), + GenericArgs::identity_for_item(cx.tcx, item.owner_id), + e, + ) + }), } }, IsFreeze::Yes | IsFreeze::Maybe => false, @@ -768,7 +774,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if let ImplItemKind::Const(_, body_id) = item.kind + if let ImplItemKind::Const(_, ct_rhs) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::Yes => false, @@ -799,13 +805,16 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { // interior mutability. IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze, - _ => !self.is_init_expr_freeze( - cx.tcx, - cx.typing_env(), - cx.tcx.typeck(item.owner_id), - GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).map_or(false, |e| { + !self.is_init_expr_freeze( + cx.tcx, + cx.typing_env(), + cx.tcx.typeck(item.owner_id), + GenericArgs::identity_for_item(cx.tcx, item.owner_id), + e, + ) + }), }, } && !item.span.in_external_macro(cx.sess().source_map()) @@ -913,20 +922,26 @@ fn get_const_hir_value<'tcx>( args: GenericArgsRef<'tcx>, ) -> Option<(&'tcx TypeckResults<'tcx>, &'tcx Expr<'tcx>)> { let did = did.as_local()?; - let (did, body_id) = match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { - Node::Item(item) if let ItemKind::Const(.., body_id) = item.kind => (did, body_id), - Node::ImplItem(item) if let ImplItemKind::Const(.., body_id) = item.kind => (did, body_id), + let (did, ct_rhs) = match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { + Node::Item(item) if let ItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), + Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), Node::TraitItem(_) if let Ok(Some(inst)) = Instance::try_resolve(tcx, typing_env, did.into(), args) && let Some(did) = inst.def_id().as_local() => { match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { - Node::ImplItem(item) if let ImplItemKind::Const(.., body_id) = item.kind => (did, body_id), - Node::TraitItem(item) if let TraitItemKind::Const(.., Some(body_id)) = item.kind => (did, body_id), + Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), + Node::TraitItem(item) if let TraitItemKind::Const(.., Some(ct_rhs)) = item.kind => (did, ct_rhs), _ => return None, } }, _ => return None, }; - Some((tcx.typeck(did), tcx.hir_body(body_id).value)) + match ct_rhs { + ConstItemRhs::Body(body_id) => Some((tcx.typeck(did), tcx.hir_body(body_id).value)), + ConstItemRhs::TypeConst(ct_arg) => match ct_arg.kind { + ConstArgKind::Anon(anon_const) => Some((tcx.typeck(did), tcx.hir_body(anon_const.body).value)), + _ => None, + }, + } } diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 9935dc309611..11d3f33331cb 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -2,6 +2,7 @@ use std::ops::ControlFlow; use std::sync::Arc; use clippy_config::Conf; +use clippy_utils::consts::const_item_rhs_to_expr; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_lint_allowed; use clippy_utils::source::walk_span_to_context; @@ -184,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } } - fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &hir::Item<'tcx>) { if item.span.in_external_macro(cx.tcx.sess.source_map()) { return; } @@ -214,7 +215,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } } -fn check_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>, (span, help_span): (Span, Span), is_doc: bool) { +fn check_has_safety_comment<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, (span, help_span): (Span, Span), is_doc: bool) { match &item.kind { ItemKind::Impl(Impl { of_trait: Some(of_trait), @@ -234,7 +235,29 @@ fn check_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>, (span, h }, ItemKind::Impl(_) => {}, // const and static items only need a safety comment if their body is an unsafe block, lint otherwise - &ItemKind::Const(.., body) | &ItemKind::Static(.., body) => { + &ItemKind::Const(.., ct_rhs) => { + if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, ct_rhs.hir_id()) { + let expr = const_item_rhs_to_expr(cx.tcx, ct_rhs); + if let Some(expr) = expr && !matches!( + expr.kind, hir::ExprKind::Block(block, _) + if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + ) { + span_lint_and_then( + cx, + UNNECESSARY_SAFETY_COMMENT, + span, + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), + |diag| { + diag.span_help(help_span, "consider removing the safety comment"); + }, + ); + } + } + } + &ItemKind::Static(.., body) => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { let body = cx.tcx.hir_body(body); if !matches!( diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 222427cd3075..d7180f4908d0 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -320,6 +320,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.body(field!(anon_const.body)); }, ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), + ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index f5e61e365c57..68fa3d191d28 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -374,7 +374,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_deref(), rb.as_deref(), |l, r| eq_anon_const(l, r)) + && both(lb.as_ref(), rb.as_ref(), |l, r| eq_const_item_rhs(l, r)) }, ( Fn(box ast::Fn { @@ -628,7 +628,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_deref(), rb.as_deref(), |l, r| eq_anon_const(l, r)) + && both(lb.as_ref(), rb.as_ref(), |l, r| eq_const_item_rhs(l, r)) }, ( Fn(box ast::Fn { @@ -786,6 +786,15 @@ pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { eq_expr(&l.value, &r.value) } +pub fn eq_const_item_rhs(l: &ConstItemRhs, r: &ConstItemRhs) -> bool { + use ConstItemRhs::*; + match (l, r) { + (TypeConst(l), TypeConst(r)) => eq_anon_const(l, r), + (Body(l), Body(r)) => eq_expr(l, r), + (TypeConst(..), Body(..)) | (Body(..), TypeConst(..)) => false, + } +} + pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { use UseTreeKind::*; match (l, r) { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 7b8c7f3f0d6b..ac408a1b59e5 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -13,7 +13,10 @@ use rustc_apfloat::Float; use rustc_apfloat::ieee::{Half, Quad}; use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath, TyKind, UnOp}; +use rustc_hir::{ + BinOpKind, Block, ConstArgKind, ConstBlock, ConstItemRhs, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath, + TyKind, UnOp, +}; use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; @@ -1130,3 +1133,14 @@ pub fn integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) pub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool { integer_const(cx, expr, ctxt) == Some(0) } + +pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx>) -> Option<&'tcx Expr<'tcx>> { + match ct_rhs { + ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), + ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { + ConstArgKind::Path(_) => None, + ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), + ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, + }, + } +} diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 710b88e92154..dd411fe21bdd 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -481,7 +481,9 @@ impl HirEqInterExpr<'_, '_, '_> { (ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) | (ConstArgKind::Infer(..), _) - | (_, ConstArgKind::Infer(..)) => false, + | (_, ConstArgKind::Infer(..)) + | (ConstArgKind::Error(..), _) + | (_, ConstArgKind::Error(..)) => false, } } @@ -1330,7 +1332,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { match &const_arg.kind { ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), - ConstArgKind::Infer(..) => {}, + ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index f7a0c3e39afd..86d17a8231d5 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -192,12 +192,12 @@ fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option Option () { @@ -17,7 +17,7 @@ /// unimplemented!(); /// } /// ``` -/// +/// /// This should, too. /// ```rust /// fn main() { @@ -25,7 +25,7 @@ /// unimplemented!(); /// } /// ``` -/// +/// /// This one too. /// ```no_run /// // the fn is not always the first line diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed index 88ba5f810b4e..959f5db11265 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(associated_const_equality, const_trait_impl)] +#![feature(const_trait_impl)] use std::any::Any; @@ -194,12 +194,3 @@ where T: Iterator + Iterator, { } -trait AssocConstTrait { - const ASSOC: usize; -} -fn assoc_const_args() -where - T: AssocConstTrait, - //~^ trait_duplication_in_bounds -{ -} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs index 19a4e70e294e..9bfecf40fc03 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(associated_const_equality, const_trait_impl)] +#![feature(const_trait_impl)] use std::any::Any; @@ -194,12 +194,3 @@ where T: Iterator + Iterator, { } -trait AssocConstTrait { - const ASSOC: usize; -} -fn assoc_const_args() -where - T: AssocConstTrait + AssocConstTrait, - //~^ trait_duplication_in_bounds -{ -} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr index a56a683de973..93488ea8e74d 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr @@ -70,11 +70,5 @@ error: these where clauses contain repeated elements LL | T: IntoIterator + IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator` -error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:202:8 - | -LL | T: AssocConstTrait + AssocConstTrait, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` - -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed new file mode 100644 index 000000000000..f2bd306a99e4 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -0,0 +1,14 @@ +#![deny(clippy::trait_duplication_in_bounds)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait AssocConstTrait { + #[type_const] + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs new file mode 100644 index 000000000000..8e7d843a44c0 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -0,0 +1,14 @@ +#![deny(clippy::trait_duplication_in_bounds)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait AssocConstTrait { + #[type_const] + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait + AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr new file mode 100644 index 000000000000..accc4d7b5bb8 --- /dev/null +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr @@ -0,0 +1,14 @@ +error: these where clauses contain repeated elements + --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:11:8 + | +LL | T: AssocConstTrait + AssocConstTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` + | +note: the lint level is defined here + --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:1:9 + | +LL | #![deny(clippy::trait_duplication_in_bounds)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From dbb33c77ab2b072b40e1a03f2dc30ef5bf768780 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 1 Nov 2025 14:39:21 -0400 Subject: [PATCH 503/525] Update crashes tests based on fixed or changed ICEs --- tests/crashes/119783.rs | 7 +++-- tests/crashes/131046.rs | 15 ----------- tests/crashes/134641.rs | 13 ---------- tests/crashes/138089.rs | 1 + .../associated_const_equality/coherence.rs | 18 +++++++++++++ .../coherence.stderr | 11 ++++++++ ...es-with-generic-in-ace-no-feature-gate.rs} | 4 +-- ...with-generic-in-ace-no-feature-gate.stderr | 23 ++++++++++++++++ .../mismatched-types-with-generic-in-ace.rs} | 8 +++--- ...ismatched-types-with-generic-in-ace.stderr | 26 +++++++++++++++++++ 10 files changed, 91 insertions(+), 35 deletions(-) delete mode 100644 tests/crashes/131046.rs delete mode 100644 tests/crashes/134641.rs create mode 100644 tests/ui/const-generics/associated_const_equality/coherence.rs create mode 100644 tests/ui/const-generics/associated_const_equality/coherence.stderr rename tests/{crashes/131406.rs => ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs} (61%) create mode 100644 tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr rename tests/{crashes/127643.rs => ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs} (51%) create mode 100644 tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr diff --git a/tests/crashes/119783.rs b/tests/crashes/119783.rs index 9a41abe69206..efde7f89ade2 100644 --- a/tests/crashes/119783.rs +++ b/tests/crashes/119783.rs @@ -1,7 +1,10 @@ //@ known-bug: #119783 -#![feature(associated_const_equality)] +#![feature(associated_const_equality, min_generic_const_args)] -trait Trait { const F: fn(); } +trait Trait { + #[type_const] + const F: fn(); +} fn take(_: impl Trait) {} diff --git a/tests/crashes/131046.rs b/tests/crashes/131046.rs deleted file mode 100644 index 2638705ae18b..000000000000 --- a/tests/crashes/131046.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #131046 - -trait Owner { - const C: u32; -} - -impl Owner for () { - const C: u32 = N; -} - -fn take0(_: impl Owner = { N }>) {} - -fn main() { - take0::<128>(()); -} diff --git a/tests/crashes/134641.rs b/tests/crashes/134641.rs deleted file mode 100644 index e3e5ab69287b..000000000000 --- a/tests/crashes/134641.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #134641 -#![feature(associated_const_equality)] - -pub trait IsVoid { - const IS_VOID: bool; -} -impl IsVoid for () { - const IS_VOID: bool = true; -} - -pub trait Maybe {} -impl Maybe for () {} -impl Maybe for () where (): IsVoid {} diff --git a/tests/crashes/138089.rs b/tests/crashes/138089.rs index acf27072bdd5..054d1b216959 100644 --- a/tests/crashes/138089.rs +++ b/tests/crashes/138089.rs @@ -5,6 +5,7 @@ struct OnDiskDirEntry<'a> {} impl<'a> OnDiskDirEntry<'a> { + #[type_const] const LFN_FRAGMENT_LEN: i64 = 2; fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { diff --git a/tests/ui/const-generics/associated_const_equality/coherence.rs b/tests/ui/const-generics/associated_const_equality/coherence.rs new file mode 100644 index 000000000000..fb5f255c1dc4 --- /dev/null +++ b/tests/ui/const-generics/associated_const_equality/coherence.rs @@ -0,0 +1,18 @@ +#![feature(associated_const_equality, min_generic_const_args)] +#![expect(incomplete_features)] + +pub trait IsVoid { + #[type_const] + const IS_VOID: bool; +} +impl IsVoid for () { + #[type_const] + const IS_VOID: bool = true; +} + +pub trait Maybe {} +impl Maybe for () {} +impl Maybe for () where (): IsVoid {} +//~^ ERROR conflicting implementations of trait `Maybe` for type `()` + +fn main() {} diff --git a/tests/ui/const-generics/associated_const_equality/coherence.stderr b/tests/ui/const-generics/associated_const_equality/coherence.stderr new file mode 100644 index 000000000000..23d6495a16a4 --- /dev/null +++ b/tests/ui/const-generics/associated_const_equality/coherence.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `Maybe` for type `()` + --> $DIR/coherence.rs:15:1 + | +LL | impl Maybe for () {} + | ----------------- first implementation here +LL | impl Maybe for () where (): IsVoid {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/131406.rs b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs similarity index 61% rename from tests/crashes/131406.rs rename to tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs index ea642f949280..1bc7c3cf3391 100644 --- a/tests/crashes/131406.rs +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs @@ -1,11 +1,11 @@ -//@ known-bug: #131406 - trait Owner { const C: u32 = N; + //~^ ERROR: generic const items are experimental } impl Owner for () {} fn take0(_: impl Owner = { N }>) {} +//~^ ERROR: associated const equality is incomplete fn main() { take0::<128>(()); diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr new file mode 100644 index 000000000000..0b487b6a7aa0 --- /dev/null +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr @@ -0,0 +1,23 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:7:38 + | +LL | fn take0(_: impl Owner = { N }>) {} + | ^^^^^^^^^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` 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]: generic const items are experimental + --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:2:12 + | +LL | const C: u32 = N; + | ^^^^^^^^^^^^^^ + | + = note: see issue #113521 for more information + = help: add `#![feature(generic_const_items)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/crashes/127643.rs b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs similarity index 51% rename from tests/crashes/127643.rs rename to tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs index b5ec58b70e93..33afa7e3228e 100644 --- a/tests/crashes/127643.rs +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs @@ -1,18 +1,20 @@ -//@ known-bug: #127643 - -#![feature(generic_const_items, associated_const_equality)] +#![feature(generic_const_items, associated_const_equality, min_generic_const_args)] #![expect(incomplete_features)] trait Foo { + #[type_const] const ASSOC: u32; } impl Foo for () { + #[type_const] const ASSOC: u32 = N; } fn bar = { N }>>() {} +//~^ ERROR: the constant `N` is not of type `u32` fn main() { bar::<10_u64, ()>(); + //~^ ERROR: the constant `10` is not of type `u32` } diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr new file mode 100644 index 000000000000..c2fb7faa3a3a --- /dev/null +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr @@ -0,0 +1,26 @@ +error: the constant `N` is not of type `u32` + --> $DIR/mismatched-types-with-generic-in-ace.rs:14:29 + | +LL | fn bar = { N }>>() {} + | ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | +note: required by a const generic parameter in `Foo::ASSOC` + --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 + | +LL | const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` + +error: the constant `10` is not of type `u32` + --> $DIR/mismatched-types-with-generic-in-ace.rs:18:5 + | +LL | bar::<10_u64, ()>(); + | ^^^^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | +note: required by a const generic parameter in `Foo::ASSOC` + --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 + | +LL | const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` + +error: aborting due to 2 previous errors + From 66267da3e953f3a59a45044ae7a121ba11114e32 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 1 Nov 2025 15:11:26 -0400 Subject: [PATCH 504/525] Use "rhs" terminology instead of "body" --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 43 ++++++------------- .../rustc_ast_passes/src/ast_validation.rs | 6 +-- .../rustc_ast_pretty/src/pprust/state/item.rs | 8 ++-- compiler/rustc_builtin_macros/src/test.rs | 2 +- compiler/rustc_expand/src/build.rs | 4 +- compiler/rustc_hir/src/hir.rs | 10 ++--- compiler/rustc_hir/src/intravisit.rs | 8 ++-- .../rustc_hir_analysis/src/collect/type_of.rs | 20 ++++----- compiler/rustc_lint/src/unused.rs | 4 +- compiler/rustc_parse/src/parser/item.rs | 24 +++++------ compiler/rustc_passes/src/reachable.rs | 6 +-- compiler/rustc_resolve/src/late.rs | 18 ++++---- src/librustdoc/clean/mod.rs | 4 +- .../clippy/clippy_utils/src/ast_utils/mod.rs | 8 ++-- 15 files changed, 76 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 45a873109161..e35ae9043f09 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3746,7 +3746,7 @@ pub struct ConstItem { pub ident: Ident, pub generics: Generics, pub ty: Box, - pub body: Option, + pub rhs: Option, pub define_opaque: Option>, } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5cb5149e2875..fed4eb1b0ca4 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -184,27 +184,22 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::Static(*m, ident, ty, body_id) } ItemKind::Const(box ast::ConstItem { - ident, - generics, - ty, - body, - define_opaque, - .. + ident, generics, ty, rhs, define_opaque, .. }) => { let ident = self.lower_ident(*ident); - let (generics, (ty, body)) = self.lower_generics( + let (generics, (ty, rhs)) = self.lower_generics( generics, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = this.lower_const_item_rhs(attrs, body.as_ref(), span); - (ty, body) + let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), span); + (ty, rhs) }, ); self.lower_define_opaque(hir_id, &define_opaque); - hir::ItemKind::Const(ident, generics, ty, body) + hir::ItemKind::Const(ident, generics, ty, rhs) } ItemKind::Fn(box Fn { sig: FnSig { decl, header, span: fn_sig_span }, @@ -797,12 +792,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (ident, generics, kind, has_default) = match &i.kind { AssocItemKind::Const(box ConstItem { - ident, - generics, - ty, - body, - define_opaque, - .. + ident, generics, ty, rhs, define_opaque, .. }) => { let (generics, kind) = self.lower_generics( generics, @@ -811,15 +801,15 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); - let body = body + let rhs = rhs .as_ref() - .map(|body| this.lower_const_item_rhs(attrs, Some(body), i.span)); - hir::TraitItemKind::Const(ty, body) + .map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span)); + hir::TraitItemKind::Const(ty, rhs) }, ); if define_opaque.is_some() { - if body.is_some() { + if rhs.is_some() { self.lower_define_opaque(hir_id, &define_opaque); } else { self.dcx().span_err( @@ -829,7 +819,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - (*ident, generics, kind, body.is_some()) + (*ident, generics, kind, rhs.is_some()) } AssocItemKind::Fn(box Fn { sig, ident, generics, body: None, define_opaque, .. @@ -1016,12 +1006,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (ident, (generics, kind)) = match &i.kind { AssocItemKind::Const(box ConstItem { - ident, - generics, - ty, - body, - define_opaque, - .. + ident, generics, ty, rhs, define_opaque, .. }) => ( *ident, self.lower_generics( @@ -1032,8 +1017,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = this .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); this.lower_define_opaque(hir_id, &define_opaque); - let body = this.lower_const_item_rhs(attrs, body.as_ref(), i.span); - hir::ImplItemKind::Const(ty, body) + let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span); + hir::ImplItemKind::Const(ty, rhs) }, ), ), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ca3a20c296f3..7a79accc66c2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1239,9 +1239,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } }); } - ItemKind::Const(box ConstItem { defaultness, body, .. }) => { + ItemKind::Const(box ConstItem { defaultness, rhs, .. }) => { self.check_defaultness(item.span, *defaultness); - if body.is_none() { + if rhs.is_none() { self.dcx().emit_err(errors::ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1581,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let AssocCtxt::Impl { .. } = ctxt { match &item.kind { - AssocItemKind::Const(box ConstItem { body: None, .. }) => { + AssocItemKind::Const(box ConstItem { rhs: None, .. }) => { self.dcx().emit_err(errors::AssocConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 6db19285f273..afdab79f3097 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -210,7 +210,7 @@ impl<'a> State<'a> { ident, generics, ty, - body, + rhs, define_opaque, }) => { self.print_item_const( @@ -218,7 +218,7 @@ impl<'a> State<'a> { None, generics, ty, - body.as_ref().map(|ct| ct.expr()), + rhs.as_ref().map(|ct| ct.expr()), &item.vis, ast::Safety::Default, *defaultness, @@ -566,7 +566,7 @@ impl<'a> State<'a> { ident, generics, ty, - body, + rhs, define_opaque, }) => { self.print_item_const( @@ -574,7 +574,7 @@ impl<'a> State<'a> { None, generics, ty, - body.as_ref().map(|ct| ct.expr()), + rhs.as_ref().map(|ct| ct.expr()), vis, ast::Safety::Default, *defaultness, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 21fd4689b9aa..449e0d771bac 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -289,7 +289,7 @@ pub(crate) fn expand_test_or_bench( ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), define_opaque: None, // test::TestDescAndFn { - body: Some(ast::ConstItemRhs::Body( + rhs: Some(ast::ConstItemRhs::Body( cx.expr_struct( sp, test_path("TestDescAndFn"), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index f8497dea9f4b..6be65b0fff16 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -726,7 +726,7 @@ impl<'a> ExtCtxt<'a> { span: Span, ident: Ident, ty: Box, - body: ast::ConstItemRhs, + rhs: ast::ConstItemRhs, ) -> Box { let defaultness = ast::Defaultness::Final; self.item( @@ -739,7 +739,7 @@ impl<'a> ExtCtxt<'a> { // FIXME(generic_const_items): Pass the generics as a parameter. generics: ast::Generics::default(), ty, - body: Some(body), + rhs: Some(rhs), define_opaque: None, } .into(), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 58fb3798d17d..432f78f0de99 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3102,7 +3102,7 @@ impl<'hir> TraitItem<'hir> { expect_methods_self_kind! { expect_const, (&'hir Ty<'hir>, Option>), - TraitItemKind::Const(ty, body), (ty, *body); + TraitItemKind::Const(ty, rhs), (ty, *rhs); expect_fn, (&FnSig<'hir>, &TraitFn<'hir>), TraitItemKind::Fn(ty, trfn), (ty, trfn); @@ -3195,9 +3195,9 @@ impl<'hir> ImplItem<'hir> { } expect_methods_self_kind! { - expect_const, (&'hir Ty<'hir>, ConstItemRhs<'hir>), ImplItemKind::Const(ty, body), (ty, *body); - expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); - expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; + expect_const, (&'hir Ty<'hir>, ConstItemRhs<'hir>), ImplItemKind::Const(ty, rhs), (ty, *rhs); + expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); + expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; } } @@ -4136,7 +4136,7 @@ impl<'hir> Item<'hir> { ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body); expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>), - ItemKind::Const(ident, generics, ty, ct_arg), (*ident, generics, ty, *ct_arg); + ItemKind::Const(ident, generics, ty, rhs), (*ident, generics, ty, *rhs); expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId), ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 57d4ffe28bd6..9328ffad1c9a 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -551,11 +551,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_nested_body(body)); } - ItemKind::Const(ident, ref generics, ref typ, body) => { + ItemKind::Const(ident, ref generics, ref typ, rhs) => { try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_ty_unambig(typ)); - try_visit!(visitor.visit_const_item_rhs(body)); + try_visit!(visitor.visit_const_item_rhs(rhs)); } ItemKind::Fn { ident, sig, generics, body: body_id, .. } => { try_visit!(visitor.visit_ident(ident)); @@ -1288,9 +1288,9 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( } } match *kind { - ImplItemKind::Const(ref ty, body) => { + ImplItemKind::Const(ref ty, rhs) => { try_visit!(visitor.visit_ty_unambig(ty)); - visitor.visit_const_item_rhs(body) + visitor.visit_const_item_rhs(rhs) } ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn( FnKind::Method(impl_item.ident, sig), diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f9aae54bbcdb..e56405e8f537 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -158,15 +158,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - TraitItemKind::Const(ty, body) => body - .and_then(|ct_arg| { + TraitItemKind::Const(ty, rhs) => rhs + .and_then(|rhs| { ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( icx.lowerer(), def_id, - ct_arg.hir_id(), + rhs.hir_id(), ty.span, - ct_arg.span(tcx), + rhs.span(tcx), item.ident, "associated constant", ) @@ -184,14 +184,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - ImplItemKind::Const(ty, ct_arg) => { + ImplItemKind::Const(ty, rhs) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, - ct_arg.hir_id(), + rhs.hir_id(), ty.span, - ct_arg.span(tcx), + rhs.span(tcx), item.ident, "associated constant", ) @@ -232,14 +232,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } } } - ItemKind::Const(ident, _, ty, body) => { + ItemKind::Const(ident, _, ty, rhs) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, - body.hir_id(), + rhs.hir_id(), ty.span, - body.span(tcx), + rhs.span(tcx), ident, "constant", ) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index cb3d09a08c05..40df5ecb0f3c 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1032,8 +1032,8 @@ trait UnusedDelimLint { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { use ast::ItemKind::*; - let expr = if let Const(box ast::ConstItem { body: Some(body), .. }) = &item.kind { - body.expr() + let expr = if let Const(box ast::ConstItem { rhs: Some(rhs), .. }) = &item.kind { + rhs.expr() } else if let Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind { expr } else { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9bc6e991d63f..599ec80e0a38 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -257,13 +257,13 @@ impl<'a> Parser<'a> { } else { self.recover_const_mut(const_span); self.recover_missing_kw_before_item()?; - let (ident, generics, ty, body) = self.parse_const_item(attrs)?; + let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?; ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ident, generics, ty, - body, + rhs, define_opaque: None, })) } @@ -1012,13 +1012,13 @@ impl<'a> Parser<'a> { define_opaque, }) => { self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span }); - let body = expr.map(ConstItemRhs::Body); + let rhs = expr.map(ConstItemRhs::Body); AssocItemKind::Const(Box::new(ConstItem { defaultness: Defaultness::Final, ident, generics: Generics::default(), ty, - body, + rhs, define_opaque, })) } @@ -1252,7 +1252,7 @@ impl<'a> Parser<'a> { let kind = match ForeignItemKind::try_from(kind) { Ok(kind) => kind, Err(kind) => match kind { - ItemKind::Const(box ConstItem { ident, ty, body, .. }) => { + ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => { let const_span = Some(span.with_hi(ident.span.lo())) .filter(|span| span.can_be_used_for_suggestions()); self.dcx().emit_err(errors::ExternItemCannotBeConst { @@ -1263,7 +1263,7 @@ impl<'a> Parser<'a> { ident, ty, mutability: Mutability::Not, - expr: body.map(|b| match b { + expr: rhs.map(|b| match b { ConstItemRhs::TypeConst(anon_const) => anon_const.value, ConstItemRhs::Body(expr) => expr, }), @@ -1465,7 +1465,7 @@ impl<'a> Parser<'a> { let before_where_clause = if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() }; - let body = if self.eat(exp!(Eq)) { + let rhs = if self.eat(exp!(Eq)) { if attr::contains_name(attrs, sym::type_const) { Some(ConstItemRhs::TypeConst(self.parse_expr_anon_const()?)) } else { @@ -1481,18 +1481,18 @@ impl<'a> Parser<'a> { // Users may be tempted to write such code if they are still used to the deprecated // where-clause location on type aliases and associated types. See also #89122. if before_where_clause.has_where_token - && let Some(body) = &body + && let Some(rhs) = &rhs { self.dcx().emit_err(errors::WhereClauseBeforeConstBody { span: before_where_clause.span, name: ident.span, - body: body.span(), + body: rhs.span(), sugg: if !after_where_clause.has_where_token { - self.psess.source_map().span_to_snippet(body.span()).ok().map(|body_s| { + self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| { errors::WhereClauseBeforeConstBodySugg { left: before_where_clause.span.shrink_to_lo(), snippet: body_s, - right: before_where_clause.span.shrink_to_hi().to(body.span()), + right: before_where_clause.span.shrink_to_hi().to(rhs.span()), } }) } else { @@ -1530,7 +1530,7 @@ impl<'a> Parser<'a> { self.expect_semi()?; - Ok((ident, generics, ty, body)) + Ok((ident, generics, ty, rhs)) } /// We were supposed to parse `":" $ty` but the `:` or the type was missing. diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index e6a97eb83add..acb64bc6990b 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -253,7 +253,7 @@ impl<'tcx> ReachableContext<'tcx> { | hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(body)) => self.visit_const_item_rhs(body), + hir::TraitItemKind::Const(_, Some(rhs)) => self.visit_const_item_rhs(rhs), hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) => { self.visit_nested_body(body_id); } @@ -261,8 +261,8 @@ impl<'tcx> ReachableContext<'tcx> { } } Node::ImplItem(impl_item) => match impl_item.kind { - hir::ImplItemKind::Const(_, body) => { - self.visit_const_item_rhs(body); + hir::ImplItemKind::Const(_, rhs) => { + self.visit_const_item_rhs(rhs); } hir::ImplItemKind::Fn(_, body) => { if recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id()) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e27a4e7da793..b0d62f97edab 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2709,7 +2709,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, ref generics, ref ty, - ref body, + ref rhs, ref define_opaque, .. }) => { @@ -2734,9 +2734,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this| this.visit_ty(ty), ); - if let Some(body) = body { + if let Some(rhs) = rhs { this.resolve_const_item_rhs( - body, + rhs, Some((ident, ConstantItemKind::Const)), ); } @@ -3056,7 +3056,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AssocItemKind::Const(box ast::ConstItem { generics, ty, - body, + rhs, define_opaque, .. }) => { @@ -3078,13 +3078,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. - if let Some(body) = body { + if let Some(rhs) = rhs { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.resolve_const_item_rhs(body, None); + this.resolve_const_item_rhs(rhs, None); } }, ) @@ -3261,7 +3261,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, generics, ty, - body, + rhs, define_opaque, .. }) => { @@ -3303,13 +3303,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_generics(generics); this.visit_ty(ty); - if let Some(body) = body { + if let Some(rhs) = rhs { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - this.resolve_const_item_rhs(body, None); + this.resolve_const_item_rhs(rhs, None); } }, ) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index eed75b0a5240..02559ecc7675 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2792,10 +2792,10 @@ fn clean_maybe_renamed_item<'tcx>( mutability, expr: Some(body_id), }), - ItemKind::Const(_, generics, ty, body) => ConstantItem(Box::new(Constant { + ItemKind::Const(_, generics, ty, rhs) => ConstantItem(Box::new(Constant { generics: clean_generics(generics, cx), type_: clean_ty(ty, cx), - kind: clean_const_item_rhs(body, def_id), + kind: clean_const_item_rhs(rhs, def_id), })), ItemKind::TyAlias(_, generics, ty) => { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 68fa3d191d28..f0b86ee3ea71 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -358,7 +358,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: li, generics: lg, ty: lt, - body: lb, + rhs: lb, define_opaque: _, }), Const(box ConstItem { @@ -366,7 +366,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: ri, generics: rg, ty: rt, - body: rb, + rhs: rb, define_opaque: _, }), ) => { @@ -612,7 +612,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: li, generics: lg, ty: lt, - body: lb, + rhs: lb, define_opaque: _, }), Const(box ConstItem { @@ -620,7 +620,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: ri, generics: rg, ty: rt, - body: rb, + rhs: rb, define_opaque: _, }), ) => { From 339dea8aece8ae918646c310b230433a1596cf57 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 3 Nov 2025 18:06:57 -0500 Subject: [PATCH 505/525] Fix rustfmt --- src/tools/rustfmt/src/items.rs | 74 +++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index ecaa4670f61d..062e2e051b1c 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2004,37 +2004,37 @@ pub(crate) struct StaticParts<'a> { generics: Option<&'a ast::Generics>, ty: &'a ast::Ty, mutability: ast::Mutability, - expr_opt: Option<&'a Box>, + expr_opt: Option<&'a ast::Expr>, defaultness: Option, span: Span, } impl<'a> StaticParts<'a> { pub(crate) fn from_item(item: &'a ast::Item) -> Self { - let (defaultness, prefix, safety, ident, ty, mutability, expr, generics) = match &item.kind - { - ast::ItemKind::Static(s) => ( - None, - "static", - s.safety, - s.ident, - &s.ty, - s.mutability, - &s.expr, - None, - ), - ast::ItemKind::Const(c) => ( - Some(c.defaultness), - "const", - ast::Safety::Default, - c.ident, - &c.ty, - ast::Mutability::Not, - &c.expr, - Some(&c.generics), - ), - _ => unreachable!(), - }; + let (defaultness, prefix, safety, ident, ty, mutability, expr_opt, generics) = + match &item.kind { + ast::ItemKind::Static(s) => ( + None, + "static", + s.safety, + s.ident, + &s.ty, + s.mutability, + s.expr.as_deref(), + None, + ), + ast::ItemKind::Const(c) => ( + Some(c.defaultness), + "const", + ast::Safety::Default, + c.ident, + &c.ty, + ast::Mutability::Not, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), + _ => unreachable!(), + }; StaticParts { prefix, safety, @@ -2043,7 +2043,7 @@ impl<'a> StaticParts<'a> { generics, ty, mutability, - expr_opt: expr.as_ref(), + expr_opt, defaultness, span: item.span, } @@ -2051,7 +2051,12 @@ impl<'a> StaticParts<'a> { pub(crate) fn from_trait_item(ti: &'a ast::AssocItem, ident: Ident) -> Self { let (defaultness, ty, expr_opt, generics) = match &ti.kind { - ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), + ast::AssocItemKind::Const(c) => ( + c.defaultness, + &c.ty, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), _ => unreachable!(), }; StaticParts { @@ -2062,15 +2067,20 @@ impl<'a> StaticParts<'a> { generics, ty, mutability: ast::Mutability::Not, - expr_opt: expr_opt.as_ref(), + expr_opt, defaultness: Some(defaultness), span: ti.span, } } pub(crate) fn from_impl_item(ii: &'a ast::AssocItem, ident: Ident) -> Self { - let (defaultness, ty, expr, generics) = match &ii.kind { - ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), + let (defaultness, ty, expr_opt, generics) = match &ii.kind { + ast::AssocItemKind::Const(c) => ( + c.defaultness, + &c.ty, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), _ => unreachable!(), }; StaticParts { @@ -2081,7 +2091,7 @@ impl<'a> StaticParts<'a> { generics, ty, mutability: ast::Mutability::Not, - expr_opt: expr.as_ref(), + expr_opt, defaultness: Some(defaultness), span: ii.span, } @@ -2144,7 +2154,7 @@ fn rewrite_static( rewrite_assign_rhs_with_comments( context, &lhs, - &**expr, + expr, Shape::legacy(remaining_width, offset.block_only()), &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, From 5171e42cec2635a2d34a64b5da0b18070d334305 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 3 Nov 2025 18:25:01 -0500 Subject: [PATCH 506/525] Fix rustdoc tests --- tests/crashes/mgca/ace-with-const-ctor.rs | 16 ++++++++++++++++ .../ice-associated-const-equality-105952.rs | 15 --------------- .../auxiliary/assoc-const-equality.rs | 4 +++- 3 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 tests/crashes/mgca/ace-with-const-ctor.rs delete mode 100644 tests/rustdoc/constant/ice-associated-const-equality-105952.rs diff --git a/tests/crashes/mgca/ace-with-const-ctor.rs b/tests/crashes/mgca/ace-with-const-ctor.rs new file mode 100644 index 000000000000..9e49bca06d52 --- /dev/null +++ b/tests/crashes/mgca/ace-with-const-ctor.rs @@ -0,0 +1,16 @@ +//@ known-bug: #132980 +// Originally a rustdoc test. Should be moved back there with @has checks +// readded once fixed. +// Previous issue (before mgca): https://github.com/rust-lang/rust/issues/105952 +#![crate_name = "foo"] +#![feature(associated_const_equality, min_generic_const_args)] +pub enum ParseMode { + Raw, +} +pub trait Parse { + #[type_const] + const PARSE_MODE: ParseMode; +} +pub trait RenderRaw {} + +impl> RenderRaw for T {} diff --git a/tests/rustdoc/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs deleted file mode 100644 index 1bcdfac73429..000000000000 --- a/tests/rustdoc/constant/ice-associated-const-equality-105952.rs +++ /dev/null @@ -1,15 +0,0 @@ -// https://github.com/rust-lang/rust/issues/105952 -#![crate_name = "foo"] - -#![feature(associated_const_equality)] -pub enum ParseMode { - Raw, -} -pub trait Parse { - const PARSE_MODE: ParseMode; -} -pub trait RenderRaw {} - -//@ hasraw foo/trait.RenderRaw.html 'impl' -//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw' -impl> RenderRaw for T {} diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs index 6a25dcea62e2..f6c03d189b5e 100644 --- a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs +++ b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs @@ -1,7 +1,9 @@ -#![feature(associated_const_equality)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] pub fn accept(_: impl Trait) {} pub trait Trait { + #[type_const] const K: i32; } From ad69a7a4492c6c1a87752948d10e56a049c1b9c6 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 6 Nov 2025 17:38:15 -0500 Subject: [PATCH 507/525] Fix rustdoc UI tests Also removed a test that was literally a duplicate of the one I kept. --- .../associated-constant-not-allowed-102467.rs | 4 ++- ...ociated-constant-not-allowed-102467.stderr | 4 +-- tests/rustdoc-ui/invalid_associated_const.rs | 11 -------- .../invalid_associated_const.stderr | 28 ------------------- 4 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 tests/rustdoc-ui/invalid_associated_const.rs delete mode 100644 tests/rustdoc-ui/invalid_associated_const.stderr diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs index d9bd48103d24..c4bbcfc2b077 100644 --- a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs @@ -1,7 +1,8 @@ // Regression test for . // It ensures that the expected error is displayed. -#![feature(associated_const_equality)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] trait T { type A: S = 34>; @@ -10,6 +11,7 @@ trait T { } trait S { + #[type_const] const C: i32; } diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr b/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr index 5c8f08afe7a5..890d7cfde9ed 100644 --- a/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr @@ -1,5 +1,5 @@ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-constant-not-allowed-102467.rs:7:17 + --> $DIR/associated-constant-not-allowed-102467.rs:8:17 | LL | type A: S = 34>; | ^^^^^^^^ associated item constraint not allowed here @@ -11,7 +11,7 @@ LL + type A: S; | error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-constant-not-allowed-102467.rs:7:17 + --> $DIR/associated-constant-not-allowed-102467.rs:8:17 | LL | type A: S = 34>; | ^^^^^^^^ associated item constraint not allowed here diff --git a/tests/rustdoc-ui/invalid_associated_const.rs b/tests/rustdoc-ui/invalid_associated_const.rs deleted file mode 100644 index f93834268f63..000000000000 --- a/tests/rustdoc-ui/invalid_associated_const.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![feature(associated_const_equality)] - -trait T { - type A: S = 34>; - //~^ ERROR associated item constraints are not allowed here - //~| ERROR associated item constraints are not allowed here -} - -trait S { - const C: i32; -} diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr deleted file mode 100644 index 66f8ffe6d729..000000000000 --- a/tests/rustdoc-ui/invalid_associated_const.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error[E0229]: associated item constraints are not allowed here - --> $DIR/invalid_associated_const.rs:4:17 - | -LL | type A: S = 34>; - | ^^^^^^^^ associated item constraint not allowed here - | -help: consider removing this associated item binding - | -LL - type A: S = 34>; -LL + type A: S; - | - -error[E0229]: associated item constraints are not allowed here - --> $DIR/invalid_associated_const.rs:4:17 - | -LL | type A: S = 34>; - | ^^^^^^^^ associated item constraint not allowed here - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this associated item binding - | -LL - type A: S = 34>; -LL + type A: S; - | - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0229`. From 45391bdbf57f50e75608c380d8bc65423c96f0f1 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 8 Nov 2025 13:46:08 -0500 Subject: [PATCH 508/525] Add tests for mismatched type_const --- .../crashes/mgca/type_const-only-in-trait.rs | 23 +++++++++++++++++++ .../mgca/type_const-only-in-impl.rs | 20 ++++++++++++++++ .../mgca/type_const-only-in-impl.stderr | 10 ++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/crashes/mgca/type_const-only-in-trait.rs create mode 100644 tests/ui/const-generics/mgca/type_const-only-in-impl.rs create mode 100644 tests/ui/const-generics/mgca/type_const-only-in-impl.stderr diff --git a/tests/crashes/mgca/type_const-only-in-trait.rs b/tests/crashes/mgca/type_const-only-in-trait.rs new file mode 100644 index 000000000000..109cf0ec670c --- /dev/null +++ b/tests/crashes/mgca/type_const-only-in-trait.rs @@ -0,0 +1,23 @@ +//@ known-bug: #132980 +// Move this test to tests/ui/const-generics/mgca/type_const-only-in-trait.rs +// once fixed. + +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait GoodTr { + #[type_const] + const NUM: usize; +} + +struct BadS; + +impl GoodTr for BadS { + const NUM: usize = 42; +} + +fn accept_good_tr>(_x: &T) {} + +fn main() { + accept_good_tr(&BadS); +} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs new file mode 100644 index 000000000000..ae4a0004232b --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs @@ -0,0 +1,20 @@ +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait BadTr { + const NUM: usize; +} + +struct GoodS; + +impl BadTr for GoodS { + #[type_const] + const NUM: usize = 84; +} + +fn accept_bad_tr>(_x: &T) {} +//~^ ERROR use of trait associated const without `#[type_const]` + +fn main() { + accept_bad_tr::<84, _>(&GoodS); +} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr new file mode 100644 index 000000000000..44632e46fb07 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr @@ -0,0 +1,10 @@ +error: use of trait associated const without `#[type_const]` + --> $DIR/type_const-only-in-impl.rs:15:43 + | +LL | fn accept_bad_tr>(_x: &T) {} + | ^^^^^^^^^^^ + | + = note: the declaration in the trait must be marked with `#[type_const]` + +error: aborting due to 1 previous error + From 7eb54928608f70cd4c5397f71e4a54d3279b1330 Mon Sep 17 00:00:00 2001 From: Karol Zwolak Date: Sat, 8 Nov 2025 19:00:55 +0100 Subject: [PATCH 509/525] fix: disable self-contained linker when bootstrap-override-lld is set --- src/bootstrap/src/utils/helpers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index faada9a111db..c670ae88fc54 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -430,6 +430,7 @@ pub fn linker_flags( match builder.config.bootstrap_override_lld { BootstrapOverrideLld::External => { args.push("-Clinker-features=+lld".to_string()); + args.push("-Clink-self-contained=-linker".to_string()); args.push("-Zunstable-options".to_string()); } BootstrapOverrideLld::SelfContained => { From 0d64a5f467e54b67d35d1ddc97ba05615ac922fa Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 8 Nov 2025 21:02:21 +0100 Subject: [PATCH 510/525] Use the current lint note id when parsing `cfg!()` Signed-off-by: Jonathan Brouwer --- compiler/rustc_builtin_macros/src/cfg.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 387399668111..653bf9fe33b2 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -3,7 +3,7 @@ //! current compilation environment. use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AttrStyle, CRATE_NODE_ID, token}; +use rustc_ast::{AttrStyle, token}; use rustc_attr_parsing as attr; use rustc_attr_parsing::parser::MetaItemOrLitParser; use rustc_attr_parsing::{ @@ -57,7 +57,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result Date: Fri, 31 Oct 2025 23:00:02 +0700 Subject: [PATCH 511/525] constify result unwrap unchecked --- library/core/src/result.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 6fee7febde38..9afa71ec0f11 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1646,11 +1646,16 @@ impl Result { #[inline] #[track_caller] #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] - pub unsafe fn unwrap_unchecked(self) -> T { + #[rustc_const_unstable(feature = "const_result_unwrap_unchecked", issue = "148714")] + pub const unsafe fn unwrap_unchecked(self) -> T { match self { Ok(t) => t, - // SAFETY: the safety contract must be upheld by the caller. - Err(_) => unsafe { hint::unreachable_unchecked() }, + Err(e) => { + // FIXME(const-hack): to avoid E: const Destruct bound + super::mem::forget(e); + // SAFETY: the safety contract must be upheld by the caller. + unsafe { hint::unreachable_unchecked() } + } } } From 3fdde5f526fd7ea77454d62dea28903f21257b9d Mon Sep 17 00:00:00 2001 From: Crystal Durham Date: Sat, 8 Nov 2025 12:54:56 -0500 Subject: [PATCH 512/525] Add Crystal Durham to .mailmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🏳️‍⚧️ --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 6c168bbbcb55..7572eda0a67c 100644 --- a/.mailmap +++ b/.mailmap @@ -138,7 +138,6 @@ Christian Poveda <31802960+christianpoveda@users.noreply.github. Christian Poveda Christian Vallentin Christoffer Buchholz -Christopher Durham Clark Gaebel Clement Miao Clément Renault @@ -147,6 +146,7 @@ Clinton Ryan Taylor Cramer ember arlynx Crazycolorz5 +Crystal Durham csmoe <35686186+csmoe@users.noreply.github.com> Cyryl Płotnicki Damien Schoof From 610391fff9b213f48e73b106c2064adef0a068d4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 9 Nov 2025 14:26:56 +1100 Subject: [PATCH 513/525] bootstrap: Render doctest timing reports as text, not JSON --- src/bootstrap/src/utils/render_tests.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index e90a7ef42324..55eba6c696c5 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -306,6 +306,14 @@ impl<'a> Renderer<'a> { ); } + fn render_report(&self, report: &Report) { + let &Report { total_time, compilation_time } = report; + // Should match `write_merged_doctest_times` in `library/test/src/formatters/pretty.rs`. + println!( + "all doctests ran in {total_time:.2}s; merged doctests compilation took {compilation_time:.2}s" + ); + } + fn render_message(&mut self, message: Message) { match message { Message::Suite(SuiteMessage::Started { test_count }) => { @@ -323,6 +331,9 @@ impl<'a> Renderer<'a> { Message::Suite(SuiteMessage::Failed(outcome)) => { self.render_suite_outcome(Outcome::Failed, &outcome); } + Message::Report(report) => { + self.render_report(&report); + } Message::Bench(outcome) => { // The formatting for benchmarks doesn't replicate 1:1 the formatting libtest // outputs, mostly because libtest's formatting is broken in terse mode, which is @@ -435,6 +446,7 @@ enum Message { Suite(SuiteMessage), Test(TestMessage), Bench(BenchOutcome), + Report(Report), } #[derive(serde_derive::Deserialize)] @@ -481,3 +493,10 @@ struct TestOutcome { stdout: Option, message: Option, } + +/// Emitted when running doctests. +#[derive(serde_derive::Deserialize)] +struct Report { + total_time: f64, + compilation_time: f64, +} From 38ae4496e7295fead7985b83d79d386f9920d289 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 9 Nov 2025 14:02:40 +1100 Subject: [PATCH 514/525] tidy: Don't bypass stderr output capture in unit tests In unit tests, writes to stderr that don't use `eprint!` or `eprintln!` will not be captured, and instead interfere with test harness output, making it unreadable. --- src/tools/tidy/src/diagnostics.rs | 52 +++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/tools/tidy/src/diagnostics.rs b/src/tools/tidy/src/diagnostics.rs index 1e25f862522e..159500751aa5 100644 --- a/src/tools/tidy/src/diagnostics.rs +++ b/src/tools/tidy/src/diagnostics.rs @@ -1,9 +1,10 @@ use std::collections::HashSet; use std::fmt::{Display, Formatter}; +use std::io; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; -use termcolor::{Color, WriteColor}; +use termcolor::Color; #[derive(Clone, Default)] ///CLI flags used by tidy. @@ -245,30 +246,63 @@ pub const COLOR_WARNING: Color = Color::Yellow; /// Output a message to stderr. /// The message can be optionally scoped to a certain check, and it can also have a certain color. pub fn output_message(msg: &str, id: Option<&CheckId>, color: Option) { - use std::io::Write; + use termcolor::{ColorChoice, ColorSpec}; - use termcolor::{ColorChoice, ColorSpec, StandardStream}; + let stderr: &mut dyn termcolor::WriteColor = if cfg!(test) { + &mut StderrForUnitTests + } else { + &mut termcolor::StandardStream::stderr(ColorChoice::Auto) + }; - let mut stderr = StandardStream::stderr(ColorChoice::Auto); if let Some(color) = &color { stderr.set_color(ColorSpec::new().set_fg(Some(*color))).unwrap(); } match id { Some(id) => { - write!(&mut stderr, "tidy [{}", id.name).unwrap(); + write!(stderr, "tidy [{}", id.name).unwrap(); if let Some(path) = &id.path { - write!(&mut stderr, " ({})", path.display()).unwrap(); + write!(stderr, " ({})", path.display()).unwrap(); } - write!(&mut stderr, "]").unwrap(); + write!(stderr, "]").unwrap(); } None => { - write!(&mut stderr, "tidy").unwrap(); + write!(stderr, "tidy").unwrap(); } } if color.is_some() { stderr.set_color(&ColorSpec::new()).unwrap(); } - writeln!(&mut stderr, ": {msg}").unwrap(); + writeln!(stderr, ": {msg}").unwrap(); +} + +/// An implementation of `io::Write` and `termcolor::WriteColor` that writes +/// to stderr via `eprint!`, so that the output can be properly captured when +/// running tidy's unit tests. +struct StderrForUnitTests; + +impl io::Write for StderrForUnitTests { + fn write(&mut self, buf: &[u8]) -> io::Result { + eprint!("{}", String::from_utf8_lossy(buf)); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl termcolor::WriteColor for StderrForUnitTests { + fn supports_color(&self) -> bool { + false + } + + fn set_color(&mut self, _spec: &termcolor::ColorSpec) -> io::Result<()> { + Ok(()) + } + + fn reset(&mut self) -> io::Result<()> { + Ok(()) + } } From e56de95478fc5173078625511ff8ff9bde28b810 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 8 Nov 2025 15:43:29 -0500 Subject: [PATCH 515/525] Fix `#[type_const]` attribute placement validation --- .../rustc_attr_parsing/src/attributes/traits.rs | 3 ++- compiler/rustc_passes/src/check_attr.rs | 14 +------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index ced3bcad2293..0765ccf384af 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -66,7 +66,8 @@ pub(crate) struct TypeConstParser; impl NoArgsAttributeParser for TypeConstParser { const PATH: &[Symbol] = &[sym::type_const]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocConst)]); + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Const), Allow(Target::AssocConst)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 463338ee1fb5..1a422e308302 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -150,9 +150,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::ProcMacroDerive { .. }) => { self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } - &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { - self.check_type_const(hir_id, attr_span, target) - } Attribute::Parsed( AttributeKind::Stability { span: attr_span, @@ -243,6 +240,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::ParenSugar(..) | AttributeKind::AllowIncoherentImpl(..) | AttributeKind::Confusables { .. } + | AttributeKind::TypeConst{..} // `#[doc]` is actually a lot more than just doc comments, so is checked below | AttributeKind::DocComment {..} // handled below this loop and elsewhere @@ -2115,16 +2113,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, _hir_id: HirId, attr_span: Span, target: Target) { - if matches!(target, Target::AssocConst | Target::Const) { - return; - } else { - self.dcx() - .struct_span_err(attr_span, "`#[type_const]` must only be applied to const items") - .emit(); - } - } - fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { if !find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) .unwrap_or(false) From c0939d4ec01bb1d5e3858b1a7c3d6bd5b2668e12 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 8 Nov 2025 15:44:11 -0500 Subject: [PATCH 516/525] Perform WF-checking on type_const RHS's --- .../rustc_hir_analysis/src/check/check.rs | 57 +++++++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 111 ++++++++---------- .../concrete-expr-with-generics-in-env.rs | 26 ++++ .../mgca/type_const-on-generic-expr.rs | 34 ++++++ .../mgca/type_const-on-generic-expr.stderr | 47 ++++++++ .../associated-const-equality.rs | 12 +- 6 files changed, 204 insertions(+), 83 deletions(-) create mode 100644 tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs create mode 100644 tests/ui/const-generics/mgca/type_const-on-generic-expr.rs create mode 100644 tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1e12adbbfc6e..f58808f903b0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -757,22 +757,18 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), } match tcx.def_kind(def_id) { - def_kind @ (DefKind::Static { .. } | DefKind::Const) => { + DefKind::Static { .. } => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); - match def_kind { - DefKind::Static { .. } => { - check_static_inhabited(tcx, def_id); - check_static_linkage(tcx, def_id); - let ty = tcx.type_of(def_id).instantiate_identity(); - res = res.and(wfcheck::check_static_item( - tcx, def_id, ty, /* should_check_for_sync */ true, - )); - } - DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)), - _ => unreachable!(), - } + + check_static_inhabited(tcx, def_id); + check_static_linkage(tcx, def_id); + let ty = tcx.type_of(def_id).instantiate_identity(); + res = res.and(wfcheck::check_static_item( + tcx, def_id, ty, /* should_check_for_sync */ true, + )); + // Only `Node::Item` and `Node::ForeignItem` still have HIR based // checks. Returning early here does not miss any checks and // avoids this query from having a direct dependency edge on the HIR @@ -900,6 +896,36 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // avoids this query from having a direct dependency edge on the HIR return res; } + DefKind::Const => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + + res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty_span = tcx.ty_span(def_id); + let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); + wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into()); + wfcx.register_bound( + traits::ObligationCause::new( + ty_span, + def_id, + ObligationCauseCode::SizedConstOrStatic, + ), + tcx.param_env(def_id), + ty, + tcx.require_lang_item(LangItem::Sized, ty_span), + ); + check_where_clauses(wfcx, def_id); + + wfcheck::check_const_item_rhs(wfcx, def_id) + })); + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } DefKind::TyAlias => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); @@ -920,6 +946,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), })); check_variances_for_type_defn(tcx, def_id); } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::ForeignMod => { let it = tcx.hir_expect_item(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f3d6398b2085..82b708cc5ee9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -6,10 +6,11 @@ use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{AmbigArg, ItemKind}; +use rustc_hir::{AmbigArg, ItemKind, find_attr}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt}; use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; @@ -925,11 +926,11 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er #[instrument(level = "debug", skip(tcx))] pub(crate) fn check_associated_item( tcx: TyCtxt<'_>, - item_id: LocalDefId, + def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let loc = Some(WellFormedLoc::Ty(item_id)); - enter_wf_checking_ctxt(tcx, item_id, |wfcx| { - let item = tcx.associated_item(item_id); + let loc = Some(WellFormedLoc::Ty(def_id)); + enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + let item = tcx.associated_item(def_id); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. @@ -942,27 +943,33 @@ pub(crate) fn check_associated_item( } }; - let span = tcx.def_span(item_id); + let span = tcx.def_span(def_id); match item.kind { ty::AssocKind::Const { .. } => { - let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); - check_sized_if_body( - wfcx, - item.def_id.expect_local(), - ty, - Some(span), - ObligationCauseCode::SizedConstOrStatic, - ); + + if item.defaultness(tcx).has_value() { + let code = ObligationCauseCode::SizedConstOrStatic; + wfcx.register_bound( + ObligationCause::new(span, def_id, code), + wfcx.param_env, + ty, + tcx.require_lang_item(LangItem::Sized, span), + ); + + check_const_item_rhs(wfcx, def_id)?; + } + Ok(()) } ty::AssocKind::Fn { .. } => { - let sig = tcx.fn_sig(item.def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity(); let hir_sig = - tcx.hir_node_by_def_id(item_id).fn_sig().expect("bad signature for method"); - check_fn_or_method(wfcx, sig, hir_sig.decl, item_id); + tcx.hir_node_by_def_id(def_id).fn_sig().expect("bad signature for method"); + check_fn_or_method(wfcx, sig, hir_sig.decl, def_id); check_method_receiver(wfcx, hir_sig, item, self_ty) } ty::AssocKind::Type { .. } => { @@ -970,8 +977,8 @@ pub(crate) fn check_associated_item( check_associated_type_bounds(wfcx, item, span) } if item.defaultness(tcx).has_value() { - let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } Ok(()) @@ -1222,28 +1229,19 @@ pub(crate) fn check_static_item<'tcx>( }) } -pub(crate) fn check_const_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, def_id, |wfcx| { - let ty = tcx.type_of(def_id).instantiate_identity(); - let ty_span = tcx.ty_span(def_id); - let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); - - wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into()); - wfcx.register_bound( - traits::ObligationCause::new( - ty_span, - wfcx.body_def_id, - ObligationCauseCode::SizedConstOrStatic, - ), - wfcx.param_env, - ty, - tcx.require_lang_item(LangItem::Sized, ty_span), - ); - - check_where_clauses(wfcx, def_id); - - Ok(()) - }) +#[instrument(level = "debug", skip(wfcx))] +pub(super) fn check_const_item_rhs<'tcx>( + wfcx: &WfCheckingCtxt<'_, 'tcx>, + def_id: LocalDefId, +) -> Result<(), ErrorGuaranteed> { + let tcx = wfcx.tcx(); + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); + let span = tcx.def_span(def_id); + let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct); + wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into()); + } + Ok(()) } #[instrument(level = "debug", skip(tcx, impl_))] @@ -1583,33 +1581,16 @@ fn check_fn_or_method<'tcx>( } // If the function has a body, additionally require that the return type is sized. - check_sized_if_body( - wfcx, - def_id, - sig.output(), - match hir_decl.output { - hir::FnRetTy::Return(ty) => Some(ty.span), - hir::FnRetTy::DefaultReturn(_) => None, - }, - ObligationCauseCode::SizedReturnType, - ); -} - -fn check_sized_if_body<'tcx>( - wfcx: &WfCheckingCtxt<'_, 'tcx>, - def_id: LocalDefId, - ty: Ty<'tcx>, - maybe_span: Option, - code: ObligationCauseCode<'tcx>, -) { - let tcx = wfcx.tcx(); if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { - let span = maybe_span.unwrap_or(body.value.span); + let span = match hir_decl.output { + hir::FnRetTy::Return(ty) => ty.span, + hir::FnRetTy::DefaultReturn(_) => body.value.span, + }; wfcx.register_bound( - ObligationCause::new(span, def_id, code), + ObligationCause::new(span, def_id, ObligationCauseCode::SizedReturnType), wfcx.param_env, - ty, + sig.output(), tcx.require_lang_item(LangItem::Sized, span), ); } diff --git a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs new file mode 100644 index 000000000000..37f9c31feaa5 --- /dev/null +++ b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs @@ -0,0 +1,26 @@ +//@ check-pass + +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +pub trait Tr { + #[type_const] + const N1: usize; + #[type_const] + const N2: usize; + #[type_const] + const N3: usize; +} + +pub struct S; + +impl Tr for S { + #[type_const] + const N1: usize = 0; + #[type_const] + const N2: usize = 1; + #[type_const] + const N3: usize = 2; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs new file mode 100644 index 000000000000..d38d5ab7a59f --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -0,0 +1,34 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +#[type_const] +const FREE1: usize = std::mem::size_of::(); +//~^ ERROR generic parameters may not be used in const operations +#[type_const] +const FREE2: usize = I + 1; +//~^ ERROR generic parameters may not be used in const operations + +pub trait Tr { + #[type_const] + const N1: usize; + #[type_const] + const N2: usize; + #[type_const] + const N3: usize; +} + +pub struct S; + +impl Tr for S { + #[type_const] + const N1: usize = std::mem::size_of::(); + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N2: usize = I + 1; + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N3: usize = 2 & X; + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr new file mode 100644 index 000000000000..76638f27e96c --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -0,0 +1,47 @@ +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:5:45 + | +LL | const FREE1: usize = std::mem::size_of::(); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:8:38 + | +LL | const FREE2: usize = I + 1; + | ^ cannot perform const operation using `I` + | + = help: const parameters may only be used as standalone arguments here, i.e. `I` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:24:46 + | +LL | const N1: usize = std::mem::size_of::(); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:27:39 + | +LL | const N2: usize = I + 1; + | ^ cannot perform const operation using `I` + | + = help: const parameters may only be used as standalone arguments here, i.e. `I` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:30:27 + | +LL | const N3: usize = 2 & X; + | ^ cannot perform const operation using `X` + | + = help: const parameters may only be used as standalone arguments here, i.e. `X` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 5 previous errors + diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs index 0620998188b2..6f5d4985ae53 100644 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ b/tests/ui/generic-const-items/associated-const-equality.rs @@ -9,8 +9,8 @@ trait Owner { const C: u32; #[type_const] const K: u32; - #[type_const] - const Q: Maybe; + // #[type_const] + // const Q: Maybe; } impl Owner for () { @@ -18,13 +18,15 @@ impl Owner for () { const C: u32 = N; #[type_const] const K: u32 = 99 + 1; - #[type_const] - const Q: Maybe = Maybe::Nothing; + // FIXME(mgca): re-enable once we properly support ctors and generics on paths + // #[type_const] + // const Q: Maybe = Maybe::Nothing; } fn take0(_: impl Owner = { N }>) {} fn take1(_: impl Owner = 100>) {} -fn take2(_: impl Owner = { Maybe::Just(()) }>) {} +// FIXME(mgca): re-enable once we properly support ctors and generics on paths +// fn take2(_: impl Owner = { Maybe::Just(()) }>) {} fn main() { take0::<128>(()); From 9ba89327df659b47dadddfcb662fa82ff04ec616 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 8 Nov 2025 16:53:38 -0500 Subject: [PATCH 517/525] Check type_const type is ConstParamTy_ and that RHS matches it --- compiler/rustc_hir/src/hir.rs | 9 +++- .../rustc_hir_analysis/src/check/check.rs | 5 ++- .../rustc_hir_analysis/src/check/wfcheck.rs | 32 +++++++++++--- .../traits/fulfillment_errors.rs | 8 +--- .../assoc-const-eq-ambiguity.rs | 2 +- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 11 ++++- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 6 +-- .../assoc-const-eq-bound-var-in-ty.rs | 11 ++++- .../assoc-const-eq-esc-bound-var-in-ty.rs | 2 +- .../assoc-const-eq-param-in-ty.rs | 17 +++++--- .../assoc-const-eq-param-in-ty.stderr | 42 +++++++++---------- .../assoc-const-eq-supertraits.rs | 11 ++++- .../assoc-const-eq-ty-alias-noninteracting.rs | 2 +- .../mgca/type_const-mismatched-types.rs | 23 ++++++++++ .../mgca/type_const-mismatched-types.stderr | 27 ++++++++++++ .../mgca/type_const-not-constparamty.rs | 26 ++++++++++++ .../mgca/type_const-not-constparamty.stderr | 39 +++++++++++++++++ .../mgca/using-fnptr-as-type_const.rs} | 5 ++- .../mgca/using-fnptr-as-type_const.stderr | 9 ++++ .../assoc-const-no-infer-ice-115806.rs | 2 +- 20 files changed, 234 insertions(+), 55 deletions(-) create mode 100644 tests/ui/const-generics/mgca/type_const-mismatched-types.rs create mode 100644 tests/ui/const-generics/mgca/type_const-mismatched-types.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-not-constparamty.rs create mode 100644 tests/ui/const-generics/mgca/type_const-not-constparamty.stderr rename tests/{crashes/119783.rs => ui/const-generics/mgca/using-fnptr-as-type_const.rs} (54%) create mode 100644 tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 62013958c7e5..4cdfc752d989 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3065,7 +3065,7 @@ macro_rules! expect_methods_self_kind { $( #[track_caller] pub fn $name(&self) -> $ret_ty { - let $pat = &self.kind else { expect_failed(stringify!($ident), self) }; + let $pat = &self.kind else { expect_failed(stringify!($name), self) }; $ret_val } )* @@ -3077,7 +3077,7 @@ macro_rules! expect_methods_self { $( #[track_caller] pub fn $name(&self) -> $ret_ty { - let $pat = self else { expect_failed(stringify!($ident), self) }; + let $pat = self else { expect_failed(stringify!($name), self) }; $ret_val } )* @@ -4790,6 +4790,11 @@ impl<'hir> Node<'hir> { ForeignItemKind::Static(ty, ..) => Some(ty), _ => None, }, + Node::GenericParam(param) => match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { default, .. } => default, + GenericParamKind::Const { ty, .. } => Some(ty), + }, _ => None, } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f58808f903b0..7fa8f9563622 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -918,7 +918,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ); check_where_clauses(wfcx, def_id); - wfcheck::check_const_item_rhs(wfcx, def_id) + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + wfcheck::check_type_const(wfcx, def_id, ty, true)?; + } + Ok(()) })); // Only `Node::Item` and `Node::ForeignItem` still have HIR based diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 82b708cc5ee9..ccae524352a5 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -951,7 +951,12 @@ pub(crate) fn check_associated_item( let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); - if item.defaultness(tcx).has_value() { + let has_value = item.defaultness(tcx).has_value(); + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + check_type_const(wfcx, def_id, ty, has_value)?; + } + + if has_value { let code = ObligationCauseCode::SizedConstOrStatic; wfcx.register_bound( ObligationCause::new(span, def_id, code), @@ -959,8 +964,6 @@ pub(crate) fn check_associated_item( ty, tcx.require_lang_item(LangItem::Sized, span), ); - - check_const_item_rhs(wfcx, def_id)?; } Ok(()) @@ -1230,16 +1233,33 @@ pub(crate) fn check_static_item<'tcx>( } #[instrument(level = "debug", skip(wfcx))] -pub(super) fn check_const_item_rhs<'tcx>( +pub(super) fn check_type_const<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: LocalDefId, + item_ty: Ty<'tcx>, + has_value: bool, ) -> Result<(), ErrorGuaranteed> { let tcx = wfcx.tcx(); - if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + let span = tcx.def_span(def_id); + + wfcx.register_bound( + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), + wfcx.param_env, + item_ty, + tcx.require_lang_item(LangItem::ConstParamTy, span), + ); + + if has_value { let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); - let span = tcx.def_span(def_id); let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct); wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into()); + + wfcx.register_obligation(Obligation::new( + tcx, + ObligationCause::new(span, def_id, ObligationCauseCode::WellFormed(None)), + wfcx.param_env, + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)), + )); } Ok(()) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d2f2c92dda08..c282f4204260 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1286,12 +1286,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> Diag<'a> { - let param = obligation.cause.body_id; - let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } = - self.tcx.hir_node_by_def_id(param).expect_generic_param().kind - else { - bug!() - }; + let def_id = obligation.cause.body_id; + let span = self.tcx.ty_span(def_id); let mut file = None; let ty_str = self.tcx.short_string(ty, &mut file); diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs index d433af6bdd57..2ff5a0353a0a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs @@ -1,7 +1,7 @@ // We used to say "ambiguous associated type" on ambiguous associated consts. // Ensure that we now use the correct label. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait0: Parent0 + Parent0 {} diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index f6240ead0b9b..5232b895803e 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -1,9 +1,16 @@ // Check that we eventually catch types of assoc const bounds // (containing late-bound vars) that are ill-formed. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait { +use std::marker::ConstParamTy_; + +trait Trait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index b629bb4d3f8c..a0329e2b15d1 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = { () } | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = { () } | ^^^^^^ @@ -13,7 +13,7 @@ LL | K = { () } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:19:13 | LL | _: impl Trait< | _____________^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index 36b3d8a648fd..ef8077b9f44a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -3,10 +3,17 @@ // //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait { +use std::marker::ConstParamTy_; + +trait Trait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 3f48b3bfbb6d..1ab93ea596a7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -1,6 +1,6 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait<'a> { diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 5b0438e95695..0afb95a0b033 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -1,14 +1,21 @@ // Regression test for issue #108271. // Detect and reject generic params in the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait<'a, T: 'a, const N: usize> { +use std::marker::ConstParamTy_; + +trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { #[type_const] const K: &'a [T; N]; } -fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} +fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~^ ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the lifetime parameter `'r` //~| NOTE the lifetime parameter `'r` is defined here @@ -22,7 +29,7 @@ fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~| NOTE the const parameter `Q` is defined here //~| NOTE `K` has type `&'r [A; Q]` -trait Project { +trait Project: ConstParamTy_ { #[type_const] const SELF: Self; } @@ -38,7 +45,7 @@ fn take2>(_: P) {} //~| NOTE the type parameter `P` is defined here //~| NOTE `SELF` has type `P` -trait Iface<'r> { +trait Iface<'r>: ConstParamTy_ { //~^ NOTE the lifetime parameter `'r` is defined here //~| NOTE the lifetime parameter `'r` is defined here type Assoc: Trait<'r, Self, Q, K = { loop {} }> diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index 7ba1d638baa8..229dd10c0beb 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,31 +1,31 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | - ^ its type must not depend on the const parameter `Q` + | | + | the const parameter `Q` is defined here | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:30:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:37:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------ @@ -34,7 +34,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:35:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:42:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -44,9 +44,9 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | -LL | trait Iface<'r> { +LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> @@ -55,7 +55,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -63,7 +63,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -73,9 +73,9 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | -LL | trait Iface<'r> { +LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> @@ -85,7 +85,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -94,7 +94,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index 301ddf2d0104..d9b8a8cd43d7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -3,12 +3,19 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] +use std::marker::ConstParamTy_; + trait Trait: SuperTrait {} trait SuperTrait: SuperSuperTrait {} -trait SuperSuperTrait { +trait SuperSuperTrait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs index febd838e2c2e..41857eca87de 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs @@ -5,7 +5,7 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait: SuperTrait { diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs new file mode 100644 index 000000000000..8d2eae71d330 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -0,0 +1,23 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +const FREE: u32 = 5_usize; +//~^ ERROR mismatched types + +#[type_const] +const FREE2: isize = FREE; +//~^ ERROR the constant `5` is not of type `isize` + +trait Tr { + #[type_const] + const N: usize; +} + +impl Tr for () { + #[type_const] + const N: usize = false; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr new file mode 100644 index 000000000000..4029bb7b6bff --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -0,0 +1,27 @@ +error: the constant `5` is not of type `isize` + --> $DIR/type_const-mismatched-types.rs:9:1 + | +LL | const FREE2: isize = FREE; + | ^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:5:19 + | +LL | const FREE: u32 = 5_usize; + | ^^^^^^^ expected `u32`, found `usize` + | +help: change the type of the numeric literal from `usize` to `u32` + | +LL - const FREE: u32 = 5_usize; +LL + const FREE: u32 = 5_u32; + | + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:19:22 + | +LL | const N: usize = false; + | ^^^^^ expected `usize`, found `bool` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs new file mode 100644 index 000000000000..27b446e6a40d --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs @@ -0,0 +1,26 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +struct S; + +// FIXME(mgca): need support for ctors without anon const +// (we use double-braces to trigger an anon const here) +#[type_const] +const FREE: S = { { S } }; +//~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + +trait Tr { + #[type_const] + const N: S; + //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter +} + +impl Tr for S { + // FIXME(mgca): need support for ctors without anon const + // (we use double-braces to trigger an anon const here) + #[type_const] + const N: S = { { S } }; + //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr new file mode 100644 index 000000000000..6b13917a95cd --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr @@ -0,0 +1,39 @@ +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:9:13 + | +LL | const FREE: S = { { S } }; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:22:14 + | +LL | const N: S = { { S } }; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:14:14 + | +LL | const N: S; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/crashes/119783.rs b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs similarity index 54% rename from tests/crashes/119783.rs rename to tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs index efde7f89ade2..554e078ccd49 100644 --- a/tests/crashes/119783.rs +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs @@ -1,9 +1,12 @@ -//@ known-bug: #119783 +// Regression test for #119783 + +#![expect(incomplete_features)] #![feature(associated_const_equality, min_generic_const_args)] trait Trait { #[type_const] const F: fn(); + //~^ ERROR using function pointers as const generic parameters is forbidden } fn take(_: impl Trait) {} diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr new file mode 100644 index 000000000000..09d1063081fe --- /dev/null +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr @@ -0,0 +1,9 @@ +error[E0741]: using function pointers as const generic parameters is forbidden + --> $DIR/using-fnptr-as-type_const.rs:8:14 + | +LL | const F: fn(); + | ^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 57b748a6b475..7f4926fa2b71 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] pub struct NoPin; From db2fbdb714fbb88ba9897947e6f8c66093a0214e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 8 Nov 2025 17:32:35 -0500 Subject: [PATCH 518/525] Check that impls of `#[type_const]` consts also have the attr --- .../src/check/compare_impl_item.rs | 37 ++++++++++++++++++- compiler/rustc_hir_analysis/src/collect.rs | 8 +++- tests/crashes/140729.rs | 11 ------ tests/crashes/140860.rs | 10 ----- ...const-arg-coherence-conflicting-methods.rs | 17 +++++++++ ...t-arg-coherence-conflicting-methods.stderr | 29 +++++++++++++++ .../mgca/type_const-only-in-trait.rs | 5 +-- .../mgca/type_const-only-in-trait.stderr | 16 ++++++++ 8 files changed, 105 insertions(+), 28 deletions(-) delete mode 100644 tests/crashes/140729.rs delete mode 100644 tests/crashes/140860.rs create mode 100644 tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs create mode 100644 tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr rename tests/{crashes => ui/const-generics}/mgca/type_const-only-in-trait.rs (73%) create mode 100644 tests/ui/const-generics/mgca/type_const-only-in-trait.stderr 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 74bf68362fc5..6a07d2988fdf 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -6,9 +6,10 @@ use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit}; +use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, find_attr, intravisit}; use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -1984,12 +1985,46 @@ fn compare_impl_const<'tcx>( trait_const_item: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + compare_type_const(tcx, impl_const_item, trait_const_item)?; compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?; compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?; check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?; compare_const_predicate_entailment(tcx, impl_const_item, trait_const_item, impl_trait_ref) } +fn compare_type_const<'tcx>( + tcx: TyCtxt<'tcx>, + impl_const_item: ty::AssocItem, + trait_const_item: ty::AssocItem, +) -> Result<(), ErrorGuaranteed> { + let impl_is_type_const = + find_attr!(tcx.get_all_attrs(impl_const_item.def_id), AttributeKind::TypeConst(_)); + let trait_type_const_span = find_attr!( + tcx.get_all_attrs(trait_const_item.def_id), + AttributeKind::TypeConst(sp) => *sp + ); + + if let Some(trait_type_const_span) = trait_type_const_span + && !impl_is_type_const + { + return Err(tcx + .dcx() + .struct_span_err( + tcx.def_span(impl_const_item.def_id), + "implementation of `#[type_const]` const must be marked with `#[type_const]`", + ) + .with_span_note( + MultiSpan::from_spans(vec![ + tcx.def_span(trait_const_item.def_id), + trait_type_const_span, + ]), + "trait declaration of const is marked with `#[type_const]`", + ) + .emit()); + } + Ok(()) +} + /// The equivalent of [compare_method_predicate_entailment], but for associated constants /// instead of associated functions. // FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`. diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 84b0c20aaa10..2acccc1ae78e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1600,8 +1600,12 @@ fn const_of_item<'tcx>( }; let ct_arg = match ct_rhs { hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg, - hir::ConstItemRhs::Body(body_id) => { - bug!("cannot call const_of_item on a non-type_const {body_id:?}") + hir::ConstItemRhs::Body(_) => { + let e = tcx.dcx().span_delayed_bug( + tcx.def_span(def_id), + "cannot call const_of_item on a non-type_const", + ); + return ty::EarlyBinder::bind(Const::new_error(tcx, e)); } }; let icx = ItemCtxt::new(tcx, def_id); diff --git a/tests/crashes/140729.rs b/tests/crashes/140729.rs deleted file mode 100644 index a436ec58e8e8..000000000000 --- a/tests/crashes/140729.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #140729 -#![feature(min_generic_const_args)] - -const C: usize = 0; -pub struct A {} -impl A { - fn fun1() {} -} -impl A { - fn fun1() {} -} diff --git a/tests/crashes/140860.rs b/tests/crashes/140860.rs deleted file mode 100644 index 04da6bd832c3..000000000000 --- a/tests/crashes/140860.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #140860 -#![feature(min_generic_const_args)] -#![feature(unsized_const_params)] -#![feature(with_negative_coherence, negative_impls)] -trait a < const b : &'static str> {} trait c {} struct d< e >(e); -impl c for e where e: a<""> {} -impl c for d {} -impl !a for e {} -const f : &str = ""; -fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs new file mode 100644 index 000000000000..68aa30bd65bb --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs @@ -0,0 +1,17 @@ +// Regression test for #140729 + +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +const C: usize = 0; +pub struct A {} +impl A { + fn fun1() {} + //~^ ERROR duplicate definitions with name `fun1` +} +impl A { + //~^ ERROR missing generics for struct `A` + fn fun1() {} +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr new file mode 100644 index 000000000000..3d74d1db206e --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr @@ -0,0 +1,29 @@ +error[E0107]: missing generics for struct `A` + --> $DIR/const-arg-coherence-conflicting-methods.rs:12:6 + | +LL | impl A { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `M` + --> $DIR/const-arg-coherence-conflicting-methods.rs:7:12 + | +LL | pub struct A {} + | ^ -------------- +help: add missing generic argument + | +LL | impl A { + | +++ + +error[E0592]: duplicate definitions with name `fun1` + --> $DIR/const-arg-coherence-conflicting-methods.rs:9:5 + | +LL | fn fun1() {} + | ^^^^^^^^^ duplicate definitions for `fun1` +... +LL | fn fun1() {} + | --------- other definition for `fun1` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0107, E0592. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/crashes/mgca/type_const-only-in-trait.rs b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs similarity index 73% rename from tests/crashes/mgca/type_const-only-in-trait.rs rename to tests/ui/const-generics/mgca/type_const-only-in-trait.rs index 109cf0ec670c..8c8ff6259cae 100644 --- a/tests/crashes/mgca/type_const-only-in-trait.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs @@ -1,7 +1,3 @@ -//@ known-bug: #132980 -// Move this test to tests/ui/const-generics/mgca/type_const-only-in-trait.rs -// once fixed. - #![expect(incomplete_features)] #![feature(associated_const_equality, min_generic_const_args)] @@ -14,6 +10,7 @@ struct BadS; impl GoodTr for BadS { const NUM: usize = 42; + //~^ ERROR implementation of `#[type_const]` const must be marked with `#[type_const]` } fn accept_good_tr>(_x: &T) {} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr new file mode 100644 index 000000000000..29f1b724960a --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr @@ -0,0 +1,16 @@ +error: implementation of `#[type_const]` const must be marked with `#[type_const]` + --> $DIR/type_const-only-in-trait.rs:12:5 + | +LL | const NUM: usize = 42; + | ^^^^^^^^^^^^^^^^ + | +note: trait declaration of const is marked with `#[type_const]` + --> $DIR/type_const-only-in-trait.rs:5:5 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ +LL | const NUM: usize; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 1496ffa12b4d1b17adf35297bf2e903458d01932 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Sun, 9 Nov 2025 09:53:03 +0100 Subject: [PATCH 519/525] Fix typo in unstable-book link. This prevented the links from being rendered. Sorry for not noticing this before my changes were merged yesterday. --- src/doc/unstable-book/src/compiler-flags/sanitizer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index f32013d75e50..1771d1382f07 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -993,7 +993,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-kcfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-kcfi [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html -[clan-rtsan]: https://clang.llvm.org/docs/RealtimeSanitizer.html +[clang-rtsan]: https://clang.llvm.org/docs/RealtimeSanitizer.html [clang-safestack]: https://clang.llvm.org/docs/SafeStack.html [clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html From 852bd86d175e018ef310cfccf13406f79db630c3 Mon Sep 17 00:00:00 2001 From: nxsaken Date: Thu, 30 Oct 2025 13:59:39 +0400 Subject: [PATCH 520/525] Constify `ControlFlow` methods (unstable bounds) --- library/core/src/ops/control_flow.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index b760a7c4e21e..8eff1633c3b4 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -1,3 +1,4 @@ +use crate::marker::Destruct; use crate::{convert, ops}; /// Used to tell an operation whether it should exit early or go on as usual. @@ -183,7 +184,11 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - pub fn break_value(self) -> Option { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn break_value(self) -> Option + where + Self: [const] Destruct, + { match self { ControlFlow::Continue(..) => None, ControlFlow::Break(x) => Some(x), @@ -268,7 +273,11 @@ impl ControlFlow { /// to the break value in case it exists. #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - pub fn map_break(self, f: impl FnOnce(B) -> T) -> ControlFlow { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn map_break(self, f: F) -> ControlFlow + where + F: [const] FnOnce(B) -> T + [const] Destruct, + { match self { ControlFlow::Continue(x) => ControlFlow::Continue(x), ControlFlow::Break(x) => ControlFlow::Break(f(x)), @@ -288,7 +297,11 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - pub fn continue_value(self) -> Option { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn continue_value(self) -> Option + where + Self: [const] Destruct, + { match self { ControlFlow::Continue(x) => Some(x), ControlFlow::Break(..) => None, @@ -372,7 +385,11 @@ impl ControlFlow { /// to the continue value in case it exists. #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - pub fn map_continue(self, f: impl FnOnce(C) -> T) -> ControlFlow { + #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + pub const fn map_continue(self, f: F) -> ControlFlow + where + F: [const] FnOnce(C) -> T + [const] Destruct, + { match self { ControlFlow::Continue(x) => ControlFlow::Continue(f(x)), ControlFlow::Break(x) => ControlFlow::Break(x), From 3175799208fb595aae960cbbc7250d10f614d6eb Mon Sep 17 00:00:00 2001 From: nxsaken Date: Sun, 9 Nov 2025 13:33:47 +0400 Subject: [PATCH 521/525] Add tracking issue number --- library/core/src/ops/control_flow.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 8eff1633c3b4..bc497db35202 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -184,7 +184,7 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "const_control_flow", issue = "148739")] pub const fn break_value(self) -> Option where Self: [const] Destruct, @@ -273,7 +273,7 @@ impl ControlFlow { /// to the break value in case it exists. #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "const_control_flow", issue = "148739")] pub const fn map_break(self, f: F) -> ControlFlow where F: [const] FnOnce(B) -> T + [const] Destruct, @@ -297,7 +297,7 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "const_control_flow", issue = "148739")] pub const fn continue_value(self) -> Option where Self: [const] Destruct, @@ -385,7 +385,7 @@ impl ControlFlow { /// to the continue value in case it exists. #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "const_control_flow", issue = "148739")] pub const fn map_continue(self, f: F) -> ControlFlow where F: [const] FnOnce(C) -> T + [const] Destruct, From d05133f3a4964782085e3faae5ee3a411b8cdc48 Mon Sep 17 00:00:00 2001 From: nxsaken Date: Sun, 9 Nov 2025 13:36:35 +0400 Subject: [PATCH 522/525] Update feature name, add tracking issue number --- library/core/src/ops/control_flow.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index e426ff7cc057..1061ac082c02 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -150,7 +150,7 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "min_const_control_flow", issue = "148738")] pub const fn is_break(&self) -> bool { matches!(*self, ControlFlow::Break(_)) } @@ -167,7 +167,7 @@ impl ControlFlow { /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "min_const_control_flow", issue = "148738")] pub const fn is_continue(&self) -> bool { matches!(*self, ControlFlow::Continue(_)) } @@ -259,7 +259,7 @@ impl ControlFlow { /// ``` #[inline] #[unstable(feature = "control_flow_ok", issue = "140266")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "min_const_control_flow", issue = "148738")] pub const fn break_ok(self) -> Result { match self { ControlFlow::Continue(c) => Err(c), @@ -364,7 +364,7 @@ impl ControlFlow { /// ``` #[inline] #[unstable(feature = "control_flow_ok", issue = "140266")] - #[rustc_const_unstable(feature = "const_control_flow", issue = "none")] + #[rustc_const_unstable(feature = "min_const_control_flow", issue = "148738")] pub const fn continue_ok(self) -> Result { match self { ControlFlow::Continue(c) => Ok(c), From 479df91c0c4bad6653c9e6adb70cd27fa7e75d26 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 9 Nov 2025 20:46:03 +0800 Subject: [PATCH 523/525] Add myself(chenyukang) to the review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 325a62235c71..b9739149ea83 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1419,6 +1419,7 @@ compiler_leads = [ ] compiler = [ "@BoxyUwU", + "@chenyukang", "@compiler-errors", "@davidtwco", "@eholk", From d1dda8d25e0e9faaf5ebac053f6a7b82a4d63743 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Nov 2025 16:25:40 +0100 Subject: [PATCH 524/525] Fix invalid macro tag generation for keywords which can be followed by values --- src/librustdoc/html/highlight.rs | 83 +++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index dbff5c510af2..798fbd284ca8 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -789,6 +789,9 @@ impl<'a> Iterator for TokenIter<'a> { } } +/// Used to know if a keyword followed by a `!` should never be treated as a macro. +const NON_MACRO_KEYWORDS: &[&str] = &["if", "while", "match", "break", "return", "impl"]; + /// This iterator comes from the same idea than "Peekable" except that it allows to "peek" more than /// just the next item by using `peek_next`. The `peek` method always returns the next item after /// the current one whereas `peek_next` will return the next item after the last one peeked. @@ -1010,6 +1013,19 @@ impl<'src> Classifier<'src> { } } + fn new_macro_span( + &mut self, + text: &'src str, + sink: &mut dyn FnMut(Span, Highlight<'src>), + before: u32, + file_span: Span, + ) { + self.in_macro = true; + let span = new_span(before, text, file_span); + sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Macro(span) }); + sink(span, Highlight::Token { text, class: None }); + } + /// Single step of highlighting. This will classify `token`, but maybe also a couple of /// following ones as well. /// @@ -1216,16 +1232,46 @@ impl<'src> Classifier<'src> { LiteralKind::Float { .. } | LiteralKind::Int { .. } => Class::Number, }, TokenKind::GuardedStrPrefix => return no_highlight(sink), - TokenKind::Ident | TokenKind::RawIdent - if let Some((TokenKind::Bang, _)) = self.peek_non_trivia() => - { - self.in_macro = true; - let span = new_span(before, text, file_span); - sink(DUMMY_SP, Highlight::EnterSpan { class: Class::Macro(span) }); - sink(span, Highlight::Token { text, class: None }); + TokenKind::RawIdent if let Some((TokenKind::Bang, _)) = self.peek_non_trivia() => { + self.new_macro_span(text, sink, before, file_span); return; } - TokenKind::Ident => self.classify_ident(before, text), + // Macro non-terminals (meta vars) take precedence. + TokenKind::Ident if self.in_macro_nonterminal => { + self.in_macro_nonterminal = false; + Class::MacroNonTerminal + } + TokenKind::Ident => { + let file_span = self.file_span; + let span = || new_span(before, text, file_span); + + match text { + "ref" | "mut" => Class::RefKeyWord, + "false" | "true" => Class::Bool, + "self" | "Self" => Class::Self_(span()), + "Option" | "Result" => Class::PreludeTy(span()), + "Some" | "None" | "Ok" | "Err" => Class::PreludeVal(span()), + _ if self.is_weak_keyword(text) || is_keyword(Symbol::intern(text)) => { + // So if it's not a keyword which can be followed by a value (like `if` or + // `return`) and the next non-whitespace token is a `!`, then we consider + // it's a macro. + if !NON_MACRO_KEYWORDS.contains(&text) + && matches!(self.peek_non_trivia(), Some((TokenKind::Bang, _))) + { + self.new_macro_span(text, sink, before, file_span); + return; + } + Class::KeyWord + } + // If it's not a keyword and the next non whitespace token is a `!`, then + // we consider it's a macro. + _ if matches!(self.peek_non_trivia(), Some((TokenKind::Bang, _))) => { + self.new_macro_span(text, sink, before, file_span); + return; + } + _ => Class::Ident(span()), + } + } TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => { Class::Ident(new_span(before, text, file_span)) } @@ -1246,27 +1292,6 @@ impl<'src> Classifier<'src> { } } - fn classify_ident(&mut self, before: u32, text: &'src str) -> Class { - // Macro non-terminals (meta vars) take precedence. - if self.in_macro_nonterminal { - self.in_macro_nonterminal = false; - return Class::MacroNonTerminal; - } - - let file_span = self.file_span; - let span = || new_span(before, text, file_span); - - match text { - "ref" | "mut" => Class::RefKeyWord, - "false" | "true" => Class::Bool, - "self" | "Self" => Class::Self_(span()), - "Option" | "Result" => Class::PreludeTy(span()), - "Some" | "None" | "Ok" | "Err" => Class::PreludeVal(span()), - _ if self.is_weak_keyword(text) || is_keyword(Symbol::intern(text)) => Class::KeyWord, - _ => Class::Ident(span()), - } - } - fn is_weak_keyword(&mut self, text: &str) -> bool { // NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization), // `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are From 2c4a593b5c46ad971bdca7371bc268d12bd51a31 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Nov 2025 16:41:36 +0100 Subject: [PATCH 525/525] Add regression tests for keywords wrongly considered as macros --- .../failing-expansion-on-wrong-macro.rs | 13 ++++++++ .../source-code-pages/keyword-macros.rs | 30 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs create mode 100644 tests/rustdoc/source-code-pages/keyword-macros.rs diff --git a/tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs b/tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs new file mode 100644 index 000000000000..017d0be06560 --- /dev/null +++ b/tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs @@ -0,0 +1,13 @@ +// This code crashed because a `if` followed by a `!` was considered a macro, +// creating an invalid class stack. +// Regression test for . + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +enum Enum { + Variant, +} + +pub fn repro() { + if !matches!(Enum::Variant, Enum::Variant) {} +} diff --git a/tests/rustdoc/source-code-pages/keyword-macros.rs b/tests/rustdoc/source-code-pages/keyword-macros.rs new file mode 100644 index 000000000000..e5f1a7a3ea0e --- /dev/null +++ b/tests/rustdoc/source-code-pages/keyword-macros.rs @@ -0,0 +1,30 @@ +// This test ensures that keywords which can be followed by values (and therefore `!`) +// are not considered as macros. +// This is a regression test for . + +#![crate_name = "foo"] +#![feature(negative_impls)] + +//@ has 'src/foo/keyword-macros.rs.html' + +//@ has - '//*[@class="rust"]//*[@class="number"]' '2' +//@ has - '//*[@class="rust"]//*[@class="number"]' '0' +//@ has - '//*[@class="rust"]//*[@class="number"]' '1' +const ARR: [u8; 2] = [!0,! 1]; + +trait X {} + +//@ has - '//*[@class="rust"]//*[@class="kw"]' 'impl' +impl !X for i32 {} + +fn a() { + //@ has - '//*[@class="rust"]//*[@class="kw"]' 'if' + if! true{} + //@ has - '//*[@class="rust"]//*[@class="kw"]' 'match' + match !true { _ => {} } + //@ has - '//*[@class="rust"]//*[@class="kw"]' 'while' + let _ = while !true { + //@ has - '//*[@class="rust"]//*[@class="kw"]' 'break' + break !true; + }; +}