Skip to content

Update PlaceTy to use ty::Variant #90330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {

self.infcx.tcx.hir().name(var_id).to_string()
}
ty::Variant(ty, index) => {
assert_eq!(index, variant_index.unwrap());
return self.describe_field_from_ty(ty, field, variant_index);
}
_ => {
// Might need a revision when the fields in trait RFC is implemented
// (https://github.com/rust-lang/rfcs/pull/1546)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/places_conflict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ fn place_components_conflict<'tcx>(
return false;
}

(ProjectionElem::Field { .. }, ty::Adt(def, _), AccessDepth::Drop) => {
(ProjectionElem::Field { .. }, _, AccessDepth::Drop) => {
// Drop can read/write arbitrary projections, so places
// conflict regardless of further projections.
if def.has_dtor(tcx) {
if base_ty.has_dtor(tcx) {
return true;
}
}
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty);

for elem in place.projection.iter() {
if place_ty.variant_index.is_none() {
if place_ty.variant_index().is_none() {
if place_ty.ty.references_error() {
assert!(self.errors_reported);
return PlaceTy::from_ty(self.tcx().ty_error());
Expand Down Expand Up @@ -735,7 +735,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
adt_def.variants.len()
))
} else {
PlaceTy { ty: base_ty, variant_index: Some(index) }
PlaceTy { ty: self.tcx().mk_ty(ty::Variant(base_ty, index)) }
}
}
// We do not need to handle generators here, because this runs
Expand Down Expand Up @@ -802,9 +802,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
let ty = base_ty.ty;

let (variant, substs) = match base_ty {
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
let (variant, substs) = if let ty::Variant(ty, variant_index) = *ty.kind() {
match *ty.kind() {
ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
ty::Generator(def_id, substs, _) => {
let mut variants = substs.as_generator().state_tys(def_id, tcx);
Expand All @@ -822,8 +823,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
};
}
_ => bug!("can't have downcast of non-adt non-generator type"),
},
PlaceTy { ty, variant_index: None } => match *ty.kind() {
}
} else {
match *ty.kind() {
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
(&adt_def.variants[VariantIdx::new(0)], substs)
}
Expand Down Expand Up @@ -863,7 +865,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
base_ty
));
}
},
}
};

if let Some(field) = variant.fields.get(field.index()) {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ fn push_debuginfo_type_name<'tcx>(
t
);
}

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}

/// MSVC names enums differently than other platforms so that the debugging visualization
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ fn const_to_valtree_inner<'tcx>(
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..) => None,
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ crate fn eval_nullary_intrinsic<'tcx>(
| ty::Never
| ty::Tuple(_)
| ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
},
other => bug!("`{}` is not a zero arg intrinsic", other),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),

ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Opaque(..)
| ty::Projection(..)
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
t
}
}
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::Opaque(..) => t.super_fold_with(self),

ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t),

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/outlives/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ fn compute_components(
// themselves can be readily identified.
compute_components_recursive(tcx, ty.into(), out, visited);
}
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
| ty::GeneratorWitness(..)
| ty::Placeholder(..)
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
32 changes: 19 additions & 13 deletions compiler/rustc_middle/src/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@ use rustc_target::abi::VariantIdx;
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct PlaceTy<'tcx> {
pub ty: Ty<'tcx>,
/// Downcast to a particular variant of an enum, if included.
pub variant_index: Option<VariantIdx>,
}

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

impl<'tcx> PlaceTy<'tcx> {
#[inline]
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
PlaceTy { ty, variant_index: None }
PlaceTy { ty }
}

pub fn variant_index(self) -> Option<VariantIdx> {
match self.ty.kind() {
ty::Variant(_, index) => Some(*index),
_ => None,
}
}

/// `place_ty.field_ty(tcx, f)` computes the type at a given field
Expand All @@ -35,15 +40,16 @@ impl<'tcx> PlaceTy<'tcx> {
/// Note that the resulting type has not been normalized.
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
let answer = match self.ty.kind() {
ty::Variant(ty, variant_index) => match ty.kind() {
ty::Adt(adt_def, substs) => {
assert!(adt_def.is_enum());
let field_def = &adt_def.variants[*variant_index].fields[f.index()];
field_def.ty(tcx, substs)
}
_ => bug!("unexpected type: {}", ty),
},
ty::Adt(adt_def, substs) => {
let variant_def = match self.variant_index {
None => adt_def.non_enum_variant(),
Some(variant_index) => {
assert!(adt_def.is_enum());
&adt_def.variants[variant_index]
}
};
let field_def = &variant_def.fields[f.index()];
let field_def = &adt_def.non_enum_variant().fields[f.index()];
field_def.ty(tcx, substs)
}
ty::Tuple(ref tys) => tys[f.index()].expect_ty(),
Expand Down Expand Up @@ -103,7 +109,7 @@ impl<'tcx> PlaceTy<'tcx> {
})
}
ProjectionElem::Downcast(_name, index) => {
PlaceTy { ty: self.ty, variant_index: Some(index) }
PlaceTy { ty: tcx.mk_ty(ty::Variant(self.ty, index)) }
}
ProjectionElem::Field(ref f, ref fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,7 @@ impl<'tcx> TyCtxt<'tcx> {
fmt,
self.0,
Adt,
Variant,
Array,
Slice,
RawPtr,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ impl<'tcx> ty::TyS<'tcx> {
ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(),

ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
ty::Variant(ty, _) => ty.sort_string(tcx),
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
ty::Array(t, n) => {
if t.is_simple_ty() {
Expand Down Expand Up @@ -318,6 +319,10 @@ impl<'tcx> ty::TyS<'tcx> {
| ty::Never => "type".into(),
ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(),
ty::Adt(def, _) => def.descr().into(),
ty::Variant(ty, _) => match ty.kind() {
ty::Adt(def, _) => format!("{} variant", def.descr()).into(),
_ => bug!("unexpected type: {:?}", ty.kind()),
},
ty::Foreign(_) => "extern type".into(),
ty::Array(..) => "array".into(),
ty::Slice(_) => "slice".into(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub fn simplify_type(
ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)),
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
ty::Variant(ty, _) => return simplify_type(tcx, ty, can_simplify_params),
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ impl FlagComputation {
computation.add_tys(fn_sig.inputs());
computation.add_ty(fn_sig.output());
}),

&ty::Variant(ty, _) => self.add_kind(ty.kind()),
}
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
ty::Bound(..) | ty::Param(_) | ty::Error(_) => {
return Err(LayoutError::Unknown(ty));
}

ty::Variant(ty, _) => return self.layout_of_uncached(ty),
})
}
}
Expand Down Expand Up @@ -2388,6 +2390,7 @@ where
| ty::Param(_)
| ty::Infer(_)
| ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ fn characteristic_def_id_of_type_cached<'a>(
| ty::GeneratorWitness(..)
| ty::Never
| ty::Float(_) => None,

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,14 @@ pub trait PrettyPrinter<'tcx>:
ty::Adt(def, substs) => {
p!(print_def_path(def.did, substs));
}

ty::Variant(ty, idx) => match ty.kind() {
ty::Adt(def, substs) => {
p!(print_def_path(def.did, substs));
p!(write("::{}", def.variants.get(idx).unwrap().ident.name));
}
_ => bug!("unexpected type: {:?}", ty.kind()),
},
ty::Dynamic(data, r) => {
let print_r = self.region_should_not_be_omitted(r);
if print_r {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
| ty::Placeholder(..)
| ty::Never
| ty::Foreign(..) => return self,

ty::Variant(ty, _) => return ty.super_fold_with(folder),
};

if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }
Expand Down Expand Up @@ -951,6 +953,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
| ty::Param(..)
| ty::Never
| ty::Foreign(..) => ControlFlow::CONTINUE,

ty::Variant(ty, _) => return ty.super_visit_with(visitor),
}
}

Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ pub enum TyKind<'tcx> {
/// A type variable used during type checking.
Infer(InferTy),

/// Type of a variant of an enum
Variant(Ty<'tcx>, VariantIdx),

/// A placeholder for a type which could not be computed; this is
/// propagated to avoid useless error messages.
Error(DelaySpanBugEmitted),
Expand Down Expand Up @@ -1902,6 +1905,14 @@ impl<'tcx> TyS<'tcx> {
!matches!(self.kind(), Param(_) | Infer(_) | Error(_))
}

pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
match self.kind() {
Adt(adt_def, _) => adt_def.has_dtor(tcx),
Variant(ty, _) => ty.has_dtor(tcx),
_ => false,
}
}

/// Returns the type and mutability of `*ty`.
///
/// The parameter `explicit` indicates if this is an *explicit* dereference.
Expand Down Expand Up @@ -2059,6 +2070,8 @@ impl<'tcx> TyS<'tcx> {
| ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`discriminant_ty` applied to unexpected type: {:?}", self)
}

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down Expand Up @@ -2107,6 +2120,8 @@ impl<'tcx> TyS<'tcx> {
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`ptr_metadata_ty` applied to unexpected type: {:?}", tail)
}

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

Expand Down Expand Up @@ -2185,6 +2200,15 @@ impl<'tcx> TyS<'tcx> {
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
}

ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

pub fn strip_variant_type(&self) -> &Self {
match self.kind() {
ty::Variant(ty, ..) => *ty,
_ => self,
}
}
}
Expand Down
Loading