1
Fork 0

rustc: collapse Layout::CEnum into Layout::General.

This commit is contained in:
Eduard-Mihai Burtescu 2017-09-16 23:12:39 +03:00
parent 658ebfc788
commit 33a205b56f
9 changed files with 86 additions and 135 deletions

View file

@ -47,10 +47,11 @@
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(drain_filter)] #![feature(drain_filter)]
#![feature(i128_type)] #![feature(i128_type)]
#![feature(match_default_bindings)] #![feature(inclusive_range)]
#![feature(inclusive_range_syntax)] #![feature(inclusive_range_syntax)]
#![cfg_attr(windows, feature(libc))] #![cfg_attr(windows, feature(libc))]
#![feature(macro_vis_matcher)] #![feature(macro_vis_matcher)]
#![feature(match_default_bindings)]
#![feature(never_type)] #![feature(never_type)]
#![feature(nonzero)] #![feature(nonzero)]
#![feature(quote)] #![feature(quote)]

View file

@ -25,7 +25,7 @@ use std::fmt;
use std::i64; use std::i64;
use std::iter; use std::iter;
use std::mem; use std::mem;
use std::ops::{Deref, Add, Sub, Mul, AddAssign}; use std::ops::{Deref, Add, Sub, Mul, AddAssign, RangeInclusive};
use ich::StableHashingContext; use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
@ -841,9 +841,9 @@ impl<'a, 'tcx> Struct {
(&Scalar(Pointer), _) if !layout.ty.is_unsafe_ptr() => { (&Scalar(Pointer), _) if !layout.ty.is_unsafe_ptr() => {
Ok(Some((Size::from_bytes(0), Pointer))) Ok(Some((Size::from_bytes(0), Pointer)))
} }
(&CEnum { discr, .. }, &ty::TyAdt(def, _)) => { (&General { discr, .. }, &ty::TyAdt(def, _)) => {
if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) { if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
Ok(Some((Size::from_bytes(0), discr))) Ok(Some((layout.fields.offset(0), discr)))
} else { } else {
Ok(None) Ok(None)
} }
@ -1095,18 +1095,6 @@ pub enum Layout {
// Remaining variants are all ADTs such as structs, enums or tuples. // Remaining variants are all ADTs such as structs, enums or tuples.
/// C-like enums; basically an integer.
CEnum {
discr: Primitive,
/// Inclusive discriminant range.
/// If min > max, it represents min...u64::MAX followed by 0...max.
// FIXME(eddyb) always use the shortest range, e.g. by finding
// the largest space between two consecutive discriminants and
// taking everything else as the (shortest) discriminant range.
min: u64,
max: u64
},
/// Single-case enums, and structs/tuples. /// Single-case enums, and structs/tuples.
Univariant(Struct), Univariant(Struct),
@ -1118,6 +1106,12 @@ pub enum Layout {
/// at a non-0 offset, after where the discriminant would go. /// at a non-0 offset, after where the discriminant would go.
General { General {
discr: Primitive, discr: Primitive,
/// Inclusive wrap-around range of discriminant values, that is,
/// if min > max, it represents min..=u64::MAX followed by 0..=max.
// FIXME(eddyb) always use the shortest range, e.g. by finding
// the largest space between two consecutive discriminants and
// taking everything else as the (shortest) discriminant range.
discr_range: RangeInclusive<u64>,
variants: Vec<Struct>, variants: Vec<Struct>,
size: Size, size: Size,
align: Align, align: Align,
@ -1240,7 +1234,6 @@ impl<'a, 'tcx> Layout {
FieldPlacement::union(def.struct_variant().fields.len()) FieldPlacement::union(def.struct_variant().fields.len())
} }
CEnum { .. } |
General { .. } => FieldPlacement::union(1), General { .. } => FieldPlacement::union(1),
NullablePointer { ref discr_offset, .. } => { NullablePointer { ref discr_offset, .. } => {
@ -1250,19 +1243,17 @@ impl<'a, 'tcx> Layout {
} }
}; };
let abi = match *layout { let abi = match *layout {
Scalar(value) | Scalar(value) => Abi::Scalar(value),
CEnum { discr: value, .. } => Abi::Scalar(value),
Vector { .. } => Abi::Vector, Vector { .. } => Abi::Vector,
Array { .. } | Array { .. } |
FatPointer { .. } | FatPointer { .. } |
Univariant(_) | Univariant(_) |
UntaggedUnion(_) | UntaggedUnion(_) => Abi::Aggregate,
General { .. } => Abi::Aggregate,
NullablePointer { discr, discr_offset, .. } => { General { discr, .. } |
if discr_offset.bytes() == 0 && discr.size(cx) == layout.size(cx) { NullablePointer { discr, .. } => {
if fields.offset(0).bytes() == 0 && discr.size(cx) == layout.size(cx) {
Abi::Scalar(discr) Abi::Scalar(discr)
} else { } else {
Abi::Aggregate Abi::Aggregate
@ -1431,7 +1422,14 @@ impl<'a, 'tcx> Layout {
// ADTs. // ADTs.
ty::TyAdt(def, substs) => { ty::TyAdt(def, substs) => {
if def.variants.is_empty() { // Cache the field layouts.
let variants = def.variants.iter().map(|v| {
v.fields.iter().map(|field| {
cx.layout_of(field.ty(tcx, substs))
}).collect::<Result<Vec<_>, _>>()
}).collect::<Result<Vec<_>, _>>()?;
if variants.is_empty() {
// Uninhabitable; represent as unit // Uninhabitable; represent as unit
// (Typechecking will reject discriminant-sizing attrs.) // (Typechecking will reject discriminant-sizing attrs.)
@ -1439,74 +1437,39 @@ impl<'a, 'tcx> Layout {
&def.repr, StructKind::AlwaysSizedUnivariant, ty)?)); &def.repr, StructKind::AlwaysSizedUnivariant, ty)?));
} }
if def.is_enum() && def.variants.iter().all(|v| v.fields.is_empty()) { if !def.is_enum() || (variants.len() == 1 &&
// All bodies empty -> intlike !def.repr.inhibit_enum_layout_opt() &&
let (mut min, mut max) = (i64::max_value(), i64::min_value()); !variants[0].is_empty()) {
for discr in def.discriminants(tcx) {
let x = discr.to_u128_unchecked() as i64;
if x < min { min = x; }
if x > max { max = x; }
}
// FIXME: should handle i128? signed-value based impl is weird and hard to
// grok.
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
return success(CEnum {
discr: Int(discr, signed),
// FIXME: should be u128?
min: min as u64,
max: max as u64
});
}
if !def.is_enum() || (def.variants.len() == 1 &&
!def.repr.inhibit_enum_layout_opt()) {
// Struct, or union, or univariant enum equivalent to a struct. // Struct, or union, or univariant enum equivalent to a struct.
// (Typechecking will reject discriminant-sizing attrs.) // (Typechecking will reject discriminant-sizing attrs.)
let kind = if def.is_enum() || def.variants[0].fields.len() == 0{ let kind = if def.is_enum() || variants[0].len() == 0 {
StructKind::AlwaysSizedUnivariant StructKind::AlwaysSizedUnivariant
} else { } else {
let param_env = tcx.param_env(def.did); let param_env = tcx.param_env(def.did);
let fields = &def.variants[0].fields; let last_field = def.variants[0].fields.last().unwrap();
let last_field = &fields[fields.len()-1];
let always_sized = tcx.type_of(last_field.did) let always_sized = tcx.type_of(last_field.did)
.is_sized(tcx, param_env, DUMMY_SP); .is_sized(tcx, param_env, DUMMY_SP);
if !always_sized { StructKind::MaybeUnsizedUnivariant } if !always_sized { StructKind::MaybeUnsizedUnivariant }
else { StructKind::AlwaysSizedUnivariant } else { StructKind::AlwaysSizedUnivariant }
}; };
let fields = def.variants[0].fields.iter().map(|field| {
cx.layout_of(field.ty(tcx, substs))
}).collect::<Result<Vec<_>, _>>()?;
let layout = if def.is_union() { let layout = if def.is_union() {
let mut un = Union::new(dl, &def.repr); let mut un = Union::new(dl, &def.repr);
un.extend(dl, fields.iter().map(|&f| Ok(f.layout)), ty)?; un.extend(dl, variants[0].iter().map(|&f| Ok(f.layout)), ty)?;
UntaggedUnion(un) UntaggedUnion(un)
} else { } else {
Univariant(Struct::new(dl, &fields, &def.repr, kind, ty)?) Univariant(Struct::new(dl, &variants[0], &def.repr, kind, ty)?)
}; };
return success(layout); return success(layout);
} }
// Since there's at least one let no_explicit_discriminants = def.variants.iter().enumerate()
// non-empty body, explicit discriminants should have .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i));
// been rejected by a checker before this point.
for (i, v) in def.variants.iter().enumerate() {
if v.discr != ty::VariantDiscr::Relative(i) {
bug!("non-C-like enum {} with specified discriminants",
tcx.item_path_str(def.did));
}
}
// Cache the substituted and normalized variant field types. if variants.len() == 2 &&
let variants = def.variants.iter().map(|v| { !def.repr.inhibit_enum_layout_opt() &&
v.fields.iter().map(|field| { no_explicit_discriminants {
cx.layout_of(field.ty(tcx, substs))
}).collect::<Result<Vec<_>, _>>()
}).collect::<Result<Vec<_>, _>>()?;
if variants.len() == 2 && !def.repr.inhibit_enum_layout_opt() {
// Nullable pointer optimization // Nullable pointer optimization
let st0 = Struct::new(dl, &variants[0], let st0 = Struct::new(dl, &variants[0],
&def.repr, StructKind::AlwaysSizedUnivariant, ty)?; &def.repr, StructKind::AlwaysSizedUnivariant, ty)?;
@ -1554,16 +1517,23 @@ impl<'a, 'tcx> Layout {
} }
} }
// The general case. let (mut min, mut max) = (i64::max_value(), i64::min_value());
let discr_max = (variants.len() - 1) as i64; for discr in def.discriminants(tcx) {
assert!(discr_max >= 0); let x = discr.to_u128_unchecked() as i64;
let (min_ity, _) = Integer::repr_discr(tcx, ty, &def.repr, 0, discr_max); if x < min { min = x; }
if x > max { max = x; }
}
// FIXME: should handle i128? signed-value based impl is weird and hard to
// grok.
let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
let mut align = dl.aggregate_align; let mut align = dl.aggregate_align;
let mut primitive_align = dl.aggregate_align; let mut primitive_align = dl.aggregate_align;
let mut size = Size::from_bytes(0); let mut size = Size::from_bytes(0);
// We're interested in the smallest alignment, so start large. // We're interested in the smallest alignment, so start large.
let mut start_align = Align::from_bytes(256, 256).unwrap(); let mut start_align = Align::from_bytes(256, 256).unwrap();
assert_eq!(Integer::for_abi_align(dl, start_align), None);
// Create the set of structs that represent each variant. // Create the set of structs that represent each variant.
let mut variants = variants.into_iter().map(|fields| { let mut variants = variants.into_iter().map(|fields| {
@ -1644,7 +1614,10 @@ impl<'a, 'tcx> Layout {
} }
General { General {
discr: Int(ity, false), discr: Int(ity, signed),
// FIXME: should be u128?
discr_range: (min as u64)..=(max as u64),
variants, variants,
size, size,
align, align,
@ -1680,7 +1653,7 @@ impl<'a, 'tcx> Layout {
pub fn is_unsized(&self) -> bool { pub fn is_unsized(&self) -> bool {
match *self { match *self {
Scalar(_) | Vector {..} | FatPointer {..} | Scalar(_) | Vector {..} | FatPointer {..} |
CEnum {..} | UntaggedUnion {..} | General {..} | UntaggedUnion {..} | General {..} |
NullablePointer {..} => false, NullablePointer {..} => false,
Array { sized, .. } | Array { sized, .. } |
@ -1720,7 +1693,6 @@ impl<'a, 'tcx> Layout {
metadata.size(dl)).abi_align(self.align(dl)) metadata.size(dl)).abi_align(self.align(dl))
} }
CEnum { discr, .. } => discr.size(dl),
General { size, .. } => size, General { size, .. } => size,
UntaggedUnion(ref un) => un.stride(), UntaggedUnion(ref un) => un.stride(),
@ -1754,7 +1726,6 @@ impl<'a, 'tcx> Layout {
Pointer.align(dl).max(metadata.align(dl)) Pointer.align(dl).max(metadata.align(dl))
} }
CEnum { discr, .. } => discr.align(dl),
Array { align, .. } | General { align, .. } => align, Array { align, .. } | General { align, .. } => align,
UntaggedUnion(ref un) => un.align, UntaggedUnion(ref un) => un.align,
@ -1856,16 +1827,6 @@ impl<'a, 'tcx> Layout {
} }
}; };
let build_primitive_info = |name: ast::Name, value: Primitive| {
session::VariantInfo {
name: Some(name.to_string()),
kind: session::SizeKind::Exact,
align: value.align(tcx).abi(),
size: value.size(tcx).bytes(),
fields: vec![],
}
};
let build_variant_info = |n: Option<ast::Name>, let build_variant_info = |n: Option<ast::Name>,
flds: &[(ast::Name, Ty<'tcx>)], flds: &[(ast::Name, Ty<'tcx>)],
s: &Struct| { s: &Struct| {
@ -1959,17 +1920,6 @@ impl<'a, 'tcx> Layout {
record(adt_kind.into(), None, Vec::new()); record(adt_kind.into(), None, Vec::new());
} }
Layout::CEnum { discr, .. } => {
debug!("print-type-size t: `{:?}` adt c-like enum", ty);
let variant_infos: Vec<_> =
adt_def.variants.iter()
.map(|variant_def| {
build_primitive_info(variant_def.name, discr)
})
.collect();
record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
}
// other cases provide little interesting (i.e. adjustable // other cases provide little interesting (i.e. adjustable
// via representation tweaks) size info beyond total size. // via representation tweaks) size info beyond total size.
Layout::Scalar(_) | Layout::Scalar(_) |
@ -2284,6 +2234,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
FullLayout { FullLayout {
variant_index: Some(variant_index), variant_index: Some(variant_index),
fields, fields,
abi: Abi::Aggregate,
..*self ..*self
} }
} }
@ -2356,7 +2307,6 @@ impl<'a, 'tcx> FullLayout<'tcx> {
match self.variant_index { match self.variant_index {
None => match *self.layout { None => match *self.layout {
// Discriminant field for enums (where applicable). // Discriminant field for enums (where applicable).
CEnum { discr, .. } |
General { discr, .. } | General { discr, .. } |
NullablePointer { discr, .. } => { NullablePointer { discr, .. } => {
return [discr.to_ty(tcx)][i]; return [discr.to_ty(tcx)][i];
@ -2416,19 +2366,23 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout
FatPointer(ref metadata) => { FatPointer(ref metadata) => {
metadata.hash_stable(hcx, hasher); metadata.hash_stable(hcx, hasher);
} }
CEnum { discr, min, max } => {
discr.hash_stable(hcx, hasher);
min.hash_stable(hcx, hasher);
max.hash_stable(hcx, hasher);
}
Univariant(ref variant) => { Univariant(ref variant) => {
variant.hash_stable(hcx, hasher); variant.hash_stable(hcx, hasher);
} }
UntaggedUnion(ref un) => { UntaggedUnion(ref un) => {
un.hash_stable(hcx, hasher); un.hash_stable(hcx, hasher);
} }
General { discr, ref variants, size, align, primitive_align } => { General {
discr,
discr_range: RangeInclusive { start, end },
ref variants,
size,
align,
primitive_align
} => {
discr.hash_stable(hcx, hasher); discr.hash_stable(hcx, hasher);
start.hash_stable(hcx, hasher);
end.hash_stable(hcx, hasher);
variants.hash_stable(hcx, hasher); variants.hash_stable(hcx, hasher);
size.hash_stable(hcx, hasher); size.hash_stable(hcx, hasher);
align.hash_stable(hcx, hasher); align.hash_stable(hcx, hasher);

View file

@ -69,7 +69,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let l = cx.layout_of(t); let l = cx.layout_of(t);
debug!("finish_type_of: {} with layout {:#?}", t, l); debug!("finish_type_of: {} with layout {:#?}", t, l);
match *l { match *l {
layout::CEnum { .. } | layout::General { .. } | layout::UntaggedUnion { .. } => { } layout::General { .. } | layout::UntaggedUnion { .. } => { }
layout::Univariant { ..} | layout::NullablePointer { .. } => { layout::Univariant { ..} | layout::NullablePointer { .. } => {
if let layout::Abi::Scalar(_) = l.abi { if let layout::Abi::Scalar(_) = l.abi {
return; return;
@ -101,13 +101,12 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>, t: Ty<'tcx>,
name: Option<&str>) -> Type { name: Option<&str>) -> Type {
let l = cx.layout_of(t); let l = cx.layout_of(t);
debug!("adt::generic_type_of t: {:?} name: {:?}", t, name); debug!("adt::generic_type_of {:#?} name: {:?}", l, name);
match *l { if let layout::Abi::Scalar(value) = l.abi {
layout::CEnum { discr, .. } => cx.llvm_type_of(discr.to_ty(cx.tcx())), return cx.llvm_type_of(value.to_ty(cx.tcx()));
layout::NullablePointer { nndiscr, ref nonnull, .. } => {
if let layout::Abi::Scalar(_) = l.abi {
return cx.llvm_type_of(l.field(cx, 0).ty);
} }
match *l {
layout::NullablePointer { nndiscr, ref nonnull, .. } => {
match name { match name {
None => { None => {
Type::struct_(cx, &struct_llfields(cx, l.for_variant(nndiscr as usize), Type::struct_(cx, &struct_llfields(cx, l.for_variant(nndiscr as usize),

View file

@ -1282,7 +1282,6 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
} }
] ]
}, },
layout::CEnum { .. } => span_bug!(self.span, "This should be unreachable."),
ref l @ _ => bug!("Not an enum layout: {:#?}", l) ref l @ _ => bug!("Not an enum layout: {:#?}", l)
} }
} }
@ -1491,14 +1490,16 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let type_rep = cx.layout_of(enum_type); let type_rep = cx.layout_of(enum_type);
let discriminant_type_metadata = match *type_rep { let discriminant_type_metadata = match *type_rep {
layout::CEnum { discr, .. } => {
return FinalMetadata(discriminant_type_metadata(discr))
},
layout::NullablePointer { .. } | layout::Univariant { .. } => None, layout::NullablePointer { .. } | layout::Univariant { .. } => None,
layout::General { discr, .. } => Some(discriminant_type_metadata(discr)), layout::General { discr, .. } => Some(discriminant_type_metadata(discr)),
ref l @ _ => bug!("Not an enum layout: {:#?}", l) ref l @ _ => bug!("Not an enum layout: {:#?}", l)
}; };
match (type_rep.abi, discriminant_type_metadata) {
(layout::Abi::Scalar(_), Some(discr)) => return FinalMetadata(discr),
_ => {}
}
let (enum_type_size, enum_type_align) = type_rep.size_and_align(cx); let (enum_type_size, enum_type_align) = type_rep.size_and_align(cx);
let enum_name = CString::new(enum_name).unwrap(); let enum_name = CString::new(enum_name).unwrap();

View file

@ -25,6 +25,7 @@
#![allow(unused_attributes)] #![allow(unused_attributes)]
#![feature(i128_type)] #![feature(i128_type)]
#![feature(i128)] #![feature(i128)]
#![feature(inclusive_range)]
#![feature(libc)] #![feature(libc)]
#![feature(quote)] #![feature(quote)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]

View file

@ -1091,7 +1091,7 @@ fn trans_const_adt<'a, 'tcx>(
_ => 0, _ => 0,
}; };
match *l { match *l {
layout::CEnum { .. } => { layout::General { ref variants, .. } => {
let discr = match *kind { let discr = match *kind {
mir::AggregateKind::Adt(adt_def, _, _, _) => { mir::AggregateKind::Adt(adt_def, _, _, _) => {
adt_def.discriminant_for_variant(ccx.tcx(), variant_index) adt_def.discriminant_for_variant(ccx.tcx(), variant_index)
@ -1099,15 +1099,14 @@ fn trans_const_adt<'a, 'tcx>(
}, },
_ => 0, _ => 0,
}; };
assert_eq!(vals.len(), 0);
Const::new(C_int(ccx.llvm_type_of(t), discr as i64), t)
}
layout::General { ref variants, .. } => {
let discr_ty = l.field(ccx, 0).ty; let discr_ty = l.field(ccx, 0).ty;
let variant = &variants[variant_index]; let discr = Const::new(C_int(ccx.llvm_type_of(discr_ty), discr as i64),
let lldiscr = C_int(ccx.llvm_type_of(discr_ty), variant_index as i64); discr_ty);
build_const_struct(ccx, l, &variant, vals, if let layout::Abi::Scalar(_) = l.abi {
Some(Const::new(lldiscr, discr_ty))) discr
} else {
build_const_struct(ccx, l, &variants[variant_index], vals, Some(discr))
}
} }
layout::UntaggedUnion(ref un) => { layout::UntaggedUnion(ref un) => {
assert_eq!(variant_index, 0); assert_eq!(variant_index, 0);

View file

@ -367,8 +367,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
_ => bug!("discriminant not scalar: {:#?}", discr_layout) _ => bug!("discriminant not scalar: {:#?}", discr_layout)
}; };
let (min, max) = match *l { let (min, max) = match *l {
layout::CEnum { min, max, .. } => (min, max), layout::General { ref discr_range, .. } => (discr_range.start, discr_range.end),
layout::General { ref variants, .. } => (0, variants.len() as u64 - 1),
_ => (0, u64::max_value()), _ => (0, u64::max_value()),
}; };
let max_next = max.wrapping_add(1); let max_next = max.wrapping_add(1);
@ -394,7 +393,6 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
} }
}; };
match *l { match *l {
layout::CEnum { .. } |
layout::General { .. } => { layout::General { .. } => {
let signed = match discr_scalar { let signed = match discr_scalar {
layout::Int(_, signed) => signed, layout::Int(_, signed) => signed,
@ -419,7 +417,6 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
.discriminant_for_variant(bcx.tcx(), variant_index) .discriminant_for_variant(bcx.tcx(), variant_index)
.to_u128_unchecked() as u64; .to_u128_unchecked() as u64;
match *l { match *l {
layout::CEnum { .. } |
layout::General { .. } => { layout::General { .. } => {
let ptr = self.project_field(bcx, 0); let ptr = self.project_field(bcx, 0);
bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())), to as i64), bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())), to as i64),

View file

@ -277,8 +277,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
let llval = operand.immediate(); let llval = operand.immediate();
let l = bcx.ccx.layout_of(operand.ty); let l = bcx.ccx.layout_of(operand.ty);
if let Layout::CEnum { min, max, .. } = *l { if let Layout::General { ref discr_range, .. } = *l {
if max > min { if discr_range.end > discr_range.start {
// We want `table[e as usize]` to not // We want `table[e as usize]` to not
// have bound checks, and this is the most // have bound checks, and this is the most
// convenient place to put the `assume`. // convenient place to put the `assume`.
@ -286,7 +286,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
base::call_assume(&bcx, bcx.icmp( base::call_assume(&bcx, bcx.icmp(
llvm::IntULE, llvm::IntULE,
llval, llval,
C_uint(ll_t_in, max) C_uint(ll_t_in, discr_range.end)
)); ));
} }
} }

View file

@ -242,7 +242,6 @@ impl<'tcx> LayoutLlvmExt for FullLayout<'tcx> {
} }
match **self { match **self {
Layout::Scalar { .. } | Layout::Scalar { .. } |
Layout::CEnum { .. } |
Layout::UntaggedUnion { .. } => { Layout::UntaggedUnion { .. } => {
bug!("FullLayout::llvm_field_index({:?}): not applicable", self) bug!("FullLayout::llvm_field_index({:?}): not applicable", self)
} }