Skip to content

Commit 9c0558a

Browse files
committed
make enums with repr(rust) use 1 for default discriminant
1 parent 87df4dd commit 9c0558a

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

compiler/rustc_middle/src/ty/adt.rs

+35-2
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,24 @@ impl<'tcx> AdtDef {
402402
tcx: TyCtxt<'tcx>,
403403
) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
404404
assert!(self.is_enum());
405+
let no_explicit_discriminants = self
406+
.variants
407+
.iter_enumerated()
408+
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
409+
410+
let mut any_dataful_variants = false;
411+
for fields in self.variants.iter() {
412+
if fields.fields.len() > 0 {
413+
any_dataful_variants = true;
414+
break;
415+
}
416+
}
417+
let initial_discr = no_explicit_discriminants
418+
&& !self.repr.inhibit_enum_layout_opt()
419+
&& !self.repr.inhibit_struct_field_reordering_opt()
420+
&& !any_dataful_variants;
405421
let repr_type = self.repr.discr_type();
406-
let initial = repr_type.initial_discriminant(tcx);
422+
let initial = Discr { val: initial_discr as u128, ty: repr_type.to_ty(tcx) };
407423
let mut prev_discr = None::<Discr<'tcx>>;
408424
self.variants.iter_enumerated().map(move |(i, v)| {
409425
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
@@ -436,9 +452,26 @@ impl<'tcx> AdtDef {
436452
) -> Discr<'tcx> {
437453
assert!(self.is_enum());
438454
let (val, offset) = self.discriminant_def_for_variant(variant_index);
455+
let no_explicit_discriminants = self
456+
.variants
457+
.iter_enumerated()
458+
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
459+
460+
let mut any_dataful_variants = false;
461+
for fields in self.variants.iter() {
462+
if fields.fields.len() > 0 {
463+
any_dataful_variants = true;
464+
break;
465+
}
466+
}
467+
let initial_discr = no_explicit_discriminants
468+
&& !self.repr.inhibit_enum_layout_opt()
469+
&& !self.repr.inhibit_struct_field_reordering_opt()
470+
&& !any_dataful_variants;
471+
let initial = Discr { val: initial_discr as u128, ty: self.repr.discr_type().to_ty(tcx) };
439472
let explicit_value = val
440473
.and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
441-
.unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx));
474+
.unwrap_or_else(|| initial);
442475
explicit_value.checked_add(tcx, offset as u128).0
443476
}
444477

compiler/rustc_typeck/src/collect.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,22 @@ fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
927927
fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId, variants: &[hir::Variant<'_>]) {
928928
let def = tcx.adt_def(def_id);
929929
let repr_type = def.repr.discr_type();
930-
let initial = repr_type.initial_discriminant(tcx);
930+
let no_explicit_discriminants = def
931+
.variants
932+
.iter_enumerated()
933+
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
934+
let mut any_dataful_variants = false;
935+
for fields in def.variants.iter() {
936+
if fields.fields.len() > 0 {
937+
any_dataful_variants = true;
938+
break;
939+
}
940+
}
941+
let initial_discr = no_explicit_discriminants
942+
&& !def.repr.inhibit_enum_layout_opt()
943+
&& !def.repr.inhibit_struct_field_reordering_opt()
944+
&& !any_dataful_variants;
945+
let initial = Discr { val: initial_discr as u128, ty: repr_type.to_ty(tcx) };
931946
let mut prev_discr = None::<Discr<'_>>;
932947

933948
// fill the discriminant values and field types

0 commit comments

Comments
 (0)