Auto merge of #153278 - JonathanBrouwer:rollup-k88jgqQ, r=JonathanBrouwer

Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#153169 (Various small query cleanups)
 - rust-lang/rust#152304 (stabilize new RangeToInclusive type)
 - rust-lang/rust#153046 (Couple of cg_ssa refactorings)
 - rust-lang/rust#153090 (elf-raw-dylib: set type for functions)
 - rust-lang/rust#153225 (tests/ui/asm: add annotations for reference rules)
 - rust-lang/rust#153233 (test: add regression test for fuzzy_provenance_casts lint ICE)
This commit is contained in:
bors
2026-03-02 12:02:00 +00:00
66 changed files with 598 additions and 427 deletions
+4 -3
View File
@@ -485,13 +485,14 @@ fn deref<'b>(&'b self) -> &'a Self::Target {
}
impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
type Value = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Value;
type Metadata = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Metadata;
type Function = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Function;
type BasicBlock = <CodegenCx<'gcc, 'tcx> as BackendTypes>::BasicBlock;
type Type = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Type;
type Funclet = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Funclet;
type Value = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Value;
type Type = <CodegenCx<'gcc, 'tcx> as BackendTypes>::Type;
type FunctionSignature = <CodegenCx<'gcc, 'tcx> as BackendTypes>::FunctionSignature;
type DIScope = <CodegenCx<'gcc, 'tcx> as BackendTypes>::DIScope;
type DILocation = <CodegenCx<'gcc, 'tcx> as BackendTypes>::DILocation;
type DIVariable = <CodegenCx<'gcc, 'tcx> as BackendTypes>::DIVariable;
+10 -24
View File
@@ -5,9 +5,10 @@
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 @@ fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) ->
};
}
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 @@ fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) ->
}),
)))
.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 @@ fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) ->
}
}
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()))
+24 -2
View File
@@ -22,6 +22,25 @@
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>(
+4 -4
View File
@@ -380,14 +380,14 @@ pub fn bitcast_if_needed(
}
impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
type Value = RValue<'gcc>;
type Metadata = 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 FunctionSignature = Type<'gcc>;
type DIScope = (); // TODO(antoyo)
type DILocation = Location<'gcc>;
type DIVariable = (); // TODO(antoyo)
@@ -712,7 +712,7 @@ fn type_checked_load(
&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)
+4 -3
View File
@@ -196,13 +196,14 @@ pub(crate) fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &
pub(crate) const UNNAMED: *const c_char = c"".as_ptr();
impl<'ll, CX: Borrow<SCx<'ll>>> BackendTypes for GenericBuilder<'_, 'll, CX> {
type Value = <GenericCx<'ll, CX> as BackendTypes>::Value;
type Metadata = <GenericCx<'ll, CX> as BackendTypes>::Metadata;
type Function = <GenericCx<'ll, CX> as BackendTypes>::Function;
type BasicBlock = <GenericCx<'ll, CX> as BackendTypes>::BasicBlock;
type Type = <GenericCx<'ll, CX> as BackendTypes>::Type;
type Funclet = <GenericCx<'ll, CX> as BackendTypes>::Funclet;
type Value = <GenericCx<'ll, CX> as BackendTypes>::Value;
type Type = <GenericCx<'ll, CX> as BackendTypes>::Type;
type FunctionSignature = <GenericCx<'ll, CX> as BackendTypes>::FunctionSignature;
type DIScope = <GenericCx<'ll, CX> as BackendTypes>::DIScope;
type DILocation = <GenericCx<'ll, CX> as BackendTypes>::DILocation;
type DIVariable = <GenericCx<'ll, CX> as BackendTypes>::DIVariable;
+6 -10
View File
@@ -12,7 +12,7 @@
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;
@@ -20,7 +20,7 @@
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".
@@ -82,15 +82,15 @@ pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
}
impl<'ll, CX: Borrow<SCx<'ll>>> 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;
type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type;
type Funclet = Funclet<'ll>;
type Value = &'ll Value;
type Type = &'ll Type;
type FunctionSignature = &'ll Type;
type DIScope = &'ll llvm::debuginfo::DIScope;
type DILocation = &'ll llvm::debuginfo::DILocation;
type DIVariable = &'ll llvm::debuginfo::DIVariable;
@@ -359,10 +359,6 @@ fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) ->
}
}
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(
+6 -2
View File
@@ -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())
+3 -2
View File
@@ -38,7 +38,7 @@
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 @@ fn type_checked_load(
&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(
+1 -5
View File
@@ -15,7 +15,7 @@
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 @@ fn set_type_metadata(&self, function: &'ll Value, typeid: &[u8]) {
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);
@@ -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)
+3 -6
View File
@@ -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);
@@ -139,9 +137,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")
@@ -245,10 +245,7 @@ fn from_const_alloc<Bx: BuilderMethods<'a, 'tcx, Value = 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))
@@ -21,14 +21,14 @@
use crate::{CodegenResults, ModuleCodegen, TargetConfig};
pub trait BackendTypes {
type Value: CodegenObject + PartialEq;
type Metadata: CodegenObject;
type Function: CodegenObject;
type BasicBlock: Copy;
type Type: CodegenObject + PartialEq;
type Funclet;
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.).
type DIScope: Copy + Hash + PartialEq + Eq;
@@ -137,7 +137,7 @@ fn link(
}
pub trait ExtraBackendMethods:
CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
{
fn codegen_allocator<'tcx>(
&self,
@@ -50,10 +50,10 @@ pub trait BuilderMethods<'a, 'tcx>:
type CodegenCx: CodegenMethods<
'tcx,
Value = Self::Value,
Metadata = Self::Metadata,
Function = Self::Function,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
FunctionSignature = Self::FunctionSignature,
Funclet = Self::Funclet,
DIScope = Self::DIScope,
DILocation = Self::DILocation,
@@ -125,7 +125,7 @@ fn switch_with_weights(
fn invoke(
&mut self,
llty: Self::Type,
llty: Self::FunctionSignature,
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
llfn: Self::Value,
@@ -623,7 +623,7 @@ fn atomic_rmw(
/// 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,
@@ -634,7 +634,7 @@ fn call(
fn tail_call(
&mut self,
llty: Self::Type,
llty: Self::FunctionSignature,
caller_attrs: Option<&CodegenFnAttrs>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
llfn: Self::Value,
@@ -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<u64>;
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
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;
@@ -41,7 +41,7 @@ fn type_checked_load(
&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.
@@ -25,5 +25,5 @@ fn apply_vcall_visibility_metadata(
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<Self::Function>;
fn declare_c_main(&self, fn_type: Self::FunctionSignature) -> Option<Self::Function>;
}
@@ -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);
}
@@ -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.
@@ -156,9 +156,6 @@ fn is_backend_ref(&self, layout: TyAndLayout<'tcx>) -> bool {
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<Self::Metadata> {
None
}
fn add_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
}
@@ -174,11 +174,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// 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.
+3 -3
View File
@@ -150,10 +150,10 @@
// `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:
+14 -29
View File
@@ -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<Value>;
pub type IsLoadableFromDiskFn<'tcx, Key> =
fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool;
#[derive(Clone, Debug)]
pub struct CycleError<I = QueryStackFrameExtra> {
/// 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<WillCacheOnDiskForKeyFn<'tcx, C::Key>>,
pub will_cache_on_disk_for_key_fn: Option<fn(tcx: TyCtxt<'tcx>, 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<TryLoadFromDiskFn<'tcx, C::Key, C::Value>>,
pub is_loadable_from_disk_fn: Option<IsLoadableFromDiskFn<'tcx, C::Key>>,
pub try_load_from_disk_fn: Option<
fn(
tcx: TyCtxt<'tcx>,
key: &C::Key,
prev_index: SerializedDepNodeIndex,
index: DepNodeIndex,
) -> Option<C::Value>,
>,
pub is_loadable_from_disk_fn:
Option<fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool>,
/// Function pointer that hashes this query's result values.
///
@@ -151,7 +148,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
pub hash_value_fn: Option<fn(&mut StableHashingContext<'_>, &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 +213,7 @@ pub fn is_loadable_from_disk(
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)
@@ -650,18 +647,6 @@ fn clone(&self) -> Self { *self }
};
}
// 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};
@@ -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 @@ pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> {
// 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 @@ pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> {
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 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>(
}
DepKindVTable {
is_anon,
is_eval_always,
key_fingerprint_style,
force_from_dep_node_fn: can_recover.then_some(force_from_dep_node_inner::<Q>),
+19 -35
View File
@@ -5,7 +5,7 @@
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,24 +126,14 @@ 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)
}
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();
@@ -340,15 +330,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);
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)
}
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)
}
ActiveKeyStatus::Poisoned => FatalError.raise(),
}
@@ -430,12 +420,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 =
@@ -443,14 +427,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)
@@ -17,58 +17,47 @@
use crate::job::report_cycle;
pub(crate) trait Value<'tcx>: Sized {
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed)
-> Self;
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,
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::<T>(),
cycle_error.cycle,
);
let Some(guar) = tcx.sess.dcx().has_errors() else {
bug!(
"<{} as FromCycleError>::from_cycle_error called without errors: {:#?}",
std::any::type_name::<T>(),
cycle_error.cycle,
);
};
guar.raise_fatal();
}
}
impl<'tcx> Value<'tcx> for Ty<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
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.
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(Ty::new_error(tcx, guar)) }
}
}
impl<'tcx> Value<'tcx> for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
impl<'tcx> FromCycleError<'tcx> for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
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 {
// 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<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
tcx, "<error>",
))
}
}
}
impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
guar: ErrorGuaranteed,
) -> Self {
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);
let arity = if let Some(info) = cycle_error.cycle.get(0)
@@ -97,10 +86,10 @@ fn from_cycle_error(
}
}
impl<'tcx> Value<'tcx> for Representability {
impl<'tcx> FromCycleError<'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();
@@ -133,30 +122,22 @@ fn from_cycle_error(
}
}
impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, Ty<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
guar: ErrorGuaranteed,
) -> Self {
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<'_>>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
guar: ErrorGuaranteed,
) -> Self {
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,
cycle_error: CycleError,
_guar: ErrorGuaranteed,
) -> Self {
search_for_cycle_permutation(
@@ -201,10 +182,10 @@ fn search_for_cycle_permutation<Q, T>(
otherwise()
}
impl<'tcx, T> Value<'tcx> for Result<T, &'_ ty::layout::LayoutError<'_>> {
impl<'tcx, T> FromCycleError<'tcx> for Result<T, &'_ ty::layout::LayoutError<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
cycle_error: CycleError,
_guar: ErrorGuaranteed,
) -> Self {
let diag = search_for_cycle_permutation(
@@ -280,7 +261,7 @@ fn from_cycle_error(
ControlFlow::Continue(())
}
},
|| report_cycle(tcx.sess, cycle_error),
|| report_cycle(tcx.sess, &cycle_error),
);
let guar = diag.emit();
+2 -2
View File
@@ -18,10 +18,10 @@
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 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.
///
+2 -1
View File
@@ -554,7 +554,8 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
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!(
+1
View File
@@ -268,4 +268,5 @@ fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
impl_slice_index!(ops::RangeInclusive<usize>);
impl_slice_index!(range::RangeInclusive<usize>);
impl_slice_index!(ops::RangeToInclusive<usize>);
impl_slice_index!(range::RangeToInclusive<usize>);
impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));
+11 -1
View File
@@ -8,7 +8,7 @@
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 @@ fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
}
}
#[unstable(feature = "new_range_api", issue = "125687")]
impl ops::Index<range::RangeFrom<usize>> for CStr {
type Output = CStr;
#[inline]
fn index(&self, index: range::RangeFrom<usize>) -> &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<CStr> for CStr {
+45 -10
View File
@@ -43,7 +43,7 @@
// 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 @@ fn into_bounds(self) -> (Bound<T>, Bound<T>) {
}
}
#[unstable(feature = "one_sided_range", issue = "69780")]
// #[unstable(feature = "new_range_api", issue = "125687")]
#[rustc_const_unstable(feature = "const_range", issue = "none")]
impl<T> const OneSidedRange<T> for RangeFrom<T>
where
Self: RangeBounds<T>,
{
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<T> const From<RangeFrom<T>> for legacy::RangeFrom<T> {
@@ -573,9 +585,8 @@ fn from(value: legacy::RangeFrom<T>) -> Self {
/// 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 @@ fn from(value: legacy::RangeFrom<T>) -> Self {
#[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<Idx> {
/// 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<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "..=")?;
@@ -637,7 +648,7 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
/// 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<U>(&self, item: &U) -> bool
where
@@ -648,13 +659,13 @@ pub const fn contains<U>(&self, item: &U) -> bool
}
}
#[unstable(feature = "new_range_api", issue = "125687")]
#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
impl<T> From<legacy::RangeToInclusive<T>> for RangeToInclusive<T> {
fn from(value: legacy::RangeToInclusive<T>) -> Self {
Self { last: value.end }
}
}
#[unstable(feature = "new_range_api", issue = "125687")]
#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
impl<T> From<RangeToInclusive<T>> for legacy::RangeToInclusive<T> {
fn from(value: RangeToInclusive<T>) -> Self {
Self { end: value.last }
@@ -664,7 +675,7 @@ fn from(value: RangeToInclusive<T>) -> Self {
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
// 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<T> const RangeBounds<T> for RangeToInclusive<T> {
fn start_bound(&self) -> Bound<&T> {
@@ -675,6 +686,18 @@ fn end_bound(&self) -> Bound<&T> {
}
}
#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "const_range", issue = "none")]
impl<T> const RangeBounds<T> 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<T> const IntoBounds<T> for RangeToInclusive<T> {
@@ -682,3 +705,15 @@ fn into_bounds(self) -> (Bound<T>, Bound<T>) {
(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<T> const OneSidedRange<T> for RangeToInclusive<T>
where
Self: RangeBounds<T>,
{
fn bound(self) -> (OneSidedRangeBound, T) {
(OneSidedRangeBound::EndInclusive, self.last)
}
}
+2 -2
View File
@@ -129,7 +129,7 @@ impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
impl Sealed for range::Range<usize> {}
#[stable(feature = "new_range_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
impl Sealed for range::RangeInclusive<usize> {}
#[unstable(feature = "new_range_api", issue = "125687")]
#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
impl Sealed for range::RangeToInclusive<usize> {}
#[unstable(feature = "new_range_api", issue = "125687")]
impl Sealed for range::RangeFrom<usize> {}
@@ -801,7 +801,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
/// 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<T> const SliceIndex<[T]> for range::RangeToInclusive<usize> {
type Output = [T];
+46
View File
@@ -763,6 +763,52 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
}
}
/// 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<str> for range::RangeToInclusive<usize> {
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
+26 -26
View File
@@ -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
+2
View File
@@ -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
+26 -26
View File
@@ -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
+1
View File
@@ -1,4 +1,5 @@
//@ needs-asm-support
//@ reference: asm.attributes.supported-attributes
use std::arch::asm;
+5 -5
View File
@@ -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]
| ^^^^^^^^^^^^^^^^^
+1
View File
@@ -3,6 +3,7 @@
//@ revisions: reva revb
//@ only-x86_64
//@ run-pass
//@ reference: asm.attributes.supported-attributes
use std::arch::{asm, naked_asm};
+1
View File
@@ -1,6 +1,7 @@
//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
//@ reference: asm.operand-type.supported-operands.const
use std::arch::{asm, global_asm};
+8 -8
View File
@@ -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);
| ^^^^^^--
+1
View File
@@ -1,6 +1,7 @@
//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
//@ reference: asm.operand-type.supported-operands.sym
use std::arch::{asm, global_asm};
+3 -3
View File
@@ -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`
@@ -2,6 +2,7 @@
//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
//@ reference: asm.scope.naked_asm
#![crate_type = "lib"]
@@ -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!("");
| ^^^^^^^^^^^^^^
+1
View File
@@ -1,4 +1,5 @@
//@ needs-asm-support
//@ reference: attributes.codegen.naked.inline
#![crate_type = "lib"]
use std::arch::naked_asm;
+4 -4
View File
@@ -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
@@ -1,5 +1,6 @@
//@ needs-asm-support
//@ compile-flags: --test
//@ reference: attributes.codegen.naked.testing
#![feature(test)]
#![crate_type = "lib"]
@@ -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
+1
View File
@@ -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"]
+25 -25
View File
@@ -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<std::ptr::NonNull<u8>>,
| ^^^^^^^^^^^^^^
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 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1
View File
@@ -1,4 +1,5 @@
//@ needs-asm-support
//@ reference: asm.operand-type.supported-operands.const
use std::arch::global_asm;
+2 -2
View File
@@ -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 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1
View File
@@ -1,5 +1,6 @@
//@ needs-asm-support
//@ check-pass
//@ reference: asm.options.supported-options.noreturn
#![feature(never_type)]
#![crate_type = "rlib"]
+3
View File
@@ -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};
+70 -70
View File
@@ -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
+1
View File
@@ -1,5 +1,6 @@
//@ run-pass
//@ needs-asm-support
//@ reference: asm.scope.global_asm
#![allow(dead_code)]
+1
View File
@@ -1,4 +1,5 @@
//@ needs-asm-support
//@ reference: asm.operand-type.supported-operands.sym
use std::arch::asm;
+1 -1
View File
@@ -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<()>`
+1
View File
@@ -1,5 +1,6 @@
//@ needs-asm-support
//@ run-rustfix
//@ reference: asm.options.global_asm-restriction
use std::arch::global_asm;
+1
View File
@@ -1,5 +1,6 @@
//@ needs-asm-support
//@ run-rustfix
//@ reference: asm.options.global_asm-restriction
use std::arch::global_asm;
+3 -3
View File
@@ -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
@@ -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
@@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
+10 -1
View File
@@ -1,8 +1,10 @@
// Stable
use std::range::{RangeInclusive, RangeInclusiveIter};
use std::range::{RangeInclusive, RangeInclusiveIter, RangeToInclusive};
fn range_inclusive(mut r: RangeInclusive<usize>) {
&[1, 2, 3][r]; // Indexing
r.start;
r.last;
r.contains(&5);
@@ -14,6 +16,13 @@ fn range_inclusive(mut r: RangeInclusive<usize>) {
i.remainder();
}
fn range_to_inclusive(mut r: RangeToInclusive<usize>) {
&[1, 2, 3][r]; // Indexing
r.last;
r.contains(&5);
}
// Unstable module
use std::range::legacy; //~ ERROR unstable
+5 -5
View File
@@ -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;
| ^^^^^^^^^^^^^^^^^^^^^