Skip to content

Commit 43f9467

Browse files
committed
partial enum variant type support
1 parent e6f77a1 commit 43f9467

File tree

56 files changed

+1120
-578
lines changed

Some content is hidden

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

56 files changed

+1120
-578
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,22 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
744744
PlaceTy { ty: base_ty, variant_index: Some(index) }
745745
}
746746
}
747+
ty::Variant(ty, _) => match ty.kind() {
748+
ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
749+
if index.as_usize() >= adt_def.variants.len() {
750+
PlaceTy::from_ty(span_mirbug_and_err!(
751+
self,
752+
place,
753+
"cast to variant #{:?} but enum only has {:?}",
754+
index,
755+
adt_def.variants.len()
756+
))
757+
} else {
758+
PlaceTy { ty: *ty, variant_index: Some(index) }
759+
}
760+
}
761+
_ => bug!("unexpected type: {:?}", ty.kind()),
762+
},
747763
// We do not need to handle generators here, because this runs
748764
// before the generator transform stage.
749765
_ => {
@@ -812,6 +828,12 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
812828
let (variant, substs) = match base_ty {
813829
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
814830
ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
831+
ty::Variant(ty, _) => match ty.kind() {
832+
ty::Adt(adt_def, substs) => {
833+
(adt_def.variants.get(variant_index).expect(""), *substs)
834+
}
835+
_ => bug!("unexpected type: {:?}", ty.kind()),
836+
},
815837
ty::Generator(def_id, substs, _) => {
816838
let mut variants = substs.as_generator().state_tys(def_id, tcx);
817839
let mut variant = match variants.nth(variant_index.into()) {
@@ -833,6 +855,12 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
833855
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
834856
(&adt_def.variants[VariantIdx::new(0)], substs)
835857
}
858+
ty::Variant(ty, _) => match ty.kind() {
859+
ty::Adt(adt_def, substs) if adt_def.is_enum() => {
860+
(&adt_def.variants[VariantIdx::new(0)], *substs)
861+
}
862+
_ => bug!("unexpected type: {:?}", ty.kind()),
863+
},
836864
ty::Closure(_, substs) => {
837865
return match substs
838866
.as_closure()

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ fn push_debuginfo_type_name<'tcx>(
373373
t
374374
);
375375
}
376+
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
376377
}
377378

378379
/// MSVC names enums differently than other platforms so that the debugging visualization

compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ fn const_to_valtree_inner<'tcx>(
129129
| ty::Closure(..)
130130
| ty::Generator(..)
131131
| ty::GeneratorWitness(..) => None,
132+
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
132133
}
133134
}
134135

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ crate fn eval_nullary_intrinsic<'tcx>(
100100
| ty::Never
101101
| ty::Tuple(_)
102102
| ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx),
103+
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
103104
},
104105
other => bug!("`{}` is not a zero arg intrinsic", other),
105106
})

compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
6565
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
6666

6767
ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
68+
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
6869
}
6970
}
7071

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
687687
ty::Adt(adt, _) => {
688688
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
689689
}
690+
ty::Variant(ty, _) => match ty.kind() {
691+
ty::Adt(adt, _) => adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits),
692+
_ => bug!("unexpected type: {:?}", ty.kind()),
693+
}
690694
ty::Generator(def_id, substs, _) => {
691695
let substs = substs.as_generator();
692696
substs

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
219219
if tag_field == field {
220220
return match layout.ty.kind() {
221221
ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag,
222+
ty::Variant(ty, ..) => match ty.kind() {
223+
ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag,
224+
_ => bug!("non-variant type {:?}", layout.ty),
225+
},
222226
ty::Generator(..) => PathElem::GeneratorTag,
223227
_ => bug!("non-variant type {:?}", layout.ty),
224228
};
@@ -272,6 +276,20 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
272276
}
273277
}
274278

279+
ty::Variant(ty, ..) => match ty.kind() {
280+
ty::Adt(def, ..) if def.is_enum() => {
281+
// we might be projecting *to* a variant, or to a field *in* a variant.
282+
match layout.variants {
283+
Variants::Single { index } => {
284+
// Inside a variant
285+
PathElem::Field(def.variants[index].fields[field].ident.name)
286+
}
287+
Variants::Multiple { .. } => bug!("we handled variants above"),
288+
}
289+
}
290+
_ => bug!("unexpected type: {:?}", ty.kind()),
291+
},
292+
275293
// other ADTs
276294
ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].ident.name),
277295

@@ -567,6 +585,17 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
567585
self.check_safe_pointer(value, "box")?;
568586
Ok(true)
569587
}
588+
ty::Variant(ty, _) => match ty.kind() {
589+
ty::Adt(def, _) => {
590+
if def.is_box() {
591+
self.check_safe_pointer(value, "box")?;
592+
Ok(true)
593+
} else {
594+
Ok(false)
595+
}
596+
}
597+
_ => bug!("unexpected type: {:?}", ty.kind()),
598+
},
570599
ty::FnPtr(_sig) => {
571600
let value = try_validation!(
572601
self.ecx.read_immediate(value),
@@ -729,6 +758,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
729758
) -> InterpResult<'tcx> {
730759
let name = match old_op.layout.ty.kind() {
731760
ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].ident.name),
761+
ty::Variant(ty, ..) => match ty.kind() {
762+
ty::Adt(adt, ..) => PathElem::Variant(adt.variants[variant_id].ident.name),
763+
_ => bug!("unexpected type {:?}", ty.kind()),
764+
},
732765
// Generators also have variants
733766
ty::Generator(..) => PathElem::GeneratorState(variant_id),
734767
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
385385
| ty::Uint(..)
386386
| ty::Float(..)
387387
| ty::Adt(..)
388+
| ty::Variant(..)
388389
| ty::Str
389390
| ty::Error(_)
390391
| ty::Array(..)

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
7272
{
7373
let a_is_expected = relation.a_is_expected();
7474

75+
debug!("super_combine_tys: {:?} | {:?}", a.kind(), b.kind());
7576
match (a.kind(), b.kind()) {
7677
// Relate integral variables to other types
7778
(&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => {

compiler/rustc_infer/src/infer/freshen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
199199
| ty::Uint(..)
200200
| ty::Float(..)
201201
| ty::Adt(..)
202+
| ty::Variant(..)
202203
| ty::Str
203204
| ty::Error(_)
204205
| ty::Array(..)

0 commit comments

Comments
 (0)