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

+28
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

+1
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

+1
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

+1
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

+1
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

+4
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

+33
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

+1
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

+1
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

+1
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(..)

compiler/rustc_lint/src/types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11301130
| ty::GeneratorWitness(..)
11311131
| ty::Placeholder(..)
11321132
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
1133+
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
11331134
}
11341135
}
11351136

compiler/rustc_middle/src/ty/cast.rs

+10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ impl<'tcx> CastTy<'tcx> {
5959
ty::Uint(u) => Some(CastTy::Int(IntTy::U(u))),
6060
ty::Float(_) => Some(CastTy::Float),
6161
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
62+
ty::Variant(ty, _) => match ty.kind() {
63+
ty::Adt(d, _) => {
64+
if d.is_enum() && d.is_payloadfree() {
65+
Some(CastTy::Int(IntTy::CEnum))
66+
} else {
67+
None
68+
}
69+
}
70+
_ => bug!("unexpected type: {:?}", ty.kind()),
71+
}
6272
ty::RawPtr(mt) => Some(CastTy::Ptr(mt)),
6373
ty::FnPtr(..) => Some(CastTy::FnPtr),
6474
_ => None,

compiler/rustc_middle/src/ty/codec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ macro_rules! impl_decodable_via_ref {
307307
})*
308308
}
309309
}
310-
310+
// TODO(zhamlin): enum variant here?
311311
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::AdtDef {
312312
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
313313
let def_id = <DefId as Decodable<D>>::decode(decoder)?;

compiler/rustc_middle/src/ty/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,7 @@ impl<'tcx> TyCtxt<'tcx> {
19191919
fmt,
19201920
self.0,
19211921
Adt,
1922+
Variant,
19221923
Array,
19231924
Slice,
19241925
RawPtr,

compiler/rustc_middle/src/ty/error.rs

+8
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ impl<'tcx> ty::TyS<'tcx> {
244244
ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(),
245245

246246
ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
247+
ty::Variant(ty, _) => match ty.kind() {
248+
ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
249+
_ => bug!("unexpected type: {:?}", ty.kind()),
250+
}
247251
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
248252
ty::Array(t, n) => {
249253
if t.is_simple_ty() {
@@ -315,6 +319,10 @@ impl<'tcx> ty::TyS<'tcx> {
315319
| ty::Never => "type".into(),
316320
ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(),
317321
ty::Adt(def, _) => def.descr().into(),
322+
ty::Variant(ty, _) => match ty.kind() {
323+
ty::Adt(def, _) => format!("{} variant", def.descr()).into(),
324+
_ => bug!("unexpected type: {:?}", ty.kind()),
325+
}
318326
ty::Foreign(_) => "extern type".into(),
319327
ty::Array(..) => "array".into(),
320328
ty::Slice(_) => "slice".into(),

compiler/rustc_middle/src/ty/fast_reject.rs

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub fn simplify_type(
6666
ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)),
6767
ty::Float(float_type) => Some(FloatSimplifiedType(float_type)),
6868
ty::Adt(def, _) => Some(AdtSimplifiedType(def.did)),
69+
ty::Variant(ref ty, _) => match ty.kind() {
70+
ty::Adt(def, _) => Some(AdtSimplifiedType(def.did)),
71+
_ => bug!("unexpected type: {:?}", ty.kind()),
72+
}
6973
ty::Str => Some(StrSimplifiedType),
7074
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
7175
ty::RawPtr(_) => Some(PtrSimplifiedType),

compiler/rustc_middle/src/ty/flags.rs

+5
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ impl FlagComputation {
161161
self.add_substs(substs);
162162
}
163163

164+
&ty::Variant(ty, _) => match ty.kind() {
165+
ty::Adt(_, substs) => self.add_substs(substs),
166+
_ => bug!("unexpected type: {:?}", ty.kind()),
167+
}
168+
164169
&ty::Projection(data) => {
165170
self.add_flags(TypeFlags::HAS_TY_PROJECTION);
166171
self.add_projection_ty(data);

0 commit comments

Comments
 (0)