diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 7f85b52f083a7..a972061d88b3b 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -34,13 +34,13 @@ impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} pub trait DispatchFromDyn {} // &T -> &U -impl<'a, T: ?Sized+Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized+Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} +impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} impl, U: ?Sized> DispatchFromDyn> for Box {} #[lang = "receiver"] @@ -285,7 +285,6 @@ impl PartialEq for u32 { } } - impl PartialEq for u64 { fn eq(&self, other: &u64) -> bool { (*self) == (*other) @@ -358,7 +357,7 @@ impl PartialEq for *const T { } } -impl PartialEq for Option { +impl PartialEq for Option { fn eq(&self, other: &Self) -> bool { match (self, other) { (Some(lhs), Some(rhs)) => *lhs == *rhs, @@ -469,7 +468,11 @@ pub fn panic(_msg: &'static str) -> ! { #[track_caller] fn panic_bounds_check(index: usize, len: usize) -> ! { unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); + libc::printf( + "index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, + len, + index, + ); intrinsics::abort(); } } @@ -495,9 +498,8 @@ pub trait Deref { } #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull(pub *const T); +pub struct NonNull(pub Ranged<*const T, { 1..=(usize::MAX as u128) }>); impl CoerceUnsized> for NonNull where T: Unsize {} impl DispatchFromDyn> for NonNull where T: Unsize {} @@ -585,7 +587,7 @@ pub mod libc { // functions. legacy_stdio_definitions.lib which provides the printf wrapper functions as normal // symbols to link against. #[cfg_attr(unix, link(name = "c"))] - #[cfg_attr(target_env="msvc", link(name="legacy_stdio_definitions"))] + #[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))] extern "C" { pub fn printf(format: *const i8, ...) -> i32; } @@ -624,7 +626,7 @@ impl Index for [T] { } } -extern { +extern "C" { type VaListImpl; } @@ -634,23 +636,33 @@ pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] -pub macro stringify($($t:tt)*) { /* compiler built-in */ } +pub macro stringify($($t:tt)*) { + /* compiler built-in */ +} #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] -pub macro file() { /* compiler built-in */ } +pub macro file() { + /* compiler built-in */ +} #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] -pub macro line() { /* compiler built-in */ } +pub macro line() { + /* compiler built-in */ +} #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] -pub macro cfg() { /* compiler built-in */ } +pub macro cfg() { + /* compiler built-in */ +} #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] -pub macro global_asm() { /* compiler built-in */ } +pub macro global_asm() { + /* compiler built-in */ +} pub static A_STATIC: u8 = 42; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 8aa56c275d91b..bfcc0462b356e 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -761,7 +761,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // *After* all of this, check the ABI. We need to check the ABI to handle // types like `NonNull` where the `Scalar` info is more restrictive than what - // the fields say (`rustc_layout_scalar_valid_range_start`). + // the fields say (`Ranged`). // But in most cases, this will just propagate what the fields say, // and then we want the error to point at the field -- so, first recurse, // then check ABI. @@ -783,6 +783,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } Abi::ScalarPair(a_layout, b_layout) => { + // FIXME: range restrictions work on the first element of a pair. // There is no `rustc_layout_scalar_valid_range_start` for pairs, so // we would validate these things as we descend into the fields, // but that can miss bugs in layout computation. Layout computation diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index aee1f93b1a39c..09fa388f34487 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -466,7 +466,10 @@ macro_rules! make_value_visitor { ); // ... that contains a `NonNull`... (gladly, only a single field here) assert_eq!(nonnull_ptr.layout().fields.count(), 1); - let raw_ptr = nonnull_ptr.project_field(self.ecx(), 0)?; // the actual raw ptr + let ranged = nonnull_ptr.project_field(self.ecx(), 0)?; // the Ranged struct + // ... which then contains a `Ranged<*const T>` ... + assert_eq!(ranged.layout().fields.count(), 1); + let raw_ptr = ranged.project_field(self.ecx(), 0)?; // the actual raw ptr // ... whose only field finally is a raw ptr we can dereference. self.visit_box(&raw_ptr)?; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 81b82a21fa1a7..4b9e23376d872 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -121,6 +121,7 @@ struct TypeChecker<'a, 'tcx> { } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + #[track_caller] fn fail(&self, location: Location, msg: impl AsRef) { let span = self.body.source_info(location).span; // We use `delay_span_bug` as we might see broken MIR when other errors have already @@ -281,12 +282,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let check_equal = |this: &Self, location, f_ty| { if !this.mir_assign_valid_types(ty, f_ty) { this.fail( - location, - format!( - "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`", - parent, f, ty, f_ty + location, + format!( + "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`", + parent, f, ty, f_ty + ) ) - ) } }; diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index bc5bfe2a24448..0a88984435e9b 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -211,13 +211,6 @@ passes_export_name = attribute should be applied to a free function, impl method or static .label = not a free function, impl method or static -passes_rustc_layout_scalar_valid_range_not_struct = - attribute should be applied to a struct - .label = not a struct - -passes_rustc_layout_scalar_valid_range_arg = - expected exactly one integer literal argument - passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics .label = non-const generic parameter diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 14c8e3c458c49..2a6b1de095ad0 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -659,16 +659,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Layout related: // ========================================================================== - rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ - niche optimizations in libcore and libstd and will never be stable", - ), - rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ - niche optimizations in libcore and libstd and will never be stable", - ), rustc_attr!( rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \ diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index a55224d10972a..3d6eca63650c5 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -193,6 +193,8 @@ language_item_table! { Index, sym::index, index_trait, Target::Trait, GenericRequirement::Exact(1); IndexMut, sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1); + Ranged, sym::ranged , ranged_type, Target::Struct, GenericRequirement::None; + UnsafeCell, sym::unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None; VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 27c04d828111d..41a2a9541f28b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -52,7 +52,7 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{Abi, VariantIdx}; use rustc_trait_selection::traits::{self, misc::can_type_implement_copy}; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -2524,32 +2524,27 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { } // Recurse and checks for some compound types. (but not unions) Adt(adt_def, substs) if !adt_def.is_union() => { - // First check if this ADT has a layout attribute (like `NonNull` and friends). - use std::ops::Bound; - match cx.tcx.layout_scalar_valid_range(adt_def.did()) { - // We exploit here that `layout_scalar_valid_range` will never - // return `Bound::Excluded`. (And we have tests checking that we - // handle the attribute correctly.) - // We don't add a span since users cannot declare such types anyway. - (Bound::Included(lo), Bound::Included(hi)) if 0 < lo && lo < hi => { - return Some((format!("`{}` must be non-null", ty), None)); - } - (Bound::Included(lo), Bound::Unbounded) if 0 < lo => { - return Some((format!("`{}` must be non-null", ty), None)); - } - (Bound::Included(_), _) | (_, Bound::Included(_)) - if init == InitKind::Uninit => - { - return Some(( - format!( - "`{}` must be initialized inside its custom valid range", - ty, - ), - None, - )); + // First check if this ADT has a constrained layout (like `NonNull` and friends). + if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) { + match &layout.abi { + Abi::Scalar(scalar) | Abi::ScalarPair(scalar, _) => { + let range = scalar.valid_range(cx); + if !range.contains(0) { + return Some((format!("`{}` must be non-null", ty), None)); + } else if init == InitKind::Uninit && !scalar.is_always_valid(cx) { + return Some(( + format!( + "`{}` must be initialized inside its custom valid range", + ty, + ), + None, + )); + } + } + _ => {} } - _ => {} } + // Handle structs. if adt_def.is_struct() { return variant_find_init_error( diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 36bda3e0f6bb2..e02fa347babdc 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -47,7 +47,7 @@ pub fn symbols(input: TokenStream) -> TokenStream { /// `u32::MAX`. You can also customize things like the `Debug` impl, /// what traits are derived, and so forth via the macro. #[proc_macro] -#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)] +#[allow_internal_unstable(step_trait, rustc_attrs, ranged_int, trusted_step)] pub fn newtype_index(input: TokenStream) -> TokenStream { newtype::newtype(input) } diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index 0a77b734c7641..49647ce301977 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -138,7 +138,7 @@ impl Parse for Newtype { } impl ::rustc_serialize::Encodable for #name { fn encode(&self, e: &mut E) { - e.emit_u32(self.private); + e.emit_u32(self.as_u32()); } } } @@ -196,10 +196,10 @@ impl Parse for Newtype { Ok(Self(quote! { #(#attrs)* #[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)] - #[rustc_layout_scalar_valid_range_end(#max)] + #[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_end(#max))] #[rustc_pass_by_value] #vis struct #name { - private: u32, + private: std::num::Ranged, } #(#consts)* @@ -249,7 +249,7 @@ impl Parse for Newtype { /// Prefer using `from_u32`. #[inline] #vis const unsafe fn from_u32_unchecked(value: u32) -> Self { - Self { private: value } + Self { private: std::num::Ranged::new_unchecked(value) } } /// Extracts the value of this index as a `usize`. @@ -261,7 +261,7 @@ impl Parse for Newtype { /// Extracts the value of this index as a `u32`. #[inline] #vis const fn as_u32(self) -> u32 { - self.private + self.private.get() } /// Extracts the value of this index as a `usize`. diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index efd7357afc46c..765c630f75dcc 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -30,14 +30,11 @@ pub enum UnsafetyViolationKind { pub enum UnsafetyViolationDetails { CallToUnsafeFunction, UseOfInlineAssembly, - InitializingTypeWith, CastOfPointerToInt, UseOfMutableStatic, UseOfExternStatic, DerefOfRawPointer, AccessToUnionField, - MutationOfLayoutConstrainedField, - BorrowOfLayoutConstrainedField, CallToFunctionWith, } @@ -54,11 +51,6 @@ impl UnsafetyViolationDetails { "use of inline assembly", "inline assembly is entirely unchecked and can cause undefined behavior", ), - InitializingTypeWith => ( - "initializing type with `rustc_layout_scalar_valid_range` attr", - "initializing a layout restricted type's field with a value outside the valid \ - range is undefined behavior", - ), CastOfPointerToInt => { ("cast of pointer to int", "casting pointers to integers in constants") } @@ -82,15 +74,6 @@ impl UnsafetyViolationDetails { "the field may not be properly initialized: using uninitialized data will cause \ undefined behavior", ), - MutationOfLayoutConstrainedField => ( - "mutation of layout constrained field", - "mutating layout constrained fields cannot statically be checked for valid values", - ), - BorrowOfLayoutConstrainedField => ( - "borrow of layout constrained field with interior mutability", - "references to fields of layout constrained fields lose the constraints. Coupled \ - with interior mutability, the field can be changed to invalid values", - ), CallToFunctionWith => ( "call to function with `#[target_feature]`", "can only be called if the required target features are available", diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index b0a2412ab153f..d162ec4b43816 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -51,6 +51,8 @@ bitflags! { const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. const IS_UNSAFE_CELL = 1 << 9; + /// Indicates whether the type is `Ranged`. + const IS_RANGED = 1 << 10; } } @@ -249,6 +251,9 @@ impl AdtDefData { if Some(did) == tcx.lang_items().unsafe_cell_type() { flags |= AdtFlags::IS_UNSAFE_CELL; } + if Some(did) == tcx.lang_items().ranged_type() { + flags |= AdtFlags::IS_RANGED; + } AdtDefData { did, variants, flags, repr } } @@ -341,6 +346,12 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_UNSAFE_CELL) } + /// Returns `true` if this is `Ranged`. + #[inline] + pub fn is_ranged(self) -> bool { + self.flags().contains(AdtFlags::IS_RANGED) + } + /// Returns `true` if this is `ManuallyDrop`. #[inline] pub fn is_manually_drop(self) -> bool { diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 7436f0f6f4d33..f3186e1c30c3d 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -245,6 +245,18 @@ impl ScalarInt { self.to_bits(size) } + // Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt` + // in not equal to `Size { raw: 1 }` or if the value is not 0 or 1 and returns the `size` + // value of the `ScalarInt` in that case. + #[inline] + pub fn try_to_bool(self) -> Result { + match self.try_to_u8()? { + 0 => Ok(false), + 1 => Ok(true), + _ => Err(self.size()), + } + } + // Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt` // in not equal to `Size { raw: 1 }` and returns the `size` value of the `ScalarInt` in // that case. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8e24f4813a7e8..1f6e62799c8fe 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -77,7 +77,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::iter; use std::mem; -use std::ops::{Bound, Deref}; +use std::ops::Deref; use std::sync::Arc; use super::{ImplPolarity, ResolverOutputs, RvalueScopes}; @@ -1190,36 +1190,6 @@ impl<'tcx> TyCtxt<'tcx> { self.create_memory_alloc(alloc) } - /// Returns a range of the start/end indices specified with the - /// `rustc_layout_scalar_valid_range` attribute. - // FIXME(eddyb) this is an awkward spot for this method, maybe move it? - pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound, Bound) { - let get = |name| { - let Some(attr) = self.get_attr(def_id, name) else { - return Bound::Unbounded; - }; - debug!("layout_scalar_valid_range: attr={:?}", attr); - if let Some( - &[ - ast::NestedMetaItem::Literal(ast::Lit { - kind: ast::LitKind::Int(a, _), .. - }), - ], - ) = attr.meta_item_list().as_deref() - { - Bound::Included(a) - } else { - self.sess - .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute"); - Bound::Unbounded - } - }; - ( - get(sym::rustc_layout_scalar_valid_range_start), - get(sym::rustc_layout_scalar_valid_range_end), - ) - } - pub fn lift>(self, value: T) -> Option { value.lift_to_tcx(self) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3312f44c67b2a..1f6edcf50328a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -16,7 +16,6 @@ use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Targ use std::cmp::{self}; use std::fmt; use std::num::NonZeroUsize; -use std::ops::Bound; pub trait IntegerExt { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>; @@ -331,13 +330,12 @@ impl<'tcx> SizeSkeleton<'tcx> { if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 { return Ok(SizeSkeleton::Pointer { non_zero: non_zero - || match tcx.layout_scalar_valid_range(def.did()) { - (Bound::Included(start), Bound::Unbounded) => start > 0, - (Bound::Included(start), Bound::Included(end)) => { - 0 < start && start < end - } - _ => false, - }, + || def.is_ranged() + && substs[1].expect_const().to_valtree().unwrap_branch()[0] + .unwrap_leaf() + .try_to_u128() + .unwrap() + > 0, tail, }); } else { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index cbcf9cd129f3f..86b49994eab0d 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1037,5 +1037,3 @@ mod expr; mod matches; mod misc; mod scope; - -pub(crate) use expr::category::Category as ExprCategory; diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index fb1ea9ed300ad..7478cfe5791aa 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1,9 +1,7 @@ -use crate::build::ExprCategory; use rustc_middle::thir::visit::{self, Visitor}; use rustc_errors::struct_span_err; use rustc_hir as hir; -use rustc_middle::mir::BorrowKind; use rustc_middle::thir::*; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; @@ -13,7 +11,6 @@ use rustc_span::symbol::Symbol; use rustc_span::Span; use std::borrow::Cow; -use std::ops::Bound; struct UnsafetyVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -33,7 +30,6 @@ struct UnsafetyVisitor<'a, 'tcx> { assignment_info: Option<(Ty<'tcx>, Span)>, in_union_destructure: bool, param_env: ParamEnv<'tcx>, - inside_adt: bool, } impl<'tcx> UnsafetyVisitor<'_, 'tcx> { @@ -134,50 +130,6 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { } } -// Searches for accesses to layout constrained fields. -struct LayoutConstrainedPlaceVisitor<'a, 'tcx> { - found: bool, - thir: &'a Thir<'tcx>, - tcx: TyCtxt<'tcx>, -} - -impl<'a, 'tcx> LayoutConstrainedPlaceVisitor<'a, 'tcx> { - fn new(thir: &'a Thir<'tcx>, tcx: TyCtxt<'tcx>) -> Self { - Self { found: false, thir, tcx } - } -} - -impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> { - fn thir(&self) -> &'a Thir<'tcx> { - self.thir - } - - fn visit_expr(&mut self, expr: &Expr<'tcx>) { - match expr.kind { - ExprKind::Field { lhs, .. } => { - if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() { - if (Bound::Unbounded, Bound::Unbounded) - != self.tcx.layout_scalar_valid_range(adt_def.did()) - { - self.found = true; - } - } - visit::walk_expr(self, expr); - } - - // Keep walking through the expression as long as we stay in the same - // place, i.e. the expression is a place expression and not a dereference - // (since dereferencing something leads us to a different place). - ExprKind::Deref { .. } => {} - ref kind if ExprCategory::of(kind).map_or(true, |cat| cat == ExprCategory::Place) => { - visit::walk_expr(self, expr); - } - - _ => {} - } - } -} - impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { fn thir(&self) -> &'a Thir<'tcx> { &self.thir @@ -236,12 +188,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { std::mem::replace(&mut self.in_union_destructure, true); visit::walk_pat(self, pat); self.in_union_destructure = old_in_union_destructure; - } else if (Bound::Unbounded, Bound::Unbounded) - != self.tcx.layout_scalar_valid_range(adt_def.did()) - { - let old_inside_adt = std::mem::replace(&mut self.inside_adt, true); - visit::walk_pat(self, pat); - self.inside_adt = old_inside_adt; } else { visit::walk_pat(self, pat); } @@ -249,33 +195,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { visit::walk_pat(self, pat); } } - PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => { - if self.inside_adt { - let ty::Ref(_, ty, _) = ty.kind() else { - span_bug!( - pat.span, - "BindingMode::ByRef in pattern, but found non-reference type {}", - ty - ); - }; - match borrow_kind { - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => { - if !ty.is_freeze(self.tcx, self.param_env) { - self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField); - } - } - BorrowKind::Mut { .. } => { - self.requires_unsafe(pat.span, MutationOfLayoutConstrainedField); - } - } - } - visit::walk_pat(self, pat); - } - PatKind::Deref { .. } => { - let old_inside_adt = std::mem::replace(&mut self.inside_adt, false); - visit::walk_pat(self, pat); - self.inside_adt = old_inside_adt; - } _ => { visit::walk_pat(self, pat); } @@ -383,17 +302,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { ExprKind::InlineAsm { .. } => { self.requires_unsafe(expr.span, UseOfInlineAssembly); } - ExprKind::Adt(box AdtExpr { - adt_def, - variant_index: _, - substs: _, - user_ty: _, - fields: _, - base: _, - }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) { - (Bound::Unbounded, Bound::Unbounded) => {} - _ => self.requires_unsafe(expr.span, InitializingTypeWith), - }, ExprKind::Closure(box ClosureExpr { closure_id, substs: _, @@ -434,14 +342,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } ExprKind::Assign { lhs, rhs } | ExprKind::AssignOp { lhs, rhs, .. } => { let lhs = &self.thir[lhs]; - // First, check whether we are mutating a layout constrained field - let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx); - visit::walk_expr(&mut visitor, lhs); - if visitor.found { - self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField); - } - - // Second, check for accesses to union fields + // Check for accesses to union fields // don't have any special handling for AssignOp since it causes a read *and* write to lhs if matches!(expr.kind, ExprKind::Assign { .. }) { self.assignment_info = Some((lhs.ty, expr.span)); @@ -451,23 +352,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { return; // we have already visited everything by now } } - ExprKind::Borrow { borrow_kind, arg } => { - let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx); - visit::walk_expr(&mut visitor, expr); - if visitor.found { - match borrow_kind { - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique - if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) => - { - self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField) - } - BorrowKind::Mut { .. } => { - self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField) - } - BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {} - } - } - } ExprKind::Let { expr: expr_id, .. } => { let let_expr = &self.thir[expr_id]; if let ty::Adt(adt_def, _) = let_expr.ty.kind() && adt_def.is_union() { @@ -516,13 +400,10 @@ impl BodyUnsafety { enum UnsafeOpKind { CallToUnsafeFunction(Option), UseOfInlineAssembly, - InitializingTypeWith, UseOfMutableStatic, UseOfExternStatic, DerefOfRawPointer, AccessToUnionField, - MutationOfLayoutConstrainedField, - BorrowOfLayoutConstrainedField, CallToFunctionWith(DefId), } @@ -533,15 +414,10 @@ impl UnsafeOpKind { match self { CallToUnsafeFunction(..) => "call to unsafe function", UseOfInlineAssembly => "use of inline assembly", - InitializingTypeWith => "initializing type with `rustc_layout_scalar_valid_range` attr", UseOfMutableStatic => "use of mutable static", UseOfExternStatic => "use of extern static", DerefOfRawPointer => "dereference of raw pointer", AccessToUnionField => "access to union field", - MutationOfLayoutConstrainedField => "mutation of layout constrained field", - BorrowOfLayoutConstrainedField => { - "borrow of layout constrained field with interior mutability" - } CallToFunctionWith(..) => "call to function with `#[target_feature]`", } } @@ -561,11 +437,6 @@ impl UnsafeOpKind { Cow::Borrowed(self.simple_description()), "inline assembly is entirely unchecked and can cause undefined behavior", ), - InitializingTypeWith => ( - Cow::Borrowed(self.simple_description()), - "initializing a layout restricted type's field with a value outside the valid \ - range is undefined behavior", - ), UseOfMutableStatic => ( Cow::Borrowed(self.simple_description()), "mutable statics can be mutated by multiple threads: aliasing violations or data \ @@ -586,15 +457,6 @@ impl UnsafeOpKind { "the field may not be properly initialized: using uninitialized data will cause \ undefined behavior", ), - MutationOfLayoutConstrainedField => ( - Cow::Borrowed(self.simple_description()), - "mutating layout constrained fields cannot statically be checked for valid values", - ), - BorrowOfLayoutConstrainedField => ( - Cow::Borrowed(self.simple_description()), - "references to fields of layout constrained fields lose the constraints. Coupled \ - with interior mutability, the field can be changed to invalid values", - ), CallToFunctionWith(did) => ( Cow::from(format!( "call to function `{}` with `#[target_feature]`", @@ -650,7 +512,6 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam { body: &'a Body<'tcx>, body_did: LocalDefId, @@ -112,16 +110,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { match rvalue { Rvalue::Aggregate(box ref aggregate, _) => match aggregate { - &AggregateKind::Array(..) | &AggregateKind::Tuple => {} - &AggregateKind::Adt(adt_did, ..) => { - match self.tcx.layout_scalar_valid_range(adt_did) { - (Bound::Unbounded, Bound::Unbounded) => {} - _ => self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::InitializingTypeWith, - ), - } - } + &AggregateKind::Array(..) | &AggregateKind::Tuple | &AggregateKind::Adt(..) => {} &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => { let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = self.tcx.unsafety_check_result(def_id); @@ -134,16 +123,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - // On types with `scalar_valid_range`, prevent - // * `&mut x.field` - // * `x.field = y;` - // * `&x.field` if `field`'s type has interior mutability - // because either of these would allow modifying the layout constrained field and - // insert values that violate the layout constraints. - if context.is_mutating_use() || context.is_borrow() { - self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use()); - } - // Some checks below need the extra meta info of the local declaration. let decl = &self.body.local_decls[place.local]; @@ -286,44 +265,6 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { self.used_unsafe_blocks.insert(hir_id); }); } - fn check_mut_borrowing_layout_constrained_field( - &mut self, - place: Place<'tcx>, - is_mut_use: bool, - ) { - for (place_base, elem) in place.iter_projections().rev() { - match elem { - // Modifications behind a dereference don't affect the value of - // the pointer. - ProjectionElem::Deref => return, - ProjectionElem::Field(..) => { - let ty = place_base.ty(&self.body.local_decls, self.tcx).ty; - if let ty::Adt(def, _) = ty.kind() { - if self.tcx.layout_scalar_valid_range(def.did()) - != (Bound::Unbounded, Bound::Unbounded) - { - let details = if is_mut_use { - UnsafetyViolationDetails::MutationOfLayoutConstrainedField - - // Check `is_freeze` as late as possible to avoid cycle errors - // with opaque types. - } else if !place - .ty(self.body, self.tcx) - .ty - .is_freeze(self.tcx, self.param_env) - { - UnsafetyViolationDetails::BorrowOfLayoutConstrainedField - } else { - continue; - }; - self.require_unsafe(UnsafetyViolationKind::General, details); - } - } - } - _ => {} - } - } - } /// Checks whether calling `func_did` needs an `unsafe` context or not, i.e. whether /// the called function has target features the calling function hasn't. diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index ef8d6bb65590e..5acb9bf5bae8f 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -4,11 +4,12 @@ use crate::MirPass; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_index::vec::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; -use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; /// Constructs the types used when accessing a Box's pointer pub fn build_ptr_tys<'tcx>( @@ -16,24 +17,28 @@ pub fn build_ptr_tys<'tcx>( pointee: Ty<'tcx>, unique_did: DefId, nonnull_did: DefId, -) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) { + ranged_did: DefId, + ranged_range: ty::GenericArg<'tcx>, +) -> [Ty<'tcx>; 4] { let substs = tcx.intern_substs(&[pointee.into()]); let unique_ty = tcx.bound_type_of(unique_did).subst(tcx, substs); let nonnull_ty = tcx.bound_type_of(nonnull_did).subst(tcx, substs); let ptr_ty = tcx.mk_imm_ptr(pointee); - (unique_ty, nonnull_ty, ptr_ty) + let substs = tcx.intern_substs(&[ptr_ty.into(), ranged_range]); + let ranged_ty = tcx.bound_type_of(ranged_did).subst(tcx, substs); + + [unique_ty, nonnull_ty, ranged_ty, ptr_ty] } // Constructs the projection needed to access a Box's pointer pub fn build_projection<'tcx>( - unique_ty: Ty<'tcx>, - nonnull_ty: Ty<'tcx>, - ptr_ty: Ty<'tcx>, -) -> [PlaceElem<'tcx>; 3] { + [unique_ty, nonnull_ty, ranged_ty, ptr_ty]: [Ty<'tcx>; 4], +) -> [PlaceElem<'tcx>; 4] { [ PlaceElem::Field(Field::new(0), unique_ty), PlaceElem::Field(Field::new(0), nonnull_ty), + PlaceElem::Field(Field::new(0), ranged_ty), PlaceElem::Field(Field::new(0), ptr_ty), ] } @@ -42,6 +47,8 @@ struct ElaborateBoxDerefVisitor<'tcx, 'a> { tcx: TyCtxt<'tcx>, unique_did: DefId, nonnull_did: DefId, + ranged_did: DefId, + ranged_range: ty::GenericArg<'tcx>, local_decls: &'a mut LocalDecls<'tcx>, patch: MirPatch<'tcx>, } @@ -65,17 +72,22 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> { if place.projection.first() == Some(&PlaceElem::Deref) && base_ty.is_box() { let source_info = self.local_decls[place.local].source_info; - let (unique_ty, nonnull_ty, ptr_ty) = - build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did); + let field_types = build_ptr_tys( + tcx, + base_ty.boxed_ty(), + self.unique_did, + self.nonnull_did, + self.ranged_did, + self.ranged_range, + ); - let ptr_local = self.patch.new_internal(ptr_ty, source_info.span); + let ptr_local = self.patch.new_internal(field_types[3], source_info.span); self.patch.add_assign( location, Place::from(ptr_local), Rvalue::Use(Operand::Copy( - Place::from(place.local) - .project_deeper(&build_projection(unique_ty, nonnull_ty, ptr_ty), tcx), + Place::from(place.local).project_deeper(&build_projection(field_types), tcx), )), ); @@ -93,18 +105,34 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { if let Some(def_id) = tcx.lang_items().owned_box() { let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[0].did; - let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else { + let Some(unique_def) = tcx.type_of(unique_did).ty_adt_def() else { span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") }; - let nonnull_did = nonnull_def.non_enum_variant().fields[0].did; + let nonnull_did = unique_def.non_enum_variant().fields[0].did; + let ranged_did = tcx.require_lang_item(LangItem::Ranged, Some(body.span)); + let Some(nonnull_def) = tcx.type_of(nonnull_did).ty_adt_def() else { + span_bug!(tcx.def_span(nonnull_did), "expected Unique to contain NonNull") + }; + let ranged_field = nonnull_def.non_enum_variant().fields[0].did; + let ty::Adt(_, substs) = tcx.type_of(ranged_field).kind() else { + span_bug!(tcx.def_span(ranged_field), "expected NonNull to contain Ranged") + }; + let ranged_range = substs[1]; let patch = MirPatch::new(body); let local_decls = &mut body.local_decls; - let mut visitor = - ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch }; + let mut visitor = ElaborateBoxDerefVisitor { + tcx, + unique_did, + nonnull_did, + ranged_did, + ranged_range, + local_decls, + patch, + }; for (block, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { visitor.visit_basic_block_data(block, data); @@ -123,13 +151,17 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { if elem == PlaceElem::Deref && base_ty.is_box() { let new_projections = new_projections.get_or_insert_default(); - let (unique_ty, nonnull_ty, ptr_ty) = - build_ptr_tys(tcx, base_ty.boxed_ty(), unique_did, nonnull_did); + let field_types = build_ptr_tys( + tcx, + base_ty.boxed_ty(), + unique_did, + nonnull_did, + ranged_did, + ranged_range, + ); new_projections.extend_from_slice(&base.projection[last_deref..]); - new_projections.extend_from_slice(&build_projection( - unique_ty, nonnull_ty, ptr_ty, - )); + new_projections.extend_from_slice(&build_projection(field_types)); new_projections.push(PlaceElem::Deref); last_deref = i; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 42781bd25f05b..027407c2a5634 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -33,6 +33,7 @@ fn custom_coerce_unsize_info<'tcx>( def_id, substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), }); + let trait_ref = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), trait_ref); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 27a57adf964a3..ca61f8dd6d236 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -8,7 +8,7 @@ use crate::errors::{ self, AttrApplication, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel, ObjectLifetimeErr, OnlyHasEffectOn, TransparentIncompatible, UnrecognizedReprHint, }; -use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; +use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{fluent, Applicability, MultiSpan}; use rustc_expand::base::resolve_path; @@ -103,10 +103,6 @@ impl CheckAttrVisitor<'_> { ), sym::no_link => self.check_no_link(hir_id, &attr, span, target), sym::export_name => self.check_export_name(hir_id, &attr, span, target), - sym::rustc_layout_scalar_valid_range_start - | sym::rustc_layout_scalar_valid_range_end => { - self.check_rustc_layout_scalar_valid_range(&attr, span, target) - } sym::allow_internal_unstable => { self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs) } @@ -1347,32 +1343,6 @@ impl CheckAttrVisitor<'_> { } } - fn check_rustc_layout_scalar_valid_range( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { - if target != Target::Struct { - self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeNotStruct { - attr_span: attr.span, - span, - }); - return false; - } - - let Some(list) = attr.meta_item_list() else { - return false; - }; - - if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) { - true - } else { - self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span }); - false - } - } - /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index fb883ae2ed0a7..97927ef661732 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -404,22 +404,6 @@ pub struct ExportName { pub span: Span, } -#[derive(Diagnostic)] -#[diag(passes_rustc_layout_scalar_valid_range_not_struct)] -pub struct RustcLayoutScalarValidRangeNotStruct { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(passes_rustc_layout_scalar_valid_range_arg)] -pub struct RustcLayoutScalarValidRangeArg { - #[primary_span] - pub attr_span: Span, -} - #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_only)] pub struct RustcLegacyConstGenericsOnly { diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index bbeabdb55a72a..f5555846d20a7 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -34,7 +34,7 @@ impl CrateNum { impl fmt::Display for CrateNum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.private, f) + fmt::Display::fmt(&self.as_u32(), f) } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 191186af6fa08..99a8b03fa39ad 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -76,7 +76,7 @@ pub struct ExpnId { impl fmt::Debug for ExpnId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Generate crate_::{{expn_}}. - write!(f, "{:?}::{{{{expn{}}}}}", self.krate, self.local_id.private) + write!(f, "{:?}::{{{{expn{}}}}}", self.krate, self.local_id.as_u32()) } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cccc4897ecca6..673e313ba81f6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1158,6 +1158,7 @@ symbols! { question_mark, quote, range_inclusive_new, + ranged, raw_dylib, raw_eq, raw_identifiers, @@ -1268,8 +1269,6 @@ symbols! { rustc_inherit_overflow_checks, rustc_insignificant_dtor, rustc_layout, - rustc_layout_scalar_valid_range_end, - rustc_layout_scalar_valid_range_start, rustc_legacy_const_generics, rustc_lint_diagnostics, rustc_lint_opt_deny_field_access, diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 52ba0eee97cd5..ccdf03ae1097f 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -16,7 +16,6 @@ use rustc_target::abi::*; use std::cmp::{self, Ordering}; use std::iter; use std::num::NonZeroUsize; -use std::ops::Bound; use rand::{seq::SliceRandom, SeedableRng}; use rand_xoshiro::Xoshiro128StarStar; @@ -602,14 +601,14 @@ fn layout_of_uncached<'tcx>( // Compute the ABI of the element type: let e_ly = cx.layout_of(e_ty)?; let Abi::Scalar(e_abi) = e_ly.abi else { - // This error isn't caught in typeck, e.g., if - // the element type of the vector is generic. - tcx.sess.fatal(&format!( - "monomorphising SIMD type `{}` with a non-primitive-scalar \ - (integer/float/pointer) element type `{}`", - ty, e_ty - )) - }; + // This error isn't caught in typeck, e.g., if + // the element type of the vector is generic. + tcx.sess.fatal(&format!( + "monomorphising SIMD type `{}` with a non-primitive-scalar \ + (integer/float/pointer) element type `{}`", + ty, e_ty + )) + }; // Compute the size and alignment of the vector: let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?; @@ -784,54 +783,54 @@ fn layout_of_uncached<'tcx>( return Ok(tcx.intern_layout(st)); } - let (start, end) = cx.tcx.layout_scalar_valid_range(def.did()); - match st.abi { - Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { - // the asserts ensure that we are not using the - // `#[rustc_layout_scalar_valid_range(n)]` - // attribute to widen the range of anything as that would probably - // result in UB somewhere - // FIXME(eddyb) the asserts are probably not needed, - // as larger validity ranges would result in missed - // optimizations, *not* wrongly assuming the inner - // value is valid. e.g. unions enlarge validity ranges, - // because the values may be uninitialized. - if let Bound::Included(start) = start { - // FIXME(eddyb) this might be incorrect - it doesn't - // account for wrap-around (end < start) ranges. + if def.is_ranged() { + match st.abi { + Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { + match substs[0].expect_ty().kind() { + ty::Int(_) | ty::Uint(_) | ty::RawPtr(_) => {} + _ => bug!( + "unsupported type in Ranged lang item generics: {:?}", + substs[0] + ), + } + let [start, end, exhausted] = substs[1].expect_const().to_valtree().unwrap_branch() else { + bug!("invalid range constant in Ranged lang item: {:?}", substs[1]); + }; + let start = start.unwrap_leaf().try_to_u128().unwrap(); + let end = end.unwrap_leaf().try_to_u128().unwrap(); + let exhausted = exhausted.unwrap_leaf().try_to_bool().unwrap(); + assert!(!exhausted); + + let max_value = scalar.size(cx).unsigned_int_max(); + assert!(start <= max_value, "{start} > {max_value}"); + assert!(end <= max_value, "{end} > {max_value}"); + let valid_range = scalar.valid_range_mut(); - assert!(valid_range.start <= start); valid_range.start = start; - } - if let Bound::Included(end) = end { - // FIXME(eddyb) this might be incorrect - it doesn't - // account for wrap-around (end < start) ranges. - let valid_range = scalar.valid_range_mut(); - assert!(valid_range.end >= end); valid_range.end = end; - } - // Update `largest_niche` if we have introduced a larger niche. - let niche = Niche::from_scalar(dl, Size::ZERO, *scalar); - if let Some(niche) = niche { - match st.largest_niche { - Some(largest_niche) => { - // Replace the existing niche even if they're equal, - // because this one is at a lower offset. - if largest_niche.available(dl) <= niche.available(dl) { - st.largest_niche = Some(niche); + // Update `largest_niche` if we have introduced a larger niche. + let niche = Niche::from_scalar(dl, Size::ZERO, *scalar); + if let Some(niche) = niche { + match st.largest_niche { + Some(largest_niche) => { + // Replace the existing niche even if they're equal, + // because this one is at a lower offset. + if largest_niche.available(dl) <= niche.available(dl) { + st.largest_niche = Some(niche); + } } + None => st.largest_niche = Some(niche), } - None => st.largest_niche = Some(niche), } } + _ => span_bug!( + tcx.def_span(def.did()), + "nonscalar layout for Ranged type {:?}: {:#?}", + def, + st, + ), } - _ => assert!( - start == Bound::Unbounded && end == Bound::Unbounded, - "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}", - def, - st, - ), } return Ok(tcx.intern_layout(st)); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7fbe78aa52353..cc3f0f61054e1 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -808,7 +808,7 @@ impl UniverseIndex { /// name the region `'a`, but that region was not nameable from /// `U` because it was not in scope there. pub fn next_universe(self) -> UniverseIndex { - UniverseIndex::from_u32(self.private.checked_add(1).unwrap()) + UniverseIndex::from_u32(self.as_u32().checked_add(1).unwrap()) } /// Returns `true` if `self` can name a name from `other` -- in other words, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 659409557c910..0a82feb11fbbe 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -154,6 +154,7 @@ #![feature(maybe_uninit_uninit_array)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] +#![feature(ranged_int)] #![feature(slice_ptr_get)] #![feature(slice_split_at_unchecked)] #![feature(str_internals)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 311c5fa5b6834..960fa7818a7ba 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -45,6 +45,7 @@ mod uint_macros; // import uint_impl! mod error; mod int_log10; mod nonzero; +mod ranged; #[unstable(feature = "saturating_int_impl", issue = "87920")] mod saturating; mod wrapping; @@ -58,6 +59,9 @@ pub use wrapping::Wrapping; #[cfg(not(no_fp_fmt_parse))] pub use dec2flt::ParseFloatError; +#[unstable(feature = "ranged_int", issue = "none")] +pub use ranged::Ranged; + #[cfg(not(no_fp_fmt_parse))] #[stable(feature = "rust1", since = "1.0.0")] impl Error for ParseFloatError { diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 6b6f3417f8ad5..f538fc80b6da1 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -5,6 +5,7 @@ use crate::ops::{BitOr, BitOrAssign, Div, Rem}; use crate::str::FromStr; use super::from_str_radix; +use super::Ranged; use super::{IntErrorKind, ParseIntError}; use crate::intrinsics; @@ -23,7 +24,7 @@ macro_rules! impl_nonzero_fmt { } macro_rules! nonzero_integers { - ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => { + ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int:ty, $UnsignedInt:ty); )+ ) => { $( /// An integer that is known not to equal zero. /// @@ -37,10 +38,10 @@ macro_rules! nonzero_integers { #[$stability] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] - #[rustc_layout_scalar_valid_range_start(1)] + #[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(1))] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = stringify!($Ty)] - pub struct $Ty($Int); + pub struct $Ty(Ranged<$Int, {1..=(<$Int>::wrapping_sub(0, 1) as $UnsignedInt as u128)}>); impl $Ty { /// Creates a non-zero without checking whether the value is non-zero. @@ -51,6 +52,7 @@ macro_rules! nonzero_integers { /// The value must not be zero. #[$stability] #[$const_new_unchecked_stability] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { @@ -60,19 +62,20 @@ macro_rules! nonzero_integers { concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument"), (n: $Int) => n != 0 ); - Self(n) + Self(Ranged::new_unchecked(n)) } } /// Creates a non-zero if the given value is not zero. #[$stability] #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use] #[inline] pub const fn new(n: $Int) -> Option { if n != 0 { // SAFETY: we just checked that there's no `0` - Some(unsafe { Self(n) }) + Some(unsafe { Self(Ranged::new_unchecked(n)) }) } else { None } @@ -82,8 +85,9 @@ macro_rules! nonzero_integers { #[$stability] #[inline] #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] pub const fn get(self) -> $Int { - self.0 + self.0.get() } } @@ -94,7 +98,7 @@ macro_rules! nonzero_integers { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { - nonzero.0 + nonzero.0.get() } } @@ -162,18 +166,18 @@ macro_rules! nonzero_integers { } nonzero_integers! { - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8, u8); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16, u16); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32, u32); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64, u64); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128, u128); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize, usize); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8, u8); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16, u16); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32, u32); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64, u64); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128, u128); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize, usize); } macro_rules! from_str_radix_nzint_impl { @@ -213,12 +217,13 @@ macro_rules! nonzero_leading_trailing_zeros { /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] pub const fn leading_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`. - unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 } + unsafe { intrinsics::ctlz_nonzero(self.0.get() as $Uint) as u32 } } /// Returns the number of trailing zeros in the binary representation @@ -237,12 +242,13 @@ macro_rules! nonzero_leading_trailing_zeros { /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] pub const fn trailing_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. - unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 } + unsafe { intrinsics::cttz_nonzero(self.0.get() as $Uint) as u32 } } } @@ -497,7 +503,7 @@ macro_rules! nonzero_unsigned_operations { without modifying the original"] #[inline] pub const fn ilog10(self) -> u32 { - super::int_log10::$Int(self.0) + super::int_log10::$Int(self.0.get()) } } )+ diff --git a/library/core/src/num/ranged.rs b/library/core/src/num/ranged.rs new file mode 100644 index 0000000000000..ce417a63ebe51 --- /dev/null +++ b/library/core/src/num/ranged.rs @@ -0,0 +1,108 @@ +//! Definitions for `Ranged` type. + +use crate::ops::{CoerceUnsized, DispatchFromDyn, RangeInclusive}; + +#[cfg_attr(not(bootstrap), lang = "ranged")] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[repr(transparent)] +#[unstable(feature = "ranged_int", issue = "none")] +/// A type that can only represent types in the given range. +/// Layout optimizations will take. +pub struct Ranged>(T); + +impl> Ranged { + /// Create a new `Ranged` value if the passed argument is within `RANGE`. + #[unstable(feature = "ranged_int", issue = "none")] + #[inline(always)] + pub fn new(i: T) -> Option { + i.in_range(RANGE).then(|| Self(i)) + } + + /// Create a new `Ranged` value. + /// + /// Safety: the passed argument must be within `RANGE` + #[unstable(feature = "ranged_int", issue = "none")] + #[rustc_const_unstable(feature = "ranged_int", issue = "none")] + #[inline(always)] + pub const unsafe fn new_unchecked(i: T) -> Self { + Self(i) + } + + /// Fetch the wrapped value. + #[unstable(feature = "ranged_int", issue = "none")] + #[rustc_const_unstable(feature = "ranged_int", issue = "none")] + #[inline(always)] + pub const fn get(self) -> T { + self.0 + } +} + +#[unstable(feature = "ranged_int", issue = "none")] +impl> crate::ops::Deref for Ranged { + type Target = T; + #[inline(always)] + fn deref(&self) -> &T { + &self.0 + } +} + +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl> CoerceUnsized> for Ranged where + T: CoerceUnsized +{ +} + +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl> DispatchFromDyn> for Ranged where + T: DispatchFromDyn +{ +} + +/// A helper trait until we can declare `struct Ranged>(T);`. +/// This is not meant to ever be stabilized. +#[unstable(feature = "ranged_int", issue = "none")] +pub trait CheckInRange { + /// Returns `true` if the range contains `self`. + fn in_range(&self, range: RangeInclusive) -> bool; +} + +macro_rules! check_in_range { + ($(($ty:ty | $signed:ty)),*) => { + $( + #[unstable(feature = "ranged_int", issue = "none")] + impl CheckInRange for $ty { + #[inline(always)] + fn in_range(&self, range: RangeInclusive) -> bool { + range.contains(&(*self as u128)) + } + } + )* + $( + #[unstable(feature = "ranged_int", issue = "none")] + impl CheckInRange for $signed { + #[inline(always)] + fn in_range(&self, range: RangeInclusive) -> bool { + range.contains(&(*self as $ty as u128)) + } + } + )* + }; +} + +check_in_range!((u8 | i8), (u16 | i16), (u32 | i32), (u64 | i64), (u128 | i128), (usize | isize)); + +#[unstable(feature = "ranged_int", issue = "none")] +impl CheckInRange for *const T { + #[inline(always)] + fn in_range(&self, range: RangeInclusive) -> bool { + range.contains(&((*self as *const ()).addr() as u128)) + } +} + +#[unstable(feature = "ranged_int", issue = "none")] +impl CheckInRange for *mut T { + #[inline(always)] + fn in_range(&self, range: RangeInclusive) -> bool { + range.contains(&((*self as *mut ()).addr() as u128)) + } +} diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c18264d13ebac..378c1bf53ac44 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -6,6 +6,8 @@ use crate::intrinsics::assert_unsafe_precondition; use crate::marker::Unsize; use crate::mem::{self, MaybeUninit}; use crate::num::NonZeroUsize; +#[cfg(not(bootstrap))] +use crate::num::Ranged; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; @@ -48,9 +50,12 @@ use crate::slice::{self, SliceIndex}; /// [`UnsafeCell`]: crate::cell::UnsafeCell #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(1)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(1))] #[rustc_nonnull_optimization_guaranteed] pub struct NonNull { + #[cfg(not(bootstrap))] + pointer: Ranged<*const T, { 1..=(usize::MAX as u128) }>, + #[cfg(bootstrap)] pointer: *const T, } @@ -193,12 +198,20 @@ impl NonNull { /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[inline] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { // SAFETY: the caller must guarantee that `ptr` is non-null. unsafe { assert_unsafe_precondition!("NonNull::new_unchecked requires that the pointer is non-null", [T: ?Sized](ptr: *mut T) => !ptr.is_null()); - NonNull { pointer: ptr as _ } + #[cfg(not(bootstrap))] + { + NonNull { pointer: Ranged::new_unchecked(ptr as _) } + } + #[cfg(bootstrap)] + { + NonNull { pointer: ptr as _ } + } } } @@ -329,10 +342,18 @@ impl NonNull { /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use] #[inline] pub const fn as_ptr(self) -> *mut T { - self.pointer as *mut T + #[cfg(not(bootstrap))] + { + self.pointer.get() as *mut T + } + #[cfg(bootstrap)] + { + self.pointer as *mut T + } } /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] @@ -786,8 +807,16 @@ impl const From<&mut T> for NonNull { /// This conversion is safe and infallible since references cannot be null. #[inline] fn from(reference: &mut T) -> Self { + #[cfg(not(bootstrap))] // SAFETY: A mutable reference cannot be null. - unsafe { NonNull { pointer: reference as *mut T } } + unsafe { + NonNull { pointer: Ranged::new_unchecked(reference as *mut T) } + } + #[cfg(bootstrap)] + // SAFETY: A mutable reference cannot be null. + unsafe { + NonNull { pointer: reference as *mut T } + } } } @@ -799,8 +828,17 @@ impl const From<&T> for NonNull { /// This conversion is safe and infallible since references cannot be null. #[inline] fn from(reference: &T) -> Self { + #[cfg(not(bootstrap))] // SAFETY: A reference cannot be null, so the conditions for // new_unchecked() are respected. - unsafe { NonNull { pointer: reference as *const T } } + unsafe { + NonNull { pointer: Ranged::new_unchecked(reference as *const T) } + } + #[cfg(bootstrap)] + // SAFETY: A reference cannot be null, so the conditions for + // new_unchecked() are respected. + unsafe { + NonNull { pointer: reference as *const T } + } } } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 37c3611d0a908..56996e47c18c7 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -21,6 +21,7 @@ use crate::fmt; use crate::iter::Sum; +use crate::num::Ranged; use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; const NANOS_PER_SEC: u32 = 1_000_000_000; @@ -29,20 +30,6 @@ const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(999_999_999)] -struct Nanoseconds(u32); - -impl Default for Nanoseconds { - #[inline] - fn default() -> Self { - // SAFETY: 0 is within the valid range - unsafe { Nanoseconds(0) } - } -} - /// A `Duration` type to represent a span of time, typically used for system /// timeouts. /// @@ -81,11 +68,18 @@ impl Default for Nanoseconds { /// compatibility, you may wish to format `Duration` objects yourself or use a /// crate to do so. #[stable(feature = "duration", since = "1.3.0")] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(not(test), rustc_diagnostic_item = "Duration")] pub struct Duration { secs: u64, - nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC + nanos: Ranged, +} + +#[stable(feature = "duration", since = "1.3.0")] +impl Default for Duration { + fn default() -> Self { + Self { secs: 0, nanos: Ranged::new(0).unwrap() } + } } impl Duration { @@ -196,6 +190,7 @@ impl Duration { #[inline] #[must_use] #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] pub const fn new(secs: u64, nanos: u32) -> Duration { let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { Some(secs) => secs, @@ -203,7 +198,7 @@ impl Duration { }; let nanos = nanos % NANOS_PER_SEC; // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range - Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } + Duration { secs, nanos: unsafe { Ranged::new_unchecked(nanos) } } } /// Creates a new `Duration` from the specified number of whole seconds. @@ -307,7 +302,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")] #[inline] pub const fn is_zero(&self) -> bool { - self.secs == 0 && self.nanos.0 == 0 + self.secs == 0 && self.subsec_nanos() == 0 } /// Returns the number of _whole_ seconds contained by this `Duration`. @@ -358,7 +353,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_millis(&self) -> u32 { - self.nanos.0 / NANOS_PER_MILLI + self.subsec_nanos() / NANOS_PER_MILLI } /// Returns the fractional part of this `Duration`, in whole microseconds. @@ -381,7 +376,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_micros(&self) -> u32 { - self.nanos.0 / NANOS_PER_MICRO + self.subsec_nanos() / NANOS_PER_MICRO } /// Returns the fractional part of this `Duration`, in nanoseconds. @@ -401,10 +396,11 @@ impl Duration { /// ``` #[stable(feature = "duration", since = "1.3.0")] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[must_use] #[inline] pub const fn subsec_nanos(&self) -> u32 { - self.nanos.0 + self.nanos.get() } /// Returns the total number of whole milliseconds contained by this `Duration`. @@ -422,7 +418,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_millis(&self) -> u128 { - self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MILLI) as u128 + self.secs as u128 * MILLIS_PER_SEC as u128 + (self.subsec_nanos() / NANOS_PER_MILLI) as u128 } /// Returns the total number of whole microseconds contained by this `Duration`. @@ -440,7 +436,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_micros(&self) -> u128 { - self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MICRO) as u128 + self.secs as u128 * MICROS_PER_SEC as u128 + (self.subsec_nanos() / NANOS_PER_MICRO) as u128 } /// Returns the total number of nanoseconds contained by this `Duration`. @@ -458,7 +454,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_nanos(&self) -> u128 { - self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.0 as u128 + self.secs as u128 * NANOS_PER_SEC as u128 + self.subsec_nanos() as u128 } /// Checked `Duration` addition. Computes `self + other`, returning [`None`] @@ -481,7 +477,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_add(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_add(rhs.secs) { - let mut nanos = self.nanos.0 + rhs.nanos.0; + let mut nanos = self.subsec_nanos() + rhs.subsec_nanos(); if nanos >= NANOS_PER_SEC { nanos -= NANOS_PER_SEC; if let Some(new_secs) = secs.checked_add(1) { @@ -541,11 +537,11 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_sub(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { - let nanos = if self.nanos.0 >= rhs.nanos.0 { - self.nanos.0 - rhs.nanos.0 + let nanos = if self.subsec_nanos() >= rhs.subsec_nanos() { + self.subsec_nanos() - rhs.subsec_nanos() } else if let Some(sub_secs) = secs.checked_sub(1) { secs = sub_secs; - self.nanos.0 + NANOS_PER_SEC - rhs.nanos.0 + self.subsec_nanos() + NANOS_PER_SEC - rhs.subsec_nanos() } else { return None; }; @@ -599,7 +595,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_mul(self, rhs: u32) -> Option { // Multiply nanoseconds as u64, because it cannot overflow that way. - let total_nanos = self.nanos.0 as u64 * rhs as u64; + let total_nanos = self.subsec_nanos() as u64 * rhs as u64; let extra_secs = total_nanos / (NANOS_PER_SEC as u64); let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32; if let Some(s) = self.secs.checked_mul(rhs as u64) { @@ -659,7 +655,7 @@ impl Duration { let secs = self.secs / (rhs as u64); let carry = self.secs - secs * (rhs as u64); let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64); - let nanos = self.nanos.0 / rhs + (extra_nanos as u32); + let nanos = self.subsec_nanos() / rhs + (extra_nanos as u32); debug_assert!(nanos < NANOS_PER_SEC); Some(Duration::new(secs, nanos)) } else { @@ -683,7 +679,7 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn as_secs_f64(&self) -> f64 { - (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64) + (self.secs as f64) + (self.subsec_nanos() as f64) / (NANOS_PER_SEC as f64) } /// Returns the number of seconds contained by this `Duration` as `f32`. @@ -702,7 +698,7 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn as_secs_f32(&self) -> f32 { - (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32) + (self.secs as f32) + (self.subsec_nanos() as f32) / (NANOS_PER_SEC as f32) } /// Creates a new `Duration` from the specified number of seconds represented @@ -993,13 +989,13 @@ macro_rules! sum_durations { for entry in $iter { total_secs = total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations"); - total_nanos = match total_nanos.checked_add(entry.nanos.0 as u64) { + total_nanos = match total_nanos.checked_add(entry.nanos.get() as u64) { Some(n) => n, None => { total_secs = total_secs .checked_add(total_nanos / NANOS_PER_SEC as u64) .expect("overflow in iter::sum over durations"); - (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.0 as u64 + (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.get() as u64 } }; } @@ -1191,27 +1187,27 @@ impl fmt::Debug for Duration { let prefix = if f.sign_plus() { "+" } else { "" }; if self.secs > 0 { - fmt_decimal(f, self.secs, self.nanos.0, NANOS_PER_SEC / 10, prefix, "s") - } else if self.nanos.0 >= NANOS_PER_MILLI { + fmt_decimal(f, self.secs, self.subsec_nanos(), NANOS_PER_SEC / 10, prefix, "s") + } else if self.subsec_nanos() >= NANOS_PER_MILLI { fmt_decimal( f, - (self.nanos.0 / NANOS_PER_MILLI) as u64, - self.nanos.0 % NANOS_PER_MILLI, + (self.subsec_nanos() / NANOS_PER_MILLI) as u64, + self.subsec_nanos() % NANOS_PER_MILLI, NANOS_PER_MILLI / 10, prefix, "ms", ) - } else if self.nanos.0 >= NANOS_PER_MICRO { + } else if self.subsec_nanos() >= NANOS_PER_MICRO { fmt_decimal( f, - (self.nanos.0 / NANOS_PER_MICRO) as u64, - self.nanos.0 % NANOS_PER_MICRO, + (self.subsec_nanos() / NANOS_PER_MICRO) as u64, + self.subsec_nanos() % NANOS_PER_MICRO, NANOS_PER_MICRO / 10, prefix, "µs", ) } else { - fmt_decimal(f, self.nanos.0 as u64, 0, 1, prefix, "ns") + fmt_decimal(f, self.subsec_nanos() as u64, 0, 1, prefix, "ns") } } } diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index a05128de471ab..c4ca818e7de7c 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -11,6 +11,13 @@ fn creation() { assert_eq!(Duration::from_millis(4000), Duration::new(4, 0)); } +#[test] +fn niche() { + assert_eq!(std::mem::size_of::(), 16); + #[cfg(not(bootstrap))] + assert_eq!(std::mem::size_of::>(), 16); +} + #[test] #[should_panic] fn new_overflow() { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 385585dada896..304d2f95c0d19 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -265,6 +265,7 @@ #![feature(never_type)] #![feature(platform_intrinsics)] #![feature(prelude_import)] +#![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(staged_api)] @@ -305,6 +306,7 @@ #![feature(prelude_2024)] #![feature(provide_any)] #![feature(ptr_as_uninit)] +#![feature(ranged_int)] #![feature(raw_os_nonzero)] #![feature(slice_internals)] #![feature(slice_ptr_get)] diff --git a/library/std/src/num.rs b/library/std/src/num.rs index 46064bd283770..473d70088a38e 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -27,6 +27,9 @@ pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, #[stable(feature = "int_error_matching", since = "1.55.0")] pub use core::num::IntErrorKind; +#[unstable(feature = "ranged_int", issue = "none")] +pub use core::num::Ranged; + #[cfg(test)] use crate::fmt; #[cfg(test)] diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index c16518577f7c4..c48d610a68bf3 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -9,6 +9,7 @@ use crate::fs; use crate::io; use crate::marker::PhantomData; use crate::mem::forget; +use crate::num::Ranged; #[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))] use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -28,15 +29,15 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; /// descriptor, which is then borrowed under the same lifetime. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(0))] // libstd/os/raw/mod.rs assures me that every libstd-supported platform has a // 32-bit c_int. Below is -2, in two's complement, but that only works out // because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct BorrowedFd<'fd> { - fd: RawFd, + fd: Ranged, _phantom: PhantomData<&'fd OwnedFd>, } @@ -49,15 +50,15 @@ pub struct BorrowedFd<'fd> { /// passed as a consumed argument or returned as an owned value, and it never /// has the value `-1`. #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(0))] // libstd/os/raw/mod.rs assures me that every libstd-supported platform has a // 32-bit c_int. Below is -2, in two's complement, but that only works out // because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct OwnedFd { - fd: RawFd, + fd: Ranged, } impl BorrowedFd<'_> { @@ -69,11 +70,12 @@ impl BorrowedFd<'_> { /// the returned `BorrowedFd`, and it must not have the value `-1`. #[inline] #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(fd: RawFd) -> Self { assert!(fd != u32::MAX as RawFd); // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd, _phantom: PhantomData } } + unsafe { Self { fd: Ranged::new_unchecked(fd), _phantom: PhantomData } } } } @@ -126,7 +128,7 @@ impl BorrowedFd<'_> { impl AsRawFd for BorrowedFd<'_> { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.get() } } @@ -134,7 +136,7 @@ impl AsRawFd for BorrowedFd<'_> { impl AsRawFd for OwnedFd { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.get() } } @@ -144,7 +146,7 @@ impl IntoRawFd for OwnedFd { fn into_raw_fd(self) -> RawFd { let fd = self.fd; forget(self); - fd + fd.get() } } @@ -159,8 +161,14 @@ impl FromRawFd for OwnedFd { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> Self { assert_ne!(fd, u32::MAX as RawFd); + let fd = Ranged::new(fd).unwrap(); + #[cfg(bootstrap)] // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd } } + unsafe { + Self { fd } + } + #[cfg(not(bootstrap))] + Self { fd } } } @@ -174,7 +182,7 @@ impl Drop for OwnedFd { // the file descriptor was closed or not, and if we retried (for // something like EINTR), we might close another valid file descriptor // opened after we closed ours. - let _ = libc::close(self.fd); + let _ = libc::close(self.fd.get()); } } } diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index 72cb3406dcada..0d5d292665638 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -8,6 +8,7 @@ use crate::io; use crate::marker::PhantomData; use crate::mem; use crate::mem::forget; +use crate::num::Ranged; use crate::sys; use crate::sys::c; #[cfg(not(target_vendor = "uwp"))] @@ -28,17 +29,20 @@ use crate::sys::cvt; /// socket, which is then borrowed under the same lifetime. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(0))] // This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] #[cfg_attr( - target_pointer_width = "64", + all(bootstrap, target_pointer_width = "32"), + rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) +)] +#[cfg_attr( + all(bootstrap, target_pointer_width = "64"), rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) )] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct BorrowedSocket<'socket> { - socket: RawSocket, + socket: Ranged, _phantom: PhantomData<&'socket OwnedSocket>, } @@ -51,17 +55,20 @@ pub struct BorrowedSocket<'socket> { /// argument or returned as an owned value, and it never has the value /// `INVALID_SOCKET`. #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] +#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start(0))] // This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] #[cfg_attr( - target_pointer_width = "64", + all(bootstrap, target_pointer_width = "32"), + rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) +)] +#[cfg_attr( + all(bootstrap, target_pointer_width = "64"), rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) )] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct OwnedSocket { - socket: RawSocket, + socket: Ranged, } impl BorrowedSocket<'_> { @@ -74,9 +81,11 @@ impl BorrowedSocket<'_> { /// `INVALID_SOCKET`. #[inline] #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] + #[rustc_allow_const_fn_unstable(ranged_int)] #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(socket: RawSocket) -> Self { assert!(socket != c::INVALID_SOCKET as RawSocket); + let socket = Ranged::new_unchecked(socket); Self { socket, _phantom: PhantomData } } } @@ -167,7 +176,7 @@ fn last_error() -> io::Error { impl AsRawSocket for BorrowedSocket<'_> { #[inline] fn as_raw_socket(&self) -> RawSocket { - self.socket + self.socket.get() } } @@ -175,7 +184,7 @@ impl AsRawSocket for BorrowedSocket<'_> { impl AsRawSocket for OwnedSocket { #[inline] fn as_raw_socket(&self) -> RawSocket { - self.socket + self.socket.get() } } @@ -185,7 +194,7 @@ impl IntoRawSocket for OwnedSocket { fn into_raw_socket(self) -> RawSocket { let socket = self.socket; forget(self); - socket + socket.get() } } @@ -194,6 +203,7 @@ impl FromRawSocket for OwnedSocket { #[inline] unsafe fn from_raw_socket(socket: RawSocket) -> Self { debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket); + let socket = Ranged::new(socket).unwrap(); Self { socket } } } @@ -203,7 +213,7 @@ impl Drop for OwnedSocket { #[inline] fn drop(&mut self) { unsafe { - let _ = c::closesocket(self.socket); + let _ = c::closesocket(self.socket.get()); } } } diff --git a/library/std/src/sys/solid/fs.rs b/library/std/src/sys/solid/fs.rs index 6c66b93a3e1a3..e4838501cc177 100644 --- a/library/std/src/sys/solid/fs.rs +++ b/library/std/src/sys/solid/fs.rs @@ -16,11 +16,6 @@ pub use crate::sys_common::fs::try_exists; /// A file descriptor. #[derive(Clone, Copy)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] struct FileDesc { fd: c_int, } @@ -29,9 +24,7 @@ impl FileDesc { #[inline] fn new(fd: c_int) -> FileDesc { assert_ne!(fd, -1i32); - // Safety: we just asserted that the value is in the valid range and - // isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { FileDesc { fd } } + FileDesc { fd } } #[inline] diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs index 1b98ef993b04a..0dcf12b583f86 100644 --- a/library/std/src/sys/solid/net.rs +++ b/library/std/src/sys/solid/net.rs @@ -29,11 +29,6 @@ const fn max_iov() -> usize { } /// A file descriptor. -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] struct FileDesc { fd: c_int, } @@ -42,9 +37,7 @@ impl FileDesc { #[inline] fn new(fd: c_int) -> FileDesc { assert_ne!(fd, -1i32); - // Safety: we just asserted that the value is in the valid range and - // isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { FileDesc { fd } } + FileDesc { fd } } #[inline] diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index cca9c67670161..b047829a0aad4 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::num::Ranged; use crate::time::Duration; pub use self::inner::Instant; @@ -6,12 +7,6 @@ pub use self::inner::Instant; const NSEC_PER_SEC: u64 = 1_000_000_000; pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(999_999_999)] -struct Nanoseconds(u32); - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SystemTime { pub(in crate::sys::unix) t: Timespec, @@ -20,7 +15,7 @@ pub struct SystemTime { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(in crate::sys::unix) struct Timespec { tv_sec: i64, - tv_nsec: Nanoseconds, + tv_nsec: Ranged, } impl SystemTime { @@ -52,7 +47,7 @@ impl fmt::Debug for SystemTime { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SystemTime") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec.0) + .field("tv_nsec", &self.t.tv_nsec.get()) .finish() } } @@ -65,7 +60,7 @@ impl Timespec { const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec { assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64); // SAFETY: The assert above checks tv_nsec is within the valid range - Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } } + Timespec { tv_sec, tv_nsec: unsafe { Ranged::new_unchecked(tv_nsec as u32) } } } pub fn sub_timespec(&self, other: &Timespec) -> Result { @@ -83,12 +78,12 @@ impl Timespec { // // Ideally this code could be rearranged such that it more // directly expresses the lower-cost behavior we want from it. - let (secs, nsec) = if self.tv_nsec.0 >= other.tv_nsec.0 { - ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.0 - other.tv_nsec.0) + let (secs, nsec) = if self.tv_nsec.get() >= other.tv_nsec.get() { + ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.get() - other.tv_nsec.get()) } else { ( (self.tv_sec - other.tv_sec - 1) as u64, - self.tv_nsec.0 + (NSEC_PER_SEC as u32) - other.tv_nsec.0, + self.tv_nsec.get() + (NSEC_PER_SEC as u32) - other.tv_nsec.get(), ) }; @@ -110,7 +105,7 @@ impl Timespec { // Nano calculations can't overflow because nanos are <1B which fit // in a u32. - let mut nsec = other.subsec_nanos() + self.tv_nsec.0; + let mut nsec = other.subsec_nanos() + self.tv_nsec.get(); if nsec >= NSEC_PER_SEC as u32 { nsec -= NSEC_PER_SEC as u32; secs = secs.checked_add(1)?; @@ -126,7 +121,7 @@ impl Timespec { .and_then(|secs| self.tv_sec.checked_sub(secs))?; // Similar to above, nanos can't overflow. - let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32; + let mut nsec = self.tv_nsec.get() as i32 - other.subsec_nanos() as i32; if nsec < 0 { nsec += NSEC_PER_SEC as i32; secs = secs.checked_sub(1)?; @@ -138,7 +133,7 @@ impl Timespec { pub fn to_timespec(&self) -> Option { Some(libc::timespec { tv_sec: self.tv_sec.try_into().ok()?, - tv_nsec: self.tv_nsec.0.try_into().ok()?, + tv_nsec: self.tv_nsec.get().try_into().ok()?, }) } } @@ -301,7 +296,7 @@ mod inner { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Instant") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec.0) + .field("tv_nsec", &self.t.tv_nsec.get()) .finish() } } diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py index 8171cb4e9a68a..ffe57cb715df9 100644 --- a/src/etc/gdb_lookup.py +++ b/src/etc/gdb_lookup.py @@ -92,4 +92,7 @@ def lookup(valobj): if rust_type == RustType.STD_NONZERO_NUMBER: return StdNonZeroNumberProvider(valobj) + if rust_type == RustType.STD_RANGED_NUMBER: + return StdRangedNumberProvider(valobj) + return None diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index c351c3450f582..8085be07245d4 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -14,8 +14,17 @@ def unwrap_unique_or_non_null(unique_or_nonnull): # https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067 # BACKCOMPAT: rust 1.60 # https://github.com/rust-lang/rust/commit/2a91eeac1a2d27dd3de1bf55515d765da20fd86f + ptr = unique_or_nonnull["pointer"] - return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]] + if ptr.type.code == gdb.TYPE_CODE_PTR: + return ptr + + # Grab the Ranged field of NonZero* + ptr = ptr[ptr.type.fields()[0]] + if ptr.type.code == gdb.TYPE_CODE_PTR: + return ptr + + return ptr[ptr.type.fields()[0]] class EnumProvider: @@ -242,6 +251,17 @@ def to_string(self): return self.value +class StdRangedNumberProvider: + def __init__(self, valobj): + fields = valobj.type.fields() + assert len(fields) == 1 + field = list(fields)[0] + self.value = str(valobj[field.name]) + + def to_string(self): + return self.value + + # Yields children (in a provider's sense of the word) for a BTreeMap. def children_of_btree_map(map): # Yields each key/value pair in the node and in any child nodes. @@ -388,6 +408,7 @@ def __init__(self, valobj, show_values=True): table_inner = table["table"] capacity = int(table_inner["bucket_mask"]) + 1 ctrl = table_inner["ctrl"]["pointer"] + ctrl = ctrl[ctrl.type.fields()[0]] self.size = int(table_inner["items"]) self.pair_type = table.type.template_argument(0).strip_typedefs() diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index bca9c2ae192a7..41687618183ea 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -58,6 +58,9 @@ def summary_lookup(valobj, dict): if rust_type == RustType.STD_NONZERO_NUMBER: return StdNonZeroNumberSummaryProvider(valobj, dict) + if rust_type == RustType.STD_RANGED_NUMBER: + return StdRangedNumberSummaryProvider(valobj, dict) + return "" diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 8a9927e7d96d7..ede716f93453f 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -66,7 +66,13 @@ def unwrap_unique_or_non_null(unique_or_nonnull): # BACKCOMPAT: rust 1.60 # https://github.com/rust-lang/rust/commit/2a91eeac1a2d27dd3de1bf55515d765da20fd86f ptr = unique_or_nonnull.GetChildMemberWithName("pointer") - return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0) + if ptr.TypeIsPointerType(): + return ptr + # Grab the Ranged field of NonZero* + ptr = ptr.GetChildAtIndex(0) + if ptr.TypeIsPointerType(): + return ptr + return ptr.GetChildAtIndex(0) class DefaultSynthteticProvider: @@ -534,7 +540,7 @@ def update(self): inner_table = table.GetChildMemberWithName("table") capacity = inner_table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1 - ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) + ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0).GetChildAtIndex(0) self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned() self.pair_type = table.type.template_args[0] @@ -743,7 +749,11 @@ def has_children(self): def StdNonZeroNumberSummaryProvider(valobj, _dict): # type: (SBValue, dict) -> str - objtype = valobj.GetType() - field = objtype.GetFieldAtIndex(0) - element = valobj.GetChildMemberWithName(field.name) + field = valobj.GetChildAtIndex(0) + element = field.GetChildAtIndex(0) + return element.GetValue() + +def StdRangedNumberSummaryProvider(valobj, _dict): + # type: (SBValue, dict) -> str + element = field.GetChildAtIndex(0) return element.GetValue() diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 624d8cc5cc55a..c7dec020a4651 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -40,6 +40,10 @@ value + + + {__0} + {__0} diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py index bf512bc99b8f2..dec38f4ead384 100644 --- a/src/etc/rust_types.py +++ b/src/etc/rust_types.py @@ -32,6 +32,7 @@ class RustType(object): STD_REF_MUT = "StdRefMut" STD_REF_CELL = "StdRefCell" STD_NONZERO_NUMBER = "StdNonZeroNumber" + STD_RANGED_NUMBER = "StdRangedNumber" STD_STRING_REGEX = re.compile(r"^(alloc::(\w+::)+)String$") @@ -51,6 +52,7 @@ class RustType(object): STD_REF_MUT_REGEX = re.compile(r"^(core::(\w+::)+)RefMut<.+>$") STD_REF_CELL_REGEX = re.compile(r"^(core::(\w+::)+)RefCell<.+>$") STD_NONZERO_NUMBER_REGEX = re.compile(r"^core::num::([a-z_]+::)*NonZero.+$") +STD_RANGED_NUMBER_REGEX = re.compile(r"^core::num::([a-z_]+::)*Ranged<.+>$") TUPLE_ITEM_REGEX = re.compile(r"__\d+$") @@ -75,6 +77,7 @@ class RustType(object): RustType.STD_REF_CELL: STD_REF_CELL_REGEX, RustType.STD_CELL: STD_CELL_REGEX, RustType.STD_NONZERO_NUMBER: STD_NONZERO_NUMBER_REGEX, + RustType.STD_RANGED_NUMBER: STD_RANGED_NUMBER_REGEX, } def is_tuple_fields(fields): diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs index 7f1be6f27847c..11412be60fe8d 100644 --- a/src/test/debuginfo/msvc-pretty-enums.rs +++ b/src/test/debuginfo/msvc-pretty-enums.rs @@ -137,7 +137,7 @@ #![feature(repr128)] #![feature(arbitrary_enum_discriminant)] -use std::num::{NonZeroI128, NonZeroU32}; +use std::num::{NonZeroI128, NonZeroU32, Ranged}; pub enum CStyleEnum { Low = 2, @@ -173,14 +173,9 @@ enum NicheLayoutWithFields3 { F, } -#[rustc_layout_scalar_valid_range_start(340282366920938463463374607431768211454)] -#[rustc_layout_scalar_valid_range_end(1)] -#[repr(transparent)] -struct Wrapping128(u128); - // #[rustc_layout(debug)] enum Wrapping128Niche { - X(Wrapping128), + X(Ranged), Y, Z, } @@ -214,7 +209,7 @@ fn main() { let niche128_none: Option = None; let wrapping_niche128_untagged = - unsafe { Wrapping128Niche::X(Wrapping128(340282366920938463463374607431768211454)) }; + Wrapping128Niche::X(Ranged::new(340282366920938463463374607431768211454).unwrap()); let wrapping_niche128_none1 = Wrapping128Niche::Y; let wrapping_niche128_none2 = Wrapping128Niche::Z; diff --git a/src/test/debuginfo/numeric-types.rs b/src/test/debuginfo/numeric-types.rs index c41c9ee21df89..475c2c3182b36 100644 --- a/src/test/debuginfo/numeric-types.rs +++ b/src/test/debuginfo/numeric-types.rs @@ -202,40 +202,40 @@ // lldb-command:run // lldb-command:print/d nz_i8 -// lldb-check:[...]$0 = 11 { __0 = 11 } +// lldb-check:[...]$0 = 11 { __0 = { __0 = 11 } } // lldb-command:print nz_i16 -// lldb-check:[...]$1 = 22 { __0 = 22 } +// lldb-check:[...]$1 = 22 { __0 = { __0 = 22 } } // lldb-command:print nz_i32 -// lldb-check:[...]$2 = 33 { __0 = 33 } +// lldb-check:[...]$2 = 33 { __0 = { __0 = 33 } } // lldb-command:print nz_i64 -// lldb-check:[...]$3 = 44 { __0 = 44 } +// lldb-check:[...]$3 = 44 { __0 = { __0 = 44 } } // lldb-command:print nz_i128 -// lldb-check:[...]$4 = 55 { __0 = 55 } +// lldb-check:[...]$4 = 55 { __0 = { __0 = 55 } } // lldb-command:print nz_isize -// lldb-check:[...]$5 = 66 { __0 = 66 } +// lldb-check:[...]$5 = 66 { __0 = { __0 = 66 } } // lldb-command:print/d nz_u8 -// lldb-check:[...]$6 = 77 { __0 = 77 } +// lldb-check:[...]$6 = 77 { __0 = { __0 = 77 } } // lldb-command:print nz_u16 -// lldb-check:[...]$7 = 88 { __0 = 88 } +// lldb-check:[...]$7 = 88 { __0 = { __0 = 88 } } // lldb-command:print nz_u32 -// lldb-check:[...]$8 = 99 { __0 = 99 } +// lldb-check:[...]$8 = 99 { __0 = { __0 = 99 } } // lldb-command:print nz_u64 -// lldb-check:[...]$9 = 100 { __0 = 100 } +// lldb-check:[...]$9 = 100 { __0 = { __0 = 100 } } // lldb-command:print nz_u128 -// lldb-check:[...]$10 = 111 { __0 = 111 } +// lldb-check:[...]$10 = 111 { __0 = { __0 = 111 } } // lldb-command:print nz_usize -// lldb-check:[...]$11 = 122 { __0 = 122 } +// lldb-check:[...]$11 = 122 { __0 = { __0 = 122 } } use std::num::*; diff --git a/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs b/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs deleted file mode 100644 index bfb5e539cc18c..0000000000000 --- a/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs +++ /dev/null @@ -1,19 +0,0 @@ -// We should not see the unused_attributes lint fire for -// rustc_layout_scalar_valid_range_start, but with this bug we are -// seeing it fire (on subsequent runs) if incremental compilation is -// enabled. - -// revisions: cfail1 cfail2 -// build-pass (FIXME(62277): could be check-pass?) - -#![feature(rustc_attrs)] -#![deny(unused_attributes)] - -#[rustc_layout_scalar_valid_range_start(10)] -#[rustc_layout_scalar_valid_range_end(30)] -struct RestrictedRange(u32); -const OKAY_RANGE: RestrictedRange = unsafe { RestrictedRange(20) }; - -fn main() { - OKAY_RANGE.0; -} diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff index 5ec421eb2edd9..21702863bf2c9 100644 --- a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff @@ -35,11 +35,11 @@ bb1: { StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 - _8 = (((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21 + _8 = ((((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: std::num::Ranged<*const i32, _>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21 (*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+1:19: +1:21 _3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +1:22 StorageDead(_7); // scope 0 at $DIR/boxes.rs:+1:21: +1:22 - _9 = (((_3.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 + _9 = ((((_3.0: std::ptr::Unique).0: std::ptr::NonNull).0: std::num::Ranged<*const i32, _>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 _2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:26 StorageDead(_2); // scope 0 at $DIR/boxes.rs:+1:25: +1:26 diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff index 2a4dc9e3e8099..710b49512193c 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff @@ -16,7 +16,7 @@ } scope 2 { } -+ scope 3 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:8:33: 8:43 ++ scope 3 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:9:33: 9:43 + let mut _9: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + } @@ -26,21 +26,21 @@ _3 = AlignOf(std::vec::Vec); // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43 _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43 // mir::Constant - // + span: $DIR/inline_into_box_place.rs:8:29: 8:43 + // + span: $DIR/inline_into_box_place.rs:9:29: 9:43 // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } } bb1: { StorageLive(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 _5 = ShallowInitBox(move _4, std::vec::Vec); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 - _7 = (((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + _7 = ((((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: std::num::Ranged<*const std::vec::Vec, std::ops::RangeInclusive:: { start: 1, end: 18446744073709551615, exhausted: false }>).0: *const std::vec::Vec); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 - (*_7) = Vec::::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + StorageLive(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + _8 = &mut (*_7); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant -- // + span: $DIR/inline_into_box_place.rs:8:33: 8:41 +- // + span: $DIR/inline_into_box_place.rs:9:33: 9:41 - // + user_ty: UserType(1) - // + literal: Const { ty: fn() -> Vec {Vec::::new}, val: Value() } - } @@ -75,7 +75,7 @@ - bb5 (cleanup): { - _6 = alloc::alloc::box_free::, std::alloc::Global>(move (_5.0: std::ptr::Unique>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43 - // mir::Constant -- // + span: $DIR/inline_into_box_place.rs:8:42: 8:43 +- // + span: $DIR/inline_into_box_place.rs:9:42: 9:43 - // + literal: Const { ty: unsafe fn(Unique>, std::alloc::Global) {alloc::alloc::box_free::, std::alloc::Global>}, val: Value() } } } diff --git a/src/test/mir-opt/inline/inline_into_box_place.rs b/src/test/mir-opt/inline/inline_into_box_place.rs index 232bcc7b27d46..1cb7ebdcc69f2 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.rs +++ b/src/test/mir-opt/inline/inline_into_box_place.rs @@ -1,6 +1,7 @@ // ignore-endian-big // ignore-wasm32-bare compiled with panic=abort by default // compile-flags: -Z mir-opt-level=4 +// only-64bit #![feature(box_syntax)] // EMIT_MIR inline_into_box_place.main.Inline.diff diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index 777681e1ce7ec..8ecb210eb196c 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -6,7 +6,7 @@ fn a(_1: &mut [T]) -> &mut [T] { let mut _2: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _3: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _4: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:3:5: 3:15 + scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:5:5: 5:15 debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 83545c991000e..7b87d8f6b28c8 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -6,7 +6,7 @@ fn b(_1: &mut Box) -> &mut T { let mut _2: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _3: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:5: 8:15 + scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:10:5: 10:15 debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -22,7 +22,7 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _8 = (((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _8 = ((((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: std::num::Ranged<*const T, std::ops::RangeInclusive:: { start: 1, end: 18446744073709551615, exhausted: false }>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir index ed4e9927ce9cd..3b9bd163bbf70 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir @@ -5,7 +5,7 @@ fn c(_1: &[T]) -> &[T] { let mut _0: &[T]; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:25: +0:29 let _2: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _3: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:13:5: 13:15 + scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:15:5: 15:15 debug self => _3; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index 18a2670be2158..a727297e5ede4 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -5,7 +5,7 @@ fn d(_1: &Box) -> &T { let mut _0: &T; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:28: +0:30 let _2: &T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 let mut _3: &std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:18:5: 18:15 + scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:20:5: 20:15 debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _4: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -16,7 +16,7 @@ fn d(_1: &Box) -> &T { StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _5 = (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = ((((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: std::num::Ranged<*const T, std::ops::RangeInclusive:: { start: 1, end: 18446744073709551615, exhausted: false }>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs index 94f926d39648f..aa3b7670e45b5 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs @@ -1,3 +1,5 @@ +// only-64bit + // EMIT_MIR issue_58867_inline_as_ref_as_mut.a.Inline.after.mir pub fn a(x: &mut [T]) -> &mut [T] { x.as_mut() diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr index dbd05b8f4249a..7fe74940a49ef 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr @@ -1,8 +1,8 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:12:1 + --> $DIR/ub-nonnull.rs:13:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .pointer: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -10,16 +10,16 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:18:30 + --> $DIR/ub-nonnull.rs:19:30 | LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ dereferencing pointer failed: alloc11 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^ dereferencing pointer failed: alloc27 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:22:1 + --> $DIR/ub-nonnull.rs:23:1 | LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 1, align: 1) { @@ -27,10 +27,10 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:24:1 + --> $DIR/ub-nonnull.rs:25:1 | LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -38,16 +38,16 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:32:36 + --> $DIR/ub-nonnull.rs:33:36 | LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:41:1 + --> $DIR/ub-nonnull.rs:39:1 | -LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 +LL | const BAD_RANGE1: Ranged = unsafe { Ranged::new_unchecked(42) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -55,10 +55,10 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:47:1 + --> $DIR/ub-nonnull.rs:42:1 | -LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 +LL | const BAD_RANGE2: Ranged = unsafe { Ranged::new_unchecked(20) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr index 5a1ac09bd35ac..e41b08b3ab447 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr @@ -1,8 +1,8 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:12:1 + --> $DIR/ub-nonnull.rs:13:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .pointer: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { @@ -10,16 +10,16 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:18:30 + --> $DIR/ub-nonnull.rs:19:30 | LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ dereferencing pointer failed: alloc11 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^ dereferencing pointer failed: alloc27 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:22:1 + --> $DIR/ub-nonnull.rs:23:1 | LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 1, align: 1) { @@ -27,10 +27,10 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:24:1 + --> $DIR/ub-nonnull.rs:25:1 | LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { @@ -38,16 +38,16 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:32:36 + --> $DIR/ub-nonnull.rs:33:36 | LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:41:1 + --> $DIR/ub-nonnull.rs:39:1 | -LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 +LL | const BAD_RANGE1: Ranged = unsafe { Ranged::new_unchecked(42) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -55,10 +55,10 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:47:1 + --> $DIR/ub-nonnull.rs:42:1 | -LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 +LL | const BAD_RANGE2: Ranged = unsafe { Ranged::new_unchecked(20) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs index d22a99cd01e68..b8ea9848a6a82 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.rs +++ b/src/test/ui/consts/const-eval/ub-nonnull.rs @@ -1,10 +1,11 @@ // stderr-per-bitwidth -#![feature(rustc_attrs)] +#![feature(ranged_int)] #![allow(invalid_value)] // make sure we cannot allow away the errors tested here use std::mem; use std::ptr::NonNull; use std::num::{NonZeroU8, NonZeroUsize}; +use std::num::Ranged; const NON_NULL: NonNull = unsafe { mem::transmute(1usize) }; const NON_NULL_PTR: NonNull = unsafe { mem::transmute(&1) }; @@ -33,18 +34,12 @@ const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed //~| uninitialized -// Also test other uses of rustc_layout_scalar_valid_range_start +// Also test other uses of Ranged -#[rustc_layout_scalar_valid_range_start(10)] -#[rustc_layout_scalar_valid_range_end(30)] -struct RestrictedRange1(u32); -const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; +const BAD_RANGE1: Ranged = unsafe { Ranged::new_unchecked(42) }; //~^ ERROR it is undefined behavior to use this value -#[rustc_layout_scalar_valid_range_start(30)] -#[rustc_layout_scalar_valid_range_end(10)] -struct RestrictedRange2(u32); -const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; +const BAD_RANGE2: Ranged = unsafe { Ranged::new_unchecked(20) }; //~^ ERROR it is undefined behavior to use this value fn main() {} diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 6f5c028cbcab6..50f7fb8dbd117 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -6,7 +6,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾─alloc3──╼ │ ╾──╼ + ╾─alloc7──╼ │ ╾──╼ } error[E0080]: it is undefined behavior to use this value @@ -17,7 +17,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾─alloc7──╼ │ ╾──╼ + ╾─alloc11─╼ │ ╾──╼ } error[E0080]: it is undefined behavior to use this value @@ -141,11 +141,11 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:59:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc45, but expected a function pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾─alloc41─╼ │ ╾──╼ + ╾─alloc45─╼ │ ╾──╼ } error: aborting due to 16 previous errors diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 5ffb710d45683..aab89835ba39c 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -6,7 +6,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc3────────╼ │ ╾──────╼ + ╾───────alloc7────────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value @@ -17,7 +17,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc7────────╼ │ ╾──────╼ + ╾───────alloc11───────╼ │ ╾──────╼ } error[E0080]: it is undefined behavior to use this value @@ -141,11 +141,11 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:59:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc45, but expected a function pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────alloc41───────╼ │ ╾──────╼ + ╾───────alloc45───────╼ │ ╾──────╼ } error: aborting due to 16 previous errors diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index c8b46608d6bac..99989a21f2aa2 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -6,7 +6,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN──╼ e7 03 00 00 │ ╾──╼.... + ╾─allocN─╼ e7 03 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 70574d2dc3b5f..e851a0bc47849 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -6,7 +6,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN────────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + ╾───────allocN───────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value diff --git a/src/test/ui/impl-trait/unsafety-checking-cycle.rs b/src/test/ui/impl-trait/unsafety-checking-cycle.rs deleted file mode 100644 index 4a5831c5b73df..0000000000000 --- a/src/test/ui/impl-trait/unsafety-checking-cycle.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Ensure that we don't get a cycle error from trying to determine whether an -// opaque type implements `Freeze` in safety checking, when it doesn't matter. - -// check-pass - -#![feature(rustc_attrs)] - -struct AnyValue(T); - -// No need to check for `Freeze` here, there's no -// `rustc_layout_scalar_valid_range_start` involved. -fn not_restricted(c: bool) -> impl Sized { - if c { - let x = AnyValue(not_restricted(false)); - &x.0; - } - 2u32 -} - -#[rustc_layout_scalar_valid_range_start(1)] -struct NonZero(T); - -// No need to check for `Freeze` here, we're not borrowing the field. -fn not_field(c: bool) -> impl Sized { - if c { - let x = unsafe { NonZero(not_field(false)) }; - &x; - } - 5u32 -} - -fn main() {} diff --git a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs deleted file mode 100644 index 06cf8c0f0f6d5..0000000000000 --- a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(u32::MAX)] //~ ERROR -pub struct A(u32); - -#[rustc_layout_scalar_valid_range_end(1, 2)] //~ ERROR -pub struct B(u8); - -#[rustc_layout_scalar_valid_range_end(a = "a")] //~ ERROR -pub struct C(i32); - -#[rustc_layout_scalar_valid_range_end(1)] //~ ERROR -enum E { - X = 1, - Y = 14, -} - -#[rustc_layout_scalar_valid_range_start(rustc_layout_scalar_valid_range_start)] //~ ERROR -struct NonZero(T); - -fn not_field() -> impl Send { - NonZero(false) -} - -fn main() { - let _ = A(0); - let _ = B(0); - let _ = C(0); - let _ = E::X; -} diff --git a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr deleted file mode 100644 index 7879e7358c00a..0000000000000 --- a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error: expected exactly one integer literal argument - --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:3:1 - | -LL | #[rustc_layout_scalar_valid_range_start(u32::MAX)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected exactly one integer literal argument - --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:6:1 - | -LL | #[rustc_layout_scalar_valid_range_end(1, 2)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected exactly one integer literal argument - --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:9:1 - | -LL | #[rustc_layout_scalar_valid_range_end(a = "a")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: attribute should be applied to a struct - --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:12:1 - | -LL | #[rustc_layout_scalar_valid_range_end(1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | / enum E { -LL | | X = 1, -LL | | Y = 14, -LL | | } - | |_- not a struct - -error: expected exactly one integer literal argument - --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:18:1 - | -LL | #[rustc_layout_scalar_valid_range_start(rustc_layout_scalar_valid_range_start)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors - diff --git a/src/test/ui/lint/invalid_value.rs b/src/test/ui/lint/invalid_value.rs index 57d8cbe7c9341..b036190c3098f 100644 --- a/src/test/ui/lint/invalid_value.rs +++ b/src/test/ui/lint/invalid_value.rs @@ -1,13 +1,14 @@ // This test checks that calling `mem::{uninitialized,zeroed}` with certain types results // in a lint. -#![feature(never_type, rustc_attrs)] +#![feature(never_type, ranged_int)] #![allow(deprecated)] #![deny(invalid_value)] use std::mem::{self, MaybeUninit}; use std::ptr::NonNull; use std::num::NonZeroU32; +use std::num::Ranged; enum Void {} @@ -17,10 +18,7 @@ struct RefPair((&'static i32, i32)); struct Wrap { wrapped: T } enum WrapEnum { Wrapped(T) } -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(128)] -#[repr(transparent)] -pub(crate) struct NonBig(u64); +type NonBig = Ranged; /// A two-variant enum, thus needs a tag and may not remain uninitialized. enum Fruit { @@ -44,9 +42,7 @@ enum TwoUninhabited { B(Void), } -#[rustc_layout_scalar_valid_range_start(254)] -#[rustc_layout_scalar_valid_range_end(1)] -pub(crate) struct WrapAroundRange(u8); +type WrapAroundRange = Ranged; #[allow(unused)] fn generic() { diff --git a/src/test/ui/lint/invalid_value.stderr b/src/test/ui/lint/invalid_value.stderr index 76afb765f0f05..e5e4e83a1c157 100644 --- a/src/test/ui/lint/invalid_value.stderr +++ b/src/test/ui/lint/invalid_value.stderr @@ -1,5 +1,5 @@ error: the type `&T` does not permit zero-initialization - --> $DIR/invalid_value.rs:54:32 + --> $DIR/invalid_value.rs:50:32 | LL | let _val: &'static T = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ error: the type `&T` does not permit being left uninitialized - --> $DIR/invalid_value.rs:55:32 + --> $DIR/invalid_value.rs:51:32 | LL | let _val: &'static T = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _val: &'static T = mem::uninitialized(); = note: references must be non-null error: the type `Wrap<&T>` does not permit zero-initialization - --> $DIR/invalid_value.rs:57:38 + --> $DIR/invalid_value.rs:53:38 | LL | let _val: Wrap<&'static T> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -34,14 +34,10 @@ LL | let _val: Wrap<&'static T> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ + = note: `Wrap<&T>` must be non-null error: the type `Wrap<&T>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:58:38 + --> $DIR/invalid_value.rs:54:38 | LL | let _val: Wrap<&'static T> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -49,14 +45,10 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ + = note: `Wrap<&T>` must be non-null error: the type `!` does not permit zero-initialization - --> $DIR/invalid_value.rs:65:23 + --> $DIR/invalid_value.rs:61:23 | LL | let _val: ! = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -67,7 +59,7 @@ LL | let _val: ! = mem::zeroed(); = note: the `!` type has no valid value error: the type `!` does not permit being left uninitialized - --> $DIR/invalid_value.rs:66:23 + --> $DIR/invalid_value.rs:62:23 | LL | let _val: ! = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +70,7 @@ LL | let _val: ! = mem::uninitialized(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit zero-initialization - --> $DIR/invalid_value.rs:68:30 + --> $DIR/invalid_value.rs:64:30 | LL | let _val: (i32, !) = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -89,7 +81,7 @@ LL | let _val: (i32, !) = mem::zeroed(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit being left uninitialized - --> $DIR/invalid_value.rs:69:30 + --> $DIR/invalid_value.rs:65:30 | LL | let _val: (i32, !) = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +92,7 @@ LL | let _val: (i32, !) = mem::uninitialized(); = note: integers must not be uninitialized error: the type `Void` does not permit zero-initialization - --> $DIR/invalid_value.rs:71:26 + --> $DIR/invalid_value.rs:67:26 | LL | let _val: Void = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -109,13 +101,13 @@ LL | let _val: Void = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: enums with no inhabited variants have no valid value - --> $DIR/invalid_value.rs:12:1 + --> $DIR/invalid_value.rs:13:1 | LL | enum Void {} | ^^^^^^^^^ error: the type `Void` does not permit being left uninitialized - --> $DIR/invalid_value.rs:72:26 + --> $DIR/invalid_value.rs:68:26 | LL | let _val: Void = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -124,13 +116,13 @@ LL | let _val: Void = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: enums with no inhabited variants have no valid value - --> $DIR/invalid_value.rs:12:1 + --> $DIR/invalid_value.rs:13:1 | LL | enum Void {} | ^^^^^^^^^ error: the type `&i32` does not permit zero-initialization - --> $DIR/invalid_value.rs:74:34 + --> $DIR/invalid_value.rs:70:34 | LL | let _val: &'static i32 = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -141,7 +133,7 @@ LL | let _val: &'static i32 = mem::zeroed(); = note: references must be non-null error: the type `&i32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:75:34 + --> $DIR/invalid_value.rs:71:34 | LL | let _val: &'static i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -152,7 +144,7 @@ LL | let _val: &'static i32 = mem::uninitialized(); = note: references must be non-null error: the type `Ref` does not permit zero-initialization - --> $DIR/invalid_value.rs:77:25 + --> $DIR/invalid_value.rs:73:25 | LL | let _val: Ref = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -160,14 +152,10 @@ LL | let _val: Ref = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:14:12 - | -LL | struct Ref(&'static i32); - | ^^^^^^^^^^^^ + = note: `Ref` must be non-null error: the type `Ref` does not permit being left uninitialized - --> $DIR/invalid_value.rs:78:25 + --> $DIR/invalid_value.rs:74:25 | LL | let _val: Ref = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -175,14 +163,10 @@ LL | let _val: Ref = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:14:12 - | -LL | struct Ref(&'static i32); - | ^^^^^^^^^^^^ + = note: `Ref` must be non-null error: the type `fn()` does not permit zero-initialization - --> $DIR/invalid_value.rs:80:26 + --> $DIR/invalid_value.rs:76:26 | LL | let _val: fn() = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -193,7 +177,7 @@ LL | let _val: fn() = mem::zeroed(); = note: function pointers must be non-null error: the type `fn()` does not permit being left uninitialized - --> $DIR/invalid_value.rs:81:26 + --> $DIR/invalid_value.rs:77:26 | LL | let _val: fn() = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +188,7 @@ LL | let _val: fn() = mem::uninitialized(); = note: function pointers must be non-null error: the type `Wrap` does not permit zero-initialization - --> $DIR/invalid_value.rs:83:32 + --> $DIR/invalid_value.rs:79:32 | LL | let _val: Wrap = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -212,14 +196,10 @@ LL | let _val: Wrap = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: function pointers must be non-null (in this struct field) - --> $DIR/invalid_value.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ + = note: `Wrap` must be non-null error: the type `Wrap` does not permit being left uninitialized - --> $DIR/invalid_value.rs:84:32 + --> $DIR/invalid_value.rs:80:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -227,14 +207,10 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: function pointers must be non-null (in this struct field) - --> $DIR/invalid_value.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ + = note: `Wrap` must be non-null error: the type `WrapEnum` does not permit zero-initialization - --> $DIR/invalid_value.rs:86:36 + --> $DIR/invalid_value.rs:82:36 | LL | let _val: WrapEnum = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -242,14 +218,10 @@ LL | let _val: WrapEnum = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: function pointers must be non-null (in this field of the only potentially inhabited enum variant) - --> $DIR/invalid_value.rs:18:28 - | -LL | enum WrapEnum { Wrapped(T) } - | ^ + = note: `WrapEnum` must be non-null error: the type `WrapEnum` does not permit being left uninitialized - --> $DIR/invalid_value.rs:87:36 + --> $DIR/invalid_value.rs:83:36 | LL | let _val: WrapEnum = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -257,14 +229,10 @@ LL | let _val: WrapEnum = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: function pointers must be non-null (in this field of the only potentially inhabited enum variant) - --> $DIR/invalid_value.rs:18:28 - | -LL | enum WrapEnum { Wrapped(T) } - | ^ + = note: `WrapEnum` must be non-null error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization - --> $DIR/invalid_value.rs:89:42 + --> $DIR/invalid_value.rs:85:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -272,14 +240,14 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:15:16 +note: `RefPair` must be non-null (in this struct field) + --> $DIR/invalid_value.rs:18:18 | -LL | struct RefPair((&'static i32, i32)); - | ^^^^^^^^^^^^^^^^^^^ +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:90:42 + --> $DIR/invalid_value.rs:86:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -287,14 +255,14 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: references must be non-null (in this struct field) - --> $DIR/invalid_value.rs:15:16 +note: `RefPair` must be non-null (in this struct field) + --> $DIR/invalid_value.rs:18:18 | -LL | struct RefPair((&'static i32, i32)); - | ^^^^^^^^^^^^^^^^^^^ +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ error: the type `NonNull` does not permit zero-initialization - --> $DIR/invalid_value.rs:92:34 + --> $DIR/invalid_value.rs:88:34 | LL | let _val: NonNull = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -305,7 +273,7 @@ LL | let _val: NonNull = mem::zeroed(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/invalid_value.rs:93:34 + --> $DIR/invalid_value.rs:89:34 | LL | let _val: NonNull = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -316,7 +284,7 @@ LL | let _val: NonNull = mem::uninitialized(); = note: `std::ptr::NonNull` must be non-null error: the type `(NonZeroU32, i32)` does not permit zero-initialization - --> $DIR/invalid_value.rs:95:39 + --> $DIR/invalid_value.rs:91:39 | LL | let _val: (NonZeroU32, i32) = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -327,7 +295,7 @@ LL | let _val: (NonZeroU32, i32) = mem::zeroed(); = note: `std::num::NonZeroU32` must be non-null error: the type `(NonZeroU32, i32)` does not permit being left uninitialized - --> $DIR/invalid_value.rs:96:39 + --> $DIR/invalid_value.rs:92:39 | LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -338,7 +306,7 @@ LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); = note: `std::num::NonZeroU32` must be non-null error: the type `*const dyn Send` does not permit zero-initialization - --> $DIR/invalid_value.rs:98:37 + --> $DIR/invalid_value.rs:94:37 | LL | let _val: *const dyn Send = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -349,7 +317,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn Send` does not permit being left uninitialized - --> $DIR/invalid_value.rs:99:37 + --> $DIR/invalid_value.rs:95:37 | LL | let _val: *const dyn Send = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -360,7 +328,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); = note: the vtable of a wide raw pointer must be non-null error: the type `[fn(); 2]` does not permit zero-initialization - --> $DIR/invalid_value.rs:101:31 + --> $DIR/invalid_value.rs:97:31 | LL | let _val: [fn(); 2] = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -371,7 +339,7 @@ LL | let _val: [fn(); 2] = mem::zeroed(); = note: function pointers must be non-null error: the type `[fn(); 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:102:31 + --> $DIR/invalid_value.rs:98:31 | LL | let _val: [fn(); 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -382,7 +350,7 @@ LL | let _val: [fn(); 2] = mem::uninitialized(); = note: function pointers must be non-null error: the type `TwoUninhabited` does not permit zero-initialization - --> $DIR/invalid_value.rs:104:36 + --> $DIR/invalid_value.rs:100:36 | LL | let _val: TwoUninhabited = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -391,13 +359,13 @@ LL | let _val: TwoUninhabited = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: enums with no inhabited variants have no valid value - --> $DIR/invalid_value.rs:42:1 + --> $DIR/invalid_value.rs:40:1 | LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `TwoUninhabited` does not permit being left uninitialized - --> $DIR/invalid_value.rs:105:36 + --> $DIR/invalid_value.rs:101:36 | LL | let _val: TwoUninhabited = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -406,13 +374,13 @@ LL | let _val: TwoUninhabited = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: enums with no inhabited variants have no valid value - --> $DIR/invalid_value.rs:42:1 + --> $DIR/invalid_value.rs:40:1 | LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit zero-initialization - --> $DIR/invalid_value.rs:107:37 + --> $DIR/invalid_value.rs:103:37 | LL | let _val: OneFruitNonZero = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -420,14 +388,10 @@ LL | let _val: OneFruitNonZero = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) - --> $DIR/invalid_value.rs:39:12 - | -LL | Banana(NonZeroU32), - | ^^^^^^^^^^ + = note: `OneFruitNonZero` must be non-null error: the type `OneFruitNonZero` does not permit being left uninitialized - --> $DIR/invalid_value.rs:108:37 + --> $DIR/invalid_value.rs:104:37 | LL | let _val: OneFruitNonZero = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -435,14 +399,10 @@ LL | let _val: OneFruitNonZero = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) - --> $DIR/invalid_value.rs:39:12 - | -LL | Banana(NonZeroU32), - | ^^^^^^^^^^ + = note: `OneFruitNonZero` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:112:26 + --> $DIR/invalid_value.rs:108:26 | LL | let _val: bool = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -453,7 +413,7 @@ LL | let _val: bool = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized - --> $DIR/invalid_value.rs:115:32 + --> $DIR/invalid_value.rs:111:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -461,14 +421,10 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: characters must be a valid Unicode codepoint (in this struct field) - --> $DIR/invalid_value.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ + = note: `Wrap` must be initialized inside its custom valid range -error: the type `NonBig` does not permit being left uninitialized - --> $DIR/invalid_value.rs:118:28 +error: the type `Ranged { start: 0, end: 128, exhausted: false }>` does not permit being left uninitialized + --> $DIR/invalid_value.rs:114:28 | LL | let _val: NonBig = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -476,10 +432,10 @@ LL | let _val: NonBig = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: `NonBig` must be initialized inside its custom valid range + = note: `std::num::Ranged { start: 0, end: 128, exhausted: false }>` must be initialized inside its custom valid range error: the type `Fruit` does not permit being left uninitialized - --> $DIR/invalid_value.rs:121:27 + --> $DIR/invalid_value.rs:117:27 | LL | let _val: Fruit = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -487,14 +443,10 @@ LL | let _val: Fruit = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: enums with multiple inhabited variants have to be initialized to a variant - --> $DIR/invalid_value.rs:26:1 - | -LL | enum Fruit { - | ^^^^^^^^^^ + = note: `Fruit` must be initialized inside its custom valid range error: the type `[bool; 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:124:31 + --> $DIR/invalid_value.rs:120:31 | LL | let _val: [bool; 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +457,7 @@ LL | let _val: [bool; 2] = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `i32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:127:25 + --> $DIR/invalid_value.rs:123:25 | LL | let _val: i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +468,7 @@ LL | let _val: i32 = mem::uninitialized(); = note: integers must not be uninitialized error: the type `f32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:130:25 + --> $DIR/invalid_value.rs:126:25 | LL | let _val: f32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -527,7 +479,7 @@ LL | let _val: f32 = mem::uninitialized(); = note: floats must not be uninitialized error: the type `*const ()` does not permit being left uninitialized - --> $DIR/invalid_value.rs:133:31 + --> $DIR/invalid_value.rs:129:31 | LL | let _val: *const () = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -538,7 +490,7 @@ LL | let _val: *const () = mem::uninitialized(); = note: raw pointers must not be uninitialized error: the type `*const [()]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:136:33 + --> $DIR/invalid_value.rs:132:33 | LL | let _val: *const [()] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -548,8 +500,8 @@ LL | let _val: *const [()] = mem::uninitialized(); | = note: raw pointers must not be uninitialized -error: the type `WrapAroundRange` does not permit being left uninitialized - --> $DIR/invalid_value.rs:139:37 +error: the type `Ranged { start: 254, end: 1, exhausted: false }>` does not permit being left uninitialized + --> $DIR/invalid_value.rs:135:37 | LL | let _val: WrapAroundRange = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -557,10 +509,10 @@ LL | let _val: WrapAroundRange = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: `WrapAroundRange` must be initialized inside its custom valid range + = note: `std::num::Ranged { start: 254, end: 1, exhausted: false }>` must be initialized inside its custom valid range error: the type `Result` does not permit being left uninitialized - --> $DIR/invalid_value.rs:144:38 + --> $DIR/invalid_value.rs:140:38 | LL | let _val: Result = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -568,14 +520,10 @@ LL | let _val: Result = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: enums with multiple inhabited variants have to be initialized to a variant - --> $SRC_DIR/core/src/result.rs:LL:COL - | -LL | pub enum Result { - | ^^^^^^^^^^^^^^^^^^^^^ + = note: `std::result::Result` must be initialized inside its custom valid range error: the type `&i32` does not permit zero-initialization - --> $DIR/invalid_value.rs:152:34 + --> $DIR/invalid_value.rs:148:34 | LL | let _val: &'static i32 = mem::transmute(0usize); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -586,7 +534,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); = note: references must be non-null error: the type `&[i32]` does not permit zero-initialization - --> $DIR/invalid_value.rs:153:36 + --> $DIR/invalid_value.rs:149:36 | LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -597,7 +545,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); = note: references must be non-null error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/invalid_value.rs:154:32 + --> $DIR/invalid_value.rs:150:32 | LL | let _val: NonZeroU32 = mem::transmute(0); | ^^^^^^^^^^^^^^^^^ @@ -608,7 +556,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); = note: `std::num::NonZeroU32` must be non-null error: the type `NonNull` does not permit zero-initialization - --> $DIR/invalid_value.rs:157:34 + --> $DIR/invalid_value.rs:153:34 | LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -619,7 +567,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/invalid_value.rs:158:34 + --> $DIR/invalid_value.rs:154:34 | LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -630,7 +578,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:159:26 + --> $DIR/invalid_value.rs:155:26 | LL | let _val: bool = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/mir/ssa-analysis-regression-50041.rs b/src/test/ui/mir/ssa-analysis-regression-50041.rs index ebc3e2f8c0e31..55d9a1a9fe01b 100644 --- a/src/test/ui/mir/ssa-analysis-regression-50041.rs +++ b/src/test/ui/mir/ssa-analysis-regression-50041.rs @@ -2,10 +2,10 @@ // compile-flags: -Z mir-opt-level=4 #![crate_type = "lib"] -#![feature(lang_items)] +#![feature(lang_items, ranged_int)] #![no_std] -struct NonNull(*const T); +struct NonNull(core::num::Ranged<*const T, { 1..=(usize::MAX as u128) }>); struct Unique(NonNull); @@ -19,7 +19,7 @@ impl Drop for Box { #[lang = "box_free"] #[inline(always)] unsafe fn box_free(ptr: Unique) { - dealloc(ptr.0.0) + dealloc(ptr.0.0.get()) } #[inline(never)] diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 0716cee21c662..1f8cd9f365fb8 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -14,19 +14,20 @@ // aligned (while on most it is 8-byte aligned) and so the resulting // padding and overall computed sizes can be quite different. +// ignore-tidy-linelength +// normalize-stdout-test "(print-type-size type: `std::ops::RangeInclusive`:).*" -> "$1 PLATFORM_DEPENDENT_THINGS" +// normalize-stdout-test "(print-type-size end padding:) (7|3) bytes.*" -> "$1 PLATFORM_DEPENDENT_SIZE" + #![feature(start)] -#![feature(rustc_attrs)] +#![feature(ranged_int)] #![allow(dead_code)] use std::num::NonZeroU32; +use std::num::Ranged; pub enum MyOption { None, Some(T) } -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] -pub struct MyNotNegativeOne { - _i: i32, -} +type MyNotNegativeOne = Ranged; impl Default for MyOption { fn default() -> Self { MyOption::None } @@ -89,6 +90,7 @@ fn start(_: isize, _: *const *const u8) -> isize { let _f: Enum4<(), (), bool, ()> = Enum4::One(()); let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); let _h: MyOption = Default::default(); + let _h2: MyOption> = Default::default(); // Unions do not currently participate in niche filling. let _i: MyOption> = Default::default(); diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index d1753c26ca83b..cc2f57f3b88bb 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -1,3 +1,8 @@ +print-type-size type: `std::ops::RangeInclusive`: PLATFORM_DEPENDENT_THINGS +print-type-size field `.start`: 16 bytes +print-type-size field `.end`: 16 bytes +print-type-size field `.exhausted`: 1 bytes +print-type-size end padding: PLATFORM_DEPENDENT_SIZE print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes print-type-size field `.nested`: 8 bytes print-type-size field `.post`: 2 bytes @@ -43,17 +48,19 @@ print-type-size variant `Three`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Four`: 0 bytes print-type-size field `.0`: 0 bytes -print-type-size type: `MyNotNegativeOne`: 4 bytes, alignment: 4 bytes -print-type-size field `._i`: 4 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size variant `None`: 0 bytes -print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption { start: 0, end: 4294967294, exhausted: false }>>`: 4 bytes, alignment: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption { start: 30, end: 10, exhausted: false }>>`: 4 bytes, alignment: 4 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size variant `None`: 0 bytes @@ -70,6 +77,12 @@ print-type-size field `.a`: 4 bytes print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::Ranged { start: 0, end: 4294967294, exhausted: false }>`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::Ranged { start: 1, end: 4294967295, exhausted: false }>`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::Ranged { start: 30, end: 10, exhausted: false }>`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes print-type-size variant `Four`: 2 bytes print-type-size field `.0`: 2 bytes diff --git a/src/test/ui/unsafe/ranged_ints.mir.stderr b/src/test/ui/unsafe/ranged_ints.mir.stderr deleted file mode 100644 index f9ef7834e1e50..0000000000000 --- a/src/test/ui/unsafe/ranged_ints.mir.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block - --> $DIR/ranged_ints.rs:10:14 - | -LL | let _x = NonZero(0); - | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr - | - = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints.rs b/src/test/ui/unsafe/ranged_ints.rs deleted file mode 100644 index 05efe87ba6e03..0000000000000 --- a/src/test/ui/unsafe/ranged_ints.rs +++ /dev/null @@ -1,11 +0,0 @@ -// revisions: mir thir -// [thir]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { - let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr -} diff --git a/src/test/ui/unsafe/ranged_ints.thir.stderr b/src/test/ui/unsafe/ranged_ints.thir.stderr deleted file mode 100644 index f9ef7834e1e50..0000000000000 --- a/src/test/ui/unsafe/ranged_ints.thir.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block - --> $DIR/ranged_ints.rs:10:14 - | -LL | let _x = NonZero(0); - | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr - | - = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr deleted file mode 100644 index 427843f8d45ce..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints2.rs:11:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2.rs b/src/test/ui/unsafe/ranged_ints2.rs deleted file mode 100644 index 9a6bb18f92664..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { - let mut x = unsafe { NonZero(1) }; - let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe -} diff --git a/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr deleted file mode 100644 index 427843f8d45ce..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints2.rs:11:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr deleted file mode 100644 index c16550a58005f..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:14:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:21:22 - | -LL | let y = unsafe { &mut x.0 }; - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:27:22 - | -LL | unsafe { let y = &mut x.0; } - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints2_const.rs:14:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0133, E0658. -For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs deleted file mode 100644 index 56f5407bb6ebe..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2_const.rs +++ /dev/null @@ -1,29 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { -} - -const fn foo() -> NonZero { - let mut x = unsafe { NonZero(1) }; - let y = &mut x.0; //~ ERROR mutable references - //~^ ERROR mutation of layout constrained field is unsafe - unsafe { NonZero(1) } -} - -const fn bar() -> NonZero { - let mut x = unsafe { NonZero(1) }; - let y = unsafe { &mut x.0 }; //~ ERROR mutable references - unsafe { NonZero(1) } -} - -const fn boo() -> NonZero { - let mut x = unsafe { NonZero(1) }; - unsafe { let y = &mut x.0; } //~ ERROR mutable references - unsafe { NonZero(1) } -} diff --git a/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr deleted file mode 100644 index b3f139f7213ff..0000000000000 --- a/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints2_const.rs:14:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:14:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:21:22 - | -LL | let y = unsafe { &mut x.0 }; - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/ranged_ints2_const.rs:27:22 - | -LL | unsafe { let y = &mut x.0; } - | ^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0133, E0658. -For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr deleted file mode 100644 index 9eec0b09e9b18..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3.rs:13:13 - | -LL | let y = &x.0; - | ^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3.rs b/src/test/ui/unsafe/ranged_ints3.rs deleted file mode 100644 index 76d4bfe95307d..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3.rs +++ /dev/null @@ -1,14 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { - let mut x = unsafe { NonZero(Cell::new(1)) }; - let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability -} diff --git a/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr deleted file mode 100644 index 9eec0b09e9b18..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3.rs:13:13 - | -LL | let y = &x.0; - | ^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr deleted file mode 100644 index 62df933306962..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability - --> $DIR/ranged_ints3_const.rs:15:13 - | -LL | let y = &x.0; - | ^^^^ - | - = note: see issue #80384 for more information - = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable - -error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability - --> $DIR/ranged_ints3_const.rs:22:22 - | -LL | let y = unsafe { &x.0 }; - | ^^^^ - | - = note: see issue #80384 for more information - = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable - -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_const.rs:15:13 - | -LL | let y = &x.0; - | ^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0133, E0658. -For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_const.rs b/src/test/ui/unsafe/ranged_ints3_const.rs deleted file mode 100644 index 637198d360422..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_const.rs +++ /dev/null @@ -1,24 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() {} - -const fn foo() -> NonZero> { - let mut x = unsafe { NonZero(Cell::new(1)) }; - let y = &x.0; //~ ERROR the borrowed element may contain interior mutability - //~^ ERROR borrow of layout constrained field with interior mutability - unsafe { NonZero(Cell::new(1)) } -} - -const fn bar() -> NonZero> { - let mut x = unsafe { NonZero(Cell::new(1)) }; - let y = unsafe { &x.0 }; //~ ERROR the borrowed element may contain interior mutability - unsafe { NonZero(Cell::new(1)) } -} diff --git a/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr deleted file mode 100644 index 5dbc563aad261..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_const.rs:15:13 - | -LL | let y = &x.0; - | ^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability - --> $DIR/ranged_ints3_const.rs:15:13 - | -LL | let y = &x.0; - | ^^^^ - | - = note: see issue #80384 for more information - = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable - -error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability - --> $DIR/ranged_ints3_const.rs:22:22 - | -LL | let y = unsafe { &x.0 }; - | ^^^^ - | - = note: see issue #80384 for more information - = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0133, E0658. -For more information about an error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr deleted file mode 100644 index 27c06640928fa..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_match.rs:14:17 - | -LL | NonZero(ref x) => { x } - | ^^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_match.rs:20:23 - | -LL | match y { NonZero(ref mut y) => { y } }; - | ^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_match.rs b/src/test/ui/unsafe/ranged_ints3_match.rs deleted file mode 100644 index d9fcf0bd665c2..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_match.rs +++ /dev/null @@ -1,22 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { - let mut x = unsafe { NonZero(Cell::new(1)) }; - match x { - NonZero(ref x) => { x } - //~^ ERROR borrow of layout constrained field with interior mutability - }; - - let mut y = unsafe { NonZero(42) }; - match y { NonZero(ref y) => { y } }; // OK, type of `y` is freeze - match y { NonZero(ref mut y) => { y } }; - //~^ ERROR mutation of layout constrained field -} diff --git a/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr deleted file mode 100644 index 27c06640928fa..0000000000000 --- a/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_match.rs:14:17 - | -LL | NonZero(ref x) => { x } - | ^^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_match.rs:20:23 - | -LL | match y { NonZero(ref mut y) => { y } }; - | ^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr deleted file mode 100644 index 493483d2c4540..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints4.rs:11:5 - | -LL | x.0 = 0; - | ^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4.rs b/src/test/ui/unsafe/ranged_ints4.rs deleted file mode 100644 index fe80af454cb8d..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4.rs +++ /dev/null @@ -1,12 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() { - let mut x = unsafe { NonZero(1) }; - x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe -} diff --git a/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr deleted file mode 100644 index 493483d2c4540..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints4.rs:11:5 - | -LL | x.0 = 0; - | ^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr deleted file mode 100644 index a06c6f479b8da..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints4_const.rs:13:5 - | -LL | x.0 = 0; - | ^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints4_const.rs b/src/test/ui/unsafe/ranged_ints4_const.rs deleted file mode 100644 index a43c8be71c4fd..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4_const.rs +++ /dev/null @@ -1,22 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() {} - -const fn foo() -> NonZero { - let mut x = unsafe { NonZero(1) }; - x.0 = 0; - //~^ ERROR mutation of layout constrained field is unsafe - x -} - -const fn bar() -> NonZero { - let mut x = unsafe { NonZero(1) }; - unsafe { x.0 = 0 }; // this is UB - x -} diff --git a/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr deleted file mode 100644 index a06c6f479b8da..0000000000000 --- a/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints4_const.rs:13:5 - | -LL | x.0 = 0; - | ^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_const.mir.stderr b/src/test/ui/unsafe/ranged_ints_const.mir.stderr deleted file mode 100644 index 33d134c7ce59e..0000000000000 --- a/src/test/ui/unsafe/ranged_ints_const.mir.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block - --> $DIR/ranged_ints_const.rs:11:34 - | -LL | const fn foo() -> NonZero { NonZero(0) } - | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr - | - = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_const.rs b/src/test/ui/unsafe/ranged_ints_const.rs deleted file mode 100644 index 472b096815075..0000000000000 --- a/src/test/ui/unsafe/ranged_ints_const.rs +++ /dev/null @@ -1,14 +0,0 @@ -// revisions: mir thir -// [thir]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); -fn main() {} - -const fn foo() -> NonZero { NonZero(0) } -//~^ ERROR initializing type with `rustc_layout_scalar_valid_range` attr is unsafe - -const fn bar() -> NonZero { unsafe { NonZero(0) } } diff --git a/src/test/ui/unsafe/ranged_ints_const.thir.stderr b/src/test/ui/unsafe/ranged_ints_const.thir.stderr deleted file mode 100644 index 33d134c7ce59e..0000000000000 --- a/src/test/ui/unsafe/ranged_ints_const.thir.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block - --> $DIR/ranged_ints_const.rs:11:34 - | -LL | const fn foo() -> NonZero { NonZero(0) } - | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr - | - = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints_macro.rs b/src/test/ui/unsafe/ranged_ints_macro.rs deleted file mode 100644 index 8293d029951fa..0000000000000 --- a/src/test/ui/unsafe/ranged_ints_macro.rs +++ /dev/null @@ -1,19 +0,0 @@ -// build-pass -// revisions: mir thir -// [thir]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] - -macro_rules! apply { - ($val:expr) => { - #[rustc_layout_scalar_valid_range_start($val)] - #[repr(transparent)] - pub(crate) struct NonZero(pub(crate) T); - } -} - -apply!(1); - -fn main() { - let _x = unsafe { NonZero(1) }; -} diff --git a/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr deleted file mode 100644 index 9abc51424abaf..0000000000000 --- a/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-assign.rs:12:5 - | -LL | foo.0.0 = 0; - | ^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-assign.rs b/src/test/ui/unsafe/unsafe-assign.rs deleted file mode 100644 index 15273165b5e13..0000000000000 --- a/src/test/ui/unsafe/unsafe-assign.rs +++ /dev/null @@ -1,25 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] -#![allow(unused,dead_code)] - -fn nested_field() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero(T); - - let mut foo = unsafe { NonZero((1,)) }; - foo.0.0 = 0; - //~^ ERROR: mutation of layout constrained field is unsafe -} - -fn block() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero(T); - - let mut foo = unsafe { NonZero((1,)) }; - { foo.0 }.0 = 0; - // ^ not unsafe because the result of the block expression is a new place -} - -fn main() {} diff --git a/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr deleted file mode 100644 index 9abc51424abaf..0000000000000 --- a/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-assign.rs:12:5 - | -LL | foo.0.0 = 0; - | ^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr deleted file mode 100644 index a206722495ac3..0000000000000 --- a/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:12:13 - | -LL | let a = &mut foo.0.0; - | ^^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:32:13 - | -LL | let a = &mut foo.0[2]; - | ^^^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:51:18 - | -LL | NonZero((a,)) => *a = 0, - | ^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/unsafe-borrow.rs b/src/test/ui/unsafe/unsafe-borrow.rs deleted file mode 100644 index 8dddc70be45c7..0000000000000 --- a/src/test/ui/unsafe/unsafe-borrow.rs +++ /dev/null @@ -1,56 +0,0 @@ -// revisions: mirunsafeck thirunsafeck -// [thirunsafeck]compile-flags: -Z thir-unsafeck - -#![feature(rustc_attrs)] -#![allow(unused,dead_code)] - -fn tuple_struct() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero(T); - - let mut foo = unsafe { NonZero((1,)) }; - let a = &mut foo.0.0; - //~^ ERROR: mutation of layout constrained field is unsafe -} - -fn slice() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero<'a, T>(&'a mut [T]); - - let mut nums = [1, 2, 3, 4]; - let mut foo = unsafe { NonZero(&mut nums[..]) }; - let a = &mut foo.0[2]; - // ^ not unsafe because there is an implicit dereference here -} - -fn array() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero([T; 4]); - - let nums = [1, 2, 3, 4]; - let mut foo = unsafe { NonZero(nums) }; - let a = &mut foo.0[2]; - //~^ ERROR: mutation of layout constrained field is unsafe -} - -fn block() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero(T); - - let foo = unsafe { NonZero((1,)) }; - &mut { foo.0 }.0; - // ^ not unsafe because the result of the block expression is a new place -} - -fn mtch() { - #[rustc_layout_scalar_valid_range_start(1)] - struct NonZero(T); - - let mut foo = unsafe { NonZero((1,)) }; - match &mut foo { - NonZero((a,)) => *a = 0, - //~^ ERROR: mutation of layout constrained field is unsafe - } -} - -fn main() {} diff --git a/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr deleted file mode 100644 index a206722495ac3..0000000000000 --- a/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:12:13 - | -LL | let a = &mut foo.0.0; - | ^^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:32:13 - | -LL | let a = &mut foo.0[2]; - | ^^^^^^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/unsafe-borrow.rs:51:18 - | -LL | NonZero((a,)) => *a = 0, - | ^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/tools/miri/tests/fail/validity/nonzero.rs b/src/tools/miri/tests/fail/validity/nonzero.rs index 384c94a556998..7a6ca62f1d9fd 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.rs +++ b/src/tools/miri/tests/fail/validity/nonzero.rs @@ -3,11 +3,12 @@ #![feature(rustc_attrs)] #![allow(unused_attributes)] -#[rustc_layout_scalar_valid_range_start(1)] -#[repr(transparent)] -pub(crate) struct NonZero(pub(crate) T); +union Moo { + x: u32, + y: std::num::NonZeroU32, +} fn main() { // Make sure that we detect this even when no function call is happening along the way - let _x = Some(unsafe { NonZero(0) }); //~ ERROR: encountered 0, but expected something greater or equal to 1 + let _x = Some(unsafe { Moo { x: 0 }.y }); //~ ERROR: encountered 0, but expected something greater or equal to 1 } diff --git a/src/tools/miri/tests/fail/validity/nonzero.stderr b/src/tools/miri/tests/fail/validity/nonzero.stderr index a9a68177ed973..7cdc1991c9089 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.stderr +++ b/src/tools/miri/tests/fail/validity/nonzero.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 --> $DIR/nonzero.rs:LL:CC | -LL | let _x = Some(unsafe { NonZero(0) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 +LL | let _x = Some(unsafe { Moo { x: 0 }.y }); + | ^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs index 39581b33a8da2..dd539bc11a9f5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs @@ -483,16 +483,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Layout related: // ========================================================================== - rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ - niche optimizations in libcore and libstd and will never be stable", - ), - rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ - niche optimizations in libcore and libstd and will never be stable", - ), rustc_attr!( rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \