From 67e8a19a252f7711365eab10e2c1d05b4d8e3f85 Mon Sep 17 00:00:00 2001 From: Jonathan Keller Date: Wed, 19 Aug 2026 15:49:44 -0700 Subject: [PATCH 01/23] [bootstrap] Don't reverse the order of dylib search path entries --- src/bootstrap/src/utils/helpers.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 8e881f1bf7734..c21de29bf98f2 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -141,11 +141,8 @@ pub fn libdir(target: TargetSelection) -> &'static str { /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. /// If the dylib_path_var is already set for this cmd, the old value will be overwritten! pub fn add_dylib_path(path: Vec, cmd: &mut BootstrapCommand) { - let mut list = dylib_path(); - for path in path { - list.insert(0, path); - } - cmd.env(dylib_path_var(), t!(env::join_paths(list))); + let paths = path.into_iter().chain(dylib_path()); + cmd.env(dylib_path_var(), t!(env::join_paths(paths))); } pub struct TimeIt(bool, Instant); From 37aaf5c30436c34ca2426b5356bebadded2b1f4c Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 6 Aug 2026 00:01:00 +0200 Subject: [PATCH 02/23] forward global target features to module-level assembly --- compiler/rustc_codegen_llvm/src/asm.rs | 12 ++++- compiler/rustc_codegen_llvm/src/back/write.rs | 4 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 18 ++++--- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 19 +++++-- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 14 ++++++ tests/ui/asm/global-target-feature.rs | 49 +++++++++++++++++++ tests/ui/asm/inline-syntax.arm.stderr | 1 + tests/ui/asm/inline-syntax.rs | 2 +- 8 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 tests/ui/asm/global-target-feature.rs diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e715f9cd16c9d..549769547da78 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -16,12 +16,12 @@ use rustc_target::spec::HasTargetSpec; use smallvec::SmallVec; use tracing::debug; -use crate::attributes; use crate::builder::Builder; use crate::common::Funclet; use crate::context::CodegenCx; use crate::llvm::{self, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; +use crate::{attributes, llvm_util}; impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn codegen_inline_asm( @@ -499,7 +499,15 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { template_str.push_str("\n.att_syntax\n"); } - llvm::append_module_inline_asm(self.llmod, template_str.as_bytes()); + let target_features = self.tcx.global_backend_features(()).join(","); + let target_cpu = llvm_util::target_cpu(self.tcx.sess); + + llvm::append_module_inline_asm( + self.llmod, + template_str.as_bytes(), + &target_features, + target_cpu, + ); } fn mangled_name(&self, instance: Instance<'tcx>) -> String { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 66b51d9184a79..b8952ffc6bf81 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1303,9 +1303,9 @@ fn embed_bitcode( // We need custom section flags, so emit module-level inline assembly. let section_flags = if cgcx.is_pe_coff { "n" } else { "e" }; let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode); - llvm::append_module_inline_asm(llmod, &asm); + llvm::append_module_inline_asm(llmod, &asm, "", ""); let asm = create_section_with_flags_asm(".llvmcmd", section_flags, &[]); - llvm::append_module_inline_asm(llmod, &asm); + llvm::append_module_inline_asm(llmod, &asm, "", ""); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 1a60b59a93525..0db9698bf9545 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -907,13 +907,6 @@ unsafe extern "C" { pub(crate) fn LLVMGetDataLayoutStr(M: &Module) -> *const c_char; pub(crate) fn LLVMSetDataLayout(M: &Module, Triple: *const c_char); - /// Append inline assembly to a module. See `Module::appendModuleInlineAsm`. - pub(crate) fn LLVMAppendModuleInlineAsm( - M: &Module, - Asm: *const c_uchar, // See "PTR_LEN_STR". - Len: size_t, - ); - /// Create the specified uniqued inline asm string. See `InlineAsm::get()`. pub(crate) fn LLVMGetInlineAsm<'ll>( Ty: &'ll Type, @@ -2119,6 +2112,17 @@ unsafe extern "C" { ConstraintsLen: size_t, ) -> bool; + /// Append inline assembly to a module. See `Module::appendModuleInlineAsm`. + pub(crate) fn LLVMRustAppendModuleInlineAsm( + M: &Module, + Asm: *const c_uchar, // See "PTR_LEN_STR". + AsmLen: size_t, + TargetFeatures: *const c_uchar, // See "PTR_LEN_STR". + TargetFeaturesLen: size_t, + TargetCpu: *const c_uchar, // See "PTR_LEN_STR". + TargetCpuLen: size_t, + ); + /// A list of pointer-length strings is passed as two pointer-length slices, /// one slice containing pointers and one slice containing their corresponding /// lengths. The implementation will check that both slices have the same length. diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index eb7a529c0b198..5452f4abc5c33 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -474,11 +474,24 @@ pub(crate) fn set_dso_local<'ll>(v: &'ll Value) { } } -/// Safe wrapper for `LLVMAppendModuleInlineAsm`, which delegates to +/// Safe wrapper for `LLVMRustAppendModuleInlineAsm`, which delegates to /// `Module::appendModuleInlineAsm`. -pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) { +pub(crate) fn append_module_inline_asm<'ll>( + llmod: &'ll Module, + asm: &[u8], + target_features: &str, + target_cpu: &str, +) { unsafe { - LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len()); + LLVMRustAppendModuleInlineAsm( + llmod, + asm.as_ptr(), + asm.len(), + target_features.as_ptr(), + target_features.len(), + target_cpu.as_ptr(), + target_cpu.len(), + ); } } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 983a506bd4ac6..c928282596cdd 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -661,6 +661,20 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, unwrap(Ty), StringRef(Constraints, ConstraintsLen))); } +extern "C" void LLVMRustAppendModuleInlineAsm( + LLVMModuleRef M, const char *Asm, size_t AsmLen, const char *TargetFeatures, + size_t TargetFeaturesLen, const char *TargetCPU, size_t TargetCPULen) { +#if LLVM_VERSION_GE(23, 0) + Module::GlobalAsmProperties Props; + Props.TargetFeatures = std::string(TargetFeatures, TargetFeaturesLen); + Props.TargetCPU = std::string(TargetCPU, TargetCPULen); + unwrap(M)->appendModuleInlineAsm( + Module::GlobalAsmFragment(std::string(Asm, AsmLen), Props)); +#else + unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen)); +#endif +} + template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap(Ref) : nullptr); } diff --git a/tests/ui/asm/global-target-feature.rs b/tests/ui/asm/global-target-feature.rs new file mode 100644 index 0000000000000..d84b4d51e6582 --- /dev/null +++ b/tests/ui/asm/global-target-feature.rs @@ -0,0 +1,49 @@ +//@ build-pass +//@ add-minicore +//@ min-llvm-version: 23 +//@ ignore-backends: gcc +// +//@ revisions: riscv opt-0-bitcode-no opt-0 opt-s-bitcode-no +// +//@[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu -Clto=thin +//@[riscv] needs-llvm-components: riscv +// +//@[opt-0-bitcode-no] compile-flags: --target armv7r-none-eabihf -Copt-level=0 -Cembed-bitcode=no +//@[opt-0-bitcode-no] needs-llvm-components: arm +// +//@[opt-0] compile-flags: --target armv7r-none-eabihf -Copt-level=0 +//@[opt-0] needs-llvm-components: arm +// +//@[opt-s-bitcode-no] compile-flags: --target armv7r-none-eabihf -Copt-level=s -Cembed-bitcode=no +//@[opt-s-bitcode-no] needs-llvm-components: arm + +// Regression test for +// +// - https://github.com/llvm/llvm-project/issues/61991 +// - https://github.com/rust-lang/rust/issues/80608 +// - https://github.com/rust-lang/rust/issues/127269 +// +// Since LLVM 23 target features are taken into account for module-level assembly. + +#![feature(no_core)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +#[cfg(target_arch = "riscv64")] +global_asm!("fld f0, 0(sp)"); + +#[cfg(target_arch = "arm")] +global_asm!( + r#" +.section .text.startup +.global _start +.code 32 +.align 0 + +_start: + vmsr fpexc, r0 +"# +); diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr index 5b4eb3cc1409c..5b193d26c8776 100644 --- a/tests/ui/asm/inline-syntax.arm.stderr +++ b/tests/ui/asm/inline-syntax.arm.stderr @@ -13,6 +13,7 @@ note: instantiated into assembly here | LL | .intel_syntax noprefix | ^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unknown directive --> $DIR/inline-syntax.rs:21:15 diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs index b48841aabfe7b..63395c1096c09 100644 --- a/tests/ui/asm/inline-syntax.rs +++ b/tests/ui/asm/inline-syntax.rs @@ -3,10 +3,10 @@ //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu //@[x86_64] check-pass //@[x86_64] needs-llvm-components: x86 -// LLVM 19+ has full support for 64-bit cookies. //@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf //@[arm] build-fail //@[arm] needs-llvm-components: arm +//@[arm] min-llvm-version: 23 //@ ignore-backends: gcc #![feature(no_core)] From 8ceed4d81b26a8d34608338cf43b7d73396eb0b2 Mon Sep 17 00:00:00 2001 From: zep Date: Wed, 26 Aug 2026 15:06:25 +0530 Subject: [PATCH 03/23] Document PartialOrd behavior for Option where T: PartialOrd --- library/core/src/option.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 201019037148d..354d728ce5030 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2456,6 +2456,16 @@ const impl PartialEq for Option { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for Option { + /// If T implements PartialOrd then Option will derive its PartialOrd implementation. + /// With this order, None compares as less than any Some, and two Some compare the same way + /// as their contained values would in T. If T also implements Ord, then so does Option. + /// + /// # Examples + /// + /// ``` + /// assert!(None < Some(0)); + /// assert!(Some(0) < Some(1)); + /// ``` #[inline] fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { From 3fec803fd7b155e397ec801ccb97798361e7eef3 Mon Sep 17 00:00:00 2001 From: zep Date: Wed, 26 Aug 2026 16:30:02 +0530 Subject: [PATCH 04/23] Formatting changes for HTML tag errors --- library/core/src/option.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 354d728ce5030..61925c3dbc628 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2456,9 +2456,9 @@ const impl PartialEq for Option { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for Option { - /// If T implements PartialOrd then Option will derive its PartialOrd implementation. - /// With this order, None compares as less than any Some, and two Some compare the same way - /// as their contained values would in T. If T also implements Ord, then so does Option. + /// If `T` implements [`PartialOrd`], then [`Option`] will derive its [`PartialOrd`] implementation. + /// With this order, `None` compares as less than any `Some`, and two `Some` values compare the + /// same way as their contained values would in `T`. If `T` also implements [`Ord`], then so does [`Option`]. /// /// # Examples /// From bb75ebf894248aa9984c3406be319a353795034f Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 27 Aug 2026 19:08:53 +0800 Subject: [PATCH 05/23] loongarch: support passing `u128`/`i128` to inline assembly --- compiler/rustc_target/src/asm/loongarch.rs | 4 +- .../language-features/asm-experimental-reg.md | 4 +- .../bad-reg.loongarch32_ilp32d.stderr | 98 +++++++++++----- .../bad-reg.loongarch32_ilp32s.stderr | 110 ++++++++++++------ .../bad-reg.loongarch64_lp64d.stderr | 18 +-- .../bad-reg.loongarch64_lp64s.stderr | 110 ++++++++++++------ tests/ui/asm/loongarch/bad-reg.rs | 9 +- 7 files changed, 240 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs index 4aa69dac2d7db..3603d54400536 100644 --- a/compiler/rustc_target/src/asm/loongarch.rs +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -53,7 +53,7 @@ impl LoongArchInlineAsmRegClass { (Self::vreg, _) => { if allow_experimental_reg { types! { - lsx: F16, F32, F64, + lsx: I128, F16, F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); } } else { @@ -63,7 +63,7 @@ impl LoongArchInlineAsmRegClass { (Self::xreg, _) => { if allow_experimental_reg { types! { - lasx: F16, F32, F64, + lasx: I128, F16, F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2), VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4); } diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md index db72c44a2dc92..854d66f96756c 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md @@ -19,8 +19,8 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Target feature | Allowed types | | ------------ | -------------- | -------------- | ------------- | -| LoongArch | `vreg` | `lsx` | `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | -| LoongArch | `xreg` | `lasx` | `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`,
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | +| LoongArch | `vreg` | `lsx` | `i128`, `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| LoongArch | `xreg` | `lasx` | `i128`, `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`,
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | ## Register aliases diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr index 28ac455c06441..dca21ad47ea10 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = 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:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = 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:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = 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:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = 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:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = 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:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -154,8 +174,18 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` 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]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -165,7 +195,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -175,7 +205,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -184,8 +214,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` 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]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -195,7 +235,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -205,7 +245,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -215,7 +255,7 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -225,7 +265,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -235,7 +275,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -245,7 +285,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -254,6 +294,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` 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 28 previous errors +error: aborting due to 32 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr index 1ee1b86989c4d..9ffab83db95cb 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = 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:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = 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:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = 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:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = 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:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = 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:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -155,31 +175,41 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:42:26 + --> $DIR/bad-reg.rs:43:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:44:26 + --> $DIR/bad-reg.rs:45:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:48:26 + --> $DIR/bad-reg.rs:49:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -189,7 +219,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -199,7 +229,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -208,8 +238,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` 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]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -219,7 +259,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -229,7 +269,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -239,13 +279,13 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:77:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -255,13 +295,13 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:89:18 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -271,7 +311,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -281,7 +321,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -290,6 +330,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` 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 34 previous errors +error: aborting due to 38 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr index 97462d6dc5f0b..067dd354f3093 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr @@ -1,41 +1,41 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error: register `$vr0` conflicts with register `$f0` - --> $DIR/bad-reg.rs:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ----------- ^^^^^^^^^^^^ register `$vr0` @@ -43,7 +43,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); | register `$f0` error: register `$xr0` conflicts with register `$f0` - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ----------- ^^^^^^^^^^^^ register `$xr0` @@ -51,7 +51,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); | register `$f0` error: register `$xr0` conflicts with register `$vr0` - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ------------ ^^^^^^^^^^^^ register `$xr0` diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr index 1ee1b86989c4d..9ffab83db95cb 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = 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:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = 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:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = 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:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = 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:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = 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:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -155,31 +175,41 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:42:26 + --> $DIR/bad-reg.rs:43:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:44:26 + --> $DIR/bad-reg.rs:45:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:48:26 + --> $DIR/bad-reg.rs:49:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -189,7 +219,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -199,7 +229,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -208,8 +238,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` 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]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` 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]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -219,7 +259,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -229,7 +269,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -239,13 +279,13 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:77:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -255,13 +295,13 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:89:18 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -271,7 +311,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -281,7 +321,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -290,6 +330,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` 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 34 previous errors +error: aborting due to 38 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs index 6bda28eb10fde..ac2eeb7d78a70 100644 --- a/tests/ui/asm/loongarch/bad-reg.rs +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -8,6 +8,7 @@ //@[loongarch64_lp64d] needs-llvm-components: loongarch //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat //@[loongarch64_lp64s] needs-llvm-components: loongarch +//@ min-llvm-version: 23 //@ ignore-backends: gcc #![cfg_attr(loongarch64_lp64d, feature(asm_experimental_reg))] @@ -20,7 +21,7 @@ extern crate minicore; use minicore::*; fn f() { - let mut x = 0; + let mut q = 0_u128; let mut f = 0.0_f32; let mut d = 0.0_f64; unsafe { @@ -49,6 +50,9 @@ fn f() { //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f asm!("", out("$vr0") _); // ok + asm!("/* {} */", in(vreg) q); + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `u128` cannot be used with this register class in stable asm!("/* {} */", in(vreg) f); //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable @@ -62,6 +66,9 @@ fn f() { //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable asm!("", out("$xr0") _); // ok + asm!("/* {} */", in(xreg) q); + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `u128` cannot be used with this register class in stable asm!("/* {} */", in(xreg) f); //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable From 97fe424048d97b383aa981fd41879f0e58c87b74 Mon Sep 17 00:00:00 2001 From: zep Date: Thu, 27 Aug 2026 20:12:35 +0530 Subject: [PATCH 06/23] Change the doc comments to link to the relevant doc section --- library/core/src/option.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 61925c3dbc628..7e6e31931813c 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2456,16 +2456,7 @@ const impl PartialEq for Option { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for Option { - /// If `T` implements [`PartialOrd`], then [`Option`] will derive its [`PartialOrd`] implementation. - /// With this order, `None` compares as less than any `Some`, and two `Some` values compare the - /// same way as their contained values would in `T`. If `T` also implements [`Ord`], then so does [`Option`]. - /// - /// # Examples - /// - /// ``` - /// assert!(None < Some(0)); - /// assert!(Some(0) < Some(1)); - /// ``` + /// See [the documentation](https://doc.rust-lang.org/std/option/#comparison-operators) for details. #[inline] fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { From a1fb7b3cb832f99ccd4a56bb237e9a65a9bf4b26 Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:25:08 -0400 Subject: [PATCH 07/23] add test --- .../lints/redundant-explicit-links-ice.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs new file mode 100644 index 0000000000000..a129baecdb79f --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs @@ -0,0 +1,13 @@ +// Regression test for . + +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +//! [queue](macro.queue.html) +//~^ ERROR redundant explicit link target + +#[macro_export] +macro_rules! queue { + () => {}; +} From 0f08915b3ef24ac1909c7c94700389238e9ee1ba Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:23:00 -0400 Subject: [PATCH 08/23] do not load macro metadata for local definitions in rustdoc --- src/librustdoc/clean/inline.rs | 20 +++++++++------- .../lints/redundant-explicit-links-ice.fixed | 13 +++++++++++ .../lints/redundant-explicit-links-ice.stderr | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed create mode 100644 tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cb7ddd0ec58e7..d7fbe64c30771 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -250,17 +250,21 @@ pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> V if let ItemType::Macro = kind { // Check to see if it is a macro 2.0 or built-in macro // More information in . - if matches!( - CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), - LoadedMacro::MacroDef { def, .. } if !def.macro_rules - ) { - once(crate_name).chain(relative).collect() + let is_macro_2_0_or_builtin = if let Some(local_def_id) = def_id.as_local() { + let (_, macro_def, _) = tcx.hir_expect_item(local_def_id).expect_macro(); + !macro_def.macro_rules } else { - vec![crate_name, *relative.last().expect("relative was empty")] + matches!( + CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), + LoadedMacro::MacroDef { def, .. } if !def.macro_rules + ) + }; + if !is_macro_2_0_or_builtin { + return vec![crate_name, *relative.last().expect("relative was empty")]; } - } else { - once(crate_name).chain(relative).collect() } + + once(crate_name).chain(relative).collect() } /// Record an external fully qualified name in the external_paths cache. diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed new file mode 100644 index 0000000000000..bfd09e970db06 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed @@ -0,0 +1,13 @@ +// Regression test for . + +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +//! [queue] +//~^ ERROR redundant explicit link target + +#[macro_export] +macro_rules! queue { + () => {}; +} diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr new file mode 100644 index 0000000000000..2caf08e26936f --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr @@ -0,0 +1,23 @@ +error: redundant explicit link target + --> $DIR/redundant-explicit-links-ice.rs:7:13 + | +LL | //! [queue](macro.queue.html) + | ----- ^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/redundant-explicit-links-ice.rs:5:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - //! [queue](macro.queue.html) +LL + //! [queue] + | + +error: aborting due to 1 previous error + From 42629e39dcec43948166b074c8143d6bb48526d3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Aug 2026 21:22:34 +0200 Subject: [PATCH 09/23] better deal with internal features being injected into doctests --- 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 +- src/bootstrap/src/bin/rustdoc.rs | 5 ++++- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index c33765f03d77d..dfc48b0bd1cd6 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -13,7 +13,7 @@ #![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] +#![doc(test(no_crate_inject, attr(deny(warnings))))] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 3b01eb6eefa7d..46d8e11cc0931 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), allow(internal_features))))] +#![doc(test(attr(deny(warnings))))] #![feature(associated_type_defaults)] #![feature(deref_patterns)] #![feature(iter_order_by)] diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index cd1e573ea28df..2aaf9cea97e44 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), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] // 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 256bc8c3fe30e..90e04fe388ad6 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), allow(internal_features))))] +#![doc(test(attr(deny(warnings))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 4adc0e139a68e..ac2d1eb7a7a42 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -43,7 +43,7 @@ //! For more information, see . #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] use std::fmt::Debug; diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index d598f88a00d27..c8859b0e349ea 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), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 39333ab00b57f..ae7c3854d00b4 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(bootstrap, feature(never_type))] -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(nonzero_internals)] diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index eba1e9ef1c5cf..da80d7cd8c599 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -65,7 +65,10 @@ fn main() { 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") + // We use `-Zcrate-attr=allow` instead of `-A` to force rustdoc to forward this flag to + // the actual doctests. Otherwise those tests all receive the + // `feature(rustdoc_internals)` without receiving the `-A` which leads to errors. + cmd.arg("-Zcrate-attr=allow(internal_features)") .arg("-Zcrate-attr=doc(rust_logo)") .arg("-Zcrate-attr=doc(html_root_url = \"https://doc.rust-lang.org/nightly/nightly-rustc/\")"); From a0ec5117dedb2802ee391df172c6e35e654c6715 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Aug 2026 20:54:52 +0200 Subject: [PATCH 10/23] fix rustc_lint_defs doctest issues --- compiler/rustc_lint_defs/src/builtin.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index def2662e15837..93e2cd971a1b9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -798,7 +798,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,compile_fail /// #![deny(dead_code_pub_in_binary)] /// /// pub fn unused_pub_fn() {} @@ -1107,9 +1107,9 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,compile_fail /// #![deny(warnings)] - /// fn foo() {} + /// struct non_standard_name; /// ``` /// /// {{produces}} From cdd3fc01eaee52874310b9dede3cf510db6dc0e1 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 27 Aug 2026 21:47:21 +0100 Subject: [PATCH 11/23] std: uefi: fix File::seek returning the EOF sentinel seek(SeekFrom::End(0)) special-cased the offset to the UEFI 0xFFFFFFFFFFFFFFFF "set position to end of file" sentinel, then returned that value as the new stream position. so seek reported u64::MAX instead of the file size, and the default Seek::stream_len did too. compute the offset from the file size in every End case instead. --- library/std/src/sys/fs/uefi.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1a0da329ce1a3..08473e245cc8e 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -360,12 +360,7 @@ impl File { let off = match pos { SeekFrom::Start(p) => p, SeekFrom::End(p) => { - // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file. - if p == 0 { - 0xFFFFFFFFFFFFFFFF - } else { - self.file_attr()?.size().checked_add_signed(p).ok_or(NEG_OFF_ERR)? - } + self.file_attr()?.size().checked_add_signed(p).ok_or(NEG_OFF_ERR)? } SeekFrom::Current(p) => self.tell()?.checked_add_signed(p).ok_or(NEG_OFF_ERR)?, }; From 7047ae88811f6ef9bf54da93810f3daa1b73f9cf Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 28 Aug 2026 08:07:48 +0800 Subject: [PATCH 12/23] Add regression test for empty contract attributes with lifetime lints --- .../lint/single-use-lifetimes-issue-146834.rs | 18 ++++++ .../single-use-lifetimes-issue-146834.stderr | 63 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/ui/lint/single-use-lifetimes-issue-146834.rs create mode 100644 tests/ui/lint/single-use-lifetimes-issue-146834.stderr diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.rs b/tests/ui/lint/single-use-lifetimes-issue-146834.rs new file mode 100644 index 0000000000000..aee16ae5731c1 --- /dev/null +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.rs @@ -0,0 +1,18 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/146834. + +//@ compile-flags: -Wsingle-use-lifetimes +//@ edition: 2024 + +#![expect(incomplete_features)] +#![feature(contracts)] + +#[core::contracts::ensures] +//~^ ERROR expected an `Fn(&_)` closure, found `()` +fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + //~^ ERROR missing lifetime specifiers + //~| WARN lifetime parameter `'a` only used once + //~| WARN lifetime parameter `'b` only used once + loop {} +} + +fn main() {} diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.stderr b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr new file mode 100644 index 0000000000000..259a908e1b818 --- /dev/null +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr @@ -0,0 +1,63 @@ +error[E0106]: missing lifetime specifiers + --> $DIR/single-use-lifetimes-issue-146834.rs:11:42 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ------- ------- ^ ^ expected named lifetime parameter + | | + | expected named lifetime parameter + | + = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments +note: these named lifetimes are available to use + --> $DIR/single-use-lifetimes-issue-146834.rs:11:6 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ ^^ +help: consider using one of the available lifetimes here + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&'lifetime i32, &'lifetime i32) { + | +++++++++ +++++++++ + +warning: lifetime parameter `'a` only used once + --> $DIR/single-use-lifetimes-issue-146834.rs:11:6 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ -- ...is used only here + | | + | this lifetime... + | + = note: requested on the command line with `-W single-use-lifetimes` +help: elide the single-use lifetime + | +LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { +LL + fn f<'b>(a: &i32, b: &'b i32) -> (&i32, &i32) { + | + +warning: lifetime parameter `'b` only used once + --> $DIR/single-use-lifetimes-issue-146834.rs:11:10 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ this lifetime... -- ...is used only here + | +help: elide the single-use lifetime + | +LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { +LL + fn f<'a>(a: &'a i32, b: &i32) -> (&i32, &i32) { + | + +error[E0277]: expected an `Fn(&_)` closure, found `()` + --> $DIR/single-use-lifetimes-issue-146834.rs:9:1 + | +LL | #[core::contracts::ensures] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected an `Fn(&_)` closure, found `()` + | required by a bound introduced by this call + | + = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` +note: required by a bound in `build_check_ensures` + --> $SRC_DIR/core/src/contracts.rs:LL:COL + +error: aborting due to 2 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0106, E0277. +For more information about an error, try `rustc --explain E0106`. From 12f970e8d77d7abed5053b0c9f90c625466d787e Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 28 Aug 2026 08:11:01 +0800 Subject: [PATCH 13/23] Reject contract attributes without arguments --- .../rustc_builtin_macros/src/contracts.rs | 15 +++++++++++++ tests/ui/contracts/empty-ensures.rs | 2 +- tests/ui/contracts/empty-ensures.stderr | 10 +-------- tests/ui/contracts/empty-requires.rs | 4 +--- tests/ui/contracts/empty-requires.stderr | 7 +++--- .../lint/single-use-lifetimes-issue-146834.rs | 2 +- .../single-use-lifetimes-issue-146834.stderr | 22 ++++++------------- ...-tokenstream-for-contracts-issue-140683.rs | 2 +- ...enstream-for-contracts-issue-140683.stderr | 20 +++++------------ 9 files changed, 36 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/contracts.rs b/compiler/rustc_builtin_macros/src/contracts.rs index e47c1b1363df0..20001400857a6 100644 --- a/compiler/rustc_builtin_macros/src/contracts.rs +++ b/compiler/rustc_builtin_macros/src/contracts.rs @@ -137,6 +137,21 @@ fn expand_contract_clause_tts( annotated: TokenStream, clause_keyword: rustc_span::Symbol, ) -> Result { + if annotation.is_empty() { + let (name, example) = if clause_keyword == kw::ContractRequires { + ("requires", "condition") + } else { + ("ensures", "|result: &T| condition") + }; + ecx.sess.dcx().span_err( + attr_span, + format!("`{name}` attribute requires an argument, e.g., `#[{name}({example})]`"), + ); + // Returning `Err` would replace it with a dummy fragment and cause cascading name-resolution errors. + // Instead, we return the original token stream so that there is no later noises. + return Ok(annotated); + } + let feature_span = ecx.with_def_site_ctxt(attr_span); expand_contract_clause(ecx, attr_span, annotated, |new_tts| { new_tts.push(TokenTree::Token( diff --git a/tests/ui/contracts/empty-ensures.rs b/tests/ui/contracts/empty-ensures.rs index 79e57df6eb984..242e903b7cc96 100644 --- a/tests/ui/contracts/empty-ensures.rs +++ b/tests/ui/contracts/empty-ensures.rs @@ -6,7 +6,7 @@ extern crate core; use core::contracts::ensures; #[ensures()] -//~^ ERROR expected an `Fn(&_)` closure, found `()` [E0277] +//~^ ERROR `ensures` attribute requires an argument fn foo(x: u32) -> u32 { x * 2 } diff --git a/tests/ui/contracts/empty-ensures.stderr b/tests/ui/contracts/empty-ensures.stderr index b87f709eeb7a4..369ba431b62ce 100644 --- a/tests/ui/contracts/empty-ensures.stderr +++ b/tests/ui/contracts/empty-ensures.stderr @@ -1,16 +1,8 @@ -error[E0277]: expected an `Fn(&_)` closure, found `()` +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` --> $DIR/empty-ensures.rs:8:1 | LL | #[ensures()] | ^^^^^^^^^^^^ - | | - | expected an `Fn(&_)` closure, found `()` - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` -note: required by a bound in `build_check_ensures` - --> $SRC_DIR/core/src/contracts.rs:LL:COL error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/empty-requires.rs b/tests/ui/contracts/empty-requires.rs index dedcc10d52cb0..eae86607acf31 100644 --- a/tests/ui/contracts/empty-requires.rs +++ b/tests/ui/contracts/empty-requires.rs @@ -1,4 +1,3 @@ -//@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes #![expect(incomplete_features)] #![feature(contracts)] @@ -7,8 +6,7 @@ extern crate core; use core::contracts::requires; #[requires()] -//~^ ERROR mismatched types [E0308] -//~| NOTE expected `bool`, found `()` +//~^ ERROR `requires` attribute requires an argument fn foo(x: u32) -> u32 { x * 2 } diff --git a/tests/ui/contracts/empty-requires.stderr b/tests/ui/contracts/empty-requires.stderr index 702b8a23c55e3..c8fa644702259 100644 --- a/tests/ui/contracts/empty-requires.stderr +++ b/tests/ui/contracts/empty-requires.stderr @@ -1,9 +1,8 @@ -error[E0308]: mismatched types - --> $DIR/empty-requires.rs:9:1 +error: `requires` attribute requires an argument, e.g., `#[requires(condition)]` + --> $DIR/empty-requires.rs:8:1 | LL | #[requires()] - | ^^^^^^^^^^^^^ expected `bool`, found `()` + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.rs b/tests/ui/lint/single-use-lifetimes-issue-146834.rs index aee16ae5731c1..8c03e40fa8070 100644 --- a/tests/ui/lint/single-use-lifetimes-issue-146834.rs +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.rs @@ -7,7 +7,7 @@ #![feature(contracts)] #[core::contracts::ensures] -//~^ ERROR expected an `Fn(&_)` closure, found `()` +//~^ ERROR `ensures` attribute requires an argument fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { //~^ ERROR missing lifetime specifiers //~| WARN lifetime parameter `'a` only used once diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.stderr b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr index 259a908e1b818..d7b84680fd081 100644 --- a/tests/ui/lint/single-use-lifetimes-issue-146834.stderr +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr @@ -1,3 +1,9 @@ +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` + --> $DIR/single-use-lifetimes-issue-146834.rs:9:1 + | +LL | #[core::contracts::ensures] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0106]: missing lifetime specifiers --> $DIR/single-use-lifetimes-issue-146834.rs:11:42 | @@ -44,20 +50,6 @@ LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { LL + fn f<'a>(a: &'a i32, b: &i32) -> (&i32, &i32) { | -error[E0277]: expected an `Fn(&_)` closure, found `()` - --> $DIR/single-use-lifetimes-issue-146834.rs:9:1 - | -LL | #[core::contracts::ensures] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected an `Fn(&_)` closure, found `()` - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` -note: required by a bound in `build_check_ensures` - --> $SRC_DIR/core/src/contracts.rs:LL:COL - error: aborting due to 2 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0106, E0277. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs index 2b1bacf7e0c31..db85d496991f7 100644 --- a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs @@ -4,7 +4,7 @@ struct T; impl T { - #[core::contracts::ensures] //~ ERROR expected an `Fn(&_)` closure, found `()` + #[core::contracts::ensures] //~ ERROR `ensures` attribute requires an argument fn b() {(loop)} //~^ ERROR expected `{`, found `)` //~| ERROR expected `{`, found `)` diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr index 56dbdae14189b..ab6459bdc919a 100644 --- a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr @@ -6,6 +6,12 @@ LL | fn b() {(loop)} | | | while parsing this `loop` expression +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` + --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5 + | +LL | #[core::contracts::ensures] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: expected `{`, found `)` --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18 | @@ -16,19 +22,5 @@ LL | fn b() {(loop)} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0277]: expected an `Fn(&_)` closure, found `()` - --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5 - | -LL | #[core::contracts::ensures] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected an `Fn(&_)` closure, found `()` - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` -note: required by a bound in `build_check_ensures` - --> $SRC_DIR/core/src/contracts.rs:LL:COL - error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. From 9c6ebca4725d647107bbcc43fddee99195af3dd4 Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 28 Aug 2026 09:22:08 +0800 Subject: [PATCH 14/23] Add regression test for the Polonius help default --- tests/run-make/rustc-help/polonius-help.stdout | 1 + tests/run-make/rustc-help/rmake.rs | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 tests/run-make/rustc-help/polonius-help.stdout diff --git a/tests/run-make/rustc-help/polonius-help.stdout b/tests/run-make/rustc-help/polonius-help.stdout new file mode 100644 index 0000000000000..9f56fb6de9481 --- /dev/null +++ b/tests/run-make/rustc-help/polonius-help.stdout @@ -0,0 +1 @@ + -Z polonius=val -- enable polonius-based borrow-checker (default: no) diff --git a/tests/run-make/rustc-help/rmake.rs b/tests/run-make/rustc-help/rmake.rs index 17811ef18449f..a5e733fb8d9fc 100644 --- a/tests/run-make/rustc-help/rmake.rs +++ b/tests/run-make/rustc-help/rmake.rs @@ -22,6 +22,12 @@ fn main() { // Check that all help options can be invoked at once let codegen_help = bare_rustc().arg("-Chelp").run().stdout_utf8(); let unstable_help = bare_rustc().arg("-Zhelp").run().stdout_utf8(); + let polonius_help = + format!("{}\n", unstable_help.lines().find(|line| line.contains("polonius=val")).unwrap()); + diff() + .expected_file("polonius-help.stdout") + .actual_text("rustc -Zhelp (polonius)", &polonius_help) + .run(); let lints_help = bare_rustc().arg("-Whelp").run().stdout_utf8(); let expected_all = format!("{help}{codegen_help}{unstable_help}{lints_help}"); let all_help = bare_rustc().args(["--help", "-Chelp", "-Zhelp", "-Whelp"]).run().stdout_utf8(); From d471202631fd097101bfa12fbc9680d2b4a93093 Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Fri, 28 Aug 2026 06:41:43 +0200 Subject: [PATCH 15/23] fix ICE in generic_const_parameter_types with inherents --- .../src/normalize_projection_ty.rs | 12 ---------- .../inherent-type-const.rs | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 3710d41dba0d9..03dff745210d6 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -59,12 +59,6 @@ fn normalize_canonicalized_projection<'tcx>( 0, &mut obligations, ); - obligations.extend(const_arg_has_type_obligation( - tcx, - param_env, - normalized_term, - goal, - )); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that // are recursive (given some generic parameters of the opaque's type variables). @@ -147,12 +141,6 @@ fn normalize_canonicalized_inherent_projection<'tcx>( 0, &mut obligations, ); - obligations.extend(const_arg_has_type_obligation( - tcx, - param_env, - normalized_term, - goal, - )); ocx.register_obligations(obligations); Ok(NormalizationResult { normalized_term }) diff --git a/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs b/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs new file mode 100644 index 0000000000000..86eab5ec70eb2 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs @@ -0,0 +1,22 @@ +//@ check-pass +#![feature( + min_generic_const_args, + generic_const_parameter_types, + inherent_associated_types, + min_adt_const_params, + const_param_ty_trait +)] + +struct ThreeTypes(T1, T2, T3); + +impl ThreeTypes { + type const INHERENT: [T3; 0] = []; +} + +struct Struct; + +fn f() -> Struct<{ core::direct_const_arg!(ThreeTypes::::INHERENT) }> { + Struct +} + +fn main() {} From f31b77f5c6585941431eed7a7fff2dabfbf2ef34 Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 28 Aug 2026 09:32:05 +0800 Subject: [PATCH 16/23] Report the configured Polonius default in -Z help --- compiler/rustc_session/src/config.rs | 5 ++++- compiler/rustc_session/src/options.rs | 10 ++++++++-- tests/run-make/rustc-help/polonius-help.stdout | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a5053c408b155..95f6348cfbdbb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3647,11 +3647,14 @@ pub enum Polonius { impl Default for Polonius { fn default() -> Self { - if option_env!("CFG_DEFAULT_POLONIUS_NEXT").is_some() { Self::Next } else { Self::Off } + Self::DEFAULT } } impl Polonius { + pub(crate) const DEFAULT: Self = + if option_env!("CFG_DEFAULT_POLONIUS_NEXT").is_some() { Self::Next } else { Self::Off }; + /// Returns whether the legacy version of polonius is enabled pub fn is_legacy_enabled(&self) -> bool { matches!(self, Polonius::Legacy) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 90459090ced87..bab087249593a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -510,7 +510,7 @@ macro_rules! options { $( { TARGET_MODIFIER: $tmod_variant:ident } )? $( { MITIGATION: $mitigation_variant:ident } )? , - $desc:literal + $desc:expr $(, removed: $removed:ident )? ), )* @@ -2350,6 +2350,12 @@ options! { // - src/doc/rustc/src/codegen-options/index.md } +const POLONIUS_HELP: &str = match Polonius::DEFAULT { + Polonius::Off => "enable polonius-based borrow-checker (default: no)", + Polonius::Next => "enable polonius-based borrow-checker (default: next)", + Polonius::Legacy => panic!("Polonius::Legacy is not a valid default value"), +}; + options! { UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", @@ -2750,7 +2756,7 @@ options! { `vt-ptr-type-discrimination - incorporate type discrimination in authenticated vtable pointers Example: `-Zpointer-authentication=+calls,-init-fini`."), polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED], - "enable polonius-based borrow-checker (default: no)"), + POLONIUS_HELP), pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED], "a single extra argument to prepend the linker invocation (can be used several times)"), pre_link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], diff --git a/tests/run-make/rustc-help/polonius-help.stdout b/tests/run-make/rustc-help/polonius-help.stdout index 9f56fb6de9481..b1dfd15c09958 100644 --- a/tests/run-make/rustc-help/polonius-help.stdout +++ b/tests/run-make/rustc-help/polonius-help.stdout @@ -1 +1 @@ - -Z polonius=val -- enable polonius-based borrow-checker (default: no) + -Z polonius=val -- enable polonius-based borrow-checker (default: next) From 66bbc147f55c6b4cea5876ae266fc45ed652b154 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Aug 2026 12:45:04 +0200 Subject: [PATCH 17/23] Add rustdoc-html regression test for generated macro --- tests/rustdoc-html/auxiliary/generated_macro.rs | 17 +++++++++++++++++ tests/rustdoc-html/generated_macro.rs | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/rustdoc-html/auxiliary/generated_macro.rs create mode 100644 tests/rustdoc-html/generated_macro.rs diff --git a/tests/rustdoc-html/auxiliary/generated_macro.rs b/tests/rustdoc-html/auxiliary/generated_macro.rs new file mode 100644 index 0000000000000..47a2eae5b3c2c --- /dev/null +++ b/tests/rustdoc-html/auxiliary/generated_macro.rs @@ -0,0 +1,17 @@ +//@ no-prefer-dynamic + +#![crate_type = "proc-macro"] + +use std::str::FromStr; + +extern crate proc_macro; + +#[proc_macro_derive(MyDeriveMacro)] +pub fn derive_my_derive_macro(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::from_str(" + #[macro_export] + macro_rules! my_generated_macro { + ($my_macro_parameter: expr) => {}; + } + ").unwrap() +} diff --git a/tests/rustdoc-html/generated_macro.rs b/tests/rustdoc-html/generated_macro.rs new file mode 100644 index 0000000000000..3986930f8e631 --- /dev/null +++ b/tests/rustdoc-html/generated_macro.rs @@ -0,0 +1,16 @@ +// This test ensures that the macro generated by the proc macro has the correct +// "item-decl" code block. +// Regression test for . + +//@ aux-build:generated_macro.rs + +#![crate_name = "foo"] + +extern crate generated_macro; + +//@ has 'foo/macro.my_generated_macro.html' +//@ matches - '//*[@class="rust item-decl"]/code' \ +// 'macro_rules! my_generated_macro \{\s+\(\$my_macro_parameter:expr\) => \{ ... \};\s+\}' + +#[derive(generated_macro::MyDeriveMacro)] +struct MyStruct {} From 448757dcdd3bc85f968be595fed9594a6b9530f3 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 28 Aug 2026 19:09:25 +0800 Subject: [PATCH 18/23] Retroactively add relnotes for `bool::{ok_or,ok_or_else}` --- RELEASES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 940fa7c6072a9..f2d74f2e7f1f0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -67,6 +67,8 @@ Stabilized APIs - [`Atomic::get_mut_slice`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.Atomic.html#method.get_mut_slice) - [`Atomic::from_mut_slice`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.Atomic.html#method.from_mut_slice) - [`std::range::legacy`](https://doc.rust-lang.org/stable/std/range/legacy/index.html) +- [`bool::ok_or`](https://doc.rust-lang.org/stable/std/primitive.bool.html#method.ok_or) +- [`bool::ok_or_else`](https://doc.rust-lang.org/stable/std/primitive.bool.html#method.ok_or_else) From 55e9af57417fe526b4b811ce2f825307a73d55ae Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 28 Aug 2026 12:47:24 +0000 Subject: [PATCH 19/23] Windows: note normalize_lexically slash behaviour On Windows `/` is converted to `\`. --- library/std/src/path.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index dbfc00b2c2b47..0f527e902cfec 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3424,6 +3424,8 @@ impl Path { /// /// /// + /// On Windows this will convert all `/` to `\` unless a [verbatim](Prefix::is_verbatim()) path is given. + /// /// [`path::absolute`](absolute) is an alternative that preserves `..`. /// Or [`Path::canonicalize`] can be used to resolve any `..` by querying the filesystem. #[unstable(feature = "normalize_lexically", issue = "134694")] From 841df3cc5de745012a420c7ea0748944c188d32e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 28 Aug 2026 23:18:18 +1000 Subject: [PATCH 20/23] Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs` Back when hooks were first introduced, the `hooks/mod.rs` file structure would have matched `query/mod.rs`. But the list of queries has since been moved to `queries.rs`, making the hooks file seem awkward in comparison. Since the hooks module has no submodules, making it a top-level file seems simpler. --- compiler/rustc_middle/src/{hooks/mod.rs => hooks.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename compiler/rustc_middle/src/{hooks/mod.rs => hooks.rs} (100%) diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks.rs similarity index 100% rename from compiler/rustc_middle/src/hooks/mod.rs rename to compiler/rustc_middle/src/hooks.rs From d3b2959c63920fe2ab0572e4e242e51af5d97ac3 Mon Sep 17 00:00:00 2001 From: zep Date: Fri, 28 Aug 2026 21:32:58 +0530 Subject: [PATCH 21/23] Clarify None and Some comparisons in docs --- library/core/src/option.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 7e6e31931813c..40be9131931a4 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2457,6 +2457,7 @@ const impl PartialEq for Option { #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for Option { /// See [the documentation](https://doc.rust-lang.org/std/option/#comparison-operators) for details. + /// [`None`] always compares less than any [`Some`] #[inline] fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { From d20d512c3e37859e5bfc3a2177c6bcb7c9067d25 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 28 Aug 2026 19:38:03 +0200 Subject: [PATCH 22/23] std: optimize IO error formatting --- library/std/src/io/error.rs | 9 +++------ library/std/src/io/error/tests.rs | 4 ++-- library/std/src/sys/io/error/generic.rs | 6 ++++-- library/std/src/sys/io/error/hermit.rs | 7 ++++--- library/std/src/sys/io/error/motor.rs | 11 ++++++----- library/std/src/sys/io/error/sgx.rs | 11 ++++++----- library/std/src/sys/io/error/solid.rs | 6 +++--- library/std/src/sys/io/error/uefi.rs | 8 ++++---- library/std/src/sys/io/error/unix.rs | 10 +++++----- library/std/src/sys/io/error/windows.rs | 18 ++++++------------ library/std/src/sys/io/error/windows/tests.rs | 2 +- library/std/src/sys/io/error/xous.rs | 6 ++++-- library/std/src/sys/io/mod.rs | 2 +- library/std/src/sys/process/uefi.rs | 8 +++----- 14 files changed, 52 insertions(+), 56 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 6dbe37ca9fba8..f1208e090f040 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -7,7 +7,7 @@ mod tests; )] use crate::{ io::{Error, OsFunctions, RawOsError}, - sys::io::{decode_error_kind, errno, error_string, is_interrupted}, + sys::io::{decode_error_kind, errno, format_error, is_interrupted}, }; // Because std is linked in during testing, these incoherent implementations would @@ -74,11 +74,8 @@ impl Error { #[must_use] #[inline] pub fn from_raw_os_error(code: RawOsError) -> Error { - const FUNCTIONS: &'static OsFunctions = &OsFunctions { - format_os_error: |code, fmt| fmt.write_str(&error_string(code)), - decode_error_kind, - is_interrupted, - }; + const FUNCTIONS: &'static OsFunctions = + &OsFunctions { format_os_error: format_error, decode_error_kind, is_interrupted }; // SAFETY: `FUNCTIONS` is a constant and not created at runtime. unsafe { Error::from_raw_os_error_with_functions(code, FUNCTIONS) } diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index a3a2f5830ae91..7f75d7b4c980c 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -1,5 +1,5 @@ use crate::io::{Error, ErrorKind, const_error}; -use crate::sys::io::{decode_error_kind, error_string}; +use crate::sys::io::{decode_error_kind, format_error}; use crate::{assert_matches, error, fmt}; #[test] @@ -10,7 +10,7 @@ fn test_size() { #[test] fn test_debug_error() { let code = 6; - let msg = error_string(code); + let msg = fmt::from_fn(|f| format_error(code, f)).to_string(); let kind = decode_error_kind(code); let err = Error::new(ErrorKind::InvalidInput, Error::from_raw_os_error(code)); let expected = format!( diff --git a/library/std/src/sys/io/error/generic.rs b/library/std/src/sys/io/error/generic.rs index fc70fbaba7e8c..1ff0e9303041d 100644 --- a/library/std/src/sys/io/error/generic.rs +++ b/library/std/src/sys/io/error/generic.rs @@ -1,3 +1,5 @@ +use crate::fmt; + pub fn errno() -> i32 { 0 } @@ -10,6 +12,6 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("operation successful") } diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs index 5f42144bb7cfb..28735c4c8275c 100644 --- a/library/std/src/sys/io/error/hermit.rs +++ b/library/std/src/sys/io/error/hermit.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { unsafe { hermit_abi::get_errno() } @@ -30,6 +30,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { - hermit_abi::error_string(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let description = hermit_abi::error_string(errno); + f.write_str(description) } diff --git a/library/std/src/sys/io/error/motor.rs b/library/std/src/sys/io/error/motor.rs index 06417417e8554..3afbd3fa9b7f1 100644 --- a/library/std/src/sys/io/error/motor.rs +++ b/library/std/src/sys/io/error/motor.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { // Not used in Motor OS because it is ambiguous: Motor OS @@ -57,11 +57,12 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { - let error: moto_rt::Error = match errno { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = match errno { x if x < 0 => moto_rt::Error::Unknown, x if x > u16::MAX.into() => moto_rt::Error::Unknown, - x => (x as moto_rt::ErrorCode).into(), /* u16 */ + x => moto_rt::Error::from(x as moto_rt::ErrorCode), /* u16 */ }; - format!("{}", error) + + write!(f, "{error}") } diff --git a/library/std/src/sys/io/error/sgx.rs b/library/std/src/sys/io/error/sgx.rs index b7b4030422e12..2d0827aad39ab 100644 --- a/library/std/src/sys/io/error/sgx.rs +++ b/library/std/src/sys/io/error/sgx.rs @@ -1,6 +1,6 @@ use fortanix_sgx_abi::{Error, RESULT_SUCCESS}; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { RESULT_SUCCESS @@ -54,12 +54,13 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { if errno == RESULT_SUCCESS { - "operation successful".into() + f.write_str("operation successful") } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) { - format!("user-specified error {errno:08x}") + write!(f, "user-specified error {errno:08x}") } else { - format!("{}", decode_error_kind(errno)) + let kind = decode_error_kind(errno); + write!(f, "{kind}") } } diff --git a/library/std/src/sys/io/error/solid.rs b/library/std/src/sys/io/error/solid.rs index 8e9503272abbc..ced354cb4c6e2 100644 --- a/library/std/src/sys/io/error/solid.rs +++ b/library/std/src/sys/io/error/solid.rs @@ -1,5 +1,5 @@ -use crate::io; use crate::sys::pal::error; +use crate::{fmt, io}; pub fn errno() -> i32 { 0 @@ -14,6 +14,6 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { error::decode_error_kind(code) } -pub fn error_string(errno: i32) -> String { - if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") } +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(name) = error::error_name(errno) { f.write_str(name) } else { write!(f, "{errno}") } } diff --git a/library/std/src/sys/io/error/uefi.rs b/library/std/src/sys/io/error/uefi.rs index bedea240d523b..a8793f2799be9 100644 --- a/library/std/src/sys/io/error/uefi.rs +++ b/library/std/src/sys/io/error/uefi.rs @@ -1,6 +1,6 @@ use r_efi::efi::Status; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { 0 @@ -54,7 +54,7 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Keep the List in Alphabetical Order // The Messages are taken from UEFI Specification Appendix D - Status Codes #[rustfmt::skip] @@ -98,7 +98,7 @@ pub fn error_string(errno: io::RawOsError) -> String { Status::VOLUME_FULL => "There is no more space on the file system.", Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.", Status::WRITE_PROTECTED => "The device cannot be written to.", - _ => return format!("Status: {errno}"), + _ => return write!(f, "Status: {errno}"), }; - msg.to_owned() + f.write_str(msg) } diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index 12acde7311e4c..5f60abf9d9528 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -1,7 +1,7 @@ use crate::ffi::c_int; #[cfg(not(target_os = "teeos"))] use crate::ffi::{CStr, c_char}; -use crate::io; +use crate::{fmt, io}; unsafe extern "C" { #[cfg(not(any( @@ -195,7 +195,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { /// Gets a detailed string description for the given error number. #[cfg(any(target_family = "unix", target_os = "wasi"))] -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { const TMPBUF_SZ: usize = if cfg!(target_os = "wasi") { 1024 } else { 128 }; unsafe extern "C" { @@ -226,11 +226,11 @@ pub fn error_string(errno: i32) -> String { let p = p as *const _; // We can't always expect a UTF-8 environment. When we don't get that luxury, // it's better to give a low-quality error message than none at all. - String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into() + write!(f, "{}", CStr::from_ptr(p).display()) } } #[cfg(target_os = "teeos")] -pub fn error_string(_errno: i32) -> String { - "error string unimplemented".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("error string unimplemented") } diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index 0ca3aee389b3e..6056f1774c146 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs @@ -1,5 +1,5 @@ use crate::sys::pal::{api, c}; -use crate::{io, ptr}; +use crate::{fmt, io, ptr}; #[cfg(test)] mod tests; @@ -95,7 +95,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } /// Gets a detailed string description for the given error number. -pub fn error_string(mut errnum: i32) -> String { +pub fn format_error(mut errnum: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut buf = [0 as c::WCHAR; 2048]; unsafe { @@ -131,21 +131,15 @@ pub fn error_string(mut errnum: i32) -> String { if res == 0 { // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, let fm_err = errno(); - return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); + return write!(f, "OS Error {errnum} (FormatMessageW() returned error {fm_err})"); } match String::from_utf16(&buf[..res]) { - Ok(mut msg) => { + Ok(msg) => { // Trim trailing CRLF inserted by FormatMessageW - let len = msg.trim_ascii_end().len(); - msg.truncate(len); - msg + f.write_str(msg.trim_ascii_end()) } - Err(..) => format!( - "OS Error {} (FormatMessageW() returned \ - invalid UTF-16)", - errnum - ), + Err(..) => write!(f, "OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum), } } } diff --git a/library/std/src/sys/io/error/windows/tests.rs b/library/std/src/sys/io/error/windows/tests.rs index 7fc545ad00666..088472eceab71 100644 --- a/library/std/src/sys/io/error/windows/tests.rs +++ b/library/std/src/sys/io/error/windows/tests.rs @@ -1,7 +1,7 @@ use crate::io::Error; use crate::sys::pal::c; -// tests `error_string` above +// tests `format_error` #[test] fn ntstatus_error() { const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001; diff --git a/library/std/src/sys/io/error/xous.rs b/library/std/src/sys/io/error/xous.rs index 2e9ea8e4f0928..bdecf437d0126 100644 --- a/library/std/src/sys/io/error/xous.rs +++ b/library/std/src/sys/io/error/xous.rs @@ -1,3 +1,4 @@ +use crate::fmt; use crate::os::xous::ffi::Error as XousError; pub fn errno() -> i32 { @@ -12,6 +13,7 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(errno: i32) -> String { - Into::::into(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = XousError::from(errno); + write!(f, "{error}") } diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index 33182e4eb5539..b9c48e3fe6ba5 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -51,5 +51,5 @@ pub use error::errno_location; target_os = "wasi", ))] pub use error::set_errno; -pub use error::{decode_error_kind, errno, error_string, is_interrupted}; +pub use error::{decode_error_kind, errno, format_error, is_interrupted}; pub use is_terminal::is_terminal; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 0f5c7c9a58c40..8c233a0d2024e 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -8,7 +8,7 @@ use crate::num::{NonZero, NonZeroI32}; use crate::path::{Path, PathBuf}; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::io::error_string; +use crate::sys::io::format_error; use crate::sys::pal::helpers; use crate::sys::unsupported; use crate::{fmt, io}; @@ -264,8 +264,7 @@ impl ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } } @@ -280,8 +279,7 @@ pub struct ExitStatusError(r_efi::efi::Status); impl fmt::Debug for ExitStatusError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } } From aee52d782c7bd49237c3b2af967254f7ebf22f18 Mon Sep 17 00:00:00 2001 From: malezjaa Date: Fri, 28 Aug 2026 20:27:31 +0200 Subject: [PATCH 23/23] implement [u8]::split_ascii_whitespace --- library/core/src/internal_macros.rs | 4 +- library/core/src/slice/ascii.rs | 140 ++++++++++++++++++++++++++++ library/core/src/slice/mod.rs | 2 + library/core/src/str/mod.rs | 7 +- library/coretests/tests/lib.rs | 1 + library/coretests/tests/slice.rs | 27 ++++++ 6 files changed, 175 insertions(+), 6 deletions(-) diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 0d0ff23fe2946..360ad1099b335 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -72,13 +72,13 @@ macro_rules! forward_ref_op_assign { macro_rules! impl_fn_for_zst { ($( $( #[$attr: meta] )* - struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + $vis:vis struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty $body: block; )+) => { $( $( #[$attr] )* - struct $Name; + $vis struct $Name; impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { #[inline] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 2b6037b2ee53e..3f17d3591af1c 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -6,6 +6,12 @@ use crate::fmt::{self, Write}; #[cfg(not(all(target_arch = "loongarch64", target_feature = "lsx")))] use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +use crate::{ + iter::{Filter, FusedIterator}, + slice::Split, + str::{BytesIsNotEmpty, IsAsciiWhitespace}, +}; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. @@ -314,6 +320,140 @@ impl [u8] { pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() } + + /// Splits a byte slice by ASCII whitespace. + /// + /// The returned iterator yields byte slices that are subslices of the + /// original byte slice, separated by any amount of ASCII whitespace. + /// + /// This uses the same definition as [`u8::is_ascii_whitespace`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut iter = b"A few words".split_ascii_whitespace(); + /// + /// assert_eq!(Some(&b"A"[..]), iter.next()); + /// assert_eq!(Some(&b"few"[..]), iter.next()); + /// assert_eq!(Some(&b"words"[..]), iter.next()); + /// + /// assert_eq!(None, iter.next()); + /// ``` + /// + /// Various kinds of ASCII whitespace are considered + /// (see [`u8::is_ascii_whitespace`]): + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut iter = b" Mary had\ta little \n\t lamb".split_ascii_whitespace(); + /// + /// assert_eq!(Some(&b"Mary"[..]), iter.next()); + /// assert_eq!(Some(&b"had"[..]), iter.next()); + /// assert_eq!(Some(&b"a"[..]), iter.next()); + /// assert_eq!(Some(&b"little"[..]), iter.next()); + /// assert_eq!(Some(&b"lamb"[..]), iter.next()); + /// + /// assert_eq!(None, iter.next()); + /// ``` + /// + /// If the byte slice is empty or contains only ASCII whitespace, the iterator + /// yields no byte slices: + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// assert_eq!(b"".split_ascii_whitespace().next(), None); + /// assert_eq!(b" ".split_ascii_whitespace().next(), None); + /// ``` + #[must_use = "this returns the split byte slice as an iterator, without modifying the original"] + #[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] + #[inline] + pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { + let inner = self.split(IsAsciiWhitespace).filter(BytesIsNotEmpty); + SplitAsciiWhitespace { inner } + } +} + +/// An iterator over the non-ASCII-whitespace subslices of a byte slice, +/// separated by any amount of ASCII whitespace. +/// +/// This struct is created by the [`split_ascii_whitespace`] method on [`[u8]`][byteslice]. +/// See its documentation for more. +/// +/// [`split_ascii_whitespace`]: slice::split_ascii_whitespace +/// [byteslice]: prim@slice +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +#[derive(Clone, Debug)] +pub struct SplitAsciiWhitespace<'a> { + pub(crate) inner: Filter, BytesIsNotEmpty>, +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl<'a> Iterator for SplitAsciiWhitespace<'a> { + type Item = &'a [u8]; + + #[inline] + fn next(&mut self) -> Option<&'a [u8]> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + + #[inline] + fn last(mut self) -> Option<&'a [u8]> { + self.next_back() + } +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { + #[inline] + fn next_back(&mut self) -> Option<&'a [u8]> { + self.inner.next_back() + } +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl FusedIterator for SplitAsciiWhitespace<'_> {} + +impl<'a> SplitAsciiWhitespace<'a> { + /// Returns remainder of the split slice. + /// + /// If the iterator is empty, returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut split = b"Mary had a little lamb".split_ascii_whitespace(); + /// assert_eq!(split.remainder(), Some(b"Mary had a little lamb".as_slice())); + /// + /// split.next(); + /// assert_eq!(split.remainder(), Some(b"had a little lamb".as_slice())); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.remainder(), None); + /// ``` + #[inline] + #[must_use] + // This is also blocked on: https://github.com/rust-lang/rust/issues/77998 + #[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] + pub fn remainder(&self) -> Option<&'a [u8]> { + if self.inner.iter.finished { + return None; + } + + Some(self.inner.iter.v) + } } impl_fn_for_zst! { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f73f0c5390629..f787b7994ba9d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -45,6 +45,8 @@ mod specialize; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use ascii::EscapeAscii; +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +pub use ascii::SplitAsciiWhitespace; #[unstable(feature = "str_internals", issue = "none")] #[doc(hidden)] pub use ascii::is_ascii_simple; diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 79f4f29da2d43..f0dd0430230e2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -1263,8 +1263,7 @@ impl str { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { - let inner = - self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr); + let inner = self.as_bytes().split_ascii_whitespace().inner.map(UnsafeBytesToStr); SplitAsciiWhitespace { inner } } @@ -3351,7 +3350,7 @@ impl_fn_for_zst! { }; #[derive(Clone)] - struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool { + pub(crate) struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool { byte.is_ascii_whitespace() }; @@ -3361,7 +3360,7 @@ impl_fn_for_zst! { }; #[derive(Clone)] - struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool { + pub(crate) struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool { !s.is_empty() }; diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index c653fdcdf4927..b2e090e64d928 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -123,6 +123,7 @@ #![feature(try_from_int_error_kind)] #![feature(try_trait_v2)] #![feature(type_info)] +#![feature(u8_split_ascii_whitespace)] #![feature(uint_carryless_mul)] #![feature(uint_gather_scatter_bits)] #![feature(unicode_internals)] diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 9b0db0e733c57..e570bff645af7 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -2610,3 +2610,30 @@ fn test_shift_right() { case([1, 2, 3, 4], [5], [1], [2, 3, 4, 5]); case([1, 2, 3, 4, 5], [], [], [1, 2, 3, 4, 5]); } + +#[test] +fn test_split_ascii_whitespace_non_ascii() { + let bytes = b"\xff \x80 \xc2\xa0"; + + assert_eq!( + bytes.split_ascii_whitespace().collect::>(), + vec![&b"\xff"[..], &b"\x80"[..], &b"\xc2\xa0"[..]], + ); +} + +#[test] +fn test_split_ascii_whitespace_remainder() { + let bytes = b" Mary \t had "; + let mut split = bytes.split_ascii_whitespace(); + + assert_eq!(split.remainder(), Some(&bytes[..])); + + assert_eq!(split.next(), Some(&b"Mary"[..])); + assert_eq!(split.remainder(), Some(&b"\t had "[..])); + + assert_eq!(split.next(), Some(&b"had"[..])); + assert_eq!(split.remainder(), Some(&b" "[..])); + + assert_eq!(split.next(), None); + assert_eq!(split.remainder(), None); +}