From 811f708414d3e85bc3c5c3927b07d47b905840b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Feb 2026 10:34:10 +0000 Subject: [PATCH 01/19] Remove CodegenBackend supertrait of ExtraBackendMethods --- compiler/rustc_codegen_ssa/src/traits/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 7ebff77710fb0..4212e0f62db14 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -137,7 +137,7 @@ pub trait CodegenBackend { } pub trait ExtraBackendMethods: - CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync { fn codegen_allocator<'tcx>( &self, From e33e56225cbc96a08b56e6c06a8ed44f53e471bd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Feb 2026 10:36:50 +0000 Subject: [PATCH 02/19] Merge typeid_metadata into type_checked_load This allows removing the Metadata associated type from BackendTypes. --- compiler/rustc_codegen_gcc/src/builder.rs | 1 - compiler/rustc_codegen_gcc/src/context.rs | 1 - compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_codegen_llvm/src/builder.rs | 1 - compiler/rustc_codegen_llvm/src/common.rs | 3 +-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 5 +++-- compiler/rustc_codegen_llvm/src/type_.rs | 6 +----- compiler/rustc_codegen_ssa/src/meth.rs | 5 ++--- compiler/rustc_codegen_ssa/src/traits/backend.rs | 1 - compiler/rustc_codegen_ssa/src/traits/builder.rs | 1 - compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/type_.rs | 3 --- 12 files changed, 9 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index e1937f5c11eb5..d85366ce0d8e1 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -486,7 +486,6 @@ impl<'a, 'gcc, 'tcx> Deref for Builder<'a, 'gcc, 'tcx> { impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type Value = as BackendTypes>::Value; - type Metadata = as BackendTypes>::Metadata; type Function = as BackendTypes>::Function; type BasicBlock = as BackendTypes>::BasicBlock; type Type = as BackendTypes>::Type; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 03f207f457243..eab7aac58fc17 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -381,7 +381,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { type Value = RValue<'gcc>; - type Metadata = RValue<'gcc>; type Function = Function<'gcc>; type BasicBlock = Block<'gcc>; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 7e15a5eeaa5ef..fb1127ab4f48c 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -712,7 +712,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &mut self, _vtable: Self::Value, _vtable_byte_offset: u64, - _typeid: Self::Value, + _typeid: &[u8], ) -> Self::Value { // Unsupported. self.context.new_rvalue_from_int(self.int_type, 0) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4ffc836f5559c..55a061c327b20 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -197,7 +197,6 @@ pub(crate) const UNNAMED: *const c_char = c"".as_ptr(); impl<'ll, CX: Borrow>> BackendTypes for GenericBuilder<'_, 'll, CX> { type Value = as BackendTypes>::Value; - type Metadata = as BackendTypes>::Metadata; type Function = as BackendTypes>::Function; type BasicBlock = as BackendTypes>::BasicBlock; type Type = as BackendTypes>::Type; diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index f2261ab79340f..c65b2f3a013ec 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -20,7 +20,7 @@ use tracing::debug; use crate::consts::const_alloc_to_llvm; pub(crate) use crate::context::CodegenCx; use crate::context::{GenericCx, SCx}; -use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value}; +use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, TRUE, ToLlvmBool, Type, Value}; /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". @@ -83,7 +83,6 @@ impl<'ll> Funclet<'ll> { impl<'ll, CX: Borrow>> BackendTypes for GenericCx<'ll, CX> { type Value = &'ll Value; - type Metadata = &'ll Metadata; // FIXME(eddyb) replace this with a `Function` "subclass" of `Value`. type Function = &'ll Value; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 6bcc8135f35e8..40c3132e9984c 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -38,7 +38,7 @@ use crate::declare::declare_raw_fn; use crate::errors::{ AutoDiffWithoutEnable, AutoDiffWithoutLto, OffloadWithoutEnable, OffloadWithoutFatLTO, }; -use crate::llvm::{self, Metadata, Type, Value}; +use crate::llvm::{self, Type, Value}; use crate::type_of::LayoutLlvmExt; use crate::va_arg::emit_va_arg; @@ -799,8 +799,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { &mut self, llvtable: &'ll Value, vtable_byte_offset: u64, - typeid: &'ll Metadata, + typeid: &[u8], ) -> Self::Value { + let typeid = self.create_metadata(typeid); let typeid = self.get_metadata_value(typeid); let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32); let type_checked_load = self.call_intrinsic( diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index d8b77369a34ff..2026b06d104df 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -15,7 +15,7 @@ use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::common; use crate::context::{CodegenCx, GenericCx, SCx}; -use crate::llvm::{self, FALSE, Metadata, TRUE, ToGeneric, ToLlvmBool, Type, Value}; +use crate::llvm::{self, FALSE, TRUE, ToGeneric, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; impl PartialEq for Type { @@ -319,10 +319,6 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.global_set_metadata_node(function, llvm::MD_type, &v); } - fn typeid_metadata(&self, typeid: &[u8]) -> Option<&'ll Metadata> { - Some(self.create_metadata(typeid)) - } - fn add_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) { let kcfi_type_metadata = [llvm::LLVMValueAsMetadata(self.const_u32(kcfi_typeid))]; self.global_add_metadata_node(function, llvm::MD_kcfi_type, &kcfi_type_metadata); diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 2fa466b500179..e640f2e5711c0 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -139,9 +139,8 @@ pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( && bx.cx().sess().lto() == Lto::Fat { if let Some(trait_ref) = dyn_trait_in_self(bx.tcx(), ty) { - let typeid = - bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref).as_bytes()).unwrap(); - let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); + let typeid = typeid_for_trait_ref(bx.tcx(), trait_ref); + let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid.as_bytes()); return func; } else if nonnull { bug!("load nonnull value from a vtable without a principal trait") diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 4212e0f62db14..d3b0cb7a942cf 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -22,7 +22,6 @@ use crate::{CodegenResults, ModuleCodegen, TargetConfig}; pub trait BackendTypes { type Value: CodegenObject + PartialEq; - type Metadata: CodegenObject; type Function: CodegenObject; type BasicBlock: Copy; diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 3486bd140eceb..9b045aa4a1468 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -50,7 +50,6 @@ pub trait BuilderMethods<'a, 'tcx>: type CodegenCx: CodegenMethods< 'tcx, Value = Self::Value, - Metadata = Self::Metadata, Function = Self::Function, BasicBlock = Self::BasicBlock, Type = Self::Type, diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 04183c2801e7a..d1e6436f6b1eb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -41,7 +41,7 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { &mut self, llvtable: Self::Value, vtable_byte_offset: u64, - typeid: Self::Metadata, + typeid: &[u8], ) -> Self::Value; /// Trait method used to inject `va_start` on the "spoofed" `VaList` in /// Rust defined C-variadic functions. diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 32c24965e1bf6..3000f84e5e322 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -156,9 +156,6 @@ pub trait LayoutTypeCodegenMethods<'tcx>: BackendTypes { pub trait TypeMembershipCodegenMethods<'tcx>: BackendTypes { fn add_type_metadata(&self, _function: Self::Function, _typeid: &[u8]) {} fn set_type_metadata(&self, _function: Self::Function, _typeid: &[u8]) {} - fn typeid_metadata(&self, _typeid: &[u8]) -> Option { - None - } fn add_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {} fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {} } From e94aaf136d37216615d0ac12e0e29fc4d838bf84 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Feb 2026 10:39:03 +0000 Subject: [PATCH 03/19] Reorder associated types in BackendTypes to be a bit more logical --- compiler/rustc_codegen_gcc/src/builder.rs | 5 +++-- compiler/rustc_codegen_gcc/src/context.rs | 6 +++--- compiler/rustc_codegen_llvm/src/builder.rs | 5 +++-- compiler/rustc_codegen_llvm/src/common.rs | 6 +++--- compiler/rustc_codegen_ssa/src/traits/backend.rs | 6 +++--- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index d85366ce0d8e1..511d047a8031e 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -485,12 +485,13 @@ impl<'a, 'gcc, 'tcx> Deref for Builder<'a, 'gcc, 'tcx> { } impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { - type Value = as BackendTypes>::Value; type Function = as BackendTypes>::Function; type BasicBlock = as BackendTypes>::BasicBlock; - type Type = as BackendTypes>::Type; type Funclet = as BackendTypes>::Funclet; + type Value = as BackendTypes>::Value; + type Type = as BackendTypes>::Type; + type DIScope = as BackendTypes>::DIScope; type DILocation = as BackendTypes>::DILocation; type DIVariable = as BackendTypes>::DIVariable; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index eab7aac58fc17..e71963d9081b9 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -380,13 +380,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { - type Value = RValue<'gcc>; type Function = Function<'gcc>; - type BasicBlock = Block<'gcc>; - type Type = Type<'gcc>; type Funclet = (); // TODO(antoyo) + type Value = RValue<'gcc>; + type Type = Type<'gcc>; + type DIScope = (); // TODO(antoyo) type DILocation = Location<'gcc>; type DIVariable = (); // TODO(antoyo) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 55a061c327b20..250d3d35ca6a8 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -196,12 +196,13 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) const UNNAMED: *const c_char = c"".as_ptr(); impl<'ll, CX: Borrow>> BackendTypes for GenericBuilder<'_, 'll, CX> { - type Value = as BackendTypes>::Value; type Function = as BackendTypes>::Function; type BasicBlock = as BackendTypes>::BasicBlock; - type Type = as BackendTypes>::Type; type Funclet = as BackendTypes>::Funclet; + type Value = as BackendTypes>::Value; + type Type = as BackendTypes>::Type; + type DIScope = as BackendTypes>::DIScope; type DILocation = as BackendTypes>::DILocation; type DIVariable = as BackendTypes>::DIVariable; diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index c65b2f3a013ec..8db4e16b3e794 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -82,14 +82,14 @@ impl<'ll> Funclet<'ll> { } impl<'ll, CX: Borrow>> BackendTypes for GenericCx<'ll, CX> { - type Value = &'ll Value; // FIXME(eddyb) replace this with a `Function` "subclass" of `Value`. type Function = &'ll Value; - type BasicBlock = &'ll BasicBlock; - type Type = &'ll Type; type Funclet = Funclet<'ll>; + type Value = &'ll Value; + type Type = &'ll Type; + type DIScope = &'ll llvm::debuginfo::DIScope; type DILocation = &'ll llvm::debuginfo::DILocation; type DIVariable = &'ll llvm::debuginfo::DIVariable; diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index d3b0cb7a942cf..8ca620ff4fb46 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -21,13 +21,13 @@ use crate::back::write::TargetMachineFactoryFn; use crate::{CodegenResults, ModuleCodegen, TargetConfig}; pub trait BackendTypes { - type Value: CodegenObject + PartialEq; type Function: CodegenObject; - type BasicBlock: Copy; - type Type: CodegenObject + PartialEq; type Funclet; + type Value: CodegenObject + PartialEq; + type Type: CodegenObject + PartialEq; + // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.). type DIScope: Copy + Hash + PartialEq + Eq; From f03581a12b6cff3ed299bb7c977c86bea56f4122 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:27:44 +0000 Subject: [PATCH 04/19] Introduce FunctionSignature associated type for BackendTypes In Cranelift the regular Type enum can't represent function signatures. Function pointers are represented as plain pointer sized integer. --- compiler/rustc_codegen_gcc/src/builder.rs | 1 + compiler/rustc_codegen_gcc/src/context.rs | 1 + compiler/rustc_codegen_llvm/src/builder.rs | 1 + compiler/rustc_codegen_llvm/src/common.rs | 1 + compiler/rustc_codegen_ssa/src/traits/backend.rs | 1 + compiler/rustc_codegen_ssa/src/traits/builder.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/traits/misc.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/type_.rs | 4 ++-- 8 files changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 511d047a8031e..0dfa9c09ff996 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -491,6 +491,7 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type Value = as BackendTypes>::Value; type Type = as BackendTypes>::Type; + type FunctionSignature = as BackendTypes>::FunctionSignature; type DIScope = as BackendTypes>::DIScope; type DILocation = as BackendTypes>::DILocation; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index e71963d9081b9..ada3d73f612e4 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -386,6 +386,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { type Value = RValue<'gcc>; type Type = Type<'gcc>; + type FunctionSignature = Type<'gcc>; type DIScope = (); // TODO(antoyo) type DILocation = Location<'gcc>; diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 250d3d35ca6a8..8d65c0d4e0b03 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -202,6 +202,7 @@ impl<'ll, CX: Borrow>> BackendTypes for GenericBuilder<'_, 'll, CX> { type Value = as BackendTypes>::Value; type Type = as BackendTypes>::Type; + type FunctionSignature = as BackendTypes>::FunctionSignature; type DIScope = as BackendTypes>::DIScope; type DILocation = as BackendTypes>::DILocation; diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 8db4e16b3e794..b1f03f58d925f 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -89,6 +89,7 @@ impl<'ll, CX: Borrow>> BackendTypes for GenericCx<'ll, CX> { type Value = &'ll Value; type Type = &'ll Type; + type FunctionSignature = &'ll Type; type DIScope = &'ll llvm::debuginfo::DIScope; type DILocation = &'ll llvm::debuginfo::DILocation; diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 8ca620ff4fb46..60f2d4155d4bc 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -27,6 +27,7 @@ pub trait BackendTypes { type Value: CodegenObject + PartialEq; type Type: CodegenObject + PartialEq; + type FunctionSignature: CodegenObject + PartialEq; // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.). diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9b045aa4a1468..9d202effc28bb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -53,6 +53,7 @@ pub trait BuilderMethods<'a, 'tcx>: Function = Self::Function, BasicBlock = Self::BasicBlock, Type = Self::Type, + FunctionSignature = Self::FunctionSignature, Funclet = Self::Funclet, DIScope = Self::DIScope, DILocation = Self::DILocation, @@ -124,7 +125,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn invoke( &mut self, - llty: Self::Type, + llty: Self::FunctionSignature, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: Self::Value, @@ -621,7 +622,7 @@ pub trait BuilderMethods<'a, 'tcx>: /// assuming the function does not explicitly pass the destination as a pointer in `args`. fn call( &mut self, - llty: Self::Type, + llty: Self::FunctionSignature, caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, fn_val: Self::Value, @@ -632,7 +633,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn tail_call( &mut self, - llty: Self::Type, + llty: Self::FunctionSignature, caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 710fab2790166..6a0f889833492 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -25,5 +25,5 @@ pub trait MiscCodegenMethods<'tcx>: BackendTypes { fn apply_target_cpu_attr(&self, llfn: Self::Function); /// Declares the extern "C" main function for the entry point. Returns None if the symbol /// already exists. - fn declare_c_main(&self, fn_type: Self::Type) -> Option; + fn declare_c_main(&self, fn_type: Self::FunctionSignature) -> Option; } diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 3000f84e5e322..45ea8384b2d46 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -23,7 +23,7 @@ pub trait BaseTypeCodegenMethods: BackendTypes { fn type_f128(&self) -> Self::Type; fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; - fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; + fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::FunctionSignature; fn type_kind(&self, ty: Self::Type) -> TypeKind; fn type_ptr(&self) -> Self::Type; fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type; @@ -114,7 +114,7 @@ pub trait LayoutTypeCodegenMethods<'tcx>: BackendTypes { /// such as when it's stack-allocated or when it's being loaded or stored. fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type; fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type; - fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type; + fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::FunctionSignature; fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type; fn reg_backend_type(&self, ty: &Reg) -> Self::Type; /// The backend type used for a rust type when it's in an SSA register. From df4b228c71933a9d7113516e1e83ef0c98bd6d68 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:17:44 +0000 Subject: [PATCH 05/19] Merge const_data_from_alloc into static_addr_of In Cranelift a Value can't hold arbitrarily sized values. --- compiler/rustc_codegen_gcc/src/common.rs | 34 ++++++------------- compiler/rustc_codegen_gcc/src/consts.rs | 26 ++++++++++++-- compiler/rustc_codegen_llvm/src/common.rs | 6 +--- compiler/rustc_codegen_llvm/src/consts.rs | 8 +++-- compiler/rustc_codegen_ssa/src/meth.rs | 4 +-- compiler/rustc_codegen_ssa/src/mir/operand.rs | 5 +-- .../rustc_codegen_ssa/src/traits/consts.rs | 4 +-- .../rustc_codegen_ssa/src/traits/statics.rs | 4 +-- 8 files changed, 46 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 86a4eeac89d5f..79cae9e028260 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -5,9 +5,10 @@ use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods, }; use rustc_middle::mir::Mutability; -use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; +use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::layout::LayoutOf; +use crate::consts::const_alloc_to_gcc; use crate::context::{CodegenCx, new_array_type}; use crate::type_of::LayoutGccExt; @@ -260,11 +261,13 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { }; } - let init = self.const_data_from_alloc(alloc); - let alloc = alloc.inner(); - let value = match alloc.mutability { - Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), - _ => self.static_addr_of(init, alloc.align, None), + let value = match alloc.inner().mutability { + Mutability::Mut => self.static_addr_of_mut( + const_alloc_to_gcc(self, alloc), + alloc.inner().align, + None, + ), + _ => self.static_addr_of(alloc, None), }; if !self.sess().fewer_names() { // TODO(antoyo): set value name. @@ -282,8 +285,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { }), ))) .unwrap_memory(); - let init = self.const_data_from_alloc(alloc); - self.static_addr_of(init, alloc.inner().align, None) + self.static_addr_of(alloc, None) } GlobalAlloc::TypeId { .. } => { let val = self.const_usize(offset.bytes()); @@ -311,22 +313,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { } } - fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { - // We ignore the alignment for the purpose of deduping RValues - // The alignment is not handled / used in any way by `const_alloc_to_gcc`, - // so it is OK to overwrite it here. - let mut mock_alloc = alloc.inner().clone(); - mock_alloc.align = rustc_abi::Align::MAX; - // Check if the rvalue is already in the cache - if so, just return it directly. - if let Some(res) = self.const_cache.borrow().get(&mock_alloc) { - return *res; - } - // Rvalue not in the cache - convert and add it. - let res = crate::consts::const_alloc_to_gcc_uncached(self, alloc); - self.const_cache.borrow_mut().insert(mock_alloc, res); - res - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { self.context .new_array_access(None, base_addr, self.const_usize(offset.bytes())) diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 6fb96f8832b93..8afa57bc28fc9 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -22,6 +22,25 @@ use crate::base; use crate::context::CodegenCx; use crate::type_of::LayoutGccExt; +pub(crate) fn const_alloc_to_gcc<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + alloc: ConstAllocation<'_>, +) -> RValue<'gcc> { + // We ignore the alignment for the purpose of deduping RValues + // The alignment is not handled / used in any way by `const_alloc_to_gcc`, + // so it is OK to overwrite it here. + let mut mock_alloc = alloc.inner().clone(); + mock_alloc.align = rustc_abi::Align::MAX; + // Check if the rvalue is already in the cache - if so, just return it directly. + if let Some(res) = cx.const_cache.borrow().get(&mock_alloc) { + return *res; + } + // Rvalue not in the cache - convert and add it. + let res = crate::consts::const_alloc_to_gcc_uncached(cx, alloc); + cx.const_cache.borrow_mut().insert(mock_alloc, res); + res +} + fn set_global_alignment<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, gv: LValue<'gcc>, @@ -37,7 +56,10 @@ fn set_global_alignment<'gcc, 'tcx>( } impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { - fn static_addr_of(&self, cv: RValue<'gcc>, align: Align, kind: Option<&str>) -> RValue<'gcc> { + fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> RValue<'gcc> { + let cv = const_alloc_to_gcc(self, alloc); + let align = alloc.inner().align; + if let Some(variable) = self.const_globals.borrow().get(&cv) { if let Some(global_variable) = self.global_lvalues.borrow().get(variable) { let alignment = align.bits() as i32; @@ -361,7 +383,7 @@ fn codegen_static_initializer<'gcc, 'tcx>( def_id: DefId, ) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { let alloc = cx.tcx.eval_static_initializer(def_id)?; - Ok((cx.const_data_from_alloc(alloc), alloc)) + Ok((const_alloc_to_gcc(cx, alloc), alloc)) } fn check_and_apply_linkage<'gcc, 'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index b1f03f58d925f..a134e97cc8915 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -12,7 +12,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hashes::Hash128; use rustc_hir::def_id::DefId; use rustc_middle::bug; -use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; +use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::DllImport; use tracing::debug; @@ -359,10 +359,6 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { } } - fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { - const_alloc_to_llvm(self, alloc.inner(), /*static*/ false) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { unsafe { llvm::LLVMConstInBoundsGEP2( diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 2b04f81c267fd..1bdafbd3e4c6d 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -772,8 +772,12 @@ impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { /// /// The pointer will always be in the default address space. If global variables default to a /// different address space, an addrspacecast is inserted. - fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value { - let gv = self.static_addr_of_impl(cv, align, kind); + fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> &'ll Value { + // FIXME: should we cache `const_alloc_to_llvm` to avoid repeating this for the + // same `ConstAllocation`? + let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false); + + let gv = self.static_addr_of_impl(cv, alloc.inner().align, kind); // static_addr_of_impl returns the bare global variable, which might not be in the default // address space. Cast to the default address space if necessary. self.const_pointercast(gv, self.type_ptr()) diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index e640f2e5711c0..b87034f9b33b7 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -114,9 +114,7 @@ pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let vtable_alloc_id = tcx.vtable_allocation((ty, trait_ref)); let vtable_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory(); - let vtable_const = cx.const_data_from_alloc(vtable_allocation); - let align = cx.data_layout().pointer_align().abi; - let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); + let vtable = cx.static_addr_of(vtable_allocation, Some("vtable")); cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable); cx.create_vtable_debuginfo(ty, trait_ref, vtable); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 50ca676b5d05b..85fa890453d81 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -245,10 +245,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { _ if layout.is_zst() => OperandRef::zero_sized(layout), _ => { // Neither a scalar nor scalar pair. Load from a place - // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the - // same `ConstAllocation`? - let init = bx.const_data_from_alloc(alloc); - let base_addr = bx.static_addr_of(init, alloc_align, None); + let base_addr = bx.static_addr_of(alloc, None); let llval = bx.const_ptr_byte_offset(base_addr, offset); bx.load_operand(PlaceRef::new_sized(llval, layout)) diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index d83a04d814be3..4178a9742e268 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -1,5 +1,5 @@ use rustc_abi as abi; -use rustc_middle::mir::interpret::{ConstAllocation, Scalar}; +use rustc_middle::mir::interpret::Scalar; use super::BackendTypes; @@ -37,8 +37,6 @@ pub trait ConstCodegenMethods: BackendTypes { fn const_to_opt_uint(&self, v: Self::Value) -> Option; fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option; - fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value; - fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value; fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value; diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index 0e1e445c72f35..c726213025350 100644 --- a/compiler/rustc_codegen_ssa/src/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs @@ -1,10 +1,10 @@ -use rustc_abi::Align; use rustc_hir::def_id::DefId; +use rustc_middle::mir::interpret::ConstAllocation; use super::BackendTypes; pub trait StaticCodegenMethods: BackendTypes { - fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; + fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value; fn codegen_static(&mut self, def_id: DefId); } From 30fc9bd38463f6043d94b2efe8e09667fbb014dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 25 Feb 2026 14:58:55 +0100 Subject: [PATCH 06/19] elf-raw-dylib: set type for functions Avoids GNU ld warnings like: ``` type and size of dynamic symbol `meooooooooooooooow' are not defined ``` First noticed in https://github.com/rust-lang/rust/pull/152451#issuecomment-3880667900 with changes from https://github.com/rust-lang/rust/pull/149937. --- compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 45c217168a8d9..477c9478c3609 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] vers.push((version_name, dynstr)); id }; - syms.push((name, dynstr, Some(ver))); + syms.push((name, dynstr, Some(ver), symbol.is_fn)); } else { let dynstr = stub.add_dynamic_string(symbol_name.as_bytes()); - syms.push((symbol_name, dynstr, None)); + syms.push((symbol_name, dynstr, None, symbol.is_fn)); } } @@ -398,10 +398,11 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] // .dynsym stub.write_null_dynamic_symbol(); - for (_name, dynstr, _ver) in syms.iter().copied() { + for (_name, dynstr, _ver, is_fn) in syms.iter().copied() { + let sym_type = if is_fn { elf::STT_FUNC } else { elf::STT_NOTYPE }; stub.write_dynamic_symbol(&write::Sym { name: Some(dynstr), - st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE, + st_info: (elf::STB_GLOBAL << 4) | sym_type, st_other: elf::STV_DEFAULT, section: Some(text_section), st_shndx: 0, // ignored by object in favor of the `section` field @@ -417,7 +418,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] if !vers.is_empty() { // .gnu_version stub.write_null_gnu_versym(); - for (_name, _dynstr, ver) in syms.iter().copied() { + for (_name, _dynstr, ver, _is_fn) in syms.iter().copied() { stub.write_gnu_versym(if let Some(ver) = ver { assert!((2 + ver as u16) < elf::VERSYM_HIDDEN); elf::VERSYM_HIDDEN | (2 + ver as u16) From 7371a7f32dbfcaa4fbe5de57c5c4aee9b2125461 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 19 Feb 2026 19:35:43 -0800 Subject: [PATCH 07/19] tests/ui/asm: add annotations for reference rules --- tests/ui/asm/bad-template.aarch64.stderr | 52 +++---- tests/ui/asm/bad-template.rs | 2 + tests/ui/asm/bad-template.x86_64.stderr | 52 +++---- tests/ui/asm/cfg-parse-error.rs | 1 + tests/ui/asm/cfg-parse-error.stderr | 10 +- tests/ui/asm/cfg.rs | 1 + tests/ui/asm/invalid-const-operand.rs | 1 + tests/ui/asm/invalid-const-operand.stderr | 16 +- tests/ui/asm/invalid-sym-operand.rs | 1 + tests/ui/asm/invalid-sym-operand.stderr | 6 +- tests/ui/asm/naked-asm-outside-naked-fn.rs | 1 + .../ui/asm/naked-asm-outside-naked-fn.stderr | 6 +- tests/ui/asm/naked-functions-inline.rs | 1 + tests/ui/asm/naked-functions-inline.stderr | 8 +- tests/ui/asm/naked-functions-testattrs.rs | 1 + tests/ui/asm/naked-functions-testattrs.stderr | 8 +- tests/ui/asm/naked-functions.rs | 1 + tests/ui/asm/naked-functions.stderr | 50 +++---- tests/ui/asm/non-const.rs | 1 + tests/ui/asm/non-const.stderr | 4 +- tests/ui/asm/noreturn.rs | 1 + tests/ui/asm/parse-error.rs | 3 + tests/ui/asm/parse-error.stderr | 140 +++++++++--------- tests/ui/asm/simple_global_asm.rs | 1 + tests/ui/asm/tainting-on-error.rs | 1 + tests/ui/asm/tainting-on-error.stderr | 2 +- tests/ui/asm/unsupported-option.fixed | 1 + tests/ui/asm/unsupported-option.rs | 1 + tests/ui/asm/unsupported-option.stderr | 6 +- 29 files changed, 199 insertions(+), 180 deletions(-) diff --git a/tests/ui/asm/bad-template.aarch64.stderr b/tests/ui/asm/bad-template.aarch64.stderr index 30c793f3a4476..5f7ebb539107c 100644 --- a/tests/ui/asm/bad-template.aarch64.stderr +++ b/tests/ui/asm/bad-template.aarch64.stderr @@ -1,5 +1,5 @@ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:20:15 + --> $DIR/bad-template.rs:22:15 | LL | asm!("{}"); | ^^ from here @@ -7,7 +7,7 @@ LL | asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:22:15 + --> $DIR/bad-template.rs:24:15 | LL | asm!("{1}", in(reg) foo); | ^^^ from here @@ -15,7 +15,7 @@ LL | asm!("{1}", in(reg) foo); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:22:21 + --> $DIR/bad-template.rs:24:21 | LL | asm!("{1}", in(reg) foo); | ^^^^^^^^^^^ argument never used @@ -23,13 +23,13 @@ LL | asm!("{1}", in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:25:16 + --> $DIR/bad-template.rs:27:16 | LL | asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:27:15 + --> $DIR/bad-template.rs:29:15 | LL | asm!("{}", a = in(reg) foo); | ^^ --------------- named argument @@ -38,13 +38,13 @@ LL | asm!("{}", a = in(reg) foo); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:27:20 + --> $DIR/bad-template.rs:29:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:27:20 + --> $DIR/bad-template.rs:29:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -52,7 +52,7 @@ LL | asm!("{}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:30:15 + --> $DIR/bad-template.rs:32:15 | LL | asm!("{1}", a = in(reg) foo); | ^^^ from here @@ -60,7 +60,7 @@ LL | asm!("{1}", a = in(reg) foo); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:30:21 + --> $DIR/bad-template.rs:32:21 | LL | asm!("{1}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -68,7 +68,7 @@ LL | asm!("{1}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:37:15 + --> $DIR/bad-template.rs:39:15 | LL | asm!("{}", in("x0") foo); | ^^ ------------ explicit register argument @@ -77,24 +77,24 @@ LL | asm!("{}", in("x0") foo); | = note: no positional arguments were given note: explicit register arguments cannot be used in the asm template - --> $DIR/bad-template.rs:37:20 + --> $DIR/bad-template.rs:39:20 | LL | asm!("{}", in("x0") foo); | ^^^^^^^^^^^^ help: use the register name directly in the assembly code - --> $DIR/bad-template.rs:37:20 + --> $DIR/bad-template.rs:39:20 | LL | asm!("{}", in("x0") foo); | ^^^^^^^^^^^^ error: asm template modifier must be a single character - --> $DIR/bad-template.rs:39:17 + --> $DIR/bad-template.rs:41:17 | LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:42:18 + --> $DIR/bad-template.rs:44:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -104,7 +104,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:48:14 + --> $DIR/bad-template.rs:50:14 | LL | global_asm!("{}"); | ^^ from here @@ -112,7 +112,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:50:14 + --> $DIR/bad-template.rs:52:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:50:20 + --> $DIR/bad-template.rs:52:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:53:15 + --> $DIR/bad-template.rs:55:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:55:14 + --> $DIR/bad-template.rs:57:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:55:19 + --> $DIR/bad-template.rs:57:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:55:19 + --> $DIR/bad-template.rs:57:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:60:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:58:20 + --> $DIR/bad-template.rs:60:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:61:16 + --> $DIR/bad-template.rs:63:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:63:17 + --> $DIR/bad-template.rs:65:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` warning: formatting may not be suitable for sub-register argument - --> $DIR/bad-template.rs:39:15 + --> $DIR/bad-template.rs:41:15 | LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument diff --git a/tests/ui/asm/bad-template.rs b/tests/ui/asm/bad-template.rs index 966611949926d..51fae14f54d0f 100644 --- a/tests/ui/asm/bad-template.rs +++ b/tests/ui/asm/bad-template.rs @@ -1,5 +1,7 @@ //@ add-minicore //@ revisions: x86_64 aarch64 +//@ reference: asm.ts-args.at-least-once +//@ reference: asm.template-modifiers.only-one //@ [x86_64] compile-flags: --target x86_64-unknown-linux-gnu //@ [aarch64] compile-flags: --target aarch64-unknown-linux-gnu diff --git a/tests/ui/asm/bad-template.x86_64.stderr b/tests/ui/asm/bad-template.x86_64.stderr index 6b3f95677d07a..9947117621f1c 100644 --- a/tests/ui/asm/bad-template.x86_64.stderr +++ b/tests/ui/asm/bad-template.x86_64.stderr @@ -1,5 +1,5 @@ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:20:15 + --> $DIR/bad-template.rs:22:15 | LL | asm!("{}"); | ^^ from here @@ -7,7 +7,7 @@ LL | asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:22:15 + --> $DIR/bad-template.rs:24:15 | LL | asm!("{1}", in(reg) foo); | ^^^ from here @@ -15,7 +15,7 @@ LL | asm!("{1}", in(reg) foo); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:22:21 + --> $DIR/bad-template.rs:24:21 | LL | asm!("{1}", in(reg) foo); | ^^^^^^^^^^^ argument never used @@ -23,13 +23,13 @@ LL | asm!("{1}", in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:25:16 + --> $DIR/bad-template.rs:27:16 | LL | asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:27:15 + --> $DIR/bad-template.rs:29:15 | LL | asm!("{}", a = in(reg) foo); | ^^ --------------- named argument @@ -38,13 +38,13 @@ LL | asm!("{}", a = in(reg) foo); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:27:20 + --> $DIR/bad-template.rs:29:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:27:20 + --> $DIR/bad-template.rs:29:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -52,7 +52,7 @@ LL | asm!("{}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:30:15 + --> $DIR/bad-template.rs:32:15 | LL | asm!("{1}", a = in(reg) foo); | ^^^ from here @@ -60,7 +60,7 @@ LL | asm!("{1}", a = in(reg) foo); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:30:21 + --> $DIR/bad-template.rs:32:21 | LL | asm!("{1}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -68,7 +68,7 @@ LL | asm!("{1}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:34:15 + --> $DIR/bad-template.rs:36:15 | LL | asm!("{}", in("eax") foo); | ^^ ------------- explicit register argument @@ -77,24 +77,24 @@ LL | asm!("{}", in("eax") foo); | = note: no positional arguments were given note: explicit register arguments cannot be used in the asm template - --> $DIR/bad-template.rs:34:20 + --> $DIR/bad-template.rs:36:20 | LL | asm!("{}", in("eax") foo); | ^^^^^^^^^^^^^ help: use the register name directly in the assembly code - --> $DIR/bad-template.rs:34:20 + --> $DIR/bad-template.rs:36:20 | LL | asm!("{}", in("eax") foo); | ^^^^^^^^^^^^^ error: asm template modifier must be a single character - --> $DIR/bad-template.rs:39:17 + --> $DIR/bad-template.rs:41:17 | LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:42:18 + --> $DIR/bad-template.rs:44:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -104,7 +104,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:48:14 + --> $DIR/bad-template.rs:50:14 | LL | global_asm!("{}"); | ^^ from here @@ -112,7 +112,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:50:14 + --> $DIR/bad-template.rs:52:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:50:20 + --> $DIR/bad-template.rs:52:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:53:15 + --> $DIR/bad-template.rs:55:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:55:14 + --> $DIR/bad-template.rs:57:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:55:19 + --> $DIR/bad-template.rs:57:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:55:19 + --> $DIR/bad-template.rs:57:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:60:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:58:20 + --> $DIR/bad-template.rs:60:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:61:16 + --> $DIR/bad-template.rs:63:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:63:17 + --> $DIR/bad-template.rs:65:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` warning: formatting may not be suitable for sub-register argument - --> $DIR/bad-template.rs:39:15 + --> $DIR/bad-template.rs:41:15 | LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument diff --git a/tests/ui/asm/cfg-parse-error.rs b/tests/ui/asm/cfg-parse-error.rs index 0c6b63872a432..c13d003cbcebc 100644 --- a/tests/ui/asm/cfg-parse-error.rs +++ b/tests/ui/asm/cfg-parse-error.rs @@ -1,4 +1,5 @@ //@ needs-asm-support +//@ reference: asm.attributes.supported-attributes use std::arch::asm; diff --git a/tests/ui/asm/cfg-parse-error.stderr b/tests/ui/asm/cfg-parse-error.stderr index 726dee271108f..8a70d39a43dc6 100644 --- a/tests/ui/asm/cfg-parse-error.stderr +++ b/tests/ui/asm/cfg-parse-error.stderr @@ -1,5 +1,5 @@ error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/cfg-parse-error.rs:15:13 + --> $DIR/cfg-parse-error.rs:16:13 | LL | a = out(reg) x, | - expected one of 11 possible tokens @@ -7,7 +7,7 @@ LL | "", | ^^ unexpected token error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/cfg-parse-error.rs:25:13 + --> $DIR/cfg-parse-error.rs:26:13 | LL | }, | - expected one of 11 possible tokens @@ -15,19 +15,19 @@ LL | "", | ^^ unexpected token error: expected token: `,` - --> $DIR/cfg-parse-error.rs:40:26 + --> $DIR/cfg-parse-error.rs:41:26 | LL | a = out(reg) x, | ^ expected `,` error: this attribute is not supported on assembly - --> $DIR/cfg-parse-error.rs:46:13 + --> $DIR/cfg-parse-error.rs:47:13 | LL | #[rustfmt::skip] | ^^^^^^^^^^^^^^^^ error: an inner attribute is not permitted in this context - --> $DIR/cfg-parse-error.rs:52:13 + --> $DIR/cfg-parse-error.rs:53:13 | LL | #![rustfmt::skip] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/cfg.rs b/tests/ui/asm/cfg.rs index d7a2c78f58d26..74f5eb5481588 100644 --- a/tests/ui/asm/cfg.rs +++ b/tests/ui/asm/cfg.rs @@ -3,6 +3,7 @@ //@ revisions: reva revb //@ only-x86_64 //@ run-pass +//@ reference: asm.attributes.supported-attributes use std::arch::{asm, naked_asm}; diff --git a/tests/ui/asm/invalid-const-operand.rs b/tests/ui/asm/invalid-const-operand.rs index bbf4001752a4b..5c7b1a6b9654f 100644 --- a/tests/ui/asm/invalid-const-operand.rs +++ b/tests/ui/asm/invalid-const-operand.rs @@ -1,6 +1,7 @@ //@ needs-asm-support //@ ignore-nvptx64 //@ ignore-spirv +//@ reference: asm.operand-type.supported-operands.const use std::arch::{asm, global_asm}; diff --git a/tests/ui/asm/invalid-const-operand.stderr b/tests/ui/asm/invalid-const-operand.stderr index 01aa843c6fb19..3a3129ff3f6be 100644 --- a/tests/ui/asm/invalid-const-operand.stderr +++ b/tests/ui/asm/invalid-const-operand.stderr @@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:44:26 + --> $DIR/invalid-const-operand.rs:45:26 | LL | asm!("{}", const x); | ^ non-constant value @@ -11,7 +11,7 @@ LL + const x: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:47:36 + --> $DIR/invalid-const-operand.rs:48:36 | LL | asm!("{}", const const_foo(x)); | ^ non-constant value @@ -23,7 +23,7 @@ LL + const x: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:50:36 + --> $DIR/invalid-const-operand.rs:51:36 | LL | asm!("{}", const const_bar(x)); | ^ non-constant value @@ -35,7 +35,7 @@ LL + const x: /* Type */ = 0; | error: invalid type for `const` operand - --> $DIR/invalid-const-operand.rs:12:19 + --> $DIR/invalid-const-operand.rs:13:19 | LL | global_asm!("{}", const 0f32); | ^^^^^^---- @@ -45,7 +45,7 @@ LL | global_asm!("{}", const 0f32); = help: `const` operands must be of an integer type error: invalid type for `const` operand - --> $DIR/invalid-const-operand.rs:14:19 + --> $DIR/invalid-const-operand.rs:15:19 | LL | global_asm!("{}", const 0 as *mut u8); | ^^^^^^------------ @@ -55,7 +55,7 @@ LL | global_asm!("{}", const 0 as *mut u8); = help: `const` operands must be of an integer type error: invalid type for `const` operand - --> $DIR/invalid-const-operand.rs:24:20 + --> $DIR/invalid-const-operand.rs:25:20 | LL | asm!("{}", const 0f32); | ^^^^^^---- @@ -65,7 +65,7 @@ LL | asm!("{}", const 0f32); = help: `const` operands must be of an integer type error: invalid type for `const` operand - --> $DIR/invalid-const-operand.rs:26:20 + --> $DIR/invalid-const-operand.rs:27:20 | LL | asm!("{}", const 0 as *mut u8); | ^^^^^^------------ @@ -75,7 +75,7 @@ LL | asm!("{}", const 0 as *mut u8); = help: `const` operands must be of an integer type error: invalid type for `const` operand - --> $DIR/invalid-const-operand.rs:28:20 + --> $DIR/invalid-const-operand.rs:29:20 | LL | asm!("{}", const &0); | ^^^^^^-- diff --git a/tests/ui/asm/invalid-sym-operand.rs b/tests/ui/asm/invalid-sym-operand.rs index 2129c20b9681d..48df1918daf0f 100644 --- a/tests/ui/asm/invalid-sym-operand.rs +++ b/tests/ui/asm/invalid-sym-operand.rs @@ -1,6 +1,7 @@ //@ needs-asm-support //@ ignore-nvptx64 //@ ignore-spirv +//@ reference: asm.operand-type.supported-operands.sym use std::arch::{asm, global_asm}; diff --git a/tests/ui/asm/invalid-sym-operand.stderr b/tests/ui/asm/invalid-sym-operand.stderr index f0e6a17c25f6b..ef9ed04550580 100644 --- a/tests/ui/asm/invalid-sym-operand.stderr +++ b/tests/ui/asm/invalid-sym-operand.stderr @@ -1,5 +1,5 @@ error: invalid `sym` operand - --> $DIR/invalid-sym-operand.rs:27:24 + --> $DIR/invalid-sym-operand.rs:28:24 | LL | asm!("{}", sym x); | ^ is a local variable @@ -7,7 +7,7 @@ LL | asm!("{}", sym x); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/invalid-sym-operand.rs:13:19 + --> $DIR/invalid-sym-operand.rs:14:19 | LL | global_asm!("{}", sym C); | ^^^^^ is an `i32` @@ -15,7 +15,7 @@ LL | global_asm!("{}", sym C); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/invalid-sym-operand.rs:25:20 + --> $DIR/invalid-sym-operand.rs:26:20 | LL | asm!("{}", sym C); | ^^^^^ is an `i32` diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.rs b/tests/ui/asm/naked-asm-outside-naked-fn.rs index 0a15b21f4d014..1a82d0a595ef7 100644 --- a/tests/ui/asm/naked-asm-outside-naked-fn.rs +++ b/tests/ui/asm/naked-asm-outside-naked-fn.rs @@ -2,6 +2,7 @@ //@ needs-asm-support //@ ignore-nvptx64 //@ ignore-spirv +//@ reference: asm.scope.naked_asm #![crate_type = "lib"] diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.stderr b/tests/ui/asm/naked-asm-outside-naked-fn.stderr index 2cebaa9ea285d..85a50a49fecfc 100644 --- a/tests/ui/asm/naked-asm-outside-naked-fn.stderr +++ b/tests/ui/asm/naked-asm-outside-naked-fn.stderr @@ -1,17 +1,17 @@ error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` - --> $DIR/naked-asm-outside-naked-fn.rs:20:5 + --> $DIR/naked-asm-outside-naked-fn.rs:21:5 | LL | naked_asm!("") | ^^^^^^^^^^^^^^ error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` - --> $DIR/naked-asm-outside-naked-fn.rs:25:9 + --> $DIR/naked-asm-outside-naked-fn.rs:26:9 | LL | (|| naked_asm!(""))() | ^^^^^^^^^^^^^^ error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` - --> $DIR/naked-asm-outside-naked-fn.rs:31:9 + --> $DIR/naked-asm-outside-naked-fn.rs:32:9 | LL | naked_asm!(""); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs index b6fddc88e19b8..436c027fee873 100644 --- a/tests/ui/asm/naked-functions-inline.rs +++ b/tests/ui/asm/naked-functions-inline.rs @@ -1,4 +1,5 @@ //@ needs-asm-support +//@ reference: attributes.codegen.naked.inline #![crate_type = "lib"] use std::arch::naked_asm; diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr index 785ecf734b9d2..68648be72328e 100644 --- a/tests/ui/asm/naked-functions-inline.stderr +++ b/tests/ui/asm/naked-functions-inline.stderr @@ -1,5 +1,5 @@ error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:12:3 + --> $DIR/naked-functions-inline.rs:13:3 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here @@ -7,7 +7,7 @@ LL | #[inline] | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:19:3 + --> $DIR/naked-functions-inline.rs:20:3 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here @@ -15,7 +15,7 @@ LL | #[inline(always)] | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:26:3 + --> $DIR/naked-functions-inline.rs:27:3 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here @@ -23,7 +23,7 @@ LL | #[inline(never)] | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:33:18 + --> $DIR/naked-functions-inline.rs:34:18 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs index 6dc14a6840ecb..63acd11c02509 100644 --- a/tests/ui/asm/naked-functions-testattrs.rs +++ b/tests/ui/asm/naked-functions-testattrs.rs @@ -1,5 +1,6 @@ //@ needs-asm-support //@ compile-flags: --test +//@ reference: attributes.codegen.naked.testing #![feature(test)] #![crate_type = "lib"] diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr index 8aab2f04ee29e..ad2041ec118b9 100644 --- a/tests/ui/asm/naked-functions-testattrs.stderr +++ b/tests/ui/asm/naked-functions-testattrs.stderr @@ -1,5 +1,5 @@ error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:10:1 + --> $DIR/naked-functions-testattrs.rs:11:1 | LL | #[test] | ------- function marked with testing attribute here @@ -7,7 +7,7 @@ LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:18:1 + --> $DIR/naked-functions-testattrs.rs:19:1 | LL | #[test] | ------- function marked with testing attribute here @@ -15,7 +15,7 @@ LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:26:1 + --> $DIR/naked-functions-testattrs.rs:27:1 | LL | #[test] | ------- function marked with testing attribute here @@ -23,7 +23,7 @@ LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:33:1 + --> $DIR/naked-functions-testattrs.rs:34:1 | LL | #[bench] | -------- function marked with testing attribute here diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index a6f41698b4117..dadacb8d4683e 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -1,6 +1,7 @@ //@ needs-asm-support //@ ignore-nvptx64 //@ ignore-spirv +//@ reference: attributes.codegen.naked.body #![feature(asm_unwind, linkage, rustc_attrs)] #![crate_type = "lib"] diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr index b94a09bb92ed9..2b67c3aecd73c 100644 --- a/tests/ui/asm/naked-functions.stderr +++ b/tests/ui/asm/naked-functions.stderr @@ -1,107 +1,107 @@ error: the `in` operand cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:46:29 + --> $DIR/naked-functions.rs:47:29 | LL | naked_asm!("/* {0} */", in(reg) a) | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it error: the `in` operand cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:67:10 + --> $DIR/naked-functions.rs:68:10 | LL | in(reg) a, | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it error: the `noreturn` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:87:28 + --> $DIR/naked-functions.rs:88:28 | LL | naked_asm!("", options(noreturn)); | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly error: the `nomem` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:104:28 + --> $DIR/naked-functions.rs:105:28 | LL | naked_asm!("", options(nomem, preserves_flags)); | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly error: the `preserves_flags` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:104:35 + --> $DIR/naked-functions.rs:105:35 | LL | naked_asm!("", options(nomem, preserves_flags)); | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: the `readonly` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:111:28 + --> $DIR/naked-functions.rs:112:28 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly error: the `nostack` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:111:38 + --> $DIR/naked-functions.rs:112:38 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly error: the `pure` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:111:56 + --> $DIR/naked-functions.rs:112:56 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly error: the `may_unwind` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:119:28 + --> $DIR/naked-functions.rs:120:28 | LL | naked_asm!("", options(may_unwind)); | ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly error: this is a user specified error - --> $DIR/naked-functions.rs:150:5 + --> $DIR/naked-functions.rs:151:5 | LL | compile_error!("this is a user specified error") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:156:5 + --> $DIR/naked-functions.rs:157:5 | LL | compile_error!("this is a user specified error"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/naked-functions.rs:163:16 + --> $DIR/naked-functions.rs:164:16 | LL | naked_asm!(invalid_syntax) | ^^^^^^^^^^^^^^ error[E0787]: the `asm!` macro is not allowed in naked functions - --> $DIR/naked-functions.rs:12:14 + --> $DIR/naked-functions.rs:13:14 | LL | unsafe { asm!("", options(raw)) }; | ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:24:5 + --> $DIR/naked-functions.rs:25:5 | LL | mut a: u32, | ^^^^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:26:5 + --> $DIR/naked-functions.rs:27:5 | LL | &b: &i32, | ^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:28:6 + --> $DIR/naked-functions.rs:29:6 | LL | (None | Some(_)): Option>, | ^^^^^^^^^^^^^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:30:5 + --> $DIR/naked-functions.rs:31:5 | LL | P { x, y }: P, | ^^^^^^^^^^ error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:39:5 + --> $DIR/naked-functions.rs:40:5 | LL | a + 1 | ^ @@ -109,7 +109,7 @@ LL | a + 1 = help: follow the calling convention in asm block to use parameters error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:37:1 + --> $DIR/naked-functions.rs:38:1 | LL | pub extern "C" fn inc(a: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | a + 1 | ----- not allowed in naked functions error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:51:1 + --> $DIR/naked-functions.rs:52:1 | LL | pub extern "C" fn inc_closure(a: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | (|| a + 1)() | ------------ not allowed in naked functions error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:57:1 + --> $DIR/naked-functions.rs:58:1 | LL | pub extern "C" fn unsupported_operands() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,13 +144,13 @@ LL | let mut e = 0usize; | ------------------- not allowed in naked functions error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:79:1 + --> $DIR/naked-functions.rs:80:1 | LL | pub extern "C" fn missing_assembly() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:84:1 + --> $DIR/naked-functions.rs:85:1 | LL | pub extern "C" fn too_many_asm_blocks() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,7 +159,7 @@ LL | naked_asm!(""); | -------------- multiple `naked_asm!` invocations are not allowed in naked functions error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:96:11 + --> $DIR/naked-functions.rs:97:11 | LL | *&y | ^ @@ -167,7 +167,7 @@ LL | *&y = help: follow the calling convention in asm block to use parameters error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:94:5 + --> $DIR/naked-functions.rs:95:5 | LL | pub extern "C" fn inner(y: usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/non-const.rs b/tests/ui/asm/non-const.rs index dc9317b90b117..2ee4b9c1d70af 100644 --- a/tests/ui/asm/non-const.rs +++ b/tests/ui/asm/non-const.rs @@ -1,4 +1,5 @@ //@ needs-asm-support +//@ reference: asm.operand-type.supported-operands.const use std::arch::global_asm; diff --git a/tests/ui/asm/non-const.stderr b/tests/ui/asm/non-const.stderr index d7a901ba20ee5..e25960cc5a516 100644 --- a/tests/ui/asm/non-const.stderr +++ b/tests/ui/asm/non-const.stderr @@ -1,11 +1,11 @@ error[E0015]: cannot call non-const function `non_const_fn` in constants - --> $DIR/non-const.rs:10:31 + --> $DIR/non-const.rs:11:31 | LL | global_asm!("/* {} */", const non_const_fn(0)); | ^^^^^^^^^^^^^^^ | note: function `non_const_fn` is not const - --> $DIR/non-const.rs:8:1 + --> $DIR/non-const.rs:9:1 | LL | fn non_const_fn(x: i32) -> i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/noreturn.rs b/tests/ui/asm/noreturn.rs index c99715e9f8064..5351d4bc47332 100644 --- a/tests/ui/asm/noreturn.rs +++ b/tests/ui/asm/noreturn.rs @@ -1,5 +1,6 @@ //@ needs-asm-support //@ check-pass +//@ reference: asm.options.supported-options.noreturn #![feature(never_type)] #![crate_type = "rlib"] diff --git a/tests/ui/asm/parse-error.rs b/tests/ui/asm/parse-error.rs index d135ccae12804..f8e3b1622a8bc 100644 --- a/tests/ui/asm/parse-error.rs +++ b/tests/ui/asm/parse-error.rs @@ -1,4 +1,7 @@ //@ needs-asm-support +//@ reference: asm.syntax +//@ reference: asm.ts-args.syntax +//@ reference: asm.ts-args.one-or-more use std::arch::{asm, global_asm}; diff --git a/tests/ui/asm/parse-error.stderr b/tests/ui/asm/parse-error.stderr index fe6802b0c0c9e..9bb7b28b4424e 100644 --- a/tests/ui/asm/parse-error.stderr +++ b/tests/ui/asm/parse-error.stderr @@ -1,167 +1,167 @@ error: requires at least a template string argument - --> $DIR/parse-error.rs:9:9 + --> $DIR/parse-error.rs:12:9 | LL | asm!(); | ^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:11:14 + --> $DIR/parse-error.rs:14:14 | LL | asm!(foo); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:13:19 + --> $DIR/parse-error.rs:16:19 | LL | asm!("{}" foo); | ^^^ expected `,` error: expected operand, clobber_abi, options, or additional template string - --> $DIR/parse-error.rs:15:20 + --> $DIR/parse-error.rs:18:20 | LL | asm!("{}", foo); | ^^^ expected operand, clobber_abi, options, or additional template string error: expected `(`, found `foo` - --> $DIR/parse-error.rs:17:23 + --> $DIR/parse-error.rs:20:23 | LL | asm!("{}", in foo); | ^^^ expected `(` error: expected `)`, found `foo` - --> $DIR/parse-error.rs:19:27 + --> $DIR/parse-error.rs:22:27 | LL | asm!("{}", in(reg foo)); | ^^^ expected `)` error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:21:27 + --> $DIR/parse-error.rs:24:27 | LL | asm!("{}", in(reg)); | ^ expected expression error: expected register class or explicit register - --> $DIR/parse-error.rs:23:26 + --> $DIR/parse-error.rs:26:26 | LL | asm!("{}", inout(=) foo => bar); | ^ error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:25:37 + --> $DIR/parse-error.rs:28:37 | LL | asm!("{}", inout(reg) foo =>); | ^ expected expression error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` - --> $DIR/parse-error.rs:27:32 + --> $DIR/parse-error.rs:30:32 | LL | asm!("{}", in(reg) foo => bar); | ^^ expected one of 7 possible tokens error: expected a path for argument to `sym` - --> $DIR/parse-error.rs:29:24 + --> $DIR/parse-error.rs:32:24 | LL | asm!("{}", sym foo + bar); | ^^^^^^^^^ error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` - --> $DIR/parse-error.rs:31:26 + --> $DIR/parse-error.rs:34:26 | LL | asm!("", options(foo)); | ^^^ expected one of 10 possible tokens error: expected one of `)` or `,`, found `foo` - --> $DIR/parse-error.rs:33:32 + --> $DIR/parse-error.rs:36:32 | LL | asm!("", options(nomem foo)); | ^^^ expected one of `)` or `,` error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` - --> $DIR/parse-error.rs:35:33 + --> $DIR/parse-error.rs:38:33 | LL | asm!("", options(nomem, foo)); | ^^^ expected one of 10 possible tokens error: at least one abi must be provided as an argument to `clobber_abi` - --> $DIR/parse-error.rs:42:30 + --> $DIR/parse-error.rs:45:30 | LL | asm!("", clobber_abi()); | ^ error: expected string literal - --> $DIR/parse-error.rs:44:30 + --> $DIR/parse-error.rs:47:30 | LL | asm!("", clobber_abi(foo)); | ^^^ not a string literal error: expected one of `)` or `,`, found `foo` - --> $DIR/parse-error.rs:46:34 + --> $DIR/parse-error.rs:49:34 | LL | asm!("", clobber_abi("C" foo)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:48:35 + --> $DIR/parse-error.rs:51:35 | LL | asm!("", clobber_abi("C", foo)); | ^^^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:50:30 + --> $DIR/parse-error.rs:53:30 | LL | asm!("", clobber_abi(1)); | ^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:52:30 + --> $DIR/parse-error.rs:55:30 | LL | asm!("", clobber_abi(())); | ^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:54:30 + --> $DIR/parse-error.rs:57:30 | LL | asm!("", clobber_abi(uwu)); | ^^^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:56:30 + --> $DIR/parse-error.rs:59:30 | LL | asm!("", clobber_abi({})); | ^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:58:30 + --> $DIR/parse-error.rs:61:30 | LL | asm!("", clobber_abi(loop {})); | ^^^^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:60:30 + --> $DIR/parse-error.rs:63:30 | LL | asm!("", clobber_abi(if)); | ^^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:62:30 + --> $DIR/parse-error.rs:65:30 | LL | asm!("", clobber_abi(do)); | ^^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:64:30 + --> $DIR/parse-error.rs:67:30 | LL | asm!("", clobber_abi(<)); | ^ not a string literal error: expected string literal - --> $DIR/parse-error.rs:66:30 + --> $DIR/parse-error.rs:69:30 | LL | asm!("", clobber_abi(.)); | ^ not a string literal error: duplicate argument named `a` - --> $DIR/parse-error.rs:74:36 + --> $DIR/parse-error.rs:77:36 | LL | asm!("{a}", a = const foo, a = const bar); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -169,7 +169,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | previously here error: argument never used - --> $DIR/parse-error.rs:74:36 + --> $DIR/parse-error.rs:77:36 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^^^^^^^^^^^ argument never used @@ -177,151 +177,151 @@ LL | asm!("{a}", a = const foo, a = const bar); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/parse-error.rs:80:29 + --> $DIR/parse-error.rs:83:29 | LL | asm!("", options(), ""); | ^^ expected one of 11 possible tokens error: expected one of `#`, `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:82:33 + --> $DIR/parse-error.rs:85:33 | LL | asm!("{}", in(reg) foo, "{}", out(reg) foo); | ^^^^ expected one of 11 possible tokens error: asm template must be a string literal - --> $DIR/parse-error.rs:84:14 + --> $DIR/parse-error.rs:87:14 | LL | asm!(format!("{{{}}}", 0), in(reg) foo); | ^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:86:21 + --> $DIR/parse-error.rs:89:21 | LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | ^^^^^^^^^^^^^^^^^^^^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:88:28 + --> $DIR/parse-error.rs:91:28 | LL | asm!("{}", in(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:90:31 + --> $DIR/parse-error.rs:93:31 | LL | asm!("{}", inout(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:92:35 + --> $DIR/parse-error.rs:95:35 | LL | asm!("{}", inlateout(reg) _); | ^ error: requires at least a template string argument - --> $DIR/parse-error.rs:99:1 + --> $DIR/parse-error.rs:102:1 | LL | global_asm!(); | ^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:101:13 + --> $DIR/parse-error.rs:104:13 | LL | global_asm!(FOO); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:103:18 + --> $DIR/parse-error.rs:106:18 | LL | global_asm!("{}" FOO); | ^^^ expected `,` error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:105:19 + --> $DIR/parse-error.rs:108:19 | LL | global_asm!("{}", FOO); | ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:107:24 + --> $DIR/parse-error.rs:110:24 | LL | global_asm!("{}", const); | ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` - --> $DIR/parse-error.rs:109:30 + --> $DIR/parse-error.rs:112:30 | LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:111:25 + --> $DIR/parse-error.rs:114:25 | LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:113:25 + --> $DIR/parse-error.rs:116:25 | LL | global_asm!("", options(FOO,)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)` or `,`, found `FOO` - --> $DIR/parse-error.rs:115:31 + --> $DIR/parse-error.rs:118:31 | LL | global_asm!("", options(nomem FOO)); | ^^^ expected one of `)` or `,` error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:117:32 + --> $DIR/parse-error.rs:120:32 | LL | global_asm!("", options(nomem, FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected string literal - --> $DIR/parse-error.rs:120:29 + --> $DIR/parse-error.rs:123:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected one of `)` or `,`, found `FOO` - --> $DIR/parse-error.rs:122:33 + --> $DIR/parse-error.rs:125:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:124:34 + --> $DIR/parse-error.rs:127:34 | LL | global_asm!("", clobber_abi("C", FOO)); | ^^^ not a string literal error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:126:19 + --> $DIR/parse-error.rs:129:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:128:28 + --> $DIR/parse-error.rs:131:28 | LL | global_asm!("", options(), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:130:30 + --> $DIR/parse-error.rs:133:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:132:17 + --> $DIR/parse-error.rs:135:17 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` - --> $DIR/parse-error.rs:134:35 + --> $DIR/parse-error.rs:137:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -329,7 +329,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:134:35 + --> $DIR/parse-error.rs:137:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -337,67 +337,67 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `#`, `clobber_abi`, `const`, `options`, or `sym`, found `""` - --> $DIR/parse-error.rs:137:28 + --> $DIR/parse-error.rs:140:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `#`, `clobber_abi`, `const`, `options`, or `sym` error: expected one of `#`, `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:139:30 + --> $DIR/parse-error.rs:142:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `#`, `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal - --> $DIR/parse-error.rs:141:13 + --> $DIR/parse-error.rs:144:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:143:20 + --> $DIR/parse-error.rs:146:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ error: the `in` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:146:19 + --> $DIR/parse-error.rs:149:19 | LL | global_asm!("{}", in(reg)); | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it error: the `out` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:148:19 + --> $DIR/parse-error.rs:151:19 | LL | global_asm!("{}", out(reg)); | ^^^ the `out` operand is not meaningful for global-scoped inline assembly, remove it error: the `lateout` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:150:19 + --> $DIR/parse-error.rs:153:19 | LL | global_asm!("{}", lateout(reg)); | ^^^^^^^ the `lateout` operand is not meaningful for global-scoped inline assembly, remove it error: the `inout` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:152:19 + --> $DIR/parse-error.rs:155:19 | LL | global_asm!("{}", inout(reg)); | ^^^^^ the `inout` operand is not meaningful for global-scoped inline assembly, remove it error: the `inlateout` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:154:19 + --> $DIR/parse-error.rs:157:19 | LL | global_asm!("{}", inlateout(reg)); | ^^^^^^^^^ the `inlateout` operand is not meaningful for global-scoped inline assembly, remove it error: the `label` operand cannot be used with `global_asm!` - --> $DIR/parse-error.rs:156:19 + --> $DIR/parse-error.rs:159:19 | LL | global_asm!("{}", label(reg)); | ^^^^^ the `label` operand is not meaningful for global-scoped inline assembly, remove it error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:37:37 + --> $DIR/parse-error.rs:40:37 | LL | asm!("{}", options(), const foo); | ^^^ non-constant value @@ -409,7 +409,7 @@ LL + const foo: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:69:44 + --> $DIR/parse-error.rs:72:44 | LL | asm!("{}", clobber_abi("C"), const foo); | ^^^ non-constant value @@ -421,7 +421,7 @@ LL + const foo: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:72:55 + --> $DIR/parse-error.rs:75:55 | LL | asm!("{}", options(), clobber_abi("C"), const foo); | ^^^ non-constant value @@ -433,7 +433,7 @@ LL + const foo: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:74:31 + --> $DIR/parse-error.rs:77:31 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value @@ -445,7 +445,7 @@ LL + const foo: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:74:46 + --> $DIR/parse-error.rs:77:46 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value diff --git a/tests/ui/asm/simple_global_asm.rs b/tests/ui/asm/simple_global_asm.rs index 68b0b83858e18..d92c2eee1026a 100644 --- a/tests/ui/asm/simple_global_asm.rs +++ b/tests/ui/asm/simple_global_asm.rs @@ -1,5 +1,6 @@ //@ run-pass //@ needs-asm-support +//@ reference: asm.scope.global_asm #![allow(dead_code)] diff --git a/tests/ui/asm/tainting-on-error.rs b/tests/ui/asm/tainting-on-error.rs index a8e9af911580d..aa9f33de3753c 100644 --- a/tests/ui/asm/tainting-on-error.rs +++ b/tests/ui/asm/tainting-on-error.rs @@ -1,4 +1,5 @@ //@ needs-asm-support +//@ reference: asm.operand-type.supported-operands.sym use std::arch::asm; diff --git a/tests/ui/asm/tainting-on-error.stderr b/tests/ui/asm/tainting-on-error.stderr index bd706d1f310bf..a44f8fad9cbb4 100644 --- a/tests/ui/asm/tainting-on-error.stderr +++ b/tests/ui/asm/tainting-on-error.stderr @@ -1,5 +1,5 @@ error: invalid `sym` operand - --> $DIR/tainting-on-error.rs:9:13 + --> $DIR/tainting-on-error.rs:10:13 | LL | sym None::<()>, | ^^^^^^^^^^^^^^ is an `Option<()>` diff --git a/tests/ui/asm/unsupported-option.fixed b/tests/ui/asm/unsupported-option.fixed index d313d8028b6c2..a7c763c736073 100644 --- a/tests/ui/asm/unsupported-option.fixed +++ b/tests/ui/asm/unsupported-option.fixed @@ -1,5 +1,6 @@ //@ needs-asm-support //@ run-rustfix +//@ reference: asm.options.global_asm-restriction use std::arch::global_asm; diff --git a/tests/ui/asm/unsupported-option.rs b/tests/ui/asm/unsupported-option.rs index d75f8e7f5693e..4dccab5fcfac9 100644 --- a/tests/ui/asm/unsupported-option.rs +++ b/tests/ui/asm/unsupported-option.rs @@ -1,5 +1,6 @@ //@ needs-asm-support //@ run-rustfix +//@ reference: asm.options.global_asm-restriction use std::arch::global_asm; diff --git a/tests/ui/asm/unsupported-option.stderr b/tests/ui/asm/unsupported-option.stderr index 7a6927152b667..bb69a17a0097d 100644 --- a/tests/ui/asm/unsupported-option.stderr +++ b/tests/ui/asm/unsupported-option.stderr @@ -1,17 +1,17 @@ error: the `nomem` option cannot be used with `global_asm!` - --> $DIR/unsupported-option.rs:8:25 + --> $DIR/unsupported-option.rs:9:25 | LL | global_asm!("", options(nomem, readonly, noreturn, raw)); | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly error: the `readonly` option cannot be used with `global_asm!` - --> $DIR/unsupported-option.rs:8:32 + --> $DIR/unsupported-option.rs:9:32 | LL | global_asm!("", options(nomem, readonly, noreturn, raw)); | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly error: the `noreturn` option cannot be used with `global_asm!` - --> $DIR/unsupported-option.rs:8:42 + --> $DIR/unsupported-option.rs:9:42 | LL | global_asm!("", options(nomem, readonly, noreturn, raw)); | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly From 6358dcc2957f58be4ecdd0c1c0f2c0a1d20b7697 Mon Sep 17 00:00:00 2001 From: yuyahy Date: Sun, 1 Mar 2026 03:56:49 +0900 Subject: [PATCH 08/19] test: add regression test for fuzzy_provenance_casts lint ICE --- ...-fuzzy-provenance-casts-with-inner-attr.rs | 24 +++++ ...zy-provenance-casts-with-inner-attr.stderr | 93 +++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.rs create mode 100644 tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.stderr diff --git a/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.rs b/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.rs new file mode 100644 index 0000000000000..b8deb6ab3c64a --- /dev/null +++ b/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.rs @@ -0,0 +1,24 @@ +// Regression test for #137588. +// The compiler used to ICE when emitting a `fuzzy_provenance_casts` lint +// diagnostic for code with an inner attribute spanning the entire file, +// causing `draw_code_line` to panic on an empty `file_lines` from a dummy span. + +//@ edition:2024 +//@ compile-flags: -Wfuzzy-provenance-casts + +#![feature(strict_provenance_lints)] +//~^ ERROR too many leading `super` keywords [E0433] +//~| ERROR cannot find type `Ts` in this scope [E0425] +//~| ERROR `#[prelude_import]` is for use by rustc only [E0658] +//~| WARN strict provenance disallows casting integer `usize` to pointer `*const u32` +#![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] +//~^ ERROR use of unstable library feature `contracts` [E0658] +//~| ERROR inner macro attributes are unstable [E0658] +//~| ERROR cannot find type `Stars` in this scope [E0433] + +pub(super) fn foo() -> *const Ts { + unsafe { + let p2 = 0x52 as *const u32; + } +} +//~^ ERROR `main` function not found in crate diff --git a/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.stderr b/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.stderr new file mode 100644 index 0000000000000..342f39d2450d8 --- /dev/null +++ b/tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.stderr @@ -0,0 +1,93 @@ +error[E0658]: use of unstable library feature `contracts` + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:4 + | +LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #128044 for more information + = help: add `#![feature(contracts)]` 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]: inner macro attributes are unstable + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:4 + | +LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54726 for more information + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0433]: too many leading `super` keywords + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 + | +LL | / #![feature(strict_provenance_lints)] +... | +LL | | } + | |_^ there are too many leading `super` keywords + +error[E0425]: cannot find type `Ts` in this scope + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 + | +LL | / #![feature(strict_provenance_lints)] +... | +LL | | } + | |_^ not found in this scope + +error[E0658]: `#[prelude_import]` is for use by rustc only + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 + | +LL | / #![feature(strict_provenance_lints)] +... | +LL | | } + | |_^ + | + = help: add `#![feature(prelude_import)]` 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[E0601]: `main` function not found in crate `ice_fuzzy_provenance_casts_with_inner_attr` + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:23:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs` + +error[E0433]: cannot find type `Stars` in this scope + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:50 + | +LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] + | ^^^^^ use of undeclared type `Stars` + +warning: strict provenance disallows casting integer `usize` to pointer `*const u32` + --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 + | +LL | / #![feature(strict_provenance_lints)] +... | +LL | | } + | |_^ + | + = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead + = note: requested on the command line with `-W fuzzy-provenance-casts` +help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address + | +LL - #![feature(strict_provenance_lints)] +LL - +LL - +LL - +LL - +LL - #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] +LL - +LL - +LL - +LL - +LL - pub(super) fn foo() -> *const Ts { +LL - unsafe { +LL - let p2 = 0x52 as *const u32; +LL - } +LL - } +LL + (...).with_addr() + | + +error: aborting due to 7 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0425, E0433, E0601, E0658. +For more information about an error, try `rustc --explain E0425`. From bc4ceaddcd7b6673edbb0535c70f435bce9d0c67 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 7 Feb 2026 09:36:31 -0700 Subject: [PATCH 09/19] stabilize new RangeToInclusive type stabilizes `core::range::RangeToInclusive` add missing trait impls for new RangeToInclusive add missing trait impls for new RangeFrom --- library/core/src/bstr/traits.rs | 1 + library/core/src/ffi/c_str.rs | 12 ++++- library/core/src/range.rs | 55 ++++++++++++++++++----- library/core/src/slice/index.rs | 4 +- library/core/src/str/traits.rs | 46 +++++++++++++++++++ tests/ui/range/new_range_stability.rs | 11 ++++- tests/ui/range/new_range_stability.stderr | 10 ++--- 7 files changed, 120 insertions(+), 19 deletions(-) diff --git a/library/core/src/bstr/traits.rs b/library/core/src/bstr/traits.rs index 7da6c5f13cce1..bcfffd52d7419 100644 --- a/library/core/src/bstr/traits.rs +++ b/library/core/src/bstr/traits.rs @@ -268,4 +268,5 @@ impl_slice_index!(range::RangeFrom); impl_slice_index!(ops::RangeInclusive); impl_slice_index!(range::RangeInclusive); impl_slice_index!(ops::RangeToInclusive); +impl_slice_index!(range::RangeToInclusive); impl_slice_index!((ops::Bound, ops::Bound)); diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 621277179bb38..5fc97d9a69efd 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -8,7 +8,7 @@ use crate::iter::FusedIterator; use crate::marker::PhantomData; use crate::ptr::NonNull; use crate::slice::memchr; -use crate::{fmt, ops, slice, str}; +use crate::{fmt, ops, range, slice, str}; // FIXME: because this is doc(inline)d, we *have* to use intra-doc links because the actual link // depends on where the item is being documented. however, since this is libcore, we can't @@ -716,6 +716,16 @@ impl ops::Index> for CStr { } } +#[unstable(feature = "new_range_api", issue = "125687")] +impl ops::Index> for CStr { + type Output = CStr; + + #[inline] + fn index(&self, index: range::RangeFrom) -> &CStr { + ops::Index::index(self, ops::RangeFrom::from(index)) + } +} + #[stable(feature = "cstring_asref", since = "1.7.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] impl const AsRef for CStr { diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 0ef0d192a8682..16e6bb6df7da7 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -43,7 +43,7 @@ pub use iter::{RangeFromIter, RangeIter}; // pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo}; use crate::iter::Step; use crate::ops::Bound::{self, Excluded, Included, Unbounded}; -use crate::ops::{IntoBounds, RangeBounds}; +use crate::ops::{IntoBounds, OneSidedRange, OneSidedRangeBound, RangeBounds}; /// A (half-open) range bounded inclusively below and exclusively above /// (`start..end` in a future edition). @@ -546,6 +546,18 @@ impl const IntoBounds for RangeFrom { } } +#[unstable(feature = "one_sided_range", issue = "69780")] +// #[unstable(feature = "new_range_api", issue = "125687")] +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const OneSidedRange for RangeFrom +where + Self: RangeBounds, +{ + fn bound(self) -> (OneSidedRangeBound, T) { + (OneSidedRangeBound::StartInclusive, self.start) + } +} + #[unstable(feature = "new_range_api", issue = "125687")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] impl const From> for legacy::RangeFrom { @@ -573,9 +585,8 @@ impl const From> for RangeFrom { /// The `..=last` syntax is a `RangeToInclusive`: /// /// ``` -/// #![feature(new_range_api)] /// #![feature(new_range)] -/// assert_eq!((..=5), std::range::RangeToInclusive{ last: 5 }); +/// assert_eq!((..=5), std::range::RangeToInclusive { last: 5 }); /// ``` /// /// It does not have an [`IntoIterator`] implementation, so you can't use it in a @@ -606,14 +617,14 @@ impl const From> for RangeFrom { #[lang = "RangeToInclusiveCopy"] #[doc(alias = "..=")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] pub last: Idx, } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for RangeToInclusive { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "..=")?; @@ -637,7 +648,7 @@ impl> RangeToInclusive { /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn contains(&self, item: &U) -> bool where @@ -648,13 +659,13 @@ impl> RangeToInclusive { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl From> for RangeToInclusive { fn from(value: legacy::RangeToInclusive) -> Self { Self { last: value.end } } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl From> for legacy::RangeToInclusive { fn from(value: RangeToInclusive) -> Self { Self { end: value.last } @@ -664,7 +675,7 @@ impl From> for legacy::RangeToInclusive { // RangeToInclusive cannot impl From> // because underflow would be possible with (..0).into() -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const RangeBounds for RangeToInclusive { fn start_bound(&self) -> Bound<&T> { @@ -675,6 +686,18 @@ impl const RangeBounds for RangeToInclusive { } } +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const RangeBounds for RangeToInclusive<&T> { + fn start_bound(&self) -> Bound<&T> { + Unbounded + } + fn end_bound(&self) -> Bound<&T> { + Included(self.last) + } +} + +// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const IntoBounds for RangeToInclusive { @@ -682,3 +705,15 @@ impl const IntoBounds for RangeToInclusive { (Unbounded, Included(self.last)) } } + +// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] +#[unstable(feature = "one_sided_range", issue = "69780")] +#[rustc_const_unstable(feature = "const_range", issue = "none")] +impl const OneSidedRange for RangeToInclusive +where + Self: RangeBounds, +{ + fn bound(self) -> (OneSidedRangeBound, T) { + (OneSidedRangeBound::EndInclusive, self.last) + } +} diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 3a76c098bb530..59239e62916a0 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -129,7 +129,7 @@ mod private_slice_index { impl Sealed for range::Range {} #[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeInclusive {} - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeToInclusive {} #[unstable(feature = "new_range_api", issue = "125687")] impl Sealed for range::RangeFrom {} @@ -801,7 +801,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeToInclusive { } /// The methods `index` and `index_mut` panic if the end of the range is out of bounds. -#[stable(feature = "inclusive_range", since = "1.26.0")] +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex<[T]> for range::RangeToInclusive { type Output = [T]; diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index edf07c0c16f42..03d47cacf5db9 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -763,6 +763,52 @@ unsafe impl const SliceIndex for ops::RangeToInclusive { } } +/// Implements substring slicing with syntax `&self[..= last]` or `&mut +/// self[..= last]`. +/// +/// Returns a slice of the given string from the byte range \[0, `last`\]. +/// Equivalent to `&self [0 .. last + 1]`, except if `last` has the maximum +/// value for `usize`. +/// +/// This operation is *O*(1). +/// +/// # Panics +/// +/// Panics if `last` does not point to the ending byte offset of a character +/// (`last + 1` is either a starting byte offset as defined by +/// `is_char_boundary`, or equal to `len`), or if `last >= len`. +#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_index", issue = "143775")] +unsafe impl const SliceIndex for range::RangeToInclusive { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + (0..=self.last).get(slice) + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + (0..=self.last).get_mut(slice) + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked`. + unsafe { (0..=self.last).get_unchecked(slice) } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. + unsafe { (0..=self.last).get_unchecked_mut(slice) } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + (0..=self.last).index(slice) + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + (0..=self.last).index_mut(slice) + } +} + /// Parse a value from a string /// /// `FromStr`'s [`from_str`] method is often used implicitly, through diff --git a/tests/ui/range/new_range_stability.rs b/tests/ui/range/new_range_stability.rs index 7200e1ac95d27..2d129fb6815f5 100644 --- a/tests/ui/range/new_range_stability.rs +++ b/tests/ui/range/new_range_stability.rs @@ -1,8 +1,10 @@ // Stable -use std::range::{RangeInclusive, RangeInclusiveIter}; +use std::range::{RangeInclusive, RangeInclusiveIter, RangeToInclusive}; fn range_inclusive(mut r: RangeInclusive) { + &[1, 2, 3][r]; // Indexing + r.start; r.last; r.contains(&5); @@ -14,6 +16,13 @@ fn range_inclusive(mut r: RangeInclusive) { i.remainder(); } +fn range_to_inclusive(mut r: RangeToInclusive) { + &[1, 2, 3][r]; // Indexing + + r.last; + r.contains(&5); +} + // Unstable module use std::range::legacy; //~ ERROR unstable diff --git a/tests/ui/range/new_range_stability.stderr b/tests/ui/range/new_range_stability.stderr index 871d691794ff0..b5a7e06e5f2ea 100644 --- a/tests/ui/range/new_range_stability.stderr +++ b/tests/ui/range/new_range_stability.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:19:5 + --> $DIR/new_range_stability.rs:28:5 | LL | use std::range::legacy; | ^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | use std::range::legacy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:23:5 + --> $DIR/new_range_stability.rs:32:5 | LL | use std::range::RangeFrom; | ^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | use std::range::RangeFrom; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:24:5 + --> $DIR/new_range_stability.rs:33:5 | LL | use std::range::Range; | ^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | use std::range::Range; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:25:5 + --> $DIR/new_range_stability.rs:34:5 | LL | use std::range::RangeFromIter; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | use std::range::RangeFromIter; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:26:5 + --> $DIR/new_range_stability.rs:35:5 | LL | use std::range::RangeIter; | ^^^^^^^^^^^^^^^^^^^^^ From 72a001bc25217104f9de5ff4b35c280c95adcb28 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:09:39 +1100 Subject: [PATCH 10/19] Remove `DepKindVTable::is_anon`. It's unused. --- compiler/rustc_middle/src/dep_graph/dep_node.rs | 5 ----- compiler/rustc_query_impl/src/dep_kind_vtables.rs | 9 --------- 2 files changed, 14 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 599c84597a8b9..c356d566626d1 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -174,11 +174,6 @@ impl fmt::Debug for DepNode { /// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual /// jump table instead of large matches. pub struct DepKindVTable<'tcx> { - /// Anonymous queries cannot be replayed from one compiler invocation to the next. - /// When their result is needed, it is recomputed. They are useful for fine-grained - /// dependency tracking, and caching within one compiler invocation. - pub is_anon: bool, - /// Eval-always queries do not track their dependencies, and are always recomputed, even if /// their inputs have not changed since the last compiler invocation. The result is still /// cached within one compiler invocation. diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index fa82a0413b1ad..01e37ca3e3ee1 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -13,7 +13,6 @@ mod non_query { // We use this for most things when incr. comp. is turned off. pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: Some(|_, dep_node, _| { @@ -26,7 +25,6 @@ mod non_query { // We use this for the forever-red node. pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: Some(|_, dep_node, _| { @@ -38,7 +36,6 @@ mod non_query { pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: Some(|tcx, _, prev_index| { @@ -51,7 +48,6 @@ mod non_query { pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: true, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Opaque, force_from_dep_node_fn: Some(|_, _, _| bug!("cannot force an anon node")), @@ -61,7 +57,6 @@ mod non_query { pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: true, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: None, @@ -71,7 +66,6 @@ mod non_query { pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Opaque, force_from_dep_node_fn: None, @@ -81,7 +75,6 @@ mod non_query { pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Opaque, force_from_dep_node_fn: None, @@ -91,7 +84,6 @@ mod non_query { pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> { DepKindVTable { - is_anon: false, is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: None, @@ -124,7 +116,6 @@ where } DepKindVTable { - is_anon, is_eval_always, key_fingerprint_style, force_from_dep_node_fn: can_recover.then_some(force_from_dep_node_inner::), From cc1b878386666be4b97ed21e053487f1ec0f6c0c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:27:31 +1100 Subject: [PATCH 11/19] Inline and remove `handle_cycle_error`. It has a single use. --- compiler/rustc_query_impl/src/execution.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 67054b415214b..8d5aa20da1508 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -5,7 +5,7 @@ use rustc_data_structures::hash_table::{Entry, HashTable}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::{outline, sharded, sync}; -use rustc_errors::{Diag, FatalError, StashKey}; +use rustc_errors::{FatalError, StashKey}; use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex}; use rustc_middle::query::plumbing::QueryVTable; use rustc_middle::query::{ @@ -126,19 +126,10 @@ fn mk_cycle<'tcx, C: QueryCache>( cycle_error: CycleError, ) -> C::Value { let error = report_cycle(tcx.sess, &cycle_error); - handle_cycle_error(query, tcx, &cycle_error, error) -} - -fn handle_cycle_error<'tcx, C: QueryCache>( - query: &'tcx QueryVTable<'tcx, C>, - tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, - error: Diag<'_>, -) -> C::Value { match query.cycle_error_handling { CycleErrorHandling::Error => { let guar = error.emit(); - query.value_from_cycle_error(tcx, cycle_error, guar) + query.value_from_cycle_error(tcx, &cycle_error, guar) } CycleErrorHandling::Fatal => { error.emit(); @@ -147,7 +138,7 @@ fn handle_cycle_error<'tcx, C: QueryCache>( } CycleErrorHandling::DelayBug => { let guar = error.delay_as_bug(); - query.value_from_cycle_error(tcx, cycle_error, guar) + query.value_from_cycle_error(tcx, &cycle_error, guar) } CycleErrorHandling::Stash => { let guar = if let Some(root) = cycle_error.cycle.first() @@ -157,7 +148,7 @@ fn handle_cycle_error<'tcx, C: QueryCache>( } else { error.emit() }; - query.value_from_cycle_error(tcx, cycle_error, guar) + query.value_from_cycle_error(tcx, &cycle_error, guar) } } } From c0770baed8b4158a063ed27493ff2eeacfd6681c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:31:32 +1100 Subject: [PATCH 12/19] Make `from_cycle_error` consume the `CycleError`. This makes it clear the `CycleError` is not used after the call. --- compiler/rustc_middle/src/query/plumbing.rs | 4 +-- compiler/rustc_query_impl/src/execution.rs | 6 ++-- compiler/rustc_query_impl/src/values.rs | 37 +++++++-------------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 072e29aaa9063..3832a961b4194 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -151,7 +151,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> { pub hash_value_fn: Option, &C::Value) -> Fingerprint>, pub value_from_cycle_error: - fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value, + fn(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> C::Value, pub format_value: fn(&C::Value) -> String, /// Formats a human-readable description of this query and its key, as @@ -216,7 +216,7 @@ impl<'tcx, C: QueryCache> QueryVTable<'tcx, C> { pub fn value_from_cycle_error( &self, tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, + cycle_error: CycleError, guar: ErrorGuaranteed, ) -> C::Value { (self.value_from_cycle_error)(tcx, cycle_error, guar) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 8d5aa20da1508..634015403a627 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -129,7 +129,7 @@ fn mk_cycle<'tcx, C: QueryCache>( match query.cycle_error_handling { CycleErrorHandling::Error => { let guar = error.emit(); - query.value_from_cycle_error(tcx, &cycle_error, guar) + query.value_from_cycle_error(tcx, cycle_error, guar) } CycleErrorHandling::Fatal => { error.emit(); @@ -138,7 +138,7 @@ fn mk_cycle<'tcx, C: QueryCache>( } CycleErrorHandling::DelayBug => { let guar = error.delay_as_bug(); - query.value_from_cycle_error(tcx, &cycle_error, guar) + query.value_from_cycle_error(tcx, cycle_error, guar) } CycleErrorHandling::Stash => { let guar = if let Some(root) = cycle_error.cycle.first() @@ -148,7 +148,7 @@ fn mk_cycle<'tcx, C: QueryCache>( } else { error.emit() }; - query.value_from_cycle_error(tcx, &cycle_error, guar) + query.value_from_cycle_error(tcx, cycle_error, guar) } } } diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs index 8f55e98df867e..6e739ee04a024 100644 --- a/compiler/rustc_query_impl/src/values.rs +++ b/compiler/rustc_query_impl/src/values.rs @@ -18,14 +18,13 @@ use rustc_span::{ErrorGuaranteed, Span}; use crate::job::report_cycle; pub(crate) trait Value<'tcx>: Sized { - fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) - -> Self; + fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self; } impl<'tcx, T> Value<'tcx> for T { default fn from_cycle_error( tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, + cycle_error: CycleError, _guar: ErrorGuaranteed, ) -> T { tcx.sess.dcx().abort_if_errors(); @@ -38,7 +37,7 @@ impl<'tcx, T> Value<'tcx> for T { } impl<'tcx> Value<'tcx> for Ty<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self { + fn from_cycle_error(tcx: TyCtxt<'tcx>, _: CycleError, guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. unsafe { std::mem::transmute::, Ty<'_>>(Ty::new_error(tcx, guar)) } @@ -46,13 +45,13 @@ impl<'tcx> Value<'tcx> for Ty<'_> { } impl<'tcx> Value<'tcx> for Result>, CyclePlaceholder> { - fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self { + fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: CycleError, guar: ErrorGuaranteed) -> Self { Err(CyclePlaceholder(guar)) } } impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, _guar: ErrorGuaranteed) -> Self { + fn from_cycle_error(tcx: TyCtxt<'tcx>, _: CycleError, _guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. unsafe { @@ -64,11 +63,7 @@ impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { } impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { - fn from_cycle_error( - tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, - guar: ErrorGuaranteed, - ) -> Self { + fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { let err = Ty::new_error(tcx, guar); let arity = if let Some(info) = cycle_error.cycle.get(0) @@ -100,7 +95,7 @@ impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { impl<'tcx> Value<'tcx> for Representability { fn from_cycle_error( tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, + cycle_error: CycleError, _guar: ErrorGuaranteed, ) -> Self { let mut item_and_field_ids = Vec::new(); @@ -134,21 +129,13 @@ impl<'tcx> Value<'tcx> for Representability { } impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, Ty<'_>> { - fn from_cycle_error( - tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, - guar: ErrorGuaranteed, - ) -> Self { + fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { ty::EarlyBinder::bind(Ty::from_cycle_error(tcx, cycle_error, guar)) } } impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { - fn from_cycle_error( - tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, - guar: ErrorGuaranteed, - ) -> Self { + fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { ty::EarlyBinder::bind(ty::Binder::from_cycle_error(tcx, cycle_error, guar)) } } @@ -156,7 +143,7 @@ impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { impl<'tcx> Value<'tcx> for &[ty::Variance] { fn from_cycle_error( tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, + cycle_error: CycleError, _guar: ErrorGuaranteed, ) -> Self { search_for_cycle_permutation( @@ -204,7 +191,7 @@ fn search_for_cycle_permutation( impl<'tcx, T> Value<'tcx> for Result> { fn from_cycle_error( tcx: TyCtxt<'tcx>, - cycle_error: &CycleError, + cycle_error: CycleError, _guar: ErrorGuaranteed, ) -> Self { let diag = search_for_cycle_permutation( @@ -280,7 +267,7 @@ impl<'tcx, T> Value<'tcx> for Result> { ControlFlow::Continue(()) } }, - || report_cycle(tcx.sess, cycle_error), + || report_cycle(tcx.sess, &cycle_error), ); let guar = diag.emit(); From 7a4daa48b8f4dfe00deacea6f2ba950c76de8a39 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:35:45 +1100 Subject: [PATCH 13/19] Avoid an early return in `try_execute_query`. When there are two cases of equal size and importance, I find an if/else expression easier to read than an early return. --- compiler/rustc_query_impl/src/execution.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 634015403a627..3d1ebd7b23671 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -331,15 +331,15 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( // Only call `wait_for_query` if we're using a Rayon thread pool // as it will attempt to mark the worker thread as blocked. - return wait_for_query(query, tcx, span, key, latch, current_job_id); - } - - let id = job.id; - drop(state_lock); + wait_for_query(query, tcx, span, key, latch, current_job_id) + } else { + let id = job.id; + drop(state_lock); - // If we are single-threaded we know that we have cycle error, - // so we just return the error. - cycle_error(query, tcx, id, span) + // If we are single-threaded we know that we have cycle error, + // so we just return the error. + cycle_error(query, tcx, id, span) + } } ActiveKeyStatus::Poisoned => FatalError.raise(), } From fc395ed961fd0ff9b75baddb402b328aef5f99fd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:40:47 +1100 Subject: [PATCH 14/19] Merge two assertion blocks in `execute_job_non_incr`. It reads better that way. --- compiler/rustc_query_impl/src/execution.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 3d1ebd7b23671..dd929c99b1c15 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -421,12 +421,6 @@ fn execute_job_non_incr<'tcx, C: QueryCache>( ) -> (C::Value, DepNodeIndex) { debug_assert!(!tcx.dep_graph.is_fully_enabled()); - // Fingerprint the key, just to assert that it doesn't - // have anything we don't consider hashable - if cfg!(debug_assertions) { - let _ = key.to_fingerprint(tcx); - } - let prof_timer = tcx.prof.query_provider(); // Call the query provider. let value = @@ -434,14 +428,14 @@ fn execute_job_non_incr<'tcx, C: QueryCache>( let dep_node_index = tcx.dep_graph.next_virtual_depnode_index(); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); - // Similarly, fingerprint the result to assert that - // it doesn't have anything not considered hashable. - if cfg!(debug_assertions) - && let Some(hash_value_fn) = query.hash_value_fn - { - tcx.with_stable_hashing_context(|mut hcx| { - hash_value_fn(&mut hcx, &value); - }); + // Sanity: Fingerprint the key and the result to assert they don't contain anything unhashable. + if cfg!(debug_assertions) { + let _ = key.to_fingerprint(tcx); + if let Some(hash_value_fn) = query.hash_value_fn { + tcx.with_stable_hashing_context(|mut hcx| { + hash_value_fn(&mut hcx, &value); + }); + } } (value, dep_node_index) From 8129da81e247cb21f8d7cacf486f4683cc291660 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 10:48:53 +1100 Subject: [PATCH 15/19] Remove three single-use type synonyms. It's an unnecessary level of indirection. --- compiler/rustc_middle/src/query/plumbing.rs | 27 +++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 3832a961b4194..2dba891885404 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -62,18 +62,6 @@ pub enum CycleErrorHandling { Stash, } -pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool; - -pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn( - tcx: TyCtxt<'tcx>, - key: &Key, - prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, -) -> Option; - -pub type IsLoadableFromDiskFn<'tcx, Key> = - fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool; - #[derive(Clone, Debug)] pub struct CycleError { /// The query and related span that uses the cycle. @@ -126,7 +114,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> { pub cycle_error_handling: CycleErrorHandling, pub state: QueryState<'tcx, C::Key>, pub cache: C, - pub will_cache_on_disk_for_key_fn: Option>, + pub will_cache_on_disk_for_key_fn: Option, key: &C::Key) -> bool>, /// Function pointer that calls `tcx.$query(key)` for this query and /// discards the returned value. @@ -142,8 +130,17 @@ pub struct QueryVTable<'tcx, C: QueryCache> { /// This should be the only code that calls the provider function. pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, - pub try_load_from_disk_fn: Option>, - pub is_loadable_from_disk_fn: Option>, + pub try_load_from_disk_fn: Option< + fn( + tcx: TyCtxt<'tcx>, + key: &C::Key, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, + ) -> Option, + >, + + pub is_loadable_from_disk_fn: + Option, key: &C::Key, index: SerializedDepNodeIndex) -> bool>, /// Function pointer that hashes this query's result values. /// From 2aaced63444987973c1205931ed3dda94f26a26b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 14:31:51 +1100 Subject: [PATCH 16/19] Replace two `abort_if_errors` calls. Calling `abort_if_errors` after emitting an error is guaranteed to call `raise_fatal`, so just do that directly instead. --- compiler/rustc_query_impl/src/execution.rs | 5 ++--- compiler/rustc_query_impl/src/values.rs | 14 ++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index dd929c99b1c15..323d40fdbaabb 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -132,9 +132,8 @@ fn mk_cycle<'tcx, C: QueryCache>( query.value_from_cycle_error(tcx, cycle_error, guar) } CycleErrorHandling::Fatal => { - error.emit(); - tcx.dcx().abort_if_errors(); - unreachable!() + let guar = error.emit(); + guar.raise_fatal(); } CycleErrorHandling::DelayBug => { let guar = error.delay_as_bug(); diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs index 6e739ee04a024..216f36bd6e847 100644 --- a/compiler/rustc_query_impl/src/values.rs +++ b/compiler/rustc_query_impl/src/values.rs @@ -27,12 +27,14 @@ impl<'tcx, T> Value<'tcx> for T { cycle_error: CycleError, _guar: ErrorGuaranteed, ) -> T { - tcx.sess.dcx().abort_if_errors(); - bug!( - "<{} as Value>::from_cycle_error called without errors: {:#?}", - std::any::type_name::(), - cycle_error.cycle, - ); + let Some(guar) = tcx.sess.dcx().has_errors() else { + bug!( + "<{} as Value>::from_cycle_error called without errors: {:#?}", + std::any::type_name::(), + cycle_error.cycle, + ); + }; + guar.raise_fatal(); } } From 6f111d21a5ab57069727be85fd94f910a49665aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 16:39:23 +1100 Subject: [PATCH 17/19] Remove a duplicated comment. This exact comment block also appears in `compiler/rustc_middle/src/queries.rs`, which is a better place for it. --- compiler/rustc_middle/src/query/plumbing.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 2dba891885404..e1a19e5ffec7f 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -647,18 +647,6 @@ macro_rules! define_callbacks { }; } -// Each of these queries corresponds to a function pointer field in the -// `Providers` struct for requesting a value of that type, and a method -// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way -// which memoizes and does dep-graph tracking, wrapping around the actual -// `Providers` that the driver creates (using several `rustc_*` crates). -// -// The result type of each query must implement `Clone`, and additionally -// `ty::query::values::Value`, which produces an appropriate placeholder -// (error) value if the query resulted in a query cycle. -// Queries marked with `cycle_fatal` do not need the latter implementation, -// as they will raise an fatal error on query cycles instead. - mod sealed { use rustc_hir::def_id::{LocalModDefId, ModDefId}; From 5677f7c70676a99c6cae3b636098ffbf5f8c70f5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 15:11:18 +1100 Subject: [PATCH 18/19] Rename trait `Value` as `FromCycleError`. `Value` is an unhelpfully generic name. Standard naming procedure for a trait with a single method is for the trait name to match the method name, which is what this commit does. Likewise, the enclosing module is renamed from `values` to `from_cycle_error`. Also add a comment about some non-obvious behaviour. --- compiler/rustc_middle/src/queries.rs | 6 ++-- .../src/{values.rs => from_cycle_error.rs} | 28 +++++++++++-------- compiler/rustc_query_impl/src/lib.rs | 4 +-- compiler/rustc_query_impl/src/plumbing.rs | 3 +- 4 files changed, 23 insertions(+), 18 deletions(-) rename compiler/rustc_query_impl/src/{values.rs => from_cycle_error.rs} (93%) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 0ff38a0f36041..f54b291a2024f 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -150,10 +150,10 @@ use crate::{dep_graph, mir, thir}; // `Providers` that the driver creates (using several `rustc_*` crates). // // The result type of each query must implement `Clone`, and additionally -// `ty::query::values::Value`, which produces an appropriate placeholder -// (error) value if the query resulted in a query cycle. +// `ty::query::from_cycle_error::FromCycleError`, which produces an appropriate +// placeholder (error) value if the query resulted in a query cycle. // Queries marked with `cycle_fatal` do not need the latter implementation, -// as they will raise an fatal error on query cycles instead. +// as they will raise a fatal error on query cycles instead. rustc_queries! { /// Caches the expansion of a derive proc macro, e.g. `#[derive(Serialize)]`. /// The key is: diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs similarity index 93% rename from compiler/rustc_query_impl/src/values.rs rename to compiler/rustc_query_impl/src/from_cycle_error.rs index 216f36bd6e847..690eb022ea234 100644 --- a/compiler/rustc_query_impl/src/values.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -17,11 +17,15 @@ use rustc_span::{ErrorGuaranteed, Span}; use crate::job::report_cycle; -pub(crate) trait Value<'tcx>: Sized { +pub(crate) trait FromCycleError<'tcx>: Sized { + /// Try to produce a `Self` value that represents an error form (e.g. `TyKind::Error`). + /// + /// Note: the default impl calls `raise_fatal`, ending compilation immediately! Only a few + /// types override this with a non-fatal impl. fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self; } -impl<'tcx, T> Value<'tcx> for T { +impl<'tcx, T> FromCycleError<'tcx> for T { default fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: CycleError, @@ -29,7 +33,7 @@ impl<'tcx, T> Value<'tcx> for T { ) -> T { let Some(guar) = tcx.sess.dcx().has_errors() else { bug!( - "<{} as Value>::from_cycle_error called without errors: {:#?}", + "<{} as FromCycleError>::from_cycle_error called without errors: {:#?}", std::any::type_name::(), cycle_error.cycle, ); @@ -38,7 +42,7 @@ impl<'tcx, T> Value<'tcx> for T { } } -impl<'tcx> Value<'tcx> for Ty<'_> { +impl<'tcx> FromCycleError<'tcx> for Ty<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: CycleError, guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. @@ -46,13 +50,13 @@ impl<'tcx> Value<'tcx> for Ty<'_> { } } -impl<'tcx> Value<'tcx> for Result>, CyclePlaceholder> { +impl<'tcx> FromCycleError<'tcx> for Result>, CyclePlaceholder> { fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: CycleError, guar: ErrorGuaranteed) -> Self { Err(CyclePlaceholder(guar)) } } -impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { +impl<'tcx> FromCycleError<'tcx> for ty::SymbolName<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: CycleError, _guar: ErrorGuaranteed) -> Self { // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. @@ -64,7 +68,7 @@ impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { } } -impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { +impl<'tcx> FromCycleError<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { let err = Ty::new_error(tcx, guar); @@ -94,7 +98,7 @@ impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { } } -impl<'tcx> Value<'tcx> for Representability { +impl<'tcx> FromCycleError<'tcx> for Representability { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: CycleError, @@ -130,19 +134,19 @@ impl<'tcx> Value<'tcx> for Representability { } } -impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, Ty<'_>> { +impl<'tcx> FromCycleError<'tcx> for ty::EarlyBinder<'_, Ty<'_>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { ty::EarlyBinder::bind(Ty::from_cycle_error(tcx, cycle_error, guar)) } } -impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { +impl<'tcx> FromCycleError<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { ty::EarlyBinder::bind(ty::Binder::from_cycle_error(tcx, cycle_error, guar)) } } -impl<'tcx> Value<'tcx> for &[ty::Variance] { +impl<'tcx> FromCycleError<'tcx> for &[ty::Variance] { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: CycleError, @@ -190,7 +194,7 @@ fn search_for_cycle_permutation( otherwise() } -impl<'tcx, T> Value<'tcx> for Result> { +impl<'tcx, T> FromCycleError<'tcx> for Result> { fn from_cycle_error( tcx: TyCtxt<'tcx>, cycle_error: CycleError, diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 875dd07ff25f0..5be636877fa50 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -18,10 +18,10 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; pub use crate::dep_kind_vtables::make_dep_kind_vtables; +use crate::from_cycle_error::FromCycleError; pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack}; use crate::plumbing::try_mark_green; use crate::profiling_support::QueryKeyStringCache; -use crate::values::Value; #[macro_use] mod plumbing; @@ -29,9 +29,9 @@ mod plumbing; mod dep_kind_vtables; mod error; mod execution; +mod from_cycle_error; mod job; mod profiling_support; -mod values; /// Trait that knows how to look up the [`QueryVTable`] for a particular query. /// diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index f005e55418294..f22b5be75cafa 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -554,7 +554,8 @@ macro_rules! define_queries { None }), value_from_cycle_error: |tcx, cycle, guar| { - let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar); + let result: queries::$name::Value<'tcx> = + FromCycleError::from_cycle_error(tcx, cycle, guar); erase::erase_val(result) }, hash_value_fn: if_no_hash!( From 5bd28b85bd5cc0000f67035a1c37fd0b150eccd6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 27 Feb 2026 16:15:59 +1100 Subject: [PATCH 19/19] Remove `FromCycleError` impl for `SymbolName`. It has no effect. `symbol_name` is the only query that produces a `SymbolName`. If it was marked with `cycle_delayed_bug`/`cycle_stash` then this `FromCycleError` impl would make sense, but that's not the case. Maybe it was the case in the past. --- compiler/rustc_query_impl/src/from_cycle_error.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs index 690eb022ea234..a13db9004d678 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -56,18 +56,6 @@ impl<'tcx> FromCycleError<'tcx> for Result>, CyclePla } } -impl<'tcx> FromCycleError<'tcx> for ty::SymbolName<'_> { - fn from_cycle_error(tcx: TyCtxt<'tcx>, _: CycleError, _guar: ErrorGuaranteed) -> Self { - // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. - // FIXME: Represent the above fact in the trait system somehow. - unsafe { - std::mem::transmute::, ty::SymbolName<'_>>(ty::SymbolName::new( - tcx, "", - )) - } - } -} - impl<'tcx> FromCycleError<'tcx> for ty::Binder<'_, ty::FnSig<'_>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> Self { let err = Ty::new_error(tcx, guar);