Skip to content
Closed
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
@@ -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)
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/places_conflict.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -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());
@@ -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
@@ -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);
@@ -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)
}
@@ -863,7 +865,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
base_ty
));
}
},
}
};

if let Some(field) = variant.fields.get(field.index()) {
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
@@ -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
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
@@ -129,6 +129,7 @@ fn const_to_valtree_inner<'tcx>(
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..) => None,
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -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),
})
Original file line number Diff line number Diff line change
@@ -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)"),
}
}

1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
@@ -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)"),
}
}

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

2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
@@ -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)"),
}
}

1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/outlives/components.rs
Original file line number Diff line number Diff line change
@@ -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)"),
}
}

1 change: 1 addition & 0 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
@@ -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)"),
}
}

32 changes: 19 additions & 13 deletions compiler/rustc_middle/src/mir/tcx.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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(),
@@ -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)),
};
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -1932,6 +1932,7 @@ impl<'tcx> TyCtxt<'tcx> {
fmt,
self.0,
Adt,
Variant,
Array,
Slice,
RawPtr,
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
@@ -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() {
@@ -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(),
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
@@ -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),
}
}

2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
@@ -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()),
}
}

3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
@@ -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),
})
}
}
@@ -2388,6 +2390,7 @@ where
| ty::Param(_)
| ty::Infer(_)
| ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty),
ty::Variant(..) => unimplemented!("TODO(zhamlin)"),
}
}

2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
@@ -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> {
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -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 {
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
@@ -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) }
@@ -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),
}
}

24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -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),
@@ -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.
@@ -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)"),
}
}

@@ -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)"),
}
}

@@ -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,
}
}
}
Loading