Skip to content

Commit e64cbce

Browse files
committed
Remove BackendRepr::Uninhabited, replaced with an uninhabited: bool field in LayoutData.
Also update comments that refered to BackendRepr::Uninhabited.
1 parent d8810e3 commit e64cbce

File tree

26 files changed

+93
-114
lines changed

26 files changed

+93
-114
lines changed

compiler/rustc_abi/src/callconv.rs

-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
6565
Ty: TyAbiInterface<'a, C> + Copy,
6666
{
6767
match self.backend_repr {
68-
BackendRepr::Uninhabited => Err(Heterogeneous),
69-
7068
// The primitive for this algorithm.
7169
BackendRepr::Scalar(scalar) => {
7270
let kind = match scalar.primitive() {

compiler/rustc_abi/src/layout.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
129129
},
130130
backend_repr: BackendRepr::ScalarPair(a, b),
131131
largest_niche,
132+
uninhabited: false,
132133
align,
133134
size,
134135
max_repr_align: None,
@@ -220,8 +221,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
220221
LayoutData {
221222
variants: Variants::Empty,
222223
fields: FieldsShape::Primitive,
223-
backend_repr: BackendRepr::Uninhabited,
224+
backend_repr: BackendRepr::Memory { sized: true },
224225
largest_niche: None,
226+
uninhabited: true,
225227
align: dl.i8_align,
226228
size: Size::ZERO,
227229
max_repr_align: None,
@@ -399,6 +401,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
399401
fields: FieldsShape::Union(union_field_count),
400402
backend_repr: abi,
401403
largest_niche: None,
404+
uninhabited: false,
402405
align,
403406
size: size.align_to(align.abi),
404407
max_repr_align,
@@ -446,7 +449,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
446449
Scalar::Union { .. } => {}
447450
};
448451
match &mut st.backend_repr {
449-
BackendRepr::Uninhabited => {}
450452
BackendRepr::Scalar(scalar) => hide_niches(scalar),
451453
BackendRepr::ScalarPair(a, b) => {
452454
hide_niches(a);
@@ -638,9 +640,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
638640
let same_size = size == variant_layouts[largest_variant_index].size;
639641
let same_align = align == variant_layouts[largest_variant_index].align;
640642

641-
let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) {
642-
BackendRepr::Uninhabited
643-
} else if same_size && same_align && others_zst {
643+
let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited());
644+
let abi = if same_size && same_align && others_zst {
644645
match variant_layouts[largest_variant_index].backend_repr {
645646
// When the total alignment and size match, we can use the
646647
// same ABI as the scalar variant with the reserved niche.
@@ -682,6 +683,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
682683
},
683684
backend_repr: abi,
684685
largest_niche,
686+
uninhabited,
685687
size,
686688
align,
687689
max_repr_align,
@@ -852,9 +854,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
852854
};
853855
let mut abi = BackendRepr::Memory { sized: true };
854856

855-
if layout_variants.iter().all(|v| v.is_uninhabited()) {
856-
abi = BackendRepr::Uninhabited;
857-
} else if tag.size(dl) == size {
857+
let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited());
858+
if tag.size(dl) == size {
858859
// Make sure we only use scalar layout when the enum is entirely its
859860
// own tag (i.e. it has no padding nor any non-ZST variant fields).
860861
abi = BackendRepr::Scalar(tag);
@@ -994,6 +995,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
994995
memory_index: [0].into(),
995996
},
996997
largest_niche,
998+
uninhabited,
997999
backend_repr: abi,
9981000
align,
9991001
size,
@@ -1354,9 +1356,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13541356
_ => {}
13551357
}
13561358
}
1357-
if fields.iter().any(|f| f.is_uninhabited()) {
1358-
abi = BackendRepr::Uninhabited;
1359-
}
1359+
let uninhabited = fields.iter().any(|f| f.is_uninhabited());
13601360

13611361
let unadjusted_abi_align = if repr.transparent() {
13621362
match layout_of_single_non_zst_field {
@@ -1377,6 +1377,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13771377
fields: FieldsShape::Arbitrary { offsets, memory_index },
13781378
backend_repr: abi,
13791379
largest_niche,
1380+
uninhabited,
13801381
align,
13811382
size,
13821383
max_repr_align,

compiler/rustc_abi/src/lib.rs

+16-19
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,6 @@ impl AddressSpace {
14031403
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
14041404
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
14051405
pub enum BackendRepr {
1406-
Uninhabited,
14071406
Scalar(Scalar),
14081407
ScalarPair(Scalar, Scalar),
14091408
Vector {
@@ -1422,10 +1421,9 @@ impl BackendRepr {
14221421
#[inline]
14231422
pub fn is_unsized(&self) -> bool {
14241423
match *self {
1425-
BackendRepr::Uninhabited
1426-
| BackendRepr::Scalar(_)
1427-
| BackendRepr::ScalarPair(..)
1428-
| BackendRepr::Vector { .. } => false,
1424+
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
1425+
false
1426+
}
14291427
BackendRepr::Memory { sized } => !sized,
14301428
}
14311429
}
@@ -1444,12 +1442,6 @@ impl BackendRepr {
14441442
}
14451443
}
14461444

1447-
/// Returns `true` if this is an uninhabited type
1448-
#[inline]
1449-
pub fn is_uninhabited(&self) -> bool {
1450-
matches!(*self, BackendRepr::Uninhabited)
1451-
}
1452-
14531445
/// Returns `true` if this is a scalar type
14541446
#[inline]
14551447
pub fn is_scalar(&self) -> bool {
@@ -1470,7 +1462,7 @@ impl BackendRepr {
14701462
BackendRepr::Vector { element, count } => {
14711463
cx.data_layout().vector_align(element.size(cx) * count)
14721464
}
1473-
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
1465+
BackendRepr::Memory { .. } => return None,
14741466
})
14751467
}
14761468

@@ -1491,7 +1483,7 @@ impl BackendRepr {
14911483
// to make the size a multiple of align (e.g. for vectors of size 3).
14921484
(element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
14931485
}
1494-
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
1486+
BackendRepr::Memory { .. } => return None,
14951487
})
14961488
}
14971489

@@ -1505,9 +1497,7 @@ impl BackendRepr {
15051497
BackendRepr::Vector { element, count } => {
15061498
BackendRepr::Vector { element: element.to_union(), count }
15071499
}
1508-
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
1509-
BackendRepr::Memory { sized: true }
1510-
}
1500+
BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true },
15111501
}
15121502
}
15131503

@@ -1703,6 +1693,11 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
17031693
/// The leaf scalar with the largest number of invalid values
17041694
/// (i.e. outside of its `valid_range`), if it exists.
17051695
pub largest_niche: Option<Niche>,
1696+
/// Is this type known to be uninhabted?
1697+
///
1698+
/// This is separate from BackendRepr, because an uninhabited return type may require special
1699+
/// consideration based on its size or other attributes.
1700+
pub uninhabited: bool,
17061701

17071702
pub align: AbiAndPrefAlign,
17081703
pub size: Size,
@@ -1734,14 +1729,14 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
17341729
/// Returns `true` if this is an aggregate type (including a ScalarPair!)
17351730
pub fn is_aggregate(&self) -> bool {
17361731
match self.backend_repr {
1737-
BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
1732+
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
17381733
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true,
17391734
}
17401735
}
17411736

17421737
/// Returns `true` if this is an uninhabited type
17431738
pub fn is_uninhabited(&self) -> bool {
1744-
self.backend_repr.is_uninhabited()
1739+
self.uninhabited
17451740
}
17461741

17471742
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
@@ -1777,6 +1772,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
17771772
fields: FieldsShape::Primitive,
17781773
backend_repr: BackendRepr::Scalar(scalar),
17791774
largest_niche,
1775+
uninhabited: false,
17801776
size,
17811777
align,
17821778
max_repr_align: None,
@@ -1801,6 +1797,7 @@ where
18011797
backend_repr,
18021798
fields,
18031799
largest_niche,
1800+
uninhabited,
18041801
variants,
18051802
max_repr_align,
18061803
unadjusted_abi_align,
@@ -1812,6 +1809,7 @@ where
18121809
.field("abi", backend_repr)
18131810
.field("fields", fields)
18141811
.field("largest_niche", largest_niche)
1812+
.field("uninhabited", uninhabited)
18151813
.field("variants", variants)
18161814
.field("max_repr_align", max_repr_align)
18171815
.field("unadjusted_abi_align", unadjusted_abi_align)
@@ -1876,7 +1874,6 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
18761874
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
18771875
false
18781876
}
1879-
BackendRepr::Uninhabited => self.size.bytes() == 0,
18801877
BackendRepr::Memory { sized } => sized && self.size.bytes() == 0,
18811878
}
18821879
}

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> {
638638
}
639639
CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self),
640640
CPlaceInner::Addr(to_ptr, None) => {
641-
if dst_layout.size == Size::ZERO
642-
|| dst_layout.backend_repr == BackendRepr::Uninhabited
643-
{
641+
if dst_layout.size == Size::ZERO {
644642
return;
645643
}
646644

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
310310
let layout = self.layout_of(tp_ty).layout;
311311
let _use_integer_compare = match layout.backend_repr() {
312312
Scalar(_) | ScalarPair(_, _) => true,
313-
Uninhabited | Vector { .. } => false,
313+
Vector { .. } => false,
314314
Memory { .. } => {
315315
// For rusty ABIs, small aggregates are actually passed
316316
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

compiler/rustc_codegen_gcc/src/type_of.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(
8484
false,
8585
);
8686
}
87-
BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {}
87+
BackendRepr::Memory { .. } => {}
8888
}
8989

9090
let name = match *layout.ty.kind() {
@@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
179179
fn is_gcc_immediate(&self) -> bool {
180180
match self.backend_repr {
181181
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
182-
BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
183-
false
184-
}
182+
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
185183
}
186184
}
187185

188186
fn is_gcc_scalar_pair(&self) -> bool {
189187
match self.backend_repr {
190188
BackendRepr::ScalarPair(..) => true,
191-
BackendRepr::Uninhabited
192-
| BackendRepr::Scalar(_)
193-
| BackendRepr::Vector { .. }
194-
| BackendRepr::Memory { .. } => false,
189+
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
190+
false
191+
}
195192
}
196193
}
197194

compiler/rustc_codegen_llvm/src/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
475475
let layout = self.layout_of(tp_ty).layout;
476476
let use_integer_compare = match layout.backend_repr() {
477477
Scalar(_) | ScalarPair(_, _) => true,
478-
Uninhabited | Vector { .. } => false,
478+
Vector { .. } => false,
479479
Memory { .. } => {
480480
// For rusty ABIs, small aggregates are actually passed
481481
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),

compiler/rustc_codegen_llvm/src/type_of.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>(
2323
let element = layout.scalar_llvm_type_at(cx, element);
2424
return cx.type_vector(element, count);
2525
}
26-
BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
26+
BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
2727
}
2828

2929
let name = match layout.ty.kind() {
@@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
172172
fn is_llvm_immediate(&self) -> bool {
173173
match self.backend_repr {
174174
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
175-
BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
176-
false
177-
}
175+
BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
178176
}
179177
}
180178

181179
fn is_llvm_scalar_pair(&self) -> bool {
182180
match self.backend_repr {
183181
BackendRepr::ScalarPair(..) => true,
184-
BackendRepr::Uninhabited
185-
| BackendRepr::Scalar(_)
186-
| BackendRepr::Vector { .. }
187-
| BackendRepr::Memory { .. } => false,
182+
BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
183+
false
184+
}
188185
}
189186
}
190187

compiler/rustc_codegen_ssa/src/mir/operand.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
415415
bx.store(*llval, llptr, field.align.abi);
416416
*llval = bx.load(llfield_ty, llptr, field.align.abi);
417417
}
418-
(
419-
OperandValue::Immediate(_),
420-
BackendRepr::Uninhabited | BackendRepr::Memory { sized: false },
421-
) => {
418+
(OperandValue::Immediate(_), BackendRepr::Memory { sized: false }) => {
422419
bug!()
423420
}
424421
(OperandValue::Pair(..), _) => bug!(),

compiler/rustc_const_eval/src/interpret/operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
385385
(Immediate::Uninit, _) => Immediate::Uninit,
386386
// If the field is uninhabited, we can forget the data (can happen in ConstProp).
387387
// `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
388-
// has an `Uninhabited` variant, which means this case is possible.
388+
// has an uninhabited variant, which means this case is possible.
389389
_ if layout.is_uninhabited() => Immediate::Uninit,
390390
// the field contains no information, can be left uninit
391391
// (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)

compiler/rustc_const_eval/src/interpret/validity.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1274,11 +1274,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
12741274
// FIXME: We could avoid some redundant checks here. For newtypes wrapping
12751275
// scalars, we do the same check on every "level" (e.g., first we check
12761276
// MyNewtype and then the scalar in there).
1277+
if val.layout.is_uninhabited() {
1278+
let ty = val.layout.ty;
1279+
throw_validation_failure!(self.path, UninhabitedVal { ty });
1280+
}
12771281
match val.layout.backend_repr {
1278-
BackendRepr::Uninhabited => {
1279-
let ty = val.layout.ty;
1280-
throw_validation_failure!(self.path, UninhabitedVal { ty });
1281-
}
12821282
BackendRepr::Scalar(scalar_layout) => {
12831283
if !scalar_layout.is_uninit_valid() {
12841284
// There is something to check here.

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,15 @@ fn check_validity_requirement_lax<'tcx>(
111111
};
112112

113113
// Check the ABI.
114-
let valid = match this.backend_repr {
115-
BackendRepr::Uninhabited => false, // definitely UB
116-
BackendRepr::Scalar(s) => scalar_allows_raw_init(s),
117-
BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
118-
BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
119-
BackendRepr::Memory { .. } => true, // Fields are checked below.
120-
};
114+
let valid = !this.is_uninhabited() // definitely UB if uninhabited
115+
&& match this.backend_repr {
116+
BackendRepr::Scalar(s) => scalar_allows_raw_init(s),
117+
BackendRepr::ScalarPair(s1, s2) => {
118+
scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2)
119+
}
120+
BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
121+
BackendRepr::Memory { .. } => true, // Fields are checked below.
122+
};
121123
if !valid {
122124
// This is definitely not okay.
123125
return Ok(false);

compiler/rustc_middle/src/ty/layout.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,9 @@ where
772772
Some(fields) => FieldsShape::Union(fields),
773773
None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
774774
},
775-
backend_repr: BackendRepr::Uninhabited,
775+
backend_repr: BackendRepr::Memory { sized: true },
776776
largest_niche: None,
777+
uninhabited: true,
777778
align: tcx.data_layout.i8_align,
778779
size: Size::ZERO,
779780
max_repr_align: None,

0 commit comments

Comments
 (0)