Skip to content

Commit 61c2bd9

Browse files
committed
rustc: use Primitive instead of Integer for CEnum and General discriminants.
1 parent 335bd8e commit 61c2bd9

File tree

8 files changed

+57
-63
lines changed

8 files changed

+57
-63
lines changed

src/librustc/ty/layout.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ impl<'a, 'tcx> Struct {
843843
}
844844
(&CEnum { discr, .. }, &ty::TyAdt(def, _)) => {
845845
if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
846-
Ok(Some((Size::from_bytes(0), Int(discr))))
846+
Ok(Some((Size::from_bytes(0), discr)))
847847
} else {
848848
Ok(None)
849849
}
@@ -1097,7 +1097,7 @@ pub enum Layout {
10971097

10981098
/// C-like enums; basically an integer.
10991099
CEnum {
1100-
discr: Integer,
1100+
discr: Primitive,
11011101
signed: bool,
11021102
/// Inclusive discriminant range.
11031103
/// If min > max, it represents min...u64::MAX followed by 0...max.
@@ -1118,7 +1118,7 @@ pub enum Layout {
11181118
/// all space reserved for the discriminant, and their first field starts
11191119
/// at a non-0 offset, after where the discriminant would go.
11201120
General {
1121-
discr: Integer,
1121+
discr: Primitive,
11221122
variants: Vec<Struct>,
11231123
size: Size,
11241124
align: Align,
@@ -1251,8 +1251,8 @@ impl<'a, 'tcx> Layout {
12511251
}
12521252
};
12531253
let abi = match *layout {
1254-
Scalar(value) => Abi::Scalar(value),
1255-
CEnum { discr, .. } => Abi::Scalar(Int(discr)),
1254+
Scalar(value) |
1255+
CEnum { discr: value, .. } => Abi::Scalar(value),
12561256

12571257
Vector { .. } => Abi::Vector,
12581258

@@ -1453,7 +1453,7 @@ impl<'a, 'tcx> Layout {
14531453
// grok.
14541454
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
14551455
return success(CEnum {
1456-
discr,
1456+
discr: Int(discr),
14571457
signed,
14581458
// FIXME: should be u128?
14591459
min: min as u64,
@@ -1646,7 +1646,7 @@ impl<'a, 'tcx> Layout {
16461646
}
16471647

16481648
General {
1649-
discr: ity,
1649+
discr: Int(ity),
16501650
variants,
16511651
size,
16521652
align,
@@ -1722,7 +1722,7 @@ impl<'a, 'tcx> Layout {
17221722
metadata.size(dl)).abi_align(self.align(dl))
17231723
}
17241724

1725-
CEnum { discr, .. } => Int(discr).size(dl),
1725+
CEnum { discr, .. } => discr.size(dl),
17261726
General { size, .. } => size,
17271727
UntaggedUnion(ref un) => un.stride(),
17281728

@@ -1756,7 +1756,7 @@ impl<'a, 'tcx> Layout {
17561756
Pointer.align(dl).max(metadata.align(dl))
17571757
}
17581758

1759-
CEnum { discr, .. } => Int(discr).align(dl),
1759+
CEnum { discr, .. } => discr.align(dl),
17601760
Array { align, .. } | General { align, .. } => align,
17611761
UntaggedUnion(ref un) => un.align,
17621762

@@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Layout {
18581858
}
18591859
};
18601860

1861-
let build_primitive_info = |name: ast::Name, value: &Primitive| {
1861+
let build_primitive_info = |name: ast::Name, value: Primitive| {
18621862
session::VariantInfo {
18631863
name: Some(name.to_string()),
18641864
kind: session::SizeKind::Exact,
@@ -1951,7 +1951,7 @@ impl<'a, 'tcx> Layout {
19511951
variant_layout)
19521952
})
19531953
.collect();
1954-
record(adt_kind.into(), Some(discr.size()), variant_infos);
1954+
record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
19551955
}
19561956

19571957
Layout::UntaggedUnion(ref un) => {
@@ -1966,11 +1966,10 @@ impl<'a, 'tcx> Layout {
19661966
let variant_infos: Vec<_> =
19671967
adt_def.variants.iter()
19681968
.map(|variant_def| {
1969-
build_primitive_info(variant_def.name,
1970-
&Primitive::Int(discr))
1969+
build_primitive_info(variant_def.name, discr)
19711970
})
19721971
.collect();
1973-
record(adt_kind.into(), Some(discr.size()), variant_infos);
1972+
record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
19741973
}
19751974

19761975
// other cases provide little interesting (i.e. adjustable
@@ -2359,9 +2358,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
23592358
match self.variant_index {
23602359
None => match *self.layout {
23612360
// Discriminant field for enums (where applicable).
2362-
General { discr, .. } => {
2363-
return [discr.to_ty(tcx, false)][i];
2364-
}
2361+
General { discr, .. } |
23652362
NullablePointer { discr, .. } => {
23662363
return [discr.to_ty(tcx)][i];
23672364
}

src/librustc_lint/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use rustc::hir::def_id::DefId;
1414
use rustc::ty::subst::Substs;
1515
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
16-
use rustc::ty::layout::{Layout, LayoutOf, Primitive};
16+
use rustc::ty::layout::{Layout, LayoutOf};
1717
use middle::const_val::ConstVal;
1818
use rustc_const_eval::ConstContext;
1919
use util::nodemap::FxHashSet;
@@ -754,7 +754,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
754754
});
755755

756756
if let Layout::General { ref variants, ref size, discr, .. } = *layout {
757-
let discr_size = Primitive::Int(discr).size(cx.tcx).bytes();
757+
let discr_size = discr.size(cx.tcx).bytes();
758758

759759
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
760760
t, size.bytes(), layout);

src/librustc_trans/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
474474

475475
// Rust enum types that map onto C enums also need to follow
476476
// the target ABI zero-/sign-extension rules.
477-
Layout::CEnum { discr, signed, .. } => (discr, signed),
477+
Layout::CEnum { discr: layout::Int(i), signed, .. } => (i, signed),
478478

479479
_ => return
480480
};

src/librustc_trans/adt.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
103103
let l = cx.layout_of(t);
104104
debug!("adt::generic_type_of t: {:?} name: {:?}", t, name);
105105
match *l {
106-
layout::CEnum { discr, .. } => Type::from_integer(cx, discr),
106+
layout::CEnum { discr, .. } => cx.llvm_type_of(discr.to_ty(cx.tcx())),
107107
layout::NullablePointer { nndiscr, ref nonnull, .. } => {
108108
if let layout::Abi::Scalar(_) = l.abi {
109109
return cx.llvm_type_of(l.field(cx, 0).ty);
@@ -236,11 +236,3 @@ pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
236236
_ => false,
237237
}
238238
}
239-
240-
pub fn assert_discr_in_range<D: PartialOrd>(min: D, max: D, discr: D) {
241-
if min <= max {
242-
assert!(min <= discr && discr <= max)
243-
} else {
244-
assert!(min <= discr || discr <= max)
245-
}
246-
}

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,19 +1451,22 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14511451
})
14521452
.collect();
14531453

1454-
let discriminant_type_metadata = |inttype: layout::Integer, signed: bool| {
1455-
let disr_type_key = (enum_def_id, inttype);
1454+
let discriminant_type_metadata = |discr: layout::Primitive, signed: bool| {
1455+
let disr_type_key = (enum_def_id, discr);
14561456
let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
14571457
.borrow()
14581458
.get(&disr_type_key).cloned();
14591459
match cached_discriminant_type_metadata {
14601460
Some(discriminant_type_metadata) => discriminant_type_metadata,
14611461
None => {
14621462
let (discriminant_size, discriminant_align) =
1463-
(inttype.size(), inttype.align(cx));
1463+
(discr.size(cx), discr.align(cx));
14641464
let discriminant_base_type_metadata =
14651465
type_metadata(cx,
1466-
inttype.to_ty(cx.tcx(), signed),
1466+
match discr {
1467+
layout::Int(i) => i.to_ty(cx.tcx(), signed),
1468+
_ => discr.to_ty(cx.tcx())
1469+
},
14671470
syntax_pos::DUMMY_SP);
14681471
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
14691472

src/librustc_trans/debuginfo/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub struct CrateDebugContext<'tcx> {
7171
llmod: ModuleRef,
7272
builder: DIBuilderRef,
7373
created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>,
74-
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Integer), DIType>>,
74+
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
7575

7676
type_map: RefCell<TypeMap<'tcx>>,
7777
namespace_map: RefCell<DefIdMap<DIScope>>,

src/librustc_trans/mir/constant.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ fn trans_const_adt<'a, 'tcx>(
10931093
_ => 0,
10941094
};
10951095
match *l {
1096-
layout::CEnum { discr: d, min, max, .. } => {
1096+
layout::CEnum { .. } => {
10971097
let discr = match *kind {
10981098
mir::AggregateKind::Adt(adt_def, _, _, _) => {
10991099
adt_def.discriminant_for_variant(ccx.tcx(), variant_index)
@@ -1102,14 +1102,14 @@ fn trans_const_adt<'a, 'tcx>(
11021102
_ => 0,
11031103
};
11041104
assert_eq!(vals.len(), 0);
1105-
adt::assert_discr_in_range(min, max, discr);
1106-
Const::new(C_int(Type::from_integer(ccx, d), discr as i64), t)
1105+
Const::new(C_int(ccx.llvm_type_of(t), discr as i64), t)
11071106
}
1108-
layout::General { discr: d, ref variants, .. } => {
1107+
layout::General { ref variants, .. } => {
1108+
let discr_ty = l.field(ccx, 0).ty;
11091109
let variant = &variants[variant_index];
1110-
let lldiscr = C_int(Type::from_integer(ccx, d), variant_index as i64);
1110+
let lldiscr = C_int(ccx.llvm_type_of(discr_ty), variant_index as i64);
11111111
build_const_struct(ccx, l, &variant, vals,
1112-
Some(Const::new(lldiscr, d.to_ty(ccx.tcx(), false))))
1112+
Some(Const::new(lldiscr, discr_ty)))
11131113
}
11141114
layout::UntaggedUnion(ref un) => {
11151115
assert_eq!(variant_index, 0);

src/librustc_trans/mir/lvalue.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -351,25 +351,28 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
351351
}
352352

353353
/// Helper for cases where the discriminant is simply loaded.
354-
fn load_discr(self, bcx: &Builder, ity: layout::Integer, min: u64, max: u64) -> ValueRef {
355-
let bits = ity.size().bits();
356-
assert!(bits <= 64);
357-
let bits = bits as usize;
358-
let mask = !0u64 >> (64 - bits);
359-
// For a (max) discr of -1, max will be `-1 as usize`, which overflows.
360-
// However, that is fine here (it would still represent the full range),
361-
if max.wrapping_add(1) & mask == min & mask {
362-
// i.e., if the range is everything. The lo==hi case would be
363-
// rejected by the LLVM verifier (it would mean either an
364-
// empty set, which is impossible, or the entire range of the
365-
// type, which is pointless).
366-
bcx.load(self.llval, self.alignment.non_abi())
367-
} else {
368-
// llvm::ConstantRange can deal with ranges that wrap around,
369-
// so an overflow on (max + 1) is fine.
370-
bcx.load_range_assert(self.llval, min, max.wrapping_add(1), /* signed: */ llvm::True,
371-
self.alignment.non_abi())
354+
fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
355+
if let layout::Int(ity) = discr {
356+
let bits = ity.size().bits();
357+
assert!(bits <= 64);
358+
let bits = bits as usize;
359+
let mask = !0u64 >> (64 - bits);
360+
// For a (max) discr of -1, max will be `-1 as usize`, which overflows.
361+
// However, that is fine here (it would still represent the full range),
362+
if max.wrapping_add(1) & mask == min & mask {
363+
// i.e., if the range is everything. The lo==hi case would be
364+
// rejected by the LLVM verifier (it would mean either an
365+
// empty set, which is impossible, or the entire range of the
366+
// type, which is pointless).
367+
} else {
368+
// llvm::ConstantRange can deal with ranges that wrap around,
369+
// so an overflow on (max + 1) is fine.
370+
return bcx.load_range_assert(self.llval, min, max.wrapping_add(1),
371+
/* signed: */ llvm::True,
372+
self.alignment.non_abi());
373+
}
372374
}
375+
bcx.load(self.llval, self.alignment.non_abi())
373376
}
374377

375378
/// Obtain the actual discriminant of a value.
@@ -406,14 +409,13 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
406409
.discriminant_for_variant(bcx.tcx(), variant_index)
407410
.to_u128_unchecked() as u64;
408411
match *l {
409-
layout::CEnum { discr, min, max, .. } => {
410-
adt::assert_discr_in_range(min, max, to);
411-
bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
412+
layout::CEnum { .. } => {
413+
bcx.store(C_int(bcx.ccx.llvm_type_of(self.ty.to_ty(bcx.tcx())), to as i64),
412414
self.llval, self.alignment.non_abi());
413415
}
414-
layout::General { discr, .. } => {
416+
layout::General { .. } => {
415417
let ptr = self.project_field(bcx, 0);
416-
bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
418+
bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())), to as i64),
417419
ptr.llval, ptr.alignment.non_abi());
418420
}
419421
layout::Univariant { .. }

0 commit comments

Comments
 (0)