Skip to content

Commit cc13e2c

Browse files
committed
Rip out rustc_layout_scalar_valid_range_* attribute support
1 parent 2d9bc88 commit cc13e2c

74 files changed

Lines changed: 311 additions & 1318 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_abi/src/layout.rs

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::BTreeSet;
22
use std::fmt::{self, Write};
3-
use std::ops::{Bound, Deref};
3+
use std::ops::Deref;
44
use std::{cmp, iter};
55

66
use rustc_hashes::Hash64;
@@ -348,7 +348,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
348348
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
349349
is_enum: bool,
350350
is_special_no_niche: bool,
351-
scalar_valid_range: (Bound<u128>, Bound<u128>),
352351
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
353352
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
354353
always_sized: bool,
@@ -380,7 +379,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
380379
variants,
381380
is_enum,
382381
is_special_no_niche,
383-
scalar_valid_range,
384382
always_sized,
385383
present_first,
386384
)
@@ -530,7 +528,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
530528
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
531529
is_enum: bool,
532530
is_special_no_niche: bool,
533-
scalar_valid_range: (Bound<u128>, Bound<u128>),
534531
always_sized: bool,
535532
present_first: VariantIdx,
536533
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
@@ -570,52 +567,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
570567
return Ok(st);
571568
}
572569

573-
let (start, end) = scalar_valid_range;
574-
match st.backend_repr {
575-
BackendRepr::Scalar(ref mut scalar) | BackendRepr::ScalarPair(ref mut scalar, _) => {
576-
// Enlarging validity ranges would result in missed
577-
// optimizations, *not* wrongly assuming the inner
578-
// value is valid. e.g. unions already enlarge validity ranges,
579-
// because the values may be uninitialized.
580-
//
581-
// Because of that we only check that the start and end
582-
// of the range is representable with this scalar type.
583-
584-
let max_value = scalar.size(dl).unsigned_int_max();
585-
if let Bound::Included(start) = start {
586-
// FIXME(eddyb) this might be incorrect - it doesn't
587-
// account for wrap-around (end < start) ranges.
588-
assert!(start <= max_value, "{start} > {max_value}");
589-
scalar.valid_range_mut().start = start;
590-
}
591-
if let Bound::Included(end) = end {
592-
// FIXME(eddyb) this might be incorrect - it doesn't
593-
// account for wrap-around (end < start) ranges.
594-
assert!(end <= max_value, "{end} > {max_value}");
595-
scalar.valid_range_mut().end = end;
596-
}
597-
598-
// Update `largest_niche` if we have introduced a larger niche.
599-
let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
600-
if let Some(niche) = niche {
601-
match st.largest_niche {
602-
Some(largest_niche) => {
603-
// Replace the existing niche even if they're equal,
604-
// because this one is at a lower offset.
605-
if largest_niche.available(dl) <= niche.available(dl) {
606-
st.largest_niche = Some(niche);
607-
}
608-
}
609-
None => st.largest_niche = Some(niche),
610-
}
611-
}
612-
}
613-
_ => assert!(
614-
start == Bound::Unbounded && end == Bound::Unbounded,
615-
"nonscalar layout for layout_scalar_valid_range type: {st:#?}",
616-
),
617-
}
618-
619570
Ok(st)
620571
}
621572

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,34 +100,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitAutorefsParser {
100100
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitAutorefs;
101101
}
102102

103-
pub(crate) struct RustcLayoutScalarValidRangeStartParser;
104-
105-
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStartParser {
106-
const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
107-
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
108-
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
109-
const TEMPLATE: AttributeTemplate = template!(List: &["start"]);
110-
111-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
112-
parse_single_integer(cx, args)
113-
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span))
114-
}
115-
}
116-
117-
pub(crate) struct RustcLayoutScalarValidRangeEndParser;
118-
119-
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEndParser {
120-
const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
121-
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
122-
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
123-
const TEMPLATE: AttributeTemplate = template!(List: &["end"]);
124-
125-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
126-
parse_single_integer(cx, args)
127-
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span))
128-
}
129-
}
130-
131103
pub(crate) struct RustcLegacyConstGenericsParser;
132104

133105
impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {

compiler/rustc_attr_parsing/src/attributes/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool {
3434
/// Parse a single integer.
3535
///
3636
/// Used by attributes that take a single integer as argument, such as
37-
/// `#[link_ordinal]` and `#[rustc_layout_scalar_valid_range_start]`.
37+
/// `#[link_ordinal]`.
3838
/// `cx` is the context given to the attribute.
3939
/// `args` is the parser for the attribute arguments.
4040
pub(crate) fn parse_single_integer<S: Stage>(

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,6 @@ attribute_parsers!(
224224
Single<RustcDumpSymbolNameParser>,
225225
Single<RustcForceInlineParser>,
226226
Single<RustcIfThisChangedParser>,
227-
Single<RustcLayoutScalarValidRangeEndParser>,
228-
Single<RustcLayoutScalarValidRangeStartParser>,
229227
Single<RustcLegacyConstGenericsParser>,
230228
Single<RustcLintOptDenyFieldAccessParser>,
231229
Single<RustcMacroTransparencyParser>,

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
14421442
// First check that the base type is valid
14431443
self.visit_value(&val.transmute(self.ecx.layout_of(*base)?, self.ecx)?)?;
14441444
// When you extend this match, make sure to also add tests to
1445-
// tests/ui/type/pattern_types/validity.rs((
1445+
// tests/ui/type/pattern_types/validity.rs
14461446
match **pat {
14471447
// Range and non-null patterns are precisely reflected into `valid_range` and thus
14481448
// handled fully by `visit_scalar` (called below).
@@ -1457,6 +1457,37 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
14571457
// we won't see optimizations actually breaking such programs.
14581458
ty::PatternKind::Or(_patterns) => {}
14591459
}
1460+
match val.layout.backend_repr {
1461+
BackendRepr::Scalar(scalar_layout) => {
1462+
if !scalar_layout.is_uninit_valid() {
1463+
// There is something to check here.
1464+
// We read directly via `ecx` since the read cannot fail -- we already read
1465+
// this field above when recursing into the field.
1466+
let scalar = self.ecx.read_scalar(val)?;
1467+
self.visit_scalar(scalar, scalar_layout)?;
1468+
}
1469+
}
1470+
BackendRepr::ScalarPair(a_layout, b_layout) => {
1471+
// We can only proceed if *both* scalars need to be initialized.
1472+
// FIXME: find a way to also check ScalarPair when one side can be uninit but
1473+
// the other must be init.
1474+
if !a_layout.is_uninit_valid() && !b_layout.is_uninit_valid() {
1475+
// We read directly via `ecx` since the read cannot fail -- we already read
1476+
// this field above when recursing into the field.
1477+
let (a, b) = self.ecx.read_immediate(val)?.to_scalar_pair();
1478+
self.visit_scalar(a, a_layout)?;
1479+
self.visit_scalar(b, b_layout)?;
1480+
}
1481+
}
1482+
BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => {
1483+
// No checks here, we assume layout computation gets this right.
1484+
// (This is harder to check since Miri does not represent these as `Immediate`. We
1485+
// also cannot use field projections since this might be a newtype around a vector.)
1486+
}
1487+
BackendRepr::Memory { .. } => {
1488+
// Nothing to do.
1489+
}
1490+
}
14601491
}
14611492
ty::Adt(adt, _) if adt.is_maybe_dangling() => {
14621493
let old_may_dangle = mem::replace(&mut self.may_dangle, true);
@@ -1479,53 +1510,21 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
14791510
}
14801511
}
14811512

1482-
// *After* all of this, check further information stored in the layout. We need to check
1483-
// this to handle types like `NonNull` where the `Scalar` info is more restrictive than what
1484-
// the fields say (`rustc_layout_scalar_valid_range_start`). But in most cases, this will
1485-
// just propagate what the fields say, and then we want the error to point at the field --
1486-
// so, we first recurse, then we do this check.
1513+
// *After* all of this, check further information stored in the layout.
1514+
// On leaf types like `!` or empty enums, this will raise the error.
1515+
// This means that for types wrapping such a type, we won't ever get here, but it's
1516+
// just the simplest way to check for this case.
14871517
//
14881518
// FIXME: We could avoid some redundant checks here. For newtypes wrapping
14891519
// scalars, we do the same check on every "level" (e.g., first we check
1490-
// MyNewtype and then the scalar in there).
1520+
// the fields of MyNewtype, and then we check MyNewType again).
14911521
if val.layout.is_uninhabited() {
14921522
let ty = val.layout.ty;
14931523
throw_validation_failure!(
14941524
self.path,
14951525
format!("encountered a value of uninhabited type `{ty}`")
14961526
);
14971527
}
1498-
match val.layout.backend_repr {
1499-
BackendRepr::Scalar(scalar_layout) => {
1500-
if !scalar_layout.is_uninit_valid() {
1501-
// There is something to check here.
1502-
// We read directly via `ecx` since the read cannot fail -- we already read
1503-
// this field above when recursing into the field.
1504-
let scalar = self.ecx.read_scalar(val)?;
1505-
self.visit_scalar(scalar, scalar_layout)?;
1506-
}
1507-
}
1508-
BackendRepr::ScalarPair(a_layout, b_layout) => {
1509-
// We can only proceed if *both* scalars need to be initialized.
1510-
// FIXME: find a way to also check ScalarPair when one side can be uninit but
1511-
// the other must be init.
1512-
if !a_layout.is_uninit_valid() && !b_layout.is_uninit_valid() {
1513-
// We read directly via `ecx` since the read cannot fail -- we already read
1514-
// this field above when recursing into the field.
1515-
let (a, b) = self.ecx.read_immediate(val)?.to_scalar_pair();
1516-
self.visit_scalar(a, a_layout)?;
1517-
self.visit_scalar(b, b_layout)?;
1518-
}
1519-
}
1520-
BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => {
1521-
// No checks here, we assume layout computation gets this right.
1522-
// (This is harder to check since Miri does not represent these as `Immediate`. We
1523-
// also cannot use field projections since this might be a newtype around a vector.)
1524-
}
1525-
BackendRepr::Memory { .. } => {
1526-
// Nothing to do.
1527-
}
1528-
}
15291528

15301529
interp_ok(())
15311530
}

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -573,16 +573,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
573573
// Internal attributes, Layout related:
574574
// ==========================================================================
575575

576-
rustc_attr!(
577-
rustc_layout_scalar_valid_range_start,
578-
"the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
579-
niche optimizations in the standard library",
580-
),
581-
rustc_attr!(
582-
rustc_layout_scalar_valid_range_end,
583-
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
584-
niche optimizations in the standard library",
585-
),
586576
rustc_attr!(
587577
rustc_simd_monomorphize_lane_limit,
588578
"the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,12 +1444,6 @@ pub enum AttributeKind {
14441444
/// Represents `#[rustc_intrinsic_const_stable_indirect]`
14451445
RustcIntrinsicConstStableIndirect,
14461446

1447-
/// Represents `#[rustc_layout_scalar_valid_range_end]`.
1448-
RustcLayoutScalarValidRangeEnd(Box<u128>, Span),
1449-
1450-
/// Represents `#[rustc_layout_scalar_valid_range_start]`.
1451-
RustcLayoutScalarValidRangeStart(Box<u128>, Span),
1452-
14531447
/// Represents `#[rustc_legacy_const_generics]`
14541448
RustcLegacyConstGenerics {
14551449
fn_indexes: ThinVec<(usize, Span)>,

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,6 @@ impl AttributeKind {
146146
RustcInsignificantDtor => Yes,
147147
RustcIntrinsic => Yes,
148148
RustcIntrinsicConstStableIndirect => No,
149-
RustcLayoutScalarValidRangeEnd(..) => Yes,
150-
RustcLayoutScalarValidRangeStart(..) => Yes,
151149
RustcLegacyConstGenerics { .. } => Yes,
152150
RustcLintOptDenyFieldAccess { .. } => Yes,
153151
RustcLintOptTy => Yes,

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//! crate as a kind of pass. This should eventually be factored away.
1616
1717
use std::cell::Cell;
18-
use std::ops::{Bound, ControlFlow};
18+
use std::ops::ControlFlow;
1919
use std::{assert_matches, iter};
2020

2121
use rustc_abi::{ExternAbi, Size};
@@ -1035,12 +1035,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
10351035
let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id();
10361036
let ty = tcx.type_of(adt_def_id).instantiate_identity();
10371037
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
1038-
// constructors for structs with `layout_scalar_valid_range` are unsafe to call
1039-
let safety = match tcx.layout_scalar_valid_range(adt_def_id) {
1040-
(Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe,
1041-
_ => hir::Safety::Unsafe,
1042-
};
1043-
ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, ExternAbi::Rust))
1038+
ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, hir::Safety::Safe, ExternAbi::Rust))
10441039
}
10451040

10461041
Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::env::VarError;
1111
use std::ffi::OsStr;
1212
use std::hash::{Hash, Hasher};
1313
use std::marker::{PhantomData, PointeeSized};
14-
use std::ops::{Bound, Deref};
14+
use std::ops::Deref;
1515
use std::sync::{Arc, OnceLock};
1616
use std::{fmt, iter, mem};
1717

@@ -989,17 +989,6 @@ impl<'tcx> TyCtxt<'tcx> {
989989
matches!(self.as_lang_item(def_id), Some(LangItem::Sized | LangItem::MetaSized))
990990
}
991991

992-
/// Returns a range of the start/end indices specified with the
993-
/// `rustc_layout_scalar_valid_range` attribute.
994-
// FIXME(eddyb) this is an awkward spot for this method, maybe move it?
995-
pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
996-
let start = find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
997-
let end =
998-
find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
999-
.unwrap_or(Bound::Unbounded);
1000-
(start, end)
1001-
}
1002-
1003992
pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1004993
value.lift_to_interner(self)
1005994
}

0 commit comments

Comments
 (0)