Skip to content

Commit a252860

Browse files
committed
update PlaceTy to use ty::Variant
1 parent ecfe3cb commit a252860

File tree

12 files changed

+63
-31
lines changed

12 files changed

+63
-31
lines changed

compiler/rustc_borrowck/src/diagnostics/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
400400

401401
self.infcx.tcx.hir().name(var_id).to_string()
402402
}
403+
ty::Variant(ty, index) => {
404+
assert_eq!(index, variant_index.unwrap());
405+
return self.describe_field_from_ty(ty, field, variant_index);
406+
}
403407
_ => {
404408
// Might need a revision when the fields in trait RFC is implemented
405409
// (https://github.com/rust-lang/rfcs/pull/1546)

compiler/rustc_borrowck/src/places_conflict.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,10 @@ fn place_components_conflict<'tcx>(
243243
return false;
244244
}
245245

246-
(ProjectionElem::Field { .. }, ty::Adt(def, _), AccessDepth::Drop) => {
246+
(ProjectionElem::Field { .. }, _, AccessDepth::Drop) => {
247247
// Drop can read/write arbitrary projections, so places
248248
// conflict regardless of further projections.
249-
if def.has_dtor(tcx) {
249+
if base_ty.has_dtor(tcx) {
250250
return true;
251251
}
252252
}

compiler/rustc_borrowck/src/type_check/mod.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
556556
let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty);
557557

558558
for elem in place.projection.iter() {
559-
if place_ty.variant_index.is_none() {
559+
if place_ty.variant_index().is_none() {
560560
if place_ty.ty.references_error() {
561561
assert!(self.errors_reported);
562562
return PlaceTy::from_ty(self.tcx().ty_error());
@@ -735,7 +735,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
735735
adt_def.variants.len()
736736
))
737737
} else {
738-
PlaceTy { ty: base_ty, variant_index: Some(index) }
738+
PlaceTy { ty: self.tcx().mk_ty(ty::Variant(base_ty, index)) }
739739
}
740740
}
741741
// We do not need to handle generators here, because this runs
@@ -802,9 +802,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
802802
location: Location,
803803
) -> Result<Ty<'tcx>, FieldAccessError> {
804804
let tcx = self.tcx();
805+
let ty = base_ty.ty;
805806

806-
let (variant, substs) = match base_ty {
807-
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
807+
let (variant, substs) = if let ty::Variant(ty, variant_index) = *ty.kind() {
808+
match *ty.kind() {
808809
ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
809810
ty::Generator(def_id, substs, _) => {
810811
let mut variants = substs.as_generator().state_tys(def_id, tcx);
@@ -822,8 +823,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
822823
};
823824
}
824825
_ => bug!("can't have downcast of non-adt non-generator type"),
825-
},
826-
PlaceTy { ty, variant_index: None } => match *ty.kind() {
826+
}
827+
} else {
828+
match *ty.kind() {
827829
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
828830
(&adt_def.variants[VariantIdx::new(0)], substs)
829831
}
@@ -863,7 +865,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
863865
base_ty
864866
));
865867
}
866-
},
868+
}
867869
};
868870

869871
if let Some(field) = variant.fields.get(field.index()) {

compiler/rustc_middle/src/mir/tcx.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ use rustc_target::abi::VariantIdx;
1212
#[derive(Copy, Clone, Debug, TypeFoldable)]
1313
pub struct PlaceTy<'tcx> {
1414
pub ty: Ty<'tcx>,
15-
/// Downcast to a particular variant of an enum, if included.
16-
pub variant_index: Option<VariantIdx>,
1715
}
1816

1917
// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
2018
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
21-
static_assert_size!(PlaceTy<'_>, 16);
19+
static_assert_size!(PlaceTy<'_>, 8);
2220

2321
impl<'tcx> PlaceTy<'tcx> {
2422
#[inline]
2523
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
26-
PlaceTy { ty, variant_index: None }
24+
PlaceTy { ty }
25+
}
26+
27+
pub fn variant_index(self) -> Option<VariantIdx> {
28+
match self.ty.kind() {
29+
ty::Variant(_, index) => Some(*index),
30+
_ => None,
31+
}
2732
}
2833

2934
/// `place_ty.field_ty(tcx, f)` computes the type at a given field
@@ -35,15 +40,16 @@ impl<'tcx> PlaceTy<'tcx> {
3540
/// Note that the resulting type has not been normalized.
3641
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
3742
let answer = match self.ty.kind() {
43+
ty::Variant(ty, variant_index) => match ty.kind() {
44+
ty::Adt(adt_def, substs) => {
45+
assert!(adt_def.is_enum());
46+
let field_def = &adt_def.variants[*variant_index].fields[f.index()];
47+
field_def.ty(tcx, substs)
48+
}
49+
_ => bug!("unexpected type: {}", ty),
50+
},
3851
ty::Adt(adt_def, substs) => {
39-
let variant_def = match self.variant_index {
40-
None => adt_def.non_enum_variant(),
41-
Some(variant_index) => {
42-
assert!(adt_def.is_enum());
43-
&adt_def.variants[variant_index]
44-
}
45-
};
46-
let field_def = &variant_def.fields[f.index()];
52+
let field_def = &adt_def.non_enum_variant().fields[f.index()];
4753
field_def.ty(tcx, substs)
4854
}
4955
ty::Tuple(ref tys) => tys[f.index()].expect_ty(),
@@ -103,7 +109,7 @@ impl<'tcx> PlaceTy<'tcx> {
103109
})
104110
}
105111
ProjectionElem::Downcast(_name, index) => {
106-
PlaceTy { ty: self.ty, variant_index: Some(index) }
112+
PlaceTy { ty: tcx.mk_ty(ty::Variant(self.ty, index)) }
107113
}
108114
ProjectionElem::Field(ref f, ref fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
109115
};

compiler/rustc_middle/src/ty/fast_reject.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub fn simplify_type(
104104
ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)),
105105
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
106106
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
107-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
107+
ty::Variant(ty, _) => return simplify_type(tcx, ty, can_simplify_params),
108108
}
109109
}
110110

compiler/rustc_middle/src/ty/flags.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl FlagComputation {
214214
computation.add_ty(fn_sig.output());
215215
}),
216216

217-
&ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
217+
&ty::Variant(ty, _) => self.add_kind(ty.kind()),
218218
}
219219
}
220220

compiler/rustc_middle/src/ty/layout.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14031403
ty::Bound(..) | ty::Param(_) | ty::Error(_) => {
14041404
return Err(LayoutError::Unknown(ty));
14051405
}
1406-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
1406+
1407+
ty::Variant(ty, _) => return self.layout_of_uncached(ty),
14071408
})
14081409
}
14091410
}

compiler/rustc_middle/src/ty/structural_impls.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
903903
| ty::Placeholder(..)
904904
| ty::Never
905905
| ty::Foreign(..) => return self,
906-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
906+
907+
ty::Variant(ty, _) => return ty.super_fold_with(folder),
907908
};
908909

909910
if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }
@@ -952,7 +953,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
952953
| ty::Param(..)
953954
| ty::Never
954955
| ty::Foreign(..) => ControlFlow::CONTINUE,
955-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
956+
957+
ty::Variant(ty, _) => return ty.super_visit_with(visitor),
956958
}
957959
}
958960

compiler/rustc_middle/src/ty/sty.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,14 @@ impl<'tcx> TyS<'tcx> {
19051905
!matches!(self.kind(), Param(_) | Infer(_) | Error(_))
19061906
}
19071907

1908+
pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
1909+
match self.kind() {
1910+
Adt(adt_def, _) => adt_def.has_dtor(tcx),
1911+
Variant(ty, _) => ty.has_dtor(tcx),
1912+
_ => false,
1913+
}
1914+
}
1915+
19081916
/// Returns the type and mutability of `*ty`.
19091917
///
19101918
/// The parameter `explicit` indicates if this is an *explicit* dereference.
@@ -2196,6 +2204,13 @@ impl<'tcx> TyS<'tcx> {
21962204
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
21972205
}
21982206
}
2207+
2208+
pub fn strip_variant_type(&self) -> &Self {
2209+
match self.kind() {
2210+
ty::Variant(ty, ..) => *ty,
2211+
_ => self,
2212+
}
2213+
}
21992214
}
22002215

22012216
/// Extra information about why we ended up with a particular variance.

compiler/rustc_middle/src/ty/util.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,8 @@ impl<'tcx> ty::TyS<'tcx> {
712712
| ty::Param(_)
713713
| ty::Placeholder(_)
714714
| ty::Projection(_) => false,
715-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
715+
716+
ty::Variant(ty, _) => return ty.is_trivially_freeze(),
716717
}
717718
}
718719

@@ -1026,7 +1027,8 @@ pub fn needs_drop_components(
10261027
| ty::Infer(_)
10271028
| ty::Closure(..)
10281029
| ty::Generator(..) => Ok(smallvec![ty]),
1029-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
1030+
1031+
ty::Variant(ty, _) => return needs_drop_components(ty, target_layout),
10301032
}
10311033
}
10321034

compiler/rustc_trait_selection/src/traits/select/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19981998
t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)])
19991999
}
20002000

2001-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
2001+
ty::Variant(ty, _) => return self.constituent_types_for_ty(t.rebind(ty)),
20022002
}
20032003
}
20042004

compiler/rustc_trait_selection/src/traits/structural_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
211211
return ControlFlow::CONTINUE;
212212
}
213213

214-
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
214+
ty::Variant(ty, _) => return self.visit_ty(ty),
215215
};
216216

217217
if !self.seen.insert(adt_def.did) {

0 commit comments

Comments
 (0)