diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 2a2765a436bb5..8ab80c77ff9a5 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -11,7 +11,7 @@ use tracing::{debug, trace}; use crate::{ AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, LayoutData, Niche, NonZeroUsize, NumScalableVectors, Primitive, ReprOptions, Scalar, Size, - StructKind, TagEncoding, TargetDataLayout, Variants, WrappingRange, + StructKind, TagEncoding, TargetDataLayout, VariantLayout, Variants, WrappingRange, }; mod coroutine; @@ -589,6 +589,10 @@ impl LayoutCalculator { } let calculate_niche_filling_layout = || -> Option> { + struct VariantLayoutInfo { + align_abi: Align, + } + if repr.inhibit_enum_layout_opt() { return None; } @@ -600,18 +604,22 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align; + let mut combined_seed = repr.field_shuffle_seed; + let mut variants_info = IndexVec::::with_capacity(variants.len()); let mut variant_layouts = variants - .iter_enumerated() - .map(|(j, v)| { - let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; - st.variants = Variants::Single { index: j }; + .iter() + .map(|v| { + let st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; + + variants_info.push(VariantLayoutInfo { align_abi: st.align.abi }); align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); + combined_seed = combined_seed.wrapping_add(st.randomization_seed); - Some(st) + Some(VariantLayout::from_layout(st)) }) .collect::>>()?; @@ -649,7 +657,7 @@ impl LayoutCalculator { } // Determine if it'll fit after the niche. - let this_align = layout.align.abi; + let this_align = variants_info[i].align_abi; let this_offset = (niche_offset + niche_size).align_to(this_align); if this_offset + layout.size > size { @@ -657,15 +665,8 @@ impl LayoutCalculator { } // It'll fit, but we need to make some adjustments. - match layout.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for offset in offsets.iter_mut() { - *offset += this_offset; - } - } - FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { - panic!("Layout of fields should be Arbitrary for variants") - } + for offset in layout.field_offsets.iter_mut() { + *offset += this_offset; } // It can't be a Scalar or ScalarPair because the offset isn't 0. @@ -687,7 +688,7 @@ impl LayoutCalculator { .iter_enumerated() .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO); let same_size = size == variant_layouts[largest_variant_index].size; - let same_align = align == variant_layouts[largest_variant_index].align.abi; + let same_align = align == variants_info[largest_variant_index].align_abi; let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); let abi = if same_size && same_align && others_zst { @@ -710,11 +711,6 @@ impl LayoutCalculator { BackendRepr::Memory { sized: true } }; - let combined_seed = variant_layouts - .iter() - .map(|v| v.randomization_seed) - .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); - let layout = LayoutData { variants: Variants::Multiple { tag: niche_scalar, @@ -807,6 +803,7 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align; + let mut combined_seed = repr.field_shuffle_seed; let mut size = Size::ZERO; @@ -830,14 +827,13 @@ impl LayoutCalculator { // Create the set of structs that represent each variant. let mut layout_variants = variants - .iter_enumerated() - .map(|(i, field_layouts)| { - let mut st = self.univariant( + .iter() + .map(|field_layouts| { + let st = self.univariant( field_layouts, repr, StructKind::Prefixed(min_ity.size(), prefix_align), )?; - st.variants = Variants::Single { index: i }; // Find the first field we can't move later // to make room for a larger discriminant. for field_idx in st.fields.index_by_increasing_offset() { @@ -851,7 +847,8 @@ impl LayoutCalculator { align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); - Ok(st) + combined_seed = combined_seed.wrapping_add(st.randomization_seed); + Ok(VariantLayout::from_layout(st)) }) .collect::, _>>()?; @@ -906,23 +903,16 @@ impl LayoutCalculator { let old_ity_size = min_ity.size(); let new_ity_size = ity.size(); for variant in &mut layout_variants { - match variant.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for i in offsets { - if *i <= old_ity_size { - assert_eq!(*i, old_ity_size); - *i = new_ity_size; - } - } - // We might be making the struct larger. - if variant.size <= old_ity_size { - variant.size = new_ity_size; - } - } - FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { - panic!("encountered a non-arbitrary layout during enum layout") + for i in &mut variant.field_offsets { + if *i <= old_ity_size { + assert_eq!(*i, old_ity_size); + *i = new_ity_size; } } + // We might be making the struct larger. + if variant.size <= old_ity_size { + variant.size = new_ity_size; + } } } @@ -947,12 +937,10 @@ impl LayoutCalculator { let mut common_prim = None; let mut common_prim_initialized_in_all_variants = true; for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) { - let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { - panic!("encountered a non-arbitrary layout during enum layout"); - }; // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. - let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); + let mut fields = iter::zip(field_layouts, &layout_variant.field_offsets) + .filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => { common_prim_initialized_in_all_variants = false; @@ -1047,25 +1035,17 @@ impl LayoutCalculator { for variant in &mut layout_variants { // We only do this for variants with fields; the others are not accessed anyway. // Also do not overwrite any already existing "clever" ABIs. - if variant.fields.count() > 0 - && matches!(variant.backend_repr, BackendRepr::Memory { .. }) + if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields()) { variant.backend_repr = abi; - // Also need to bump up the size and alignment, so that the entire value fits - // in here. + // Also need to bump up the size, so that the entire value fits in here. variant.size = cmp::max(variant.size, size); - variant.align.abi = cmp::max(variant.align.abi, align); } } } let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); - let combined_seed = layout_variants - .iter() - .map(|v| v.randomization_seed) - .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); - let tagged_layout = LayoutData { variants: Variants::Multiple { tag, diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 815cf1e28a08c..fd68d06c93829 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -27,7 +27,7 @@ use tracing::{debug, trace}; use crate::{ BackendRepr, FieldsShape, HasDataLayout, Integer, LayoutData, Primitive, ReprOptions, Scalar, - StructKind, TagEncoding, Variants, WrappingRange, + StructKind, TagEncoding, VariantLayout, Variants, WrappingRange, }; /// Overlap eligibility and variant assignment for each CoroutineSavedLocal. @@ -230,7 +230,6 @@ pub(super) fn layout< &ReprOptions::default(), StructKind::Prefixed(prefix_size, prefix_align.abi), )?; - variant.variants = Variants::Single { index }; let FieldsShape::Arbitrary { offsets, in_memory_order } = variant.fields else { unreachable!(); @@ -281,7 +280,7 @@ pub(super) fn layout< size = size.max(variant.size); align = align.max(variant.align); - Ok(variant) + Ok(VariantLayout::from_layout(variant)) }) .collect::, _>>()?; diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 3784611b157be..b103e1e97bd96 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -143,6 +143,34 @@ impl LayoutData { size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align, + // Variant layouts never flow back into actual layout computations, + // so dummy values are fine here. + randomization_seed: Hash64::ZERO, + } + } + + /// Returns a layout for an inhabited variant. + pub fn for_variant(parent: &Self, index: VariantIdx) -> Self { + let layout = match &parent.variants { + Variants::Multiple { variants, .. } => &variants[index], + _ => panic!("Expected multi-variant layout in `Layout::for_variant`"), + }; + + Self { + fields: FieldsShape::Arbitrary { + offsets: layout.field_offsets.clone(), + in_memory_order: layout.fields_in_memory_order.clone(), + }, + variants: Variants::Single { index }, + backend_repr: layout.backend_repr, + largest_niche: layout.largest_niche, + uninhabited: layout.uninhabited, + size: layout.size, + align: parent.align, + max_repr_align: parent.max_repr_align, + unadjusted_abi_align: parent.unadjusted_abi_align, + // Variant layouts never flow back into actual layout computations, + // so dummy values are fine here. randomization_seed: Hash64::ZERO, } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index c63575704de17..5e1a95d620f2a 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1953,7 +1953,7 @@ pub enum Variants { tag: Scalar, tag_encoding: TagEncoding, tag_field: FieldIdx, - variants: IndexVec>, + variants: IndexVec>, }, } @@ -2319,3 +2319,40 @@ pub enum AbiFromStrErr { /// no "-unwind" variant can be used here NoExplicitUnwind, } + +// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +#[cfg_attr(feature = "nightly", derive(StableHash))] +pub struct VariantLayout { + pub size: Size, + pub backend_repr: BackendRepr, + pub field_offsets: IndexVec, + fields_in_memory_order: IndexVec, + largest_niche: Option, + uninhabited: bool, +} + +impl VariantLayout { + pub fn from_layout(layout: LayoutData) -> Self { + let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else { + panic!("Layout of fields should be Arbitrary for variants"); + }; + + Self { + size: layout.size, + backend_repr: layout.backend_repr, + field_offsets: offsets, + fields_in_memory_order: in_memory_order, + largest_niche: layout.largest_niche, + uninhabited: layout.uninhabited, + } + } + + pub fn is_uninhabited(&self) -> bool { + self.uninhabited + } + + pub fn has_fields(&self) -> bool { + self.field_offsets.len() > 0 + } +} diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index d823e209fd7d9..6fb25174bf1e0 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -6,7 +6,6 @@ use std::iter; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp}; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; -use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::errors::InvalidMonomorphization; @@ -18,6 +17,7 @@ use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; +use rustc_codegen_ssa::{MemFlags, RetagInfo}; use rustc_data_structures::fx::FxHashSet; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; @@ -702,6 +702,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc // FIXME(antoyo): implement. self.context.new_rvalue_from_int(self.int_type, 0) } + + fn retag_reg(&mut self, _ptr: Self::Value, _info: &RetagInfo) -> Self::Value { + unimplemented!() + } + + fn retag_mem(&mut self, _ptr: Self::Value, _info: &RetagInfo) { + unimplemented!() + } } impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 5b730b820b84a..3e575f969afab 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -959,22 +959,47 @@ impl<'ll> CodegenCx<'ll, '_> { base_name: &str, type_params: &[&'ll Type], ) -> (&'ll Type, &'ll Value) { - // This isn't an "LLVM intrinsic", but LLVM's optimization passes - // recognize it like one (including turning it into `bcmp` sometimes) - // and we use it to implement intrinsics like `raw_eq` and `compare_bytes` - if base_name == "memcmp" { - let fn_ty = self - .type_func(&[self.type_ptr(), self.type_ptr(), self.type_isize()], self.type_int()); - let f = self.declare_cfn("memcmp", llvm::UnnamedAddr::No, fn_ty); - - return (fn_ty, f); - } - - let intrinsic = llvm::Intrinsic::lookup(base_name.as_bytes()) - .unwrap_or_else(|| bug!("Unknown intrinsic: `{base_name}`")); - let f = intrinsic.get_declaration(self.llmod, &type_params); + match base_name { + // This isn't an "LLVM intrinsic", but LLVM's optimization passes + // recognize it like one (including turning it into `bcmp` sometimes) + // and we use it to implement intrinsics like `raw_eq` and `compare_bytes` + "memcmp" => { + let fn_ty = self.type_func( + &[self.type_ptr(), self.type_ptr(), self.type_isize()], + self.type_int(), + ); + let f = self.declare_cfn("memcmp", llvm::UnnamedAddr::No, fn_ty); - (self.get_type_of_global(f), f) + (fn_ty, f) + } + // Experimental retag intrinsics. + // This form is used to retag a pointer that has already been stored in a register. It receives + // the pointer and returns an alias with the same address, but different provenance. + "__rust_retag_reg" => { + let fn_ty = self.type_func(type_params, self.type_ptr()); + let llfn = self.declare_cfn(base_name, llvm::UnnamedAddr::No, fn_ty); + let nounwind = llvm::AttributeKind::NoUnwind.create_attr(self.llcx); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[nounwind]); + (fn_ty, llfn) + } + // This form is used to retag a pointer that is stored in another place. It receives a pointer to the + // place and returns `void`. This communicates the indirection without requiring an explicit load and + // store. If we used the `reg` form instead, then we would need to load the place, retag it, and then + // store the result back, which would be undefined behavior for `readonly` places. + "__rust_retag_mem" => { + let fn_ty = self.type_func(type_params, self.type_void()); + let llfn = self.declare_cfn(base_name, llvm::UnnamedAddr::No, fn_ty); + let nounwind = llvm::AttributeKind::NoUnwind.create_attr(self.llcx); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[nounwind]); + (fn_ty, llfn) + } + _ => { + let intrinsic = llvm::Intrinsic::lookup(base_name.as_bytes()) + .unwrap_or_else(|| bug!("Unknown intrinsic: `{base_name}`")); + let f = intrinsic.get_declaration(self.llmod, &type_params); + (self.get_type_of_global(f), f) + } + } } pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index f2b90403403d1..ec6f068f46580 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -6,6 +6,7 @@ use rustc_abi::{ AddressSpace, Align, BackendRepr, CVariadicStatus, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size, WrappingRange, }; +use rustc_codegen_ssa::RetagInfo; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization}; @@ -1047,6 +1048,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn va_end(&mut self, va_list: &'ll Value) -> &'ll Value { self.call_intrinsic("llvm.va_end", &[self.val_ty(va_list)], &[va_list]) } + + fn retag_reg(&mut self, ptr: Self::Value, info: &RetagInfo) -> Self::Value { + codegen_retag_inner(self, "__rust_retag_reg", ptr, info) + } + + fn retag_mem(&mut self, ptr: Self::Value, info: &RetagInfo) { + codegen_retag_inner(self, "__rust_retag_mem", ptr, info); + } } fn llvm_arch_for(rust_arch: &Arch) -> Option<&'static str> { @@ -1763,6 +1772,24 @@ fn get_rust_try_fn<'a, 'll, 'tcx>( rust_try } +fn codegen_retag_inner<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + name: &'static str, + ptr: &'ll Value, + info: &RetagInfo<&'ll Value>, +) -> &'ll Value { + let size = bx.const_usize(info.size.bytes()); + let perms = bx.const_u8(info.flags.bits()); + + bx.call_intrinsic( + name, + // Retag intrinsics have special handling within `CodegenCx::declare_intrinsic` + // to ensure that each form has the correct return type. + &[bx.type_ptr(), bx.val_ty(size), bx.type_i8(), bx.type_ptr(), bx.type_ptr()], + &[ptr, size, perms, info.im_layout, info.pin_layout], + ) +} + fn codegen_autodiff<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index ec1eb7eeb6fc0..c7446bd784b40 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -17,6 +17,7 @@ use std::io; use std::path::{Path, PathBuf}; use std::sync::Arc; +use rustc_abi::Size; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_hir::CRATE_HIR_ID; @@ -26,7 +27,7 @@ use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::{Decodable, Encodable}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProduct; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::StableLevelSpec; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; @@ -167,6 +168,37 @@ bitflags::bitflags! { } } +#[derive(Debug, Copy, Clone)] +pub struct RetagInfo { + /// The size of the initial range within the allocation that is + /// associated with the permission created by the retag. + pub size: Size, + /// Encoded type information used to determine the kind of permission + /// created by the retag. + pub flags: RetagFlags, + /// A pointer to a constant array of (offset, size) pairs describing + /// the ranges covered by `UnsafeCell` within the pointee type. + pub im_layout: V, + /// A pointer to a constant array of (offset, size) pairs describing + /// the ranges covered by `UnsafePinned` within the pointee type. + pub pin_layout: V, +} + +bitflags::bitflags! { + #[repr(C)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub struct RetagFlags: u8 { + /// If this is a function-entry retag. + const IS_PROTECTED = 1 << 0; + /// If this is a mutable reference or a `Box`. + const IS_MUTABLE = 1 << 1; + /// If this is a `Box`. + const IS_BOX = 1 << 2; + /// If the pointee type is `Freeze` + const IS_FREEZE = 1 << 3; + } +} + // This is the same as `rustc_session::cstore::NativeLib`, except: // - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't // be encoded with `FileEncoder`. @@ -342,8 +374,8 @@ impl CompiledModules { /// Instead, encode exactly the information we need. #[derive(Copy, Clone, Debug, Encodable, Decodable)] pub struct CodegenLintLevelSpecs { - linker_messages: LevelSpec, - linker_info: LevelSpec, + linker_messages: StableLevelSpec, + linker_info: StableLevelSpec, } impl CodegenLintLevelSpecs { diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index d1e6436f6b1eb..fffd9b75f2bf7 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -2,6 +2,7 @@ use rustc_middle::ty; use rustc_span::Span; use super::BackendTypes; +use crate::RetagInfo; use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; @@ -49,4 +50,8 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { /// Trait method used to inject `va_end` on the "spoofed" `VaList` before /// Rust defined C-variadic functions return. fn va_end(&mut self, val: Self::Value) -> Self::Value; + /// Trait method used to retag a pointer stored within a place. + fn retag_mem(&mut self, place: Self::Value, info: &RetagInfo); + /// Trait method used to retag a pointer that has been loaded into a register. + fn retag_reg(&mut self, ptr: Self::Value, info: &RetagInfo) -> Self::Value; } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5454b282d5226..6e4d6aa80a63a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -40,6 +40,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_semicolon_in_repeat_expr(err, expr, expr_ty) || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) || self.suggest_option_to_bool(err, expr, expr_ty, expected) + || self.suggest_collect(err, expr, expected, expr_ty) || self.suggest_compatible_variants(err, expr, expected, expr_ty) || self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty) || self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 955ce5a6b58b5..323f0fb040d6b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -250,6 +250,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Suggests calling `.collect()` on an `Iterator` it can be collected in the return type + /// ```compile_fail + /// let x: String = "foo".chars().map(|c| c); // with a .collect() here the code compiles + /// ``` + pub(crate) fn suggest_collect( + &self, + err: &mut Diag<'_>, + expr: &hir::Expr<'_>, + expected_type: Ty<'tcx>, + found_type: Ty<'tcx>, + ) -> bool { + let tcx = self.tcx; + let expected = self.resolve_vars_if_possible(expected_type); + let found = self.resolve_vars_if_possible(found_type); + + if expected.references_error() || found.references_error() || expected.is_unit() { + return false; + } + + let Some(iterator_trait_id) = tcx.get_diagnostic_item(sym::Iterator) else { + return false; + }; + + if !self + .infcx + .type_implements_trait(iterator_trait_id, [found], self.param_env) + .must_apply_modulo_regions() + { + return false; + } + + let Some(from_iterator_trait_id) = tcx.get_diagnostic_item(sym::FromIterator) else { + return false; + }; + + let Some(iterator_item_id) = tcx + .associated_items(iterator_trait_id) + .in_definition_order() + .find(|item| item.name() == sym::Item) + .map(|item| item.def_id) + else { + return false; + }; + + let item_type = Ty::new_projection(tcx, iterator_item_id, [found]); + let item_type = + self.normalize(expr.span, rustc_middle::ty::Unnormalized::new_wip(item_type)); + + let can_collect = self + .infcx + .type_implements_trait(from_iterator_trait_id, [expected, item_type], self.param_env) + .may_apply(); + + if can_collect { + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + format!( + "consider using `.collect()` to convert the `Iterator` into a `{expected}`" + ), + ".collect()", + rustc_errors::Applicability::MaybeIncorrect, + ); + return true; + } + + false + } + pub(crate) fn suggest_remove_last_method_call( &self, err: &mut Diag<'_>, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 4825b61bc6e41..3cbd02e2ed8d9 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -20,14 +20,17 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::{Pat, PatKind}; use rustc_middle::bug; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::{LevelSpec, StableLevelSpec, UnstableLevelSpec}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; use rustc_middle::ty::{ self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode, Unnormalized, }; -use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintExpectationId, LintId}; +use rustc_session::lint::{ + FutureIncompatibleInfo, Lint, LintExpectationId, LintId, StableLintExpectationId, + UnstableLintExpectationId, +}; use rustc_session::{DynLintStore, Session}; use rustc_span::edit_distance::find_best_match_for_names; use rustc_span::{Ident, Span, Symbol, sym}; @@ -510,6 +513,8 @@ pub struct EarlyContext<'a> { } pub trait LintContext { + type LintExpectationId: Copy + Into; + fn sess(&self) -> &Session; // FIXME: These methods should not take an Into -- instead, callers should need to @@ -538,7 +543,7 @@ pub trait LintContext { } /// This returns the lint level spec for the given lint at the current location. - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec; + fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec; /// This function can be used to manually fulfill an expectation. This can /// be used for lints which contain several spans, and should be suppressed, @@ -547,7 +552,7 @@ pub trait LintContext { /// Note that this function should only be called for [`LintExpectationId`]s /// retrieved from the current lint pass. Buffered or manually created ids can /// cause ICEs. - fn fulfill_expectation(&self, expectation: LintExpectationId) { + fn fulfill_expectation(&self, expectation: Self::LintExpectationId) { // We need to make sure that submitted expectation ids are correctly fulfilled suppressed // and stored between compilation sessions. To not manually do these steps, we simply create // a dummy diagnostic and emit it as usual, which will be suppressed and stored like a @@ -556,7 +561,7 @@ pub trait LintContext { .dcx() .struct_expect( "this is a dummy diagnostic, to submit and store an expectation", - expectation, + expectation.into(), ) .emit(); } @@ -585,6 +590,8 @@ impl<'a> EarlyContext<'a> { } impl<'tcx> LintContext for LateContext<'tcx> { + type LintExpectationId = StableLintExpectationId; + /// Gets the overall compiler `Session` object. fn sess(&self) -> &Session { self.tcx.sess @@ -604,12 +611,14 @@ impl<'tcx> LintContext for LateContext<'tcx> { } } - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint) -> StableLevelSpec { self.tcx.lint_level_spec_at_node(lint, self.last_node_with_lint_attrs) } } impl LintContext for EarlyContext<'_> { + type LintExpectationId = UnstableLintExpectationId; + /// Gets the overall compiler `Session` object. fn sess(&self) -> &Session { self.builder.sess() @@ -624,7 +633,7 @@ impl LintContext for EarlyContext<'_> { self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorator) } - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint) -> UnstableLevelSpec { self.builder.lint_level_spec(lint) } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 903e223e97938..df6683c14df42 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -53,7 +53,7 @@ impl<'ecx, T: EarlyLintPass> EarlyContextAndPass<'ecx, T> { { let is_crate_node = id == ast::CRATE_NODE_ID; debug!(?id); - let push = self.context.builder.push(attrs, is_crate_node, None); + let push = self.context.builder.push(attrs, is_crate_node); debug!("early context: enter_attrs({:?})", attrs); lint_callback!(self, check_attributes, attrs); diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 481e116d06e01..5364a4141805b 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -2,8 +2,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::lint::LintExpectation; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_session::lint::LintExpectationId; use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS; +use rustc_session::lint::{LintExpectationId, StableLintExpectationId}; use rustc_span::Symbol; use crate::lints::{Expectation, ExpectationNote}; @@ -12,7 +12,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { lint_expectations, check_expectations, ..*providers }; } -fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> { +fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(StableLintExpectationId, LintExpectation)> { let krate = tcx.hir_crate_items(()); let mut expectations = Vec::new(); @@ -31,30 +31,22 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { // Turn a `LintExpectationId` into a `(AttrId, lint_index)` pair. let canonicalize_id = |expect_id: &LintExpectationId| { - match *expect_id { - LintExpectationId::Unstable { attr_id, lint_index: Some(lint_index) } => { - (attr_id, lint_index) - } - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { + let (attr_id, lint_index) = match *expect_id { + LintExpectationId::Unstable(id) => (id.attr_id, id.lint_index), + LintExpectationId::Stable(id) => { // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok. - let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id(); - - (attr_id, lint_index) + (tcx.hir_attrs(id.hir_id)[id.attr_index as usize].id(), id.lint_index) } - _ => panic!("fulfilled expectations must have a lint index"), - } + }; + (attr_id, lint_index.expect("fulfilled expectations must have a lint index")) }; let fulfilled_expectations: FxHashSet<_> = fulfilled_expectations.iter().map(canonicalize_id).collect(); for (expect_id, expectation) in lint_expectations { - // This check will always be true, since `lint_expectations` only holds stable ids - let LintExpectationId::Stable { hir_id, .. } = expect_id else { - unreachable!("at this stage all `LintExpectationId`s are stable"); - }; - - let expect_id = canonicalize_id(expect_id); + let hir_id = expect_id.hir_id; + let expect_id = canonicalize_id(&LintExpectationId::Stable(*expect_id)); if !fulfilled_expectations.contains(&expect_id) && tool_filter.is_none_or(|filter| expectation.lint_tool == Some(filter)) @@ -63,7 +55,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { let note = expectation.is_unfulfilled_lint_expectations; tcx.emit_node_span_lint( UNFULFILLED_LINT_EXPECTATIONS, - *hir_id, + hir_id, expectation.emission_span, Expectation { rationale, note }, ); diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 3cc0d46d8541f..0a074c6652a1d 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -439,14 +439,6 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { filtered_passes.push(Box::new(HardwiredLints)); let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] }; - late_lint_crate_inner(tcx, context, pass); -} - -fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( - tcx: TyCtxt<'tcx>, - context: LateContext<'tcx>, - pass: T, -) { let mut cx = LateContextAndPass { context, pass }; // Visit the whole crate. diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index ad74b0ee906a1..b8da46594cfc2 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use rustc_ast as ast; use rustc_ast::attr::AttributeExt; use rustc_ast_pretty::pprust; @@ -11,8 +13,8 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_index::IndexVec; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ - LevelSpec, LintExpectation, LintLevelSource, ShallowLintLevelMap, emit_lint_base, - reveal_actual_level_spec, + LevelSpec, LintExpectation, LintLevelSource, ShallowLintLevelMap, StableLevelSpec, + UnstableLevelSpec, emit_lint_base, reveal_actual_level_spec, }; use rustc_middle::query::Providers; use rustc_middle::ty::{RegisteredTools, TyCtxt}; @@ -21,8 +23,10 @@ use rustc_session::lint::builtin::{ self, FORBIDDEN_LINT_GROUPS, RENAMED_AND_REMOVED_LINTS, SINGLE_USE_LIFETIMES, UNFULFILLED_LINT_EXPECTATIONS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES, }; -use rustc_session::lint::{Level, Lint, LintExpectationId, LintId}; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_session::lint::{ + Level, Lint, LintExpectationId, LintId, StableLintExpectationId, UnstableLintExpectationId, +}; +use rustc_span::{AttrId, DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builtin::MISSING_DOCS; @@ -64,9 +68,7 @@ rustc_index::newtype_index! { /// to find the specifications for a given lint. #[derive(Debug)] struct LintSet { - // -A,-W,-D flags, a `Symbol` for the flag itself and `LevelSpec` for which - // flag. - specs: FxIndexMap, + specs: FxIndexMap, parent: LintStackIndex, } @@ -79,9 +81,9 @@ impl LintLevelSets { &self, lint: &'static Lint, idx: LintStackIndex, - aux: Option<&FxIndexMap>, + aux: Option<&FxIndexMap>, sess: &Session, - ) -> LevelSpec { + ) -> UnstableLevelSpec { reveal_actual_level_spec(sess, LintId::of(lint), |id| { self.raw_lint_level_spec(id, idx, aux) }) @@ -91,8 +93,8 @@ impl LintLevelSets { &self, id: LintId, mut idx: LintStackIndex, - aux: Option<&FxIndexMap>, - ) -> Option { + aux: Option<&FxIndexMap>, + ) -> Option { if let Some(specs) = aux && let Some(level_spec) = specs.get(&id) { @@ -213,26 +215,53 @@ pub struct TopDown { } pub trait LintLevelsProvider { - fn current_specs(&self) -> &FxIndexMap; - fn insert(&mut self, id: LintId, level_spec: LevelSpec); - fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> LevelSpec; - fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation); + type LintExpectationId: Copy + Debug + Into; + + fn current_specs(&self) -> &FxIndexMap>; + + fn insert(&mut self, id: LintId, level_spec: LevelSpec); + + fn get_lint_level_spec( + &self, + lint: &'static Lint, + sess: &Session, + ) -> LevelSpec; + + fn push_expectation(&mut self, id: Self::LintExpectationId, expectation: LintExpectation); + + fn mk_lint_expectation_id( + &self, + attr_id: AttrId, + attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId; } impl LintLevelsProvider for TopDown { - fn current_specs(&self) -> &FxIndexMap { + type LintExpectationId = UnstableLintExpectationId; + + fn current_specs(&self) -> &FxIndexMap { &self.sets.list[self.cur].specs } - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { + fn insert(&mut self, id: LintId, level_spec: UnstableLevelSpec) { self.sets.list[self.cur].specs.insert(id, level_spec); } - fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> UnstableLevelSpec { self.sets.get_lint_level_spec(lint, self.cur, Some(self.current_specs()), sess) } - fn push_expectation(&mut self, _: LintExpectationId, _: LintExpectation) {} + fn push_expectation(&mut self, _: Self::LintExpectationId, _: LintExpectation) {} + + fn mk_lint_expectation_id( + &self, + attr_id: AttrId, + _attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId { + UnstableLintExpectationId { attr_id, lint_index } + } } struct LintLevelQueryMap<'tcx> { @@ -240,33 +269,44 @@ struct LintLevelQueryMap<'tcx> { cur: HirId, specs: ShallowLintLevelMap, /// Empty hash map to simplify code. - empty: FxIndexMap, + empty: FxIndexMap, attrs: &'tcx hir::AttributeMap<'tcx>, } impl LintLevelsProvider for LintLevelQueryMap<'_> { - fn current_specs(&self) -> &FxIndexMap { + type LintExpectationId = StableLintExpectationId; + + fn current_specs(&self) -> &FxIndexMap { self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty) } - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { + + fn insert(&mut self, id: LintId, level_spec: StableLevelSpec) { self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, level_spec); } - fn get_lint_level_spec(&self, lint: &'static Lint, _: &Session) -> LevelSpec { + + fn get_lint_level_spec(&self, lint: &'static Lint, _: &Session) -> StableLevelSpec { self.specs.lint_level_spec_at_node(self.tcx, LintId::of(lint), self.cur) } - fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) { + + fn push_expectation(&mut self, id: Self::LintExpectationId, expectation: LintExpectation) { self.specs.expectations.push((id, expectation)) } + + fn mk_lint_expectation_id( + &self, + _attr_id: AttrId, + attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId { + let attr_index = attr_index.try_into().unwrap(); + StableLintExpectationId { hir_id: self.cur, attr_index, lint_index } + } } impl<'tcx> LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> { fn add_id(&mut self, hir_id: HirId) { self.provider.cur = hir_id; - self.add( - self.provider.attrs.get(hir_id.local_id), - hir_id == hir::CRATE_HIR_ID, - Some(hir_id), - ); + self.add(self.provider.attrs.get(hir_id.local_id), hir_id == hir::CRATE_HIR_ID); } } @@ -386,7 +426,7 @@ impl<'s> LintLevelsBuilder<'s, TopDown> { crate_attrs: &[ast::Attribute], ) -> Self { let mut builder = Self::new(sess, features, lint_added_lints, store, registered_tools); - builder.add(crate_attrs, true, None); + builder.add(crate_attrs, true); builder } @@ -413,17 +453,12 @@ impl<'s> LintLevelsBuilder<'s, TopDown> { /// `#[allow]` /// /// Don't forget to call `pop`! - pub(crate) fn push( - &mut self, - attrs: &[ast::Attribute], - is_crate_node: bool, - source_hir_id: Option, - ) -> BuilderPush { + pub(crate) fn push(&mut self, attrs: &[ast::Attribute], is_crate_node: bool) -> BuilderPush { let prev = self.provider.cur; self.provider.cur = self.provider.sets.list.push(LintSet { specs: FxIndexMap::default(), parent: prev }); - self.add(attrs, is_crate_node, source_hir_id); + self.add(attrs, is_crate_node); if self.provider.current_specs().is_empty() { self.provider.sets.list.pop(); @@ -447,7 +482,10 @@ impl Drop for BuilderPush { } } -impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { +impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> +where + LevelSpec: Into, +{ pub(crate) fn sess(&self) -> &Session { self.sess } @@ -456,14 +494,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { self.features } - fn current_specs(&self) -> &FxIndexMap { - self.provider.current_specs() - } - - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { - self.provider.insert(id, level_spec) - } - fn add_command_line(&mut self) { for &(ref lint_name, level) in &self.sess.opts.lint_opts { // Checks the validity of lint names derived from the command line. @@ -520,7 +550,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { }; for &id in ids { // ForceWarn and Forbid cannot be overridden - if let Some(level_spec) = self.current_specs().get(&id) + if let Some(level_spec) = self.provider.current_specs().get(&id) && matches!(level_spec.level(), Level::ForceWarn | Level::Forbid) { continue; @@ -528,7 +558,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { if self.check_gated_lint(id, DUMMY_SP, true) { let src = LintLevelSource::CommandLine(lint_flag_val, level); - self.insert(id, LevelSpec::new(level, None, src)); + self.provider.insert(id, LevelSpec::new(level, None, src)); } } } @@ -537,7 +567,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Attempts to insert the `id` to `LevelSpec` map entry. If unsuccessful /// (e.g. if a forbid was already inserted on the same scope), then emits a /// diagnostic with no change to `specs`. - fn insert_spec(&mut self, id: LintId, level_spec: LevelSpec) { + fn insert_spec(&mut self, id: LintId, level_spec: LevelSpec) { let level = level_spec.level(); let lint_id = level_spec.lint_id(); let src = level_spec.src; @@ -562,7 +592,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // as preventing `allow(lint)` for some lint `lint` in // `lint_group`. For now, issue a future-compatibility // warning for this case. - let id_name = id.lint.name_lower(); let fcw_warning = match old_src { LintLevelSource::Default => false, LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), @@ -571,9 +600,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { debug!( "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}", fcw_warning, - self.current_specs(), + self.provider.current_specs(), old_src, - id_name + id.lint.name_lower(), ); let sub = match old_src { LintLevelSource::Default => { @@ -627,27 +656,22 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { match (old_level, level) { // If the new level is an expectation store it in `ForceWarn` (Level::ForceWarn, Level::Expect) => { - self.insert(id, LevelSpec::new(Level::ForceWarn, lint_id, old_src)) + self.provider.insert(id, LevelSpec::new(Level::ForceWarn, lint_id, old_src)) } // Keep `ForceWarn` level but drop the expectation (Level::ForceWarn, _) => { - self.insert(id, LevelSpec::new(Level::ForceWarn, None, old_src)) + self.provider.insert(id, LevelSpec::new(Level::ForceWarn, None, old_src)) } // Set the lint level as normal - _ => self.insert(id, LevelSpec::new(level, lint_id, src)), + _ => self.provider.insert(id, LevelSpec::new(level, lint_id, src)), }; } - fn add( - &mut self, - attrs: &[impl AttributeExt], - is_crate_node: bool, - source_hir_id: Option, - ) { + fn add(&mut self, attrs: &[impl AttributeExt], is_crate_node: bool) { let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { if attr.is_automatically_derived_attr() { - self.insert( + self.provider.insert( LintId::of(SINGLE_USE_LIFETIMES), LevelSpec::new(Level::Allow, None, LintLevelSource::Default), ); @@ -656,30 +680,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // `#[doc(hidden)]` disables missing_docs check. if attr.is_doc_hidden() { - self.insert( + self.provider.insert( LintId::of(MISSING_DOCS), LevelSpec::new(Level::Allow, None, LintLevelSource::Default), ); continue; } - let (level, lint_id) = match Level::from_opt_symbol(attr.name()) { + let level = match Level::from_opt_symbol(attr.name()) { None => continue, - // `Expect` is the only lint level with a `LintExpectationId` that can be created - // from an attribute. - Some(Level::Expect) => { - let id = if let Some(hir_id) = source_hir_id { - LintExpectationId::Stable { - hir_id, - attr_index: attr_index.try_into().unwrap(), - lint_index: None, - } - } else { - LintExpectationId::Unstable { attr_id: attr.id(), lint_index: None } - }; - (Level::Expect, Some(id)) - } - Some(level) => (level, None), + Some(level) => level, }; let Some(mut metas) = attr.meta_item_list() else { continue }; @@ -727,10 +737,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } for (lint_index, li) in metas.iter_mut().enumerate() { - let mut lint_id = lint_id; - if let Some(id) = &mut lint_id { - id.set_lint_index(Some(lint_index as u16)); - } + // `Expect` is the only lint level with a `LintExpectationId` that can be created + // from an attribute. + let lint_id = (level == Level::Expect).then(|| { + self.provider.mk_lint_expectation_id( + attr.id(), + attr_index, + Some(lint_index as u16), + ) + }); let sp = li.span(); let meta_item = match li { @@ -902,7 +917,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } if self.lint_added_lints && !is_crate_node { - for (id, level_spec) in self.current_specs().iter() { + for (id, level_spec) in self.provider.current_specs().iter() { if !id.lint.crate_level_only { continue; } @@ -988,7 +1003,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } /// Find the lint level for a lint. - pub fn lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + pub fn lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { self.provider.get_lint_level_spec(lint, self.sess) } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 6d9f486f627f6..091b7ac228b54 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2669,6 +2669,12 @@ pub(crate) struct RefOfMutStatic<'a> { "mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives" )] pub mut_note: bool, + #[help( + "use a type that relies on \"interior mutability\" instead; to read more on this, visit " + )] + pub interior_mutability_help: bool, + #[subdiagnostic] + pub interior_mutability_sugg: Option, } #[derive(Subdiagnostic)] @@ -2693,6 +2699,18 @@ pub(crate) enum MutRefSugg { }, } +#[derive(Subdiagnostic)] +#[suggestion( + "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable", + style = "verbose", + applicability = "maybe-incorrect", + code = "" +)] +pub(crate) struct StaticMutRefsInteriorMutabilitySugg { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")] pub(crate) struct UnqualifiedLocalImportsDiag; diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 1decb4b78e61a..67e83d0652c3d 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -1,11 +1,12 @@ use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_hir::{Expr, Stmt}; use rustc_middle::ty::{Mutability, TyKind}; use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{BytePos, Span}; -use crate::lints::{MutRefSugg, RefOfMutStatic}; +use crate::lints::{MutRefSugg, RefOfMutStatic, StaticMutRefsInteriorMutabilitySugg}; use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { @@ -67,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { match expr.kind { hir::ExprKind::AddrOf(borrow_kind, m, ex) if matches!(borrow_kind, hir::BorrowKind::Ref) - && let Some(err_span) = path_is_static_mut(ex, err_span) => + && let Some(static_mut) = path_is_static_mut(ex, err_span) => { let source_map = cx.sess().source_map(); let snippet = source_map.span_to_snippet(err_span); @@ -86,10 +87,17 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { err_span.with_hi(ex.span.lo()) }; - emit_static_mut_refs(cx, err_span, sugg_span, m, !expr.span.from_expansion()); + emit_static_mut_refs( + cx, + static_mut.err_span, + sugg_span, + m, + !expr.span.from_expansion(), + static_mut.def_id, + ); } hir::ExprKind::MethodCall(_, e, _, _) - if let Some(err_span) = path_is_static_mut(e, expr.span) + if let Some(static_mut) = path_is_static_mut(e, expr.span) && let typeck = cx.typeck_results() && let Some(method_def_id) = typeck.type_dependent_def_id(expr.hir_id) && let inputs = @@ -97,7 +105,14 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { && let Some(receiver) = inputs.get(0) && let TyKind::Ref(_, _, m) = receiver.kind() => { - emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), *m, false); + emit_static_mut_refs( + cx, + static_mut.err_span, + static_mut.err_span.shrink_to_lo(), + *m, + false, + static_mut.def_id, + ); } _ => {} } @@ -108,14 +123,26 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(_, m) = ba.0 && let Some(init) = loc.init - && let Some(err_span) = path_is_static_mut(init, init.span) + && let Some(static_mut) = path_is_static_mut(init, init.span) { - emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), m, false); + emit_static_mut_refs( + cx, + static_mut.err_span, + static_mut.err_span.shrink_to_lo(), + m, + false, + static_mut.def_id, + ); } } } -fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { +struct StaticMutInfo { + err_span: Span, + def_id: DefId, +} + +fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { if err_span.from_expansion() { err_span = expr.span; } @@ -126,11 +153,11 @@ fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { @@ -155,9 +183,106 @@ fn emit_static_mut_refs( } }; + let (interior_mutability_help, interior_mutability_sugg) = + interior_mutability_suggestion(cx, def_id); + cx.emit_span_lint( STATIC_MUT_REFS, span, - RefOfMutStatic { span, sugg, shared_label, shared_note, mut_note }, + RefOfMutStatic { + span, + sugg, + shared_label, + shared_note, + mut_note, + interior_mutability_help, + interior_mutability_sugg, + }, ); } + +// FIXME: This builds suggestion spans by handcrafting from source text. +// Replace this with HIR-based handling once we can identify the `mut` token +// in the static declaration that way. +// Context: https://github.com/rust-lang/rust/pull/151362/changes#r3210767018 +fn interior_mutability_suggestion( + cx: &LateContext<'_>, + def_id: DefId, +) -> (bool, Option) { + let static_ty = cx.tcx.type_of(def_id).skip_binder(); + let has_interior_mutability = !static_ty.is_freeze(cx.tcx, cx.typing_env()); + + if !has_interior_mutability { + return (false, None); + } + + let sugg = + static_mutability_span(cx, def_id).map(|span| StaticMutRefsInteriorMutabilitySugg { span }); + (sugg.is_none(), sugg) +} + +fn static_mutability_span(cx: &LateContext<'_>, def_id: DefId) -> Option { + let hir_id = cx.tcx.hir_get_if_local(def_id)?; + let hir::Node::Item(item) = hir_id else { return None }; + let (mutability, ident) = match item.kind { + hir::ItemKind::Static(mutability, ident, _, _) => (mutability, ident), + _ => return None, + }; + if mutability != hir::Mutability::Mut { + return None; + } + + let vis_span = item.vis_span.find_ancestor_inside(item.span)?; + if !item.span.can_be_used_for_suggestions() || !vis_span.can_be_used_for_suggestions() { + return None; + } + + let header_span = vis_span.between(ident.span); + if !header_span.can_be_used_for_suggestions() { + return None; + } + + let source_map = cx.sess().source_map(); + let snippet = source_map.span_to_snippet(header_span).ok()?; + + let (_static_start, static_end) = find_word(&snippet, "static", 0)?; + let (mut_start, mut_end) = find_word(&snippet, "mut", static_end)?; + let mut_end = extend_trailing_space(&snippet, mut_end); + + Some( + header_span + .with_lo(header_span.lo() + BytePos(mut_start as u32)) + .with_hi(header_span.lo() + BytePos(mut_end as u32)), + ) +} + +fn find_word(snippet: &str, word: &str, start: usize) -> Option<(usize, usize)> { + let bytes = snippet.as_bytes(); + let word_bytes = word.as_bytes(); + let mut search = start; + while search <= snippet.len() { + let found = snippet[search..].find(word)?; + let idx = search + found; + let end = idx + word_bytes.len(); + let before_ok = idx == 0 || !is_ident_char(bytes[idx - 1]); + let after_ok = end >= bytes.len() || !is_ident_char(bytes[end]); + if before_ok && after_ok { + return Some((idx, end)); + } + search = end; + } + None +} + +fn is_ident_char(byte: u8) -> bool { + byte.is_ascii_alphanumeric() || byte == b'_' +} + +fn extend_trailing_space(snippet: &str, mut end: usize) -> usize { + if let Some(ch) = snippet[end..].chars().next() + && (ch == ' ' || ch == '\t') + { + end += ch.len_utf8(); + } + end +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 2e690c7185f8c..fc8b2b65a8d48 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -100,47 +100,48 @@ pub enum Applicability { /// have that amount of lints listed. `u16` values should therefore suffice. #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] pub enum LintExpectationId { - /// Used for lints emitted during the `EarlyLintPass`. This id is not - /// hash stable and should not be cached. - Unstable { attr_id: AttrId, lint_index: Option }, - /// The [`HirId`] that the lint expectation is attached to. This id is - /// stable and can be cached. The additional index ensures that nodes with - /// several expectations can correctly match diagnostics to the individual - /// expectation. - Stable { hir_id: HirId, attr_index: u16, lint_index: Option }, -} - -impl LintExpectationId { - pub fn is_stable(&self) -> bool { - match self { - LintExpectationId::Unstable { .. } => false, - LintExpectationId::Stable { .. } => true, - } - } + Unstable(UnstableLintExpectationId), + Stable(StableLintExpectationId), +} - pub fn set_lint_index(&mut self, new_lint_index: Option) { - let (LintExpectationId::Unstable { lint_index, .. } - | LintExpectationId::Stable { lint_index, .. }) = self; +/// Used for lints emitted during the `EarlyLintPass`. This id is not hash +/// stable and should not be cached. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] +pub struct UnstableLintExpectationId { + pub attr_id: AttrId, + pub lint_index: Option, +} - *lint_index = new_lint_index +impl From for LintExpectationId { + fn from(id: UnstableLintExpectationId) -> LintExpectationId { + LintExpectationId::Unstable(id) } } -impl StableHash for LintExpectationId { +/// The [`HirId`] that the lint expectation is attached to. This id is stable +/// and can be cached. The additional index ensures that nodes with several +/// expectations can correctly match diagnostics to the individual expectation. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] +pub struct StableLintExpectationId { + pub hir_id: HirId, + pub attr_index: u16, + pub lint_index: Option, +} + +impl StableHash for StableLintExpectationId { #[inline] fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - match self { - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { - hir_id.stable_hash(hcx, hasher); - attr_index.stable_hash(hcx, hasher); - lint_index.stable_hash(hcx, hasher); - } - _ => { - unreachable!( - "StableHash should only be called for filled and stable `LintExpectationId`" - ) - } - } + let StableLintExpectationId { hir_id, attr_index, lint_index } = self; + + hir_id.stable_hash(hcx, hasher); + attr_index.stable_hash(hcx, hasher); + lint_index.expect("must be filled to call `stable_hash`").stable_hash(hcx, hasher); + } +} + +impl From for LintExpectationId { + fn from(id: StableLintExpectationId) -> LintExpectationId { + LintExpectationId::Stable(id) } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 41eeb1fc9811f..aa4b8f1d12c9f 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -8,7 +8,8 @@ use rustc_lint_defs::EditionFcw; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_session::Session; use rustc_session::lint::{ - FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, builtin, + FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, StableLintExpectationId, + UnstableLintExpectationId, builtin, }; use rustc_span::{DUMMY_SP, ExpnKind, Span, Symbol, kw}; use tracing::instrument; @@ -55,7 +56,7 @@ impl LintLevelSource { /// Convenience helper for things that are frequently used together. #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable)] -pub struct LevelSpec { +pub struct LevelSpec { // This field *must* be private. It must be set in tandem with `lint_id`, only in // `LevelSpec::new`, because only certain `level`/`lint_id` combinations are valid. See // `LevelSpec::new` for those combinations. @@ -68,18 +69,17 @@ pub struct LevelSpec { level: Level, // This field *must* be private. See the comment on `level`. - lint_id: Option, + lint_id: Option, pub src: LintLevelSource, } -impl LevelSpec { +pub type UnstableLevelSpec = LevelSpec; +pub type StableLevelSpec = LevelSpec; + +impl LevelSpec { // Panics if an invalid `level`/`lint_id` combination is given. - pub fn new( - level: Level, - lint_id: Option, - src: LintLevelSource, - ) -> LevelSpec { + pub fn new(level: Level, lint_id: Option, src: LintLevelSource) -> LevelSpec { match (level, lint_id) { (Level::Allow | Level::Warn | Level::Deny | Level::Forbid, None) => {} (Level::Expect, Some(_)) => {} @@ -101,29 +101,48 @@ impl LevelSpec { self.level == Level::Expect } - pub fn lint_id(self) -> Option { + pub fn lint_id(self) -> Option { self.lint_id } } +impl From for LevelSpec { + fn from(level: UnstableLevelSpec) -> LevelSpec { + let LevelSpec { level, lint_id, src } = level; + let lint_id = lint_id.map(LintExpectationId::Unstable); + LevelSpec { level, lint_id, src } + } +} + +impl From for LevelSpec { + fn from(level: StableLevelSpec) -> LevelSpec { + let LevelSpec { level, lint_id, src } = level; + let lint_id = lint_id.map(LintExpectationId::Stable); + LevelSpec { level, lint_id, src } + } +} + /// Return type for the `shallow_lint_levels_on` query. /// -/// This map represents the set of allowed lints and allowance levels given -/// by the attributes for *a single HirId*. +/// This map represents lints levels given by the attributes for *a single HirId*. #[derive(Default, Debug, StableHash)] pub struct ShallowLintLevelMap { - pub expectations: Vec<(LintExpectationId, LintExpectation)>, - pub specs: SortedMap>, + // All the specs for this HirId. This is accessed frequently, e.g. for every lint emitted. + pub specs: SortedMap>, + + // Additional information about the `expect` specs for this HirId. This is consulted only once + // per compilation session, in `check_expectations`/`lint_expectations`. + pub expectations: Vec<(StableLintExpectationId, LintExpectation)>, } /// Verify the effect of special annotations: `warnings` lint level and lint caps. /// /// The return of this function is suitable for diagnostics. -pub fn reveal_actual_level_spec( +pub fn reveal_actual_level_spec( sess: &Session, lint: LintId, - probe_for_lint_level_spec: impl Fn(LintId) -> Option, -) -> LevelSpec { + probe_for_lint_level_spec: impl Fn(LintId) -> Option>, +) -> LevelSpec { let level_spec = probe_for_lint_level_spec(lint); // If `level` is none then we actually assume the default level for this lint. @@ -185,7 +204,7 @@ impl ShallowLintLevelMap { tcx: TyCtxt<'_>, id: LintId, start: HirId, - ) -> Option { + ) -> Option { if let Some(map) = self.specs.get(&start.local_id) && let Some(level_spec) = map.get(&id) { @@ -212,7 +231,12 @@ impl ShallowLintLevelMap { /// Fetch and return the user-visible lint level spec for the given lint at the given HirId. #[instrument(level = "trace", skip(self, tcx), ret)] - pub fn lint_level_spec_at_node(&self, tcx: TyCtxt<'_>, lint: LintId, cur: HirId) -> LevelSpec { + pub fn lint_level_spec_at_node( + &self, + tcx: TyCtxt<'_>, + lint: LintId, + cur: HirId, + ) -> StableLevelSpec { reveal_actual_level_spec(tcx.sess, lint, |lint| { self.probe_for_lint_level_spec(tcx, lint, cur) }) @@ -221,7 +245,7 @@ impl ShallowLintLevelMap { impl TyCtxt<'_> { /// Fetch and return the user-visible lint level spec for the given lint at the given HirId. - pub fn lint_level_spec_at_node(self, lint: &'static Lint, id: HirId) -> LevelSpec { + pub fn lint_level_spec_at_node(self, lint: &'static Lint, id: HirId) -> StableLevelSpec { self.shallow_lint_levels_on(id.owner).lint_level_spec_at_node(self, LintId::of(lint), id) } } @@ -362,7 +386,7 @@ fn explain_lint_level_source( pub fn emit_lint_base<'a, D: Diagnostic<'a, ()> + 'a>( sess: &'a Session, lint: &'static Lint, - level_spec: LevelSpec, + level_spec: impl Into, span: Option, decorate: D, ) { @@ -556,7 +580,7 @@ pub fn emit_lint_base<'a, D: Diagnostic<'a, ()> + 'a>( emit_lint_base_impl( sess, lint, - level_spec, + level_spec.into(), span, Box::new(move |dcx, level| decorate.into_diag(dcx, level)), ); diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index a9fc5dcac8f29..d62e4ec941d21 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -75,7 +75,7 @@ use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolMangli use rustc_session::cstore::{ CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib, }; -use rustc_session::lint::LintExpectationId; +use rustc_session::lint::StableLintExpectationId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, LocalExpnId, Span, Spanned, Symbol}; use rustc_target::spec::PanicStrategy; @@ -558,7 +558,7 @@ rustc_queries! { desc { "looking up lint levels for `{}`", tcx.def_path_str(key) } } - query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { + query lint_expectations(_: ()) -> &'tcx Vec<(StableLintExpectationId, LintExpectation)> { arena_cache desc { "computing `#[expect]`ed lints in this crate" } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index e2fc663852374..168aa5e9b0219 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -781,8 +781,8 @@ where tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields)) } - Variants::Multiple { ref variants, .. } => { - cx.tcx().mk_layout(variants[variant_index].clone()) + Variants::Multiple { .. } => { + cx.tcx().mk_layout(LayoutData::for_variant(&this, variant_index)) } }; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fbe3a827d6394..31871c62fa7a2 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1072,8 +1072,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>( // // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if callsite.fn_sig.abi() == ExternAbi::RustCall && callee_body.spread_arg.is_none() { - // FIXME(edition_2024): switch back to a normal method call. - let mut args = <_>::into_iter(args); + let mut args = args.into_iter(); let self_ = create_temp_if_necessary( inliner, args.next().unwrap().node, diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index ef4cf82cf1b5d..fbf16f91610c5 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -296,15 +296,14 @@ fn run_passes_inner<'tcx>( if is_optimization_stage(body, phase_change, optimizations) && let Some(limit) = &tcx.sess.opts.unstable_opts.mir_opt_bisect_limit - { - if limited_by_opt_bisect( + && limited_by_opt_bisect( tcx, tcx.def_path_debug_str(body.source.def_id()), *limit, *pass, - ) { - continue; - } + ) + { + continue; } let dumper = if pass.is_mir_dump_enabled() diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 895374ab2cc4b..099bd44e9a065 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -3,7 +3,7 @@ use std::iter::once; use std::ops::Range; -use rustc_errors::{Applicability, DiagCtxtHandle, ErrorGuaranteed}; +use rustc_errors::{Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed}; use rustc_literal_escaper::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; use tracing::debug; @@ -172,6 +172,8 @@ pub(crate) fn emit_unescape_error( "for more information, visit \ ", ); + + foreign_escape_suggestion(&mut diag, (&ec, span), err_span); } diag.emit() } @@ -302,6 +304,44 @@ pub(crate) fn emit_unescape_error( }) } +/// Add additional suggestions for escapes that are supported by C. +fn foreign_escape_suggestion( + diag: &mut Diag<'_>, + (escaped_char, escape_span): (&str, Span), + err_span: Span, +) { + if escaped_char == "?" { + diag.span_suggestion( + err_span, + "if you meant to write a literal question mark, don't escape the character", + "?", + Applicability::MaybeIncorrect, + ); + return; + } + + if u8::from_str_radix(escaped_char, 8).is_ok() { + diag.help(r"if you meant to write an ASCII control code, use a `\xNN` hex escape"); + return; + } + + let (name, hex) = match escaped_char { + "a" => ("an audible bell", "07"), + "b" => ("a backspace", "08"), + "f" => ("a form feed", "0C"), + "v" => ("a vertical tab", "0B"), + "e" => ("an ANSI escape sequence", "1B"), + _ => return, + }; + + diag.span_suggestion( + escape_span, + format!("if you meant to write {name}, use a hex escape"), + format!("x{hex}"), + Applicability::MaybeIncorrect, + ); +} + /// Pushes a character to a message string for error reporting pub(crate) fn escaped_char(c: char) -> String { match c { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f935f43d336c8..1360dc23a78f2 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1891,9 +1891,8 @@ impl<'a> Parser<'a> { true } - /// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a - /// closing delimiter. - pub(super) fn unexpected_try_recover(&mut self, t: &TokenKind) -> PResult<'a, Recovered> { + /// Creates a `Diag` for an unexpected token `t` + pub(super) fn unexpected_err(&mut self, t: &TokenKind) -> Diag<'a> { let token_str = pprust::token_kind_to_string(t); let this_token_str = super::token_descr(&self.token); let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) { @@ -1928,7 +1927,7 @@ impl<'a> Parser<'a> { err.span_label(prev_sp, label_exp); err.span_label(sp, "unexpected token"); } - Err(err) + err } pub(super) fn expect_semi(&mut self) -> PResult<'a, ()> { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 9303be8ff0ccd..850d64c8ecf44 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -409,7 +409,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Recovered::No) } else { - self.unexpected_try_recover(&exp.tok) + Err(self.unexpected_err(&exp.tok)) } } else { self.expect_one_of(slice::from_ref(&exp), &[]) diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 5d3ea7e2c237c..92a0f14f3e94e 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, AssocTag, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint::builtin::{DEAD_CODE, DEAD_CODE_PUB_IN_BINARY}; -use rustc_session::lint::{self, Lint, LintExpectationId}; +use rustc_session::lint::{self, Lint, StableLintExpectationId}; use rustc_span::{Symbol, kw}; use crate::errors::{ @@ -1035,7 +1035,7 @@ fn mark_live_symbols_and_ignored_derived_traits( struct DeadItem { def_id: LocalDefId, name: Symbol, - level_plus: (lint::Level, Option), + level_plus: (lint::Level, Option), } struct DeadVisitor<'tcx> { @@ -1082,7 +1082,10 @@ impl<'tcx> DeadVisitor<'tcx> { ShouldWarnAboutField::Yes } - fn def_lint_level_plus(&self, id: LocalDefId) -> (lint::Level, Option) { + fn def_lint_level_plus( + &self, + id: LocalDefId, + ) -> (lint::Level, Option) { let hir_id = self.tcx.local_def_id_to_hir_id(id); let level_spec = self.tcx.lint_level_spec_at_node(self.target_lint, hir_id); (level_spec.level(), level_spec.lint_id()) @@ -1267,7 +1270,7 @@ impl<'tcx> DeadVisitor<'tcx> { return; } // FIXME: `dead_codes` should probably be morally equivalent to - // `IndexMap<(Level, LintExpectationId), (DefId, Symbol)>` + // `IndexMap<(Level, StableLintExpectationId), (DefId, Symbol)>` dead_codes.sort_by_key(|v| v.level_plus.0); for group in dead_codes.chunk_by(|a, b| a.level_plus == b.level_plus) { self.lint_at_single_level(&group, participle, Some(def_id), report_on); diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index b98a9804ce8b2..f42399241cd28 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -217,11 +217,8 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants VariantFields { - offsets: offsets.iter().as_slice().stable(tables, cx), - }, - _ => panic!("variant layout should be Arbitrary"), + .map(|v| VariantFields { + offsets: v.field_offsets.iter().as_slice().stable(tables, cx), }) .collect(), } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index d39dcb1fa280b..84221cb8c2d5e 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -487,6 +487,9 @@ impl Resolver<'_, '_> { let remove_whole_use = remove_spans.len() == 1 && remove_spans[0] == unused.item_span; let num_to_remove = ms.primary_spans().len(); + // Only offer rustfix suggestions for spans that point at directly editable code. + let can_suggest_removal = + remove_spans.iter().all(|span| span.can_be_used_for_suggestions()); // If we are in the `--test` mode, suppress a help that adds the `#[cfg(test)]` // attribute; however, if not, suggest adding the attribute. There is no way to @@ -517,11 +520,13 @@ impl Resolver<'_, '_> { unused.use_tree_id, ms, move |dcx, level, sess| { - let sugg = if remove_whole_use { - errors::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } - } else { - errors::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } - }; + let sugg = can_suggest_removal.then(|| { + if remove_whole_use { + errors::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } + } else { + errors::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } + } + }); let test_module_span = test_module_span.map(|span| { sess.downcast_ref::() .expect("expected a `Session`") diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 342484a8c0d51..4bcc7a5eb02e8 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1742,7 +1742,7 @@ pub(crate) struct ElidedLifetimesInPaths { )] pub(crate) struct UnusedImports { #[subdiagnostic] - pub sugg: UnusedImportsSugg, + pub sugg: Option, #[help("if this is a test module, consider adding a `#[cfg(test)]` to the containing module")] pub test_module_span: Option, diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index a9edaa7371a88..8c07a7ec3d2de 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -302,10 +302,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou } } for variant in variants.iter() { - // No nested "multiple". - assert_matches!(variant.variants, Variants::Single { .. }); - // Variants should have the same or a smaller size as the full thing, - // and same for alignment. + // Variants should have the same or a smaller size as the full thing. if variant.size > layout.size { bug!( "Type with size {} bytes has variant with size {} bytes: {layout:#?}", @@ -313,18 +310,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou variant.size.bytes(), ) } - if variant.align.abi > layout.align.abi { - bug!( - "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}", - layout.align.bytes(), - variant.align.bytes(), - ) - } // Skip empty variants. - if variant.size == Size::ZERO - || variant.fields.count() == 0 - || variant.is_uninhabited() - { + if variant.size == Size::ZERO || !variant.has_fields() || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check // for them. They also fail that check, since they may have // a different ABI even when the main type is diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 0968aef0b458c..f07fb91edaf0b 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -47,9 +47,9 @@ ENV \ CFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ CXX_x86_64_fortanix_unknown_sgx=clang++-11 \ CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ - AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \ - CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \ - CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \ + AR_i686_unknown_freebsd=i686-unknown-freebsd14-ar \ + CC_i686_unknown_freebsd=i686-unknown-freebsd14-clang \ + CXX_i686_unknown_freebsd=i686-unknown-freebsd14-clang++ \ CC_aarch64_unknown_uefi=clang-11 \ CXX_aarch64_unknown_uefi=clang++-11 \ CC_i686_unknown_uefi=clang-11 \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index e62aa74662bed..5f11437c786c2 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -29,9 +29,9 @@ COPY scripts/cmake.sh /scripts/ RUN /scripts/cmake.sh ENV \ - AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-ar \ - CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang \ - CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang++ + AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-ar \ + CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-clang \ + CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-clang++ ENV HOSTS=x86_64-unknown-freebsd diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 56b3c5cd82e7d..5308288d911a0 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -5,8 +5,9 @@ set -eux arch=$1 binutils_version=2.40 -freebsd_version=12.3 -triple=$arch-unknown-freebsd12 +freebsd_version=14.4 +freebsd_date=2026-03-10 +triple=$arch-unknown-freebsd14 sysroot=/usr/local/$triple hide_output() { @@ -52,16 +53,16 @@ files_to_extract=( "./usr/lib/*crt*.o" ) # Try to unpack only the libraries the build needs, to save space. -for lib in c cxxrt gcc_s m thr util; do +for lib in c c++ cxxrt gcc_s m thr util; do files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*") done -for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do +for lib in c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*") done # Originally downloaded from: # URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz -URL=https://ci-mirrors.rust-lang.org/rustc/2022-05-06-freebsd-${freebsd_version}-${freebsd_arch}-base.txz +URL=https://ci-mirrors.rust-lang.org/rustc/${freebsd_date}-freebsd-${freebsd_version}-${freebsd_arch}-base.txz curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # Clang can do cross-builds out of the box, if we give it the right @@ -70,7 +71,7 @@ curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # there might be other problems.) # # The --target option is last because the cross-build of LLVM uses -# --target without an OS version ("-freebsd" vs. "-freebsd12"). This +# --target without an OS version ("-freebsd" vs. "-freebsd14"). This # makes Clang default to libstdc++ (which no longer exists), and also # controls other features, like GNU-style symbol table hashing and # anything predicated on the version number in the __FreeBSD__ diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 87d66489753c3..d1b923edd3957 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -133,7 +133,7 @@ means the test won't be compiled or run. Some examples of `X` in `ignore-X` or `only-X`: - A full target triple: `aarch64-apple-ios` -- Architecture: `aarch64`, `arm`, `mips`, `wasm32`, `x86_64`, `x86`, +- Architecture: `aarch64`, `arm`, `csky`, `mips`, `mips64`, `wasm32`, `x86_64`, `x86`, ... - OS: `android`, `emscripten`, `freebsd`, `ios`, `linux`, `macos`, `windows`, ... diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index e17058c4ca80c..c3a8582deaeee 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -54,7 +54,7 @@ pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl f span_bug!(tcx.def_span(ty_def_id), "not an adt") }; let name = adt.variant(variant_idx).name; - let is_unsized = variant_layout.is_unsized(); + let is_unsized = variant_layout.backend_repr.is_unsized(); let is_uninhabited = variant_layout.is_uninhabited(); let size = variant_layout.size.bytes() - tag_size; let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs index cb3cb2479beed..f1837e776e824 100644 --- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs +++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind}; use rustc_errors::MultiSpan; use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext}; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::UnstableLevelSpec; use rustc_session::impl_lint_pass; use rustc_span::{FileName, Span}; use std::collections::BTreeMap; @@ -51,7 +51,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]); struct Modules { local_path: PathBuf, spans: Vec, - lint_level_specs: Vec, + lint_level_specs: Vec, } #[derive(Default)] @@ -96,7 +96,7 @@ impl EarlyLintPass for DuplicateMod { .zip(lint_level_specs) .filter_map(|(span, level_spec)| { if let Some(id) = level_spec.lint_id() { - cx.fulfill_expectation(id); + cx.fulfill_expectation(id.into()); } (!matches!(level_spec.level(), Level::Allow | Level::Expect)).then_some(*span) diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index adab1e2160480..fb795c6b447c9 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -67,6 +67,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-coverage-map", "ignore-coverage-run", "ignore-cross-compile", + "ignore-csky", "ignore-eabi", "ignore-elf", "ignore-emscripten", @@ -91,6 +92,8 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-loongarch64", "ignore-macabi", "ignore-macos", + "ignore-mips", + "ignore-mips64", "ignore-msp430", "ignore-msvc", "ignore-musl", diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.stderr b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr similarity index 91% rename from tests/rustdoc-ui/lints/unescaped_backticks.stderr rename to tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr index 1bcb88e108f20..6a2396ea1f9d6 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr @@ -1,14 +1,10 @@ error: unescaped backtick - --> $DIR/unescaped_backticks.rs:187:70 + --> $DIR/unescaped_backticks.rs:192:70 | LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = | ^ | -note: the lint level is defined here - --> $DIR/unescaped_backticks.rs:1:9 - | -LL | #![deny(rustdoc::unescaped_backticks)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: requested on the command line with `-D rustdoc::unescaped-backticks` help: the closing backtick of an inline code may be missing | LL | /// "runtime", phase = "optimized")]` if you don't. @@ -19,7 +15,7 @@ LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![c | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:232:13 + --> $DIR/unescaped_backticks.rs:237:13 | LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] | ^ @@ -34,7 +30,7 @@ LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kin | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:237:13 + --> $DIR/unescaped_backticks.rs:242:13 | LL | /// `cfg=... | ^ @@ -49,7 +45,7 @@ LL | /// \`cfg=... | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:241:42 + --> $DIR/unescaped_backticks.rs:246:42 | LL | /// `cfg=... and not `#[cfg_attr]` | ^ @@ -64,7 +60,7 @@ LL | /// `cfg=... and not `#[cfg_attr]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:193:93 + --> $DIR/unescaped_backticks.rs:198:93 | LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to | ^ @@ -79,7 +75,7 @@ LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:202:34 + --> $DIR/unescaped_backticks.rs:207:34 | LL | /// in `nt_to_tokenstream` | ^ @@ -94,7 +90,7 @@ LL | /// in `nt_to_tokenstream\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:208:62 + --> $DIR/unescaped_backticks.rs:213:62 | LL | /// that `Option` only takes up 4 bytes, because `newtype_index! reserves | ^ @@ -109,7 +105,7 @@ LL | /// that `Option` only takes up 4 bytes, because \`newtype_inde | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:216:52 + --> $DIR/unescaped_backticks.rs:221:52 | LL | /// also avoids the need to import `OpenOptions`. | ^ @@ -124,7 +120,7 @@ LL | /// also avoids the need to import `OpenOptions\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:221:47 + --> $DIR/unescaped_backticks.rs:226:47 | LL | /// `ChunkedBitSet`. Has no effect if `row` does not exist. | ^ @@ -139,7 +135,7 @@ LL | /// `ChunkedBitSet`. Has no effect if `row\` does not exist. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:247:12 + --> $DIR/unescaped_backticks.rs:252:12 | LL | /// RWU`s can get very large, so it uses a more compact representation. | ^ @@ -154,7 +150,7 @@ LL | /// RWU\`s can get very large, so it uses a more compact representation | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:254:15 + --> $DIR/unescaped_backticks.rs:259:15 | LL | /// in `U2`. | ^ @@ -169,7 +165,7 @@ LL | /// in `U2\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:271:42 + --> $DIR/unescaped_backticks.rs:276:42 | LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for | ^ @@ -184,7 +180,7 @@ LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:281:53 + --> $DIR/unescaped_backticks.rs:286:53 | LL | /// well as the second instance of `A: AutoTrait`) to suppress | ^ @@ -199,7 +195,7 @@ LL | /// well as the second instance of `A: AutoTrait\`) to suppress | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:291:40 + --> $DIR/unescaped_backticks.rs:296:40 | LL | /// `'a` with `'b` and not `'static`. But it will have to do for | ^ @@ -211,7 +207,7 @@ LL | /// `'a` with `'b` and not `'static\`. But it will have to do for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:300:54 + --> $DIR/unescaped_backticks.rs:305:54 | LL | /// `None`. Otherwise, it will return `Some(Dispatch)`. | ^ @@ -226,7 +222,7 @@ LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:304:13 + --> $DIR/unescaped_backticks.rs:309:13 | LL | /// or `None` if it isn't. | ^ @@ -238,7 +234,7 @@ LL | /// or `None\` if it isn't. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:308:14 + --> $DIR/unescaped_backticks.rs:313:14 | LL | /// `on_event` should be called. | ^ @@ -253,7 +249,7 @@ LL | /// `on_event\` should be called. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:313:29 + --> $DIR/unescaped_backticks.rs:318:29 | LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max | ^ @@ -268,7 +264,7 @@ LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the m | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -284,7 +280,7 @@ LL | | /// level changes. to this: `None`. Otherwise, it will return `Some(Dispatch)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -298,7 +294,7 @@ LL | | /// level changes. to this: or `None\` if it isn't. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -314,7 +310,7 @@ LL | | /// level changes. to this: `on_event\` should be called. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -330,7 +326,7 @@ LL | | /// level changes. to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max error: unescaped backtick - --> $DIR/unescaped_backticks.rs:349:56 + --> $DIR/unescaped_backticks.rs:354:56 | LL | /// instead and use [`CloneCounterObserver::counter`] to increment. | ^ @@ -342,7 +338,7 @@ LL | /// instead and use [`CloneCounterObserver::counter\`] to increment. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:12:5 + --> $DIR/unescaped_backticks.rs:17:5 | LL | /// ` | ^ @@ -354,7 +350,7 @@ LL | /// \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:19:7 + --> $DIR/unescaped_backticks.rs:24:7 | LL | /// \` | ^ @@ -369,7 +365,7 @@ LL | /// \\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:26:6 + --> $DIR/unescaped_backticks.rs:31:6 | LL | /// [`link1] | ^ @@ -384,7 +380,7 @@ LL | /// [\`link1] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:30:11 + --> $DIR/unescaped_backticks.rs:35:11 | LL | /// [link2`] | ^ @@ -399,7 +395,7 @@ LL | /// [link2\`] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:34:6 + --> $DIR/unescaped_backticks.rs:39:6 | LL | /// [`link_long](link_long) | ^ @@ -414,7 +410,7 @@ LL | /// [\`link_long](link_long) | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:38:6 + --> $DIR/unescaped_backticks.rs:43:6 | LL | /// [`broken-link] | ^ @@ -429,7 +425,7 @@ LL | /// [\`broken-link] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:45:8 + --> $DIR/unescaped_backticks.rs:50:8 | LL | /// | ^ @@ -444,7 +440,7 @@ LL | /// | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:55:6 + --> $DIR/unescaped_backticks.rs:60:6 | LL | /// 🦀`🦀 | ^ @@ -463,7 +459,7 @@ LL | /// 🦀\`🦀 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:59:5 + --> $DIR/unescaped_backticks.rs:64:5 | LL | /// `foo( | ^ @@ -478,7 +474,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:65:14 + --> $DIR/unescaped_backticks.rs:70:14 | LL | /// `foo `bar` | ^ @@ -493,7 +489,7 @@ LL | /// `foo `bar\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:71:5 + --> $DIR/unescaped_backticks.rs:76:5 | LL | /// `foo( | ^ @@ -508,7 +504,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:76:83 + --> $DIR/unescaped_backticks.rs:81:83 | LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. | ^ @@ -523,7 +519,7 @@ LL | /// Addition is commutative, which means that add(a, b)` is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:80:51 + --> $DIR/unescaped_backticks.rs:85:51 | LL | /// or even to add a number `n` to 42 (`add(42, b)`)! | ^ @@ -538,7 +534,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, b)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:84:83 + --> $DIR/unescaped_backticks.rs:89:83 | LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. | ^ @@ -553,7 +549,7 @@ LL | /// Addition is commutative, which means that `add(a, b) is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:88:51 + --> $DIR/unescaped_backticks.rs:93:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -568,7 +564,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:92:83 + --> $DIR/unescaped_backticks.rs:97:83 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. | ^ @@ -583,7 +579,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:96:50 + --> $DIR/unescaped_backticks.rs:101:50 | LL | /// or even to add a number `n` to 42 (add(42, n)`)! | ^ @@ -598,7 +594,7 @@ LL | /// or even to add a number `n` to 42 (add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:100:74 + --> $DIR/unescaped_backticks.rs:105:74 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). | ^ @@ -613,7 +609,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:104:51 + --> $DIR/unescaped_backticks.rs:109:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -628,7 +624,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:108:10 + --> $DIR/unescaped_backticks.rs:113:10 | LL | #[doc = "`"] | ^ @@ -639,7 +635,7 @@ LL | #[doc = "`"] to this: \` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:115:26 + --> $DIR/unescaped_backticks.rs:120:26 | LL | #[doc = concat!("\\", "`")] | ^ @@ -652,7 +648,7 @@ LL | #[doc = concat!("\\", "`")] to this: \\` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:119:9 + --> $DIR/unescaped_backticks.rs:124:9 | LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -665,7 +661,7 @@ LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same a to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:123:9 + --> $DIR/unescaped_backticks.rs:128:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -678,7 +674,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same a to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:127:9 + --> $DIR/unescaped_backticks.rs:132:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -691,7 +687,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:131:9 + --> $DIR/unescaped_backticks.rs:136:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -704,7 +700,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). error: unescaped backtick - --> $DIR/unescaped_backticks.rs:136:5 + --> $DIR/unescaped_backticks.rs:141:5 | LL | /// `foo | ^ @@ -719,7 +715,7 @@ LL | /// \`foo | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:140:7 + --> $DIR/unescaped_backticks.rs:145:7 | LL | /// # `(heading | ^ @@ -734,7 +730,7 @@ LL | /// # \`(heading | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:142:17 + --> $DIR/unescaped_backticks.rs:147:17 | LL | /// ## heading2)` | ^ @@ -749,7 +745,7 @@ LL | /// ## heading2)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:145:11 + --> $DIR/unescaped_backticks.rs:150:11 | LL | /// multi `( | ^ @@ -764,7 +760,7 @@ LL | /// multi \`( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:151:10 + --> $DIR/unescaped_backticks.rs:156:10 | LL | /// para)`(graph | ^ @@ -783,7 +779,7 @@ LL | /// para)\`(graph | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:154:10 + --> $DIR/unescaped_backticks.rs:159:10 | LL | /// para)`(graph2 | ^ @@ -802,7 +798,7 @@ LL | /// para)\`(graph2 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:157:12 + --> $DIR/unescaped_backticks.rs:162:12 | LL | /// 1. foo)` | ^ @@ -817,7 +813,7 @@ LL | /// 1. foo)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:159:8 + --> $DIR/unescaped_backticks.rs:164:8 | LL | /// 2. `(bar | ^ @@ -832,7 +828,7 @@ LL | /// 2. \`(bar | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:161:11 + --> $DIR/unescaped_backticks.rs:166:11 | LL | /// * baz)` | ^ @@ -847,7 +843,7 @@ LL | /// * baz)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:163:7 + --> $DIR/unescaped_backticks.rs:168:7 | LL | /// * `(quux | ^ @@ -862,7 +858,7 @@ LL | /// * \`(quux | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:166:5 + --> $DIR/unescaped_backticks.rs:171:5 | LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")] | ^ @@ -877,7 +873,7 @@ LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:169:62 + --> $DIR/unescaped_backticks.rs:174:62 | LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]` | ^ @@ -892,7 +888,7 @@ LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:174:7 + --> $DIR/unescaped_backticks.rs:179:7 | LL | /// | `table( | )head` | | ^ @@ -907,7 +903,7 @@ LL | /// | \`table( | )head` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:174:22 + --> $DIR/unescaped_backticks.rs:179:22 | LL | /// | `table( | )head` | | ^ @@ -922,7 +918,7 @@ LL | /// | `table( | )head\` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:178:12 + --> $DIR/unescaped_backticks.rs:183:12 | LL | /// | table`( | )`body | | ^ @@ -937,7 +933,7 @@ LL | /// | table\`( | )`body | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:178:18 + --> $DIR/unescaped_backticks.rs:183:18 | LL | /// | table`( | )`body | | ^ diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.rs b/tests/rustdoc-ui/lints/unescaped_backticks.rs index 8d6239296bf78..55ea1ac699d00 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.rs +++ b/tests/rustdoc-ui/lints/unescaped_backticks.rs @@ -1,4 +1,9 @@ -#![deny(rustdoc::unescaped_backticks)] +//@revisions: deny_cli allow_cli capped +//@[capped] compile-flags: --cap-lints=allow +//@[capped] check-pass +//@[deny_cli] compile-flags: -Drustdoc::unescaped_backticks +//@[allow_cli] compile-flags: -Arustdoc::unescaped_backticks +//@[allow_cli] check-pass #![allow(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::invalid_html_tags)] #![allow(rustdoc::redundant_explicit_links)] @@ -10,40 +15,40 @@ pub fn empty() {} pub fn empty2() {} /// ` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn single() {} /// \` pub fn escaped() {} /// \\` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn not_escaped() {} /// \\\` pub fn not_not_escaped() {} /// [`link1] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link1() {} /// [link2`] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link2() {} /// [`link_long](link_long) -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link_long() {} /// [`broken-link] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn broken_link() {} /// pub fn url() {} /// -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn not_url() {} ///

`

@@ -53,131 +58,131 @@ pub fn html_tag() {} pub fn html_escape() {} /// 🦀`🦀 -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn unicode() {} /// `foo( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// paragraph pub fn paragraph() {} /// `foo `bar` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// paragraph pub fn paragraph2() {} /// `foo( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// not paragraph pub fn not_paragraph() {} /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (add(n, 42)`), /// or even to add a number `n` to 42 (`add(42, b)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add1(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)), /// or even to add a number `n` to 42 (`add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add2(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)`), /// or even to add a number `n` to 42 (add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add3(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)), /// or even to add a number `n` to 42 (`add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add4(a: i32, b: i32) -> i32 { a + b } #[doc = "`"] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr() {} #[doc = concat!("\\", "`")] pub fn attr_escaped() {} #[doc = concat!("\\\\", "`")] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_not_escaped() {} #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add1(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add2(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add3(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add4(a: i32, b: i32) -> i32 { a + b } /// ``double backticks`` /// `foo -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn double_backticks() {} /// # `(heading -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// ## heading2)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// multi `( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// line /// ) heading /// = /// /// para)`(graph -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// para)`(graph2 -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// 1. foo)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// 2. `(bar -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// * baz)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// * `(quux -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// `#![this_is_actually_an_image(and(not), an = "attribute")] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// #![this_is_actually_an_image(and(not), an = "attribute")]` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// [this_is_actually_an_image(and(not), an = "attribute")]: `.png /// /// | `table( | )head` | -//~^ ERROR unescaped backtick -//~| ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick +//[deny_cli]~| ERROR unescaped backtick /// |---------|--------| /// | table`( | )`body | -//~^ ERROR unescaped backtick -//~| ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick +//[deny_cli]~| ERROR unescaped backtick pub fn complicated_markdown() {} /// The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This @@ -185,13 +190,13 @@ pub fn complicated_markdown() {} /// another function. The `dialect` and `phase` parameters indicate which [version of MIR][dialect /// docs] you are inserting here. Generally you'll want to use `#![custom_mir(dialect = "built")]` /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// "runtime", phase = "optimized")] if you don't. pub mod mir {} pub mod rustc { /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// ensure it gets used. pub fn ty_error_with_message() {} @@ -200,13 +205,13 @@ pub mod rustc { /// if we parsed no predicates (e.g. `struct Foo where {} /// This allows us to accurately pretty-print /// in `nt_to_tokenstream` - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub has_where_token: bool, } /// A symbol is an interned or gensymed string. The use of `newtype_index!` means /// that `Option` only takes up 4 bytes, because `newtype_index! reserves - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// the last 256 values for tagging purposes. pub struct Symbol(); @@ -214,12 +219,12 @@ pub mod rustc { /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")` /// you can write `File::with_options().read(true).open("foo.txt"). This /// also avoids the need to import `OpenOptions`. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn with_options() {} /// Subtracts `set from `row`. `set` can be either `BitSet` or /// `ChunkedBitSet`. Has no effect if `row` does not exist. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// /// Returns true if the row was changed. pub fn subtract_row() {} @@ -230,29 +235,29 @@ pub mod rustc { //! perturb the reuse results. //! //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick //! allows for doing a more fine-grained check to see if pre- or post-lto data //! was re-used. /// `cfg=... - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn foo() {} /// `cfg=... and not `#[cfg_attr]` - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn bar() {} } /// Conceptually, this is like a `Vec>`. But the number of /// RWU`s can get very large, so it uses a more compact representation. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub struct RWUTable {} /// Like [Self::canonicalize_query], but preserves distinct universes. For /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` /// in `U2`. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// /// This is used for Chalk integration. pub fn canonicalize_query_preserving_universes() {} @@ -269,7 +274,7 @@ pub mod rustc { /// ` as Trait>::Foo`. We are supposed to report /// an error for this obligation, but we legitimately should not, /// because it contains `[type error]`. Yuck! (See issue #29857 for - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// one case where this arose.) pub fn normalize_to_error() {} @@ -279,7 +284,7 @@ pub mod rustc { /// encountered a problem (later on) with `A: AutoTrait. So we /// currently set a flag on the stack node for `B: AutoTrait` (as /// well as the second instance of `A: AutoTrait`) to suppress - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// caching. pub struct TraitObligationStack; @@ -289,7 +294,7 @@ pub mod rustc { /// actually stricter than necessary: ideally, we'd support bounds /// like `for<'a: 'b`>` that might then allow us to approximate /// `'a` with `'b` and not `'static`. But it will have to do for - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// now. pub fn add_incompatible_universe(){} } @@ -298,20 +303,20 @@ pub mod rustc { /// which returns an `Option`. If all [`Dispatch`] clones that point /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return /// `None`. Otherwise, it will return `Some(Dispatch)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Returns some reference to this `[`Subscriber`] value if it is of type `T`, /// or `None` if it isn't. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Called before the filtered [`Layer]'s [`on_event`], to determine if /// `on_event` should be called. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Therefore, if the `Filter will change the value returned by this /// method, it is responsible for ensuring that /// [`rebuild_interest_cache`][rebuild] is called after the value of the max -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// level changes. pub mod tracing {} @@ -321,10 +326,10 @@ macro_rules! id { id! { /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], - //~^ ERROR unescaped backtick - //~| ERROR unescaped backtick - //~| ERROR unescaped backtick - //~| ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick /// which returns an `Option`. If all [`Dispatch`] clones that point /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return /// `None`. Otherwise, it will return `Some(Dispatch)`. @@ -347,7 +352,7 @@ pub mod trillium_server_common { /// One-indexed, because the first CloneCounter is included. If you don't /// want the original to count, construct a [``CloneCounterObserver`] /// instead and use [`CloneCounterObserver::counter`] to increment. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub struct CloneCounter; /// This is used by the above. diff --git a/tests/ui/eii/default/auxiliary/decl_with_default.rs b/tests/ui/eii/default/auxiliary/decl_with_default.rs index 8d962c19c94d9..ba855cb854afd 100644 --- a/tests/ui/eii/default/auxiliary/decl_with_default.rs +++ b/tests/ui/eii/default/auxiliary/decl_with_default.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs b/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs index 14778a40cde4a..3867bfb85c9fe 100644 --- a/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs +++ b/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ needs-unwind //@ exec-env:RUST_BACKTRACE=1 #![crate_type = "rlib"] diff --git a/tests/ui/eii/default/auxiliary/impl1.rs b/tests/ui/eii/default/auxiliary/impl1.rs index 3510ea1eb3f27..84edf24e12816 100644 --- a/tests/ui/eii/default/auxiliary/impl1.rs +++ b/tests/ui/eii/default/auxiliary/impl1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 8806c7fa7d8ce..07b2a650d3c42 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs //@ run-pass //@ check-run-results diff --git a/tests/ui/eii/default/call_default_panics.rs b/tests/ui/eii/default/call_default_panics.rs index db664e0cbcb0d..379ba8ea070b6 100644 --- a/tests/ui/eii/default/call_default_panics.rs +++ b/tests/ui/eii/default/call_default_panics.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default_panics.rs //@ edition: 2021 //@ run-pass diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index 1a972774beaeb..4553427b8c799 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs //@ aux-build: impl1.rs //@ run-pass diff --git a/tests/ui/eii/duplicate/auxiliary/impl1.rs b/tests/ui/eii/duplicate/auxiliary/impl1.rs index e99932c69b90b..ffa2cd79818cc 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl1.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl2.rs b/tests/ui/eii/duplicate/auxiliary/impl2.rs index 3a09c824b8292..592234f53fd40 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl2.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl2.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl3.rs b/tests/ui/eii/duplicate/auxiliary/impl3.rs index 09bdd8509da29..5e9fdaba0bb6b 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl3.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl3.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl4.rs b/tests/ui/eii/duplicate/auxiliary/impl4.rs index fd68a83de1252..068cc18d78e6a 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl4.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl4.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs index 2128cac70eb30..3d770232af50f 100644 --- a/tests/ui/eii/duplicate/duplicate1.rs +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ ignore-backends: gcc diff --git a/tests/ui/eii/duplicate/duplicate1.stderr b/tests/ui/eii/duplicate/duplicate1.stderr index 54cc141f88694..f691043e6a597 100644 --- a/tests/ui/eii/duplicate/duplicate1.stderr +++ b/tests/ui/eii/duplicate/duplicate1.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs index b0f1b1266e4ca..4311969ed8894 100644 --- a/tests/ui/eii/duplicate/duplicate2.rs +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ aux-build: impl3.rs diff --git a/tests/ui/eii/duplicate/duplicate2.stderr b/tests/ui/eii/duplicate/duplicate2.stderr index 033e43c8b2fbd..492d2b3e6004b 100644 --- a/tests/ui/eii/duplicate/duplicate2.stderr +++ b/tests/ui/eii/duplicate/duplicate2.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs index 4b2b0fc111b58..4504ba30c246e 100644 --- a/tests/ui/eii/duplicate/duplicate3.rs +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ aux-build: impl3.rs diff --git a/tests/ui/eii/duplicate/duplicate3.stderr b/tests/ui/eii/duplicate/duplicate3.stderr index 801d40e69c552..f3ca087a27325 100644 --- a/tests/ui/eii/duplicate/duplicate3.stderr +++ b/tests/ui/eii/duplicate/duplicate3.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/static/auxiliary/cross_crate_def.rs b/tests/ui/eii/static/auxiliary/cross_crate_def.rs index 70933440a62be..56d3f6fcdc557 100644 --- a/tests/ui/eii/static/auxiliary/cross_crate_def.rs +++ b/tests/ui/eii/static/auxiliary/cross_crate_def.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index 9b97ad4aeac7e..b24948fb39ddf 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -42,68 +42,35 @@ error: layout_of(UnsignedAroundZero) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, ], }, @@ -160,68 +127,35 @@ error: layout_of(SignedAroundZero) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, ], }, diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs index b1e552bca0293..8cf733dbfdff5 100644 --- a/tests/ui/explicit-tail-calls/become-indirect-return.rs +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -2,6 +2,27 @@ //@ ignore-backends: gcc //@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1 //@ ignore-cross-compile +// +// LLVM musttail support is incomplete for these targets. +// See https://github.com/rust-lang/rust/issues/148748 for the target test matrix. +// See https://github.com/llvm/llvm-project/issues/63214 for AIX and PowerPC. +// See https://github.com/llvm/llvm-project/issues/57795 for MIPS and MIPS64. +//@ ignore-aix +//@ ignore-csky +//@ ignore-mips +//@ ignore-mips64 +//@ ignore-powerpc +//@ ignore-powerpc64 +// +// LLVM musttail support is lacking for sret lowering on these targets. +// Returning `[u8; 24]` uses sret lowering here. +// See https://github.com/llvm/llvm-project/issues/157814 for RISC-V. +// See https://github.com/llvm/llvm-project/issues/168152 for LoongArch. +// RISC-V fix: https://github.com/llvm/llvm-project/pull/185094, should be in LLVM 23. +// LoongArch will likely be fixed with similar changes. +//@ ignore-riscv64 +//@ ignore-loongarch32 +//@ ignore-loongarch64 #![expect(incomplete_features)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/explicit-tail-calls/indirect.rs b/tests/ui/explicit-tail-calls/indirect.rs index 537976b7f6f43..b3e2613efad25 100644 --- a/tests/ui/explicit-tail-calls/indirect.rs +++ b/tests/ui/explicit-tail-calls/indirect.rs @@ -2,7 +2,26 @@ //@ ignore-backends: gcc // //@ ignore-wasm +// +// LLVM musttail support is incomplete for these targets. +// See https://github.com/rust-lang/rust/issues/148748 for the target test matrix. +// See https://github.com/llvm/llvm-project/issues/63214 for AIX and PowerPC. +// See https://github.com/llvm/llvm-project/issues/57795 for MIPS and MIPS64. +//@ ignore-aix +//@ ignore-csky +//@ ignore-mips +//@ ignore-mips64 +//@ ignore-powerpc +//@ ignore-powerpc64 +// +// LLVM musttail support is lacking for indirect arguments that do not fit in registers. +// See https://github.com/llvm/llvm-project/issues/157814 for RISC-V. +// See https://github.com/llvm/llvm-project/issues/168152 for LoongArch. +// RISC-V fix: https://github.com/llvm/llvm-project/pull/185094, should be in LLVM 23. +// LoongArch will likely be fixed with similar changes. //@ ignore-riscv64 +//@ ignore-loongarch32 +//@ ignore-loongarch64 #![feature(explicit_tail_calls)] #![expect(incomplete_features)] diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed new file mode 100644 index 0000000000000..3b7c8051122fc --- /dev/null +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed @@ -0,0 +1,23 @@ +// Regression test for +//@ edition:2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ check-pass + +mod m { + macro_rules! define_new_macro { + ($name:ident) => { + macro_rules! $name { + () => {}; + } + pub(crate) use $name; + }; + } + + define_new_macro!(item_used); + define_new_macro!(item_unused); +} + +fn main() { + m::item_used!(); +} diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs new file mode 100644 index 0000000000000..3b7c8051122fc --- /dev/null +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs @@ -0,0 +1,23 @@ +// Regression test for +//@ edition:2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ check-pass + +mod m { + macro_rules! define_new_macro { + ($name:ident) => { + macro_rules! $name { + () => {}; + } + pub(crate) use $name; + }; + } + + define_new_macro!(item_used); + define_new_macro!(item_unused); +} + +fn main() { + m::item_used!(); +} diff --git a/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs new file mode 100644 index 0000000000000..b1c4dfb9f1003 --- /dev/null +++ b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs @@ -0,0 +1,19 @@ +//@ edition: 2021 + +// Regression test for issue #41261. +// The diagnostic should point at the ambiguous cast, not at the later method call. + +struct S { + v: Vec<(u32, Vec)>, +} + +impl S { + pub fn remove(&mut self, i: u32) -> Option> { + self.v.get_mut(i as _).map(|&mut (_, ref mut v2)| { + //~^ ERROR type annotations needed + v2.drain(..) + }) + } +} + +fn main() {} diff --git a/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr new file mode 100644 index 0000000000000..da66f6237203e --- /dev/null +++ b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `&mut (_, _)` + --> $DIR/ambiguous-cast-suggestion-issue-41261.rs:12:37 + | +LL | self.v.get_mut(i as _).map(|&mut (_, ref mut v2)| { + | ^^^^^^^^^^^^^^^^^^^^ +LL | +LL | v2.drain(..) + | -- type must be known at this point + | +help: consider giving this closure parameter an explicit type, where the placeholders `_` are specified + | +LL | self.v.get_mut(i as _).map(|&mut (_, ref mut v2): &mut (_, _)| { + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index bfd2f7ec95da1..f08d1200b9fbc 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -58,55 +58,33 @@ error: layout_of(E) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(12 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - Size(4 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - 2, - ], - }, + field_offsets: [ + Size(4 bytes), + Size(4 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + 2, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -242,11 +220,8 @@ error: layout_of(Result) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -263,28 +238,17 @@ error: layout_of(Result) = Layout { valid_range: 0..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -301,22 +265,14 @@ error: layout_of(Result) = Layout { valid_range: 0..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -662,32 +618,18 @@ error: layout_of(Option) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -697,14 +639,12 @@ error: layout_of(Option) = Layout { valid_range: 0..=1, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -716,12 +656,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -782,32 +716,18 @@ error: layout_of(Option) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -817,14 +737,12 @@ error: layout_of(Option) = Layout { valid_range: 0..=1114111, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -836,12 +754,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 20e0a8642a66f..993ff476b6b6c 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -42,26 +42,15 @@ error: layout_of(A) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -118,26 +107,15 @@ error: layout_of(B) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -194,26 +172,15 @@ error: layout_of(C) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, ], }, @@ -270,26 +237,15 @@ error: layout_of(P) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -346,26 +302,15 @@ error: layout_of(T) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 61cfcbdc07f75..7e6294f894c3e 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -48,11 +48,8 @@ error: layout_of(MissingPayloadField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -68,43 +65,24 @@ error: layout_of(MissingPayloadField) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -168,11 +146,8 @@ error: layout_of(CommonPayloadField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -189,28 +164,17 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -227,22 +191,14 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -305,11 +261,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -325,28 +278,17 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -362,22 +304,14 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -444,11 +378,8 @@ error: layout_of(NicheFirst) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -465,16 +396,14 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - Size(1 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(0 bytes), + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -486,54 +415,26 @@ error: layout_of(NicheFirst) = Layout { }, ), uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -600,11 +501,8 @@ error: layout_of(NicheSecond) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -621,16 +519,14 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - Size(0 bytes), - ], - in_memory_order: [ - 1, - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + Size(0 bytes), + ], + fields_in_memory_order: [ + 1, + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -642,54 +538,26 @@ error: layout_of(NicheSecond) = Layout { }, ), uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 64e2f42c042f1..8937af2f5d494 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -36,51 +36,25 @@ error: layout_of(Aligned1) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -139,51 +113,25 @@ error: layout_of(Aligned2) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(1 bytes), - ), - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: Some( - Align(1 bytes), - ), - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index a6e603652123b..200002490d5c5 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -42,26 +42,15 @@ error: layout_of(A) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -118,26 +107,15 @@ error: layout_of(B) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -194,26 +172,15 @@ error: layout_of(C) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, ], }, @@ -270,26 +237,15 @@ error: layout_of(P) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -346,26 +302,15 @@ error: layout_of(T) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index a29586f3bb2fa..6618f162853e5 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -36,47 +36,31 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -88,12 +72,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -144,72 +122,45 @@ error: layout_of(MultipleAlignments) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(2 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(2 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -221,12 +172,6 @@ error: layout_of(MultipleAlignments) = Layout { }, ), uninhabited: false, - variants: Single { - index: 2, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -277,47 +222,31 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(3 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -329,12 +258,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -389,47 +312,31 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -441,12 +348,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs new file mode 100644 index 0000000000000..82c6b55a7623a --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs @@ -0,0 +1,18 @@ +//@ edition:2024 +// Ensure that we don't make structured suggestions for interior mutability note +// when span is not available. + +use std::sync::Mutex; + +macro_rules! declare_mutex { + () => { + static mut MACRO_MUTEX: Mutex = Mutex::new(false); + }; +} + +declare_mutex!(); + +fn main() { + let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr new file mode 100644 index 0000000000000..5ce69e1a14d83 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr @@ -0,0 +1,13 @@ +error: creating a shared reference to mutable static + --> $DIR/static-mut-refs-interior-mutability-no-sugg.rs:16:26 + | +LL | let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; + | ^^^^^^^^^^^^^^^^^^ shared reference to mutable static + | + = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit + = note: for more information, see + = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.fixed b/tests/ui/lint/static-mut-refs-interior-mutability.fixed new file mode 100644 index 0000000000000..d5b096119cce1 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.fixed @@ -0,0 +1,13 @@ +//@ edition:2024 +//@ run-rustfix + +#![allow(unused_unsafe)] + +use std::sync::Mutex; + +static STDINOUT_MUTEX: Mutex = Mutex::new(false); + +fn main() { + let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.rs b/tests/ui/lint/static-mut-refs-interior-mutability.rs new file mode 100644 index 0000000000000..f5d0fca5b45d7 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.rs @@ -0,0 +1,13 @@ +//@ edition:2024 +//@ run-rustfix + +#![allow(unused_unsafe)] + +use std::sync::Mutex; + +static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); + +fn main() { + let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.stderr b/tests/ui/lint/static-mut-refs-interior-mutability.stderr new file mode 100644 index 0000000000000..29ab5a5c404de --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.stderr @@ -0,0 +1,17 @@ +error: creating a shared reference to mutable static + --> $DIR/static-mut-refs-interior-mutability.rs:11:26 + | +LL | let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + | ^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static + | + = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = note: for more information, see + = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable + | +LL - static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); +LL + static STDINOUT_MUTEX: Mutex = Mutex::new(false); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/byte-literals.stderr b/tests/ui/parser/byte-literals.stderr index 1c89e8e2864b6..4df5f764cfe85 100644 --- a/tests/ui/parser/byte-literals.stderr +++ b/tests/ui/parser/byte-literals.stderr @@ -5,6 +5,11 @@ LL | static FOO: u8 = b'\f'; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - static FOO: u8 = b'\f'; +LL + static FOO: u8 = b'\x0C'; + | error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 @@ -13,6 +18,11 @@ LL | b'\f'; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - b'\f'; +LL + b'\x0C'; + | error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 diff --git a/tests/ui/parser/byte-string-literals.stderr b/tests/ui/parser/byte-string-literals.stderr index 3e589258d4132..d036fae68ea1f 100644 --- a/tests/ui/parser/byte-string-literals.stderr +++ b/tests/ui/parser/byte-string-literals.stderr @@ -5,6 +5,11 @@ LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - static FOO: &'static [u8] = b"\f"; +LL + static FOO: &'static [u8] = b"\x0C"; + | error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 @@ -13,6 +18,11 @@ LL | b"\f"; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - b"\f"; +LL + b"\x0C"; + | error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 diff --git a/tests/ui/parser/foreign-escapes.rs b/tests/ui/parser/foreign-escapes.rs new file mode 100644 index 0000000000000..d802f858f8e31 --- /dev/null +++ b/tests/ui/parser/foreign-escapes.rs @@ -0,0 +1,25 @@ +// Specified by both C and Rust +pub const SINGLE_QUOTE: char = '\''; +pub const DOUBLE_QUOTE: char = '\"'; +pub const BACKSLASH: char = '\\'; +pub const NEWLINE: char = '\n'; +pub const CARRIAGE_RETURN: char = '\r'; +pub const HORIZONTAL_TAB: char = '\t'; +pub const NULL: char = '\0'; + +// Specified by C, but not Rust +pub const QUESTION_MARK: char = '\?'; //~ ERROR unknown character escape +pub const AUDIBLE_BELL: char = '\a'; //~ ERROR unknown character escape +pub const BACKSPACE: char = '\b'; //~ ERROR unknown character escape +pub const FORM_FEED: char = '\f'; //~ ERROR unknown character escape +pub const VERTICAL_TAB: char = '\v'; //~ ERROR unknown character escape +pub const OCTAL: char = '\1'; //~ ERROR unknown character escape +pub const OCTAL_TWO_DIGIT: char = '\12'; //~ ERROR unknown character escape +pub const OCTAL_THREE_DIGIT: char = '\12'; //~ ERROR unknown character escape +pub const OCTAL_OUT_OF_RANGE: char = '\9'; //~ ERROR unknown character escape + +// Not specified by C, but recognized by GCC as an extension. +// Used for ANSI escape sequences in terminal emulators. +pub const ESCAPE: char = '\e'; //~ ERROR unknown character escape + +fn main() {} diff --git a/tests/ui/parser/foreign-escapes.stderr b/tests/ui/parser/foreign-escapes.stderr new file mode 100644 index 0000000000000..619d7d1e6e8b7 --- /dev/null +++ b/tests/ui/parser/foreign-escapes.stderr @@ -0,0 +1,165 @@ +error: unknown character escape: `?` + --> $DIR/foreign-escapes.rs:11:35 + | +LL | pub const QUESTION_MARK: char = '\?'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const QUESTION_MARK: char = '\?'; +LL + pub const QUESTION_MARK: char = r"\?"; + | +help: if you meant to write a literal question mark, don't escape the character + | +LL - pub const QUESTION_MARK: char = '\?'; +LL + pub const QUESTION_MARK: char = '?'; + | + +error: unknown character escape: `a` + --> $DIR/foreign-escapes.rs:12:34 + | +LL | pub const AUDIBLE_BELL: char = '\a'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const AUDIBLE_BELL: char = '\a'; +LL + pub const AUDIBLE_BELL: char = r"\a"; + | +help: if you meant to write an audible bell, use a hex escape + | +LL - pub const AUDIBLE_BELL: char = '\a'; +LL + pub const AUDIBLE_BELL: char = '\x07'; + | + +error: unknown character escape: `b` + --> $DIR/foreign-escapes.rs:13:31 + | +LL | pub const BACKSPACE: char = '\b'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const BACKSPACE: char = '\b'; +LL + pub const BACKSPACE: char = r"\b"; + | +help: if you meant to write a backspace, use a hex escape + | +LL - pub const BACKSPACE: char = '\b'; +LL + pub const BACKSPACE: char = '\x08'; + | + +error: unknown character escape: `f` + --> $DIR/foreign-escapes.rs:14:31 + | +LL | pub const FORM_FEED: char = '\f'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const FORM_FEED: char = '\f'; +LL + pub const FORM_FEED: char = r"\f"; + | +help: if you meant to write a form feed, use a hex escape + | +LL - pub const FORM_FEED: char = '\f'; +LL + pub const FORM_FEED: char = '\x0C'; + | + +error: unknown character escape: `v` + --> $DIR/foreign-escapes.rs:15:34 + | +LL | pub const VERTICAL_TAB: char = '\v'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const VERTICAL_TAB: char = '\v'; +LL + pub const VERTICAL_TAB: char = r"\v"; + | +help: if you meant to write a vertical tab, use a hex escape + | +LL - pub const VERTICAL_TAB: char = '\v'; +LL + pub const VERTICAL_TAB: char = '\x0B'; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:16:27 + | +LL | pub const OCTAL: char = '\1'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL: char = '\1'; +LL + pub const OCTAL: char = r"\1"; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:17:37 + | +LL | pub const OCTAL_TWO_DIGIT: char = '\12'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_TWO_DIGIT: char = '\12'; +LL + pub const OCTAL_TWO_DIGIT: char = r"\12"; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:18:39 + | +LL | pub const OCTAL_THREE_DIGIT: char = '\12'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_THREE_DIGIT: char = '\12'; +LL + pub const OCTAL_THREE_DIGIT: char = r"\12"; + | + +error: unknown character escape: `9` + --> $DIR/foreign-escapes.rs:19:40 + | +LL | pub const OCTAL_OUT_OF_RANGE: char = '\9'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_OUT_OF_RANGE: char = '\9'; +LL + pub const OCTAL_OUT_OF_RANGE: char = r"\9"; + | + +error: unknown character escape: `e` + --> $DIR/foreign-escapes.rs:23:28 + | +LL | pub const ESCAPE: char = '\e'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const ESCAPE: char = '\e'; +LL + pub const ESCAPE: char = r"\e"; + | +help: if you meant to write an ANSI escape sequence, use a hex escape + | +LL - pub const ESCAPE: char = '\e'; +LL + pub const ESCAPE: char = '\x1B'; + | + +error: aborting due to 10 previous errors + diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 62f6ec92d493c..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -42,11 +42,8 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -56,22 +53,14 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -134,11 +123,8 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -154,28 +140,17 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -191,22 +166,14 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -257,59 +224,35 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 3e0efad974cd2..45193552b507f 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -42,11 +42,8 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -56,22 +53,14 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -134,11 +123,8 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -154,28 +140,17 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -191,22 +166,14 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -257,59 +224,35 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 62f6ec92d493c..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -42,11 +42,8 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -56,22 +53,14 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -134,11 +123,8 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -154,28 +140,17 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -191,22 +166,14 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -257,59 +224,35 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 62f6ec92d493c..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -42,11 +42,8 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -56,22 +53,14 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -134,11 +123,8 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -154,28 +140,17 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -191,22 +166,14 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -257,59 +224,35 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index b25e4a9b7b6f5..c2f7fec38c81f 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -42,11 +42,8 @@ error: layout_of(UnivariantU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -56,22 +53,14 @@ error: layout_of(UnivariantU8) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -134,11 +123,8 @@ error: layout_of(TwoVariantsU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -154,28 +140,17 @@ error: layout_of(TwoVariantsU8) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -191,22 +166,14 @@ error: layout_of(TwoVariantsU8) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -257,59 +224,35 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr index 134129f814aa7..43b244607885d 100644 --- a/tests/ui/statics/static-lazy-init-with-arena-set.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr @@ -12,6 +12,11 @@ LL | | }); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable + | +LL - static mut ONCE: Once = Once::new(); +LL + static ONCE: Once = Once::new(); + | warning: 1 warning emitted diff --git a/tests/ui/suggestions/suggest-collect.rs b/tests/ui/suggestions/suggest-collect.rs new file mode 100644 index 0000000000000..44e8909fca20f --- /dev/null +++ b/tests/ui/suggestions/suggest-collect.rs @@ -0,0 +1,16 @@ +fn main() { + let _x: String = "hello".chars().map(|c| c); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `String` + + let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `Vec` + + let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `Result, _>` + let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `(Vec, Vec)` +} diff --git a/tests/ui/suggestions/suggest-collect.stderr b/tests/ui/suggestions/suggest-collect.stderr new file mode 100644 index 0000000000000..a7bca2bbcaa7b --- /dev/null +++ b/tests/ui/suggestions/suggest-collect.stderr @@ -0,0 +1,63 @@ +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:2:22 + | +LL | let _x: String = "hello".chars().map(|c| c); + | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected struct `String` + found struct `Map, {closure@$DIR/suggest-collect.rs:2:42: 2:45}>` +help: consider using `.collect()` to convert the `Iterator` into a `String` + | +LL | let _x: String = "hello".chars().map(|c| c).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:6:24 + | +LL | let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x); + | -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected struct `Vec` + found struct `Map, {closure@$DIR/suggest-collect.rs:6:54: 6:57}>` +help: consider using `.collect()` to convert the `Iterator` into a `Vec` + | +LL | let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:10:36 + | +LL | let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()); + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result, _>`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected enum `Result, _>` + found struct `Map, {closure@$DIR/suggest-collect.rs:10:63: 10:66}>` +help: consider using `.collect()` to convert the `Iterator` into a `Result, _>` + | +LL | let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:13:40 + | +LL | let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)); + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(Vec, Vec)`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected tuple `(Vec, Vec)` + found struct `Map, {closure@$DIR/suggest-collect.rs:13:67: 13:70}>` +help: consider using `.collect()` to convert the `Iterator` into a `(Vec, Vec)` + | +LL | let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)).collect(); + | ++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index 9f27be86bff44..7d3e61770c2c7 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -86,32 +86,18 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Scalar( Initialized { value: Pointer( @@ -122,14 +108,12 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { valid_range: 1..=18446744073709551615, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -142,12 +126,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index d0dad5648d76f..556376164d9a3 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -127,32 +127,18 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -162,14 +148,12 @@ error: layout_of(Option<(u32) is 1..>) = Layout { valid_range: 1..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -181,12 +165,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -238,32 +216,18 @@ error: layout_of(Option>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -273,14 +237,12 @@ error: layout_of(Option>) = Layout { valid_range: 1..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -292,12 +254,6 @@ error: layout_of(Option>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], },