// if they are both "path types", there's a chance of ambiguity
// due to different versions of the same crate
match (&exp_found.expected.sty, &exp_found.found.sty) {
- (&ty::TyEnum(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) |
- (&ty::TyStruct(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
- (&ty::TyEnum(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
- (&ty::TyStruct(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) => {
+ (&ty::TyAdt(exp_adt, _), &ty::TyAdt(found_adt, _)) => {
report_path_match(err, exp_adt.did, found_adt.did);
},
_ => ()
ty::TyInt(..) |
ty::TyUint(..) |
ty::TyFloat(..) |
- ty::TyEnum(..) |
+ ty::TyAdt(..) |
ty::TyBox(..) |
ty::TyStr |
ty::TyError |
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyTrait(..) |
- ty::TyStruct(..) |
- ty::TyUnion(..) |
ty::TyClosure(..) |
ty::TyNever |
ty::TyTuple(..) |
}
fn lookup_and_handle_definition(&mut self, id: ast::NodeId) {
- use ty::TypeVariants::{TyEnum, TyStruct, TyUnion};
-
let def = self.tcx.expect_def(id);
// If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
if self.tcx.trait_of_item(def.def_id()).is_some() => {
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
- match substs.substs.type_at(0).sty {
- TyEnum(tyid, _) | TyStruct(tyid, _) | TyUnion(tyid, _) => {
- self.check_def_id(tyid.did)
- }
- _ => {}
+ if let ty::TyAdt(tyid, _) = substs.substs.type_at(0).sty {
+ self.check_def_id(tyid.did);
}
}
}
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
match self.tcx.expr_ty_adjusted(lhs).sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
self.insert_def_id(def.struct_variant().field_named(name).did);
}
- _ => span_bug!(lhs.span, "named field access on non-struct/union"),
+ _ => span_bug!(lhs.span, "named field access on non-ADT"),
}
}
fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
- if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
- self.insert_def_id(def.struct_variant().fields[idx].did);
+ match self.tcx.expr_ty_adjusted(lhs).sty {
+ ty::TyAdt(def, _) => {
+ self.insert_def_id(def.struct_variant().fields[idx].did);
+ }
+ ty::TyTuple(..) => {}
+ _ => span_bug!(lhs.span, "numeric field access on non-ADT"),
}
}
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
pats: &[codemap::Spanned<hir::FieldPat>]) {
let variant = match self.tcx.node_id_to_type(lhs.id).sty {
- ty::TyStruct(adt, _) | ty::TyUnion(adt, _) | ty::TyEnum(adt, _) => {
+ ty::TyAdt(adt, _) => {
adt.variant_of_def(self.tcx.expect_def(lhs.id))
}
_ => span_bug!(lhs.span, "non-ADT in struct pattern")
}
}
hir::ExprField(ref base_expr, field) => {
- if let ty::TyUnion(..) = self.tcx.expr_ty_adjusted(base_expr).sty {
- self.require_unsafe(field.span, "access to union field");
+ if let ty::TyAdt(adt, ..) = self.tcx.expr_ty_adjusted(base_expr).sty {
+ if adt.is_union() {
+ self.require_unsafe(field.span, "access to union field");
+ }
}
}
_ => {}
fn visit_pat(&mut self, pat: &hir::Pat) {
if let PatKind::Struct(_, ref fields, _) = pat.node {
- if let ty::TyUnion(..) = self.tcx.pat_ty(pat).sty {
- for field in fields {
- self.require_unsafe(field.span, "matching on union field");
+ if let ty::TyAdt(adt, ..) = self.tcx.pat_ty(pat).sty {
+ if adt.is_union() {
+ for field in fields {
+ self.require_unsafe(field.span, "matching on union field");
+ }
}
}
}
// Select just those fields of the `with`
// expression that will actually be used
- if let ty::TyStruct(def, substs) = with_cmt.ty.sty {
- // Consume those fields of the with expression that are needed.
- for with_field in &def.struct_variant().fields {
- if !contains_field_named(with_field, fields) {
- let cmt_field = self.mc.cat_field(
- &*with_expr,
- with_cmt.clone(),
- with_field.name,
- with_field.ty(self.tcx(), substs)
- );
- self.delegate_consume(with_expr.id, with_expr.span, cmt_field);
+ match with_cmt.ty.sty {
+ ty::TyAdt(adt, substs) if adt.is_struct() => {
+ // Consume those fields of the with expression that are needed.
+ for with_field in &adt.struct_variant().fields {
+ if !contains_field_named(with_field, fields) {
+ let cmt_field = self.mc.cat_field(
+ &*with_expr,
+ with_cmt.clone(),
+ with_field.name,
+ with_field.ty(self.tcx(), substs)
+ );
+ self.delegate_consume(with_expr.id, with_expr.span, cmt_field);
+ }
}
}
- } else {
- // the base expression should always evaluate to a
- // struct; however, when EUV is run during typeck, it
- // may not. This will generate an error earlier in typeck,
- // so we can just ignore it.
- if !self.tcx().sess.has_errors() {
- span_bug!(
- with_expr.span,
- "with expression doesn't evaluate to a struct");
+ _ => {
+ // the base expression should always evaluate to a
+ // struct; however, when EUV is run during typeck, it
+ // may not. This will generate an error earlier in typeck,
+ // so we can just ignore it.
+ if !self.tcx().sess.has_errors() {
+ span_bug!(
+ with_expr.span,
+ "with expression doesn't evaluate to a struct");
+ }
}
}
Ok(deref_ptr(UnsafePtr(mt.mutbl)))
}
- ty::TyEnum(..) |
- ty::TyStruct(..) => { // newtype
+ ty::TyAdt(..) => { // newtype
Ok(deref_interior(InteriorField(PositionalField(0))))
}
}
Def::Struct(..) => {
match self.pat_ty(&pat)?.sty {
- ty::TyStruct(adt_def, _) => {
+ ty::TyAdt(adt_def, _) => {
adt_def.struct_variant().fields.len()
}
ref ty => {
use middle::cstore::LOCAL_CRATE;
use hir::def::Def;
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
-use ty::{self, TyCtxt};
+use ty::{self, TyCtxt, AdtKind};
use middle::privacy::AccessLevels;
use syntax::parse::token::InternedString;
use syntax_pos::{Span, DUMMY_SP};
hir::ExprField(ref base_e, ref field) => {
span = field.span;
match tcx.expr_ty_adjusted(base_e).sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
def.struct_variant().field_named(field.node).did
}
_ => span_bug!(e.span,
- "stability::check_expr: named field access on non-struct/union")
+ "stability::check_expr: named field access on non-ADT")
}
}
hir::ExprTupField(ref base_e, ref field) => {
span = field.span;
match tcx.expr_ty_adjusted(base_e).sty {
- ty::TyStruct(def, _) => def.struct_variant().fields[field.node].did,
+ ty::TyAdt(def, _) => {
+ def.struct_variant().fields[field.node].did
+ }
ty::TyTuple(..) => return,
_ => span_bug!(e.span,
"stability::check_expr: unnamed field access on \
}
}
hir::ExprStruct(_, ref expr_fields, _) => {
- let type_ = tcx.expr_ty(e);
- match type_.sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
- // check the stability of each field that appears
- // in the construction expression.
- for field in expr_fields {
- let did = def.struct_variant()
- .field_named(field.name.node)
- .did;
- maybe_do_stability_check(tcx, did, field.span, cb);
- }
+ match tcx.expr_ty(e).sty {
+ ty::TyAdt(adt, ..) => match adt.adt_kind() {
+ AdtKind::Struct | AdtKind::Union => {
+ // check the stability of each field that appears
+ // in the construction expression.
+ for field in expr_fields {
+ let did = adt.struct_variant().field_named(field.name.node).did;
+ maybe_do_stability_check(tcx, did, field.span, cb);
+ }
- // we're done.
- return
- }
- // we don't look at stability attributes on
- // struct-like enums (yet...), but it's definitely not
- // a bug to have construct one.
- ty::TyEnum(..) => return,
- _ => {
- span_bug!(e.span,
- "stability::check_expr: struct construction \
- of non-struct/union, type {:?}",
- type_);
- }
+ // we're done.
+ return
+ }
+ AdtKind::Enum => {
+ // we don't look at stability attributes on
+ // struct-like enums (yet...), but it's definitely not
+ // a bug to have construct one.
+ return
+ }
+ },
+ ref ty => span_bug!(e.span, "stability::check_expr: struct \
+ construction of non-ADT type: {:?}", ty)
}
}
_ => return
debug!("check_pat(pat = {:?})", pat);
if is_internal(tcx, pat.span) { return; }
- let v = match tcx.pat_ty_opt(pat) {
- Some(&ty::TyS { sty: ty::TyStruct(def, _), .. }) |
- Some(&ty::TyS { sty: ty::TyUnion(def, _), .. }) => def.struct_variant(),
- Some(_) | None => return,
+ let v = match tcx.pat_ty_opt(pat).map(|ty| &ty.sty) {
+ Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => adt.struct_variant(),
+ _ => return,
};
match pat.node {
// Foo(a, b, c)
LvalueTy::Ty { ty } =>
ty,
LvalueTy::Downcast { adt_def, substs, variant_index: _ } =>
- tcx.mk_enum(adt_def, substs),
+ tcx.mk_adt(adt_def, substs),
}
}
}
ProjectionElem::Downcast(adt_def1, index) =>
match self.to_ty(tcx).sty {
- ty::TyEnum(adt_def, substs) => {
+ ty::TyAdt(adt_def, substs) => {
+ assert!(adt_def.is_enum());
assert!(index < adt_def.variants.len());
assert_eq!(adt_def, adt_def1);
LvalueTy::Downcast { adt_def: adt_def,
variant_index: index }
}
_ => {
- bug!("cannot downcast non-enum type: `{:?}`", self)
+ bug!("cannot downcast non-ADT type: `{:?}`", self)
}
},
ProjectionElem::Field(_, fty) => LvalueTy::Ty { ty: fty }
match ty.sty {
ty::TyBox(..) | ty::TyRef(..) =>
true,
- ty::TyEnum(def, _) | ty::TyStruct(def, _) | ty::TyUnion(def, _) =>
+ ty::TyAdt(def, _) =>
def.is_fundamental(),
ty::TyTrait(ref data) =>
tcx.has_attr(data.principal.def_id(), "fundamental"),
infer_is_local.0
}
- ty::TyEnum(def, _) |
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
def.did.is_local()
}
use fmt_macros::{Parser, Piece, Position};
use hir::def_id::DefId;
use infer::{self, InferCtxt, TypeOrigin};
-use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
+use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use ty::error::ExpectedFound;
use ty::fast_reject;
use ty::fold::TypeFolder;
ty::TyBool => Some(0),
ty::TyChar => Some(1),
ty::TyStr => Some(2),
- ty::TyInt(..) | ty::TyUint(..) |
- ty::TyInfer(ty::IntVar(..)) => Some(3),
+ ty::TyInt(..) | ty::TyUint(..) | ty::TyInfer(ty::IntVar(..)) => Some(3),
ty::TyFloat(..) | ty::TyInfer(ty::FloatVar(..)) => Some(4),
- ty::TyEnum(..) => Some(5),
- ty::TyStruct(..) => Some(6),
- ty::TyBox(..) | ty::TyRef(..) | ty::TyRawPtr(..) => Some(7),
- ty::TyArray(..) | ty::TySlice(..) => Some(8),
- ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(9),
- ty::TyTrait(..) => Some(10),
- ty::TyClosure(..) => Some(11),
- ty::TyTuple(..) => Some(12),
- ty::TyProjection(..) => Some(13),
- ty::TyParam(..) => Some(14),
- ty::TyAnon(..) => Some(15),
- ty::TyNever => Some(16),
- ty::TyUnion(..) => Some(17),
+ ty::TyBox(..) | ty::TyRef(..) | ty::TyRawPtr(..) => Some(5),
+ ty::TyArray(..) | ty::TySlice(..) => Some(6),
+ ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(7),
+ ty::TyTrait(..) => Some(8),
+ ty::TyClosure(..) => Some(9),
+ ty::TyTuple(..) => Some(10),
+ ty::TyProjection(..) => Some(11),
+ ty::TyParam(..) => Some(12),
+ ty::TyAnon(..) => Some(13),
+ ty::TyNever => Some(14),
+ ty::TyAdt(adt, ..) => match adt.adt_kind() {
+ AdtKind::Struct => Some(15),
+ AdtKind::Union => Some(16),
+ AdtKind::Enum => Some(17),
+ },
ty::TyInfer(..) | ty::TyError => None
}
}
match (type_category(a), type_category(b)) {
(Some(cat_a), Some(cat_b)) => match (&a.sty, &b.sty) {
- (&ty::TyStruct(def_a, _), &ty::TyStruct(def_b, _)) |
- (&ty::TyUnion(def_a, _), &ty::TyUnion(def_b, _)) |
- (&ty::TyEnum(def_a, _), &ty::TyEnum(def_b, _)) =>
- def_a == def_b,
+ (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => def_a == def_b,
_ => cat_a == cat_b
},
// infer and error can be equated to all types
(&ty::TyArray(..), &ty::TySlice(_)) => true,
// Struct<T> -> Struct<U>.
- (&ty::TyStruct(def_id_a, _), &ty::TyStruct(def_id_b, _)) => {
+ (&ty::TyAdt(def_id_a, _), &ty::TyAdt(def_id_b, _)) if def_id_a.is_struct() => {
def_id_a == def_id_b
}
Where(ty::Binder(tys.last().into_iter().cloned().collect()))
}
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) |
- ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(ty::Binder(match sized_crit.sty {
Where(ty::Binder(tys.to_vec()))
}
- ty::TyStruct(..) | ty::TyUnion(..) | ty::TyEnum(..) |
- ty::TyProjection(..) | ty::TyParam(..) | ty::TyAnon(..) => {
+ ty::TyAdt(..) | ty::TyProjection(..) | ty::TyParam(..) | ty::TyAnon(..) => {
// Fallback to whatever user-defined impls exist in this case.
None
}
}
// for `PhantomData<T>`, we pass `T`
- ty::TyStruct(def, substs) if def.is_phantom_data() => {
+ ty::TyAdt(def, substs) if def.is_phantom_data() => {
substs.types().collect()
}
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
def.all_fields()
.map(|f| f.ty(self.tcx(), substs))
.collect()
}
// Struct<T> -> Struct<U>.
- (&ty::TyStruct(def, substs_a), &ty::TyStruct(_, substs_b)) => {
+ (&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
let fields = def
.all_fields()
.map(|f| f.unsubst_ty())
k
}
});
- let new_struct = tcx.mk_struct(def, Substs::new(tcx, params));
+ let new_struct = tcx.mk_adt(def, Substs::new(tcx, params));
let origin = TypeOrigin::Misc(obligation.cause.span);
let InferOk { obligations, .. } =
self.infcx.sub_types(false, origin, new_struct, target)
ty::TyInt(_) => Some(CastTy::Int(IntTy::I)),
ty::TyUint(u) => Some(CastTy::Int(IntTy::U(u))),
ty::TyFloat(_) => Some(CastTy::Float),
- ty::TyEnum(d,_) if d.is_payloadfree() =>
+ ty::TyAdt(d,_) if d.is_enum() && d.is_payloadfree() =>
Some(CastTy::Int(IntTy::CEnum)),
ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)),
ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)),
|ty| tc_ty(tcx, *ty, cache))
}
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) |
- ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
let mut res =
TypeContents::union(&def.variants, |v| {
TypeContents::union(&v.fields, |f| {
use traits;
use ty::{self, TraitRef, Ty, TypeAndMut};
use ty::{TyS, TypeVariants};
-use ty::{AdtDef, ClosureSubsts, Region};
+use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
use hir::FreevarMap;
use ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, TraitObject};
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
pub fn intern_adt_def(self,
did: DefId,
- kind: ty::AdtKind,
+ kind: AdtKind,
variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
-> ty::AdtDefMaster<'gcx> {
let def = ty::AdtDefData::new(self, did, kind, variants);
pub fn print_debug_stats(self) {
sty_debug_print!(
self,
- TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyTrait,
- TyStruct, TyUnion, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon);
+ TyAdt, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
+ TyTrait, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon);
println!("Substs interner: #{}", self.interners.substs.borrow().len());
println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len());
self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
}
- pub fn mk_enum(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
+ pub fn mk_adt(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
// take a copy of substs so that we own the vectors inside
- self.mk_ty(TyEnum(def, substs))
+ self.mk_ty(TyAdt(def, substs))
}
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyProjection(inner))
}
- pub fn mk_struct(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
- // take a copy of substs so that we own the vectors inside
- self.mk_ty(TyStruct(def, substs))
- }
-
- pub fn mk_union(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
- // take a copy of substs so that we own the vectors inside
- self.mk_ty(TyUnion(def, substs))
- }
-
pub fn mk_closure(self,
closure_id: DefId,
substs: &'tcx Substs<'tcx>,
ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(),
ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(),
- ty::TyEnum(def, _) => format!("enum `{}`", tcx.item_path_str(def.did)),
+ ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
ty::TyBox(_) => "box".to_string(),
ty::TyArray(_, n) => format!("array of {} elements", n),
ty::TySlice(_) => "slice".to_string(),
ty::TyTrait(ref inner) => {
format!("trait {}", tcx.item_path_str(inner.principal.def_id()))
}
- ty::TyStruct(def, _) => {
- format!("struct `{}`", tcx.item_path_str(def.did))
- }
- ty::TyUnion(def, _) => {
- format!("union `{}`", tcx.item_path_str(def.did))
- }
ty::TyClosure(..) => "closure".to_string(),
ty::TyTuple(_) => "tuple".to_string(),
ty::TyInfer(ty::TyVar(_)) => "inferred type".to_string(),
IntSimplifiedType(ast::IntTy),
UintSimplifiedType(ast::UintTy),
FloatSimplifiedType(ast::FloatTy),
- EnumSimplifiedType(DefId),
+ AdtSimplifiedType(DefId),
StrSimplifiedType,
VecSimplifiedType,
PtrSimplifiedType,
NeverSimplifiedType,
TupleSimplifiedType(usize),
TraitSimplifiedType(DefId),
- StructSimplifiedType(DefId),
- UnionSimplifiedType(DefId),
ClosureSimplifiedType(DefId),
AnonSimplifiedType(DefId),
FunctionSimplifiedType(usize),
ty::TyInt(int_type) => Some(IntSimplifiedType(int_type)),
ty::TyUint(uint_type) => Some(UintSimplifiedType(uint_type)),
ty::TyFloat(float_type) => Some(FloatSimplifiedType(float_type)),
- ty::TyEnum(def, _) => Some(EnumSimplifiedType(def.did)),
+ ty::TyAdt(def, _) => Some(AdtSimplifiedType(def.did)),
ty::TyStr => Some(StrSimplifiedType),
ty::TyArray(..) | ty::TySlice(_) => Some(VecSimplifiedType),
ty::TyRawPtr(_) => Some(PtrSimplifiedType),
ty::TyTrait(ref trait_info) => {
Some(TraitSimplifiedType(trait_info.principal.def_id()))
}
- ty::TyStruct(def, _) => {
- Some(StructSimplifiedType(def.did))
- }
- ty::TyUnion(def, _) => {
- Some(UnionSimplifiedType(def.did))
- }
ty::TyRef(_, mt) => {
// since we introduce auto-refs during method lookup, we
// just treat &T and T as equivalent from the point of
ty::TyBox(_) => {
// treat like we would treat `Box`
match tcx.lang_items.require_owned_box() {
- Ok(def_id) => Some(StructSimplifiedType(def_id)),
+ Ok(def_id) => Some(AdtSimplifiedType(def_id)),
Err(msg) => tcx.sess.fatal(&msg),
}
}
}
}
- &ty::TyEnum(_, substs) | &ty::TyStruct(_, substs) | &ty::TyUnion(_, substs) => {
+ &ty::TyAdt(_, substs) => {
self.add_substs(substs);
}
// impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
// anything other than a simple path.
match self_ty.sty {
- ty::TyStruct(adt_def, substs) |
- ty::TyUnion(adt_def, substs) |
- ty::TyEnum(adt_def, substs) => {
+ ty::TyAdt(adt_def, substs) => {
if substs.types().next().is_none() { // ignore regions
self.push_item_path(buffer, adt_def.did);
} else {
/// decisions and we may want to adjust it later.
pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
match ty.sty {
- ty::TyStruct(adt_def, _) |
- ty::TyUnion(adt_def, _) |
- ty::TyEnum(adt_def, _) => Some(adt_def.did),
+ ty::TyAdt(adt_def, _) => Some(adt_def.did),
ty::TyTrait(ref data) => Some(data.principal.def_id()),
use infer::InferCtxt;
use session::Session;
use traits;
-use ty::{self, Ty, TyCtxt, TypeFoldable};
+use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
use syntax::ast::{FloatTy, IntTy, UintTy};
use syntax::attr;
}
// Is this the NonZero lang item wrapping a pointer or integer type?
- (&Univariant { non_zero: true, .. }, &ty::TyStruct(def, substs)) => {
+ (&Univariant { non_zero: true, .. }, &ty::TyAdt(def, substs)) if def.is_struct() => {
let fields = &def.struct_variant().fields;
assert_eq!(fields.len(), 1);
match *fields[0].ty(tcx, substs).layout(infcx)? {
// Perhaps one of the fields of this struct is non-zero
// let's recurse and find out
- (_, &ty::TyStruct(def, substs)) => {
+ (_, &ty::TyAdt(def, substs)) if def.is_struct() => {
Struct::non_zero_field_path(infcx, def.struct_variant().fields
.iter().map(|field| {
field.ty(tcx, substs)
non_zero: bool
},
- /// SIMD vectors, from TyStruct marked with #[repr(simd)].
+ /// SIMD vectors, from structs marked with #[repr(simd)].
Vector {
element: Primitive,
count: u64
non_zero: bool
},
- // Remaining variants are all ADTs such as TyStruct, TyEnum or TyTuple.
+ // Remaining variants are all ADTs such as structs, enums or tuples.
/// C-like enums; basically an integer.
CEnum {
}
// ADTs.
- ty::TyStruct(def, substs) => {
- if ty.is_simd() {
- // SIMD vector types.
- let element = ty.simd_type(tcx);
- match *element.layout(infcx)? {
- Scalar { value, .. } => {
- return success(Vector {
- element: value,
- count: ty.simd_size(tcx) as u64
- });
- }
- _ => {
- tcx.sess.fatal(&format!("monomorphising SIMD type `{}` with \
- a non-machine element type `{}`",
- ty, element));
+ ty::TyAdt(def, substs) => match def.adt_kind() {
+ AdtKind::Struct => {
+ if ty.is_simd() {
+ // SIMD vector types.
+ let element = ty.simd_type(tcx);
+ match *element.layout(infcx)? {
+ Scalar { value, .. } => {
+ return success(Vector {
+ element: value,
+ count: ty.simd_size(tcx) as u64
+ });
+ }
+ _ => {
+ tcx.sess.fatal(&format!("monomorphising SIMD type `{}` with \
+ a non-machine element type `{}`",
+ ty, element));
+ }
}
}
- }
- let fields = def.struct_variant().fields.iter().map(|field| {
- field.ty(tcx, substs).layout(infcx)
- });
- let packed = tcx.lookup_packed(def.did);
- let mut st = Struct::new(dl, packed);
- st.extend(dl, fields, ty)?;
-
- Univariant {
- variant: st,
- non_zero: Some(def.did) == tcx.lang_items.non_zero()
- }
- }
- ty::TyUnion(def, substs) => {
- let fields = def.struct_variant().fields.iter().map(|field| {
- field.ty(tcx, substs).layout(infcx)
- });
- let packed = tcx.lookup_packed(def.did);
- let mut un = Union::new(dl, packed);
- un.extend(dl, fields, ty)?;
- UntaggedUnion { variants: un }
- }
- ty::TyEnum(def, substs) => {
- let hint = *tcx.lookup_repr_hints(def.did).get(0)
- .unwrap_or(&attr::ReprAny);
-
- if def.variants.is_empty() {
- // Uninhabitable; represent as unit
- // (Typechecking will reject discriminant-sizing attrs.)
- assert_eq!(hint, attr::ReprAny);
-
- return success(Univariant {
- variant: Struct::new(dl, false),
- non_zero: false
- });
- }
-
- if def.variants.iter().all(|v| v.fields.is_empty()) {
- // All bodies empty -> intlike
- let (mut min, mut max) = (i64::MAX, i64::MIN);
- for v in &def.variants {
- let x = v.disr_val.to_u64_unchecked() as i64;
- if x < min { min = x; }
- if x > max { max = x; }
- }
-
- let (discr, signed) = Integer::repr_discr(tcx, hint, min, max);
- return success(CEnum {
- discr: discr,
- signed: signed,
- min: min as u64,
- max: max as u64
+ let fields = def.struct_variant().fields.iter().map(|field| {
+ field.ty(tcx, substs).layout(infcx)
});
- }
+ let packed = tcx.lookup_packed(def.did);
+ let mut st = Struct::new(dl, packed);
+ st.extend(dl, fields, ty)?;
- // Since there's at least one
- // non-empty body, explicit discriminants should have
- // been rejected by a checker before this point.
- for (i, v) in def.variants.iter().enumerate() {
- if i as u64 != v.disr_val.to_u64_unchecked() {
- bug!("non-C-like enum {} with specified discriminants",
- tcx.item_path_str(def.did));
+ Univariant {
+ variant: st,
+ non_zero: Some(def.did) == tcx.lang_items.non_zero()
}
}
-
- if def.variants.len() == 1 {
- // Equivalent to a struct/tuple/newtype.
- // (Typechecking will reject discriminant-sizing attrs.)
- assert_eq!(hint, attr::ReprAny);
- let fields = def.variants[0].fields.iter().map(|field| {
+ AdtKind::Union => {
+ let fields = def.struct_variant().fields.iter().map(|field| {
field.ty(tcx, substs).layout(infcx)
});
- let mut st = Struct::new(dl, false);
- st.extend(dl, fields, ty)?;
- return success(Univariant { variant: st, non_zero: false });
+ let packed = tcx.lookup_packed(def.did);
+ let mut un = Union::new(dl, packed);
+ un.extend(dl, fields, ty)?;
+ UntaggedUnion { variants: un }
}
+ AdtKind::Enum => {
+ let hint = *tcx.lookup_repr_hints(def.did).get(0)
+ .unwrap_or(&attr::ReprAny);
+
+ if def.variants.is_empty() {
+ // Uninhabitable; represent as unit
+ // (Typechecking will reject discriminant-sizing attrs.)
+ assert_eq!(hint, attr::ReprAny);
+
+ return success(Univariant {
+ variant: Struct::new(dl, false),
+ non_zero: false
+ });
+ }
- // Cache the substituted and normalized variant field types.
- let variants = def.variants.iter().map(|v| {
- v.fields.iter().map(|field| field.ty(tcx, substs)).collect::<Vec<_>>()
- }).collect::<Vec<_>>();
+ if def.variants.iter().all(|v| v.fields.is_empty()) {
+ // All bodies empty -> intlike
+ let (mut min, mut max) = (i64::MAX, i64::MIN);
+ for v in &def.variants {
+ let x = v.disr_val.to_u64_unchecked() as i64;
+ if x < min { min = x; }
+ if x > max { max = x; }
+ }
- if variants.len() == 2 && hint == attr::ReprAny {
- // Nullable pointer optimization
- for discr in 0..2 {
- let other_fields = variants[1 - discr].iter().map(|ty| {
- ty.layout(infcx)
+ let (discr, signed) = Integer::repr_discr(tcx, hint, min, max);
+ return success(CEnum {
+ discr: discr,
+ signed: signed,
+ min: min as u64,
+ max: max as u64
});
- if !Struct::would_be_zero_sized(dl, other_fields)? {
- continue;
+ }
+
+ // Since there's at least one
+ // non-empty body, explicit discriminants should have
+ // been rejected by a checker before this point.
+ for (i, v) in def.variants.iter().enumerate() {
+ if i as u64 != v.disr_val.to_u64_unchecked() {
+ bug!("non-C-like enum {} with specified discriminants",
+ tcx.item_path_str(def.did));
}
- let path = Struct::non_zero_field_path(infcx,
- variants[discr].iter().cloned())?;
- let mut path = if let Some(p) = path { p } else { continue };
-
- // FIXME(eddyb) should take advantage of a newtype.
- if path == &[0] && variants[discr].len() == 1 {
- match *variants[discr][0].layout(infcx)? {
- Scalar { value, .. } => {
- return success(RawNullablePointer {
- nndiscr: discr as u64,
- value: value
- });
- }
- _ => {
- bug!("Layout::compute: `{}`'s non-zero \
- `{}` field not scalar?!",
- ty, variants[discr][0])
+ }
+
+ if def.variants.len() == 1 {
+ // Equivalent to a struct/tuple/newtype.
+ // (Typechecking will reject discriminant-sizing attrs.)
+ assert_eq!(hint, attr::ReprAny);
+ let fields = def.variants[0].fields.iter().map(|field| {
+ field.ty(tcx, substs).layout(infcx)
+ });
+ let mut st = Struct::new(dl, false);
+ st.extend(dl, fields, ty)?;
+ return success(Univariant { variant: st, non_zero: false });
+ }
+
+ // Cache the substituted and normalized variant field types.
+ let variants = def.variants.iter().map(|v| {
+ v.fields.iter().map(|field| field.ty(tcx, substs)).collect::<Vec<_>>()
+ }).collect::<Vec<_>>();
+
+ if variants.len() == 2 && hint == attr::ReprAny {
+ // Nullable pointer optimization
+ for discr in 0..2 {
+ let other_fields = variants[1 - discr].iter().map(|ty| {
+ ty.layout(infcx)
+ });
+ if !Struct::would_be_zero_sized(dl, other_fields)? {
+ continue;
+ }
+ let path = Struct::non_zero_field_path(infcx,
+ variants[discr].iter().cloned())?;
+ let mut path = if let Some(p) = path { p } else { continue };
+
+ // FIXME(eddyb) should take advantage of a newtype.
+ if path == &[0] && variants[discr].len() == 1 {
+ match *variants[discr][0].layout(infcx)? {
+ Scalar { value, .. } => {
+ return success(RawNullablePointer {
+ nndiscr: discr as u64,
+ value: value
+ });
+ }
+ _ => {
+ bug!("Layout::compute: `{}`'s non-zero \
+ `{}` field not scalar?!",
+ ty, variants[discr][0])
+ }
}
}
+
+ path.push(0); // For GEP through a pointer.
+ path.reverse();
+ let mut st = Struct::new(dl, false);
+ st.extend(dl, variants[discr].iter().map(|ty| ty.layout(infcx)), ty)?;
+ return success(StructWrappedNullablePointer {
+ nndiscr: discr as u64,
+ nonnull: st,
+ discrfield: path
+ });
}
+ }
- path.push(0); // For GEP through a pointer.
- path.reverse();
- let mut st = Struct::new(dl, false);
- st.extend(dl, variants[discr].iter().map(|ty| ty.layout(infcx)), ty)?;
- return success(StructWrappedNullablePointer {
- nndiscr: discr as u64,
- nonnull: st,
- discrfield: path
+ // The general case.
+ let discr_max = (variants.len() - 1) as i64;
+ assert!(discr_max >= 0);
+ let (min_ity, _) = Integer::repr_discr(tcx, hint, 0, discr_max);
+
+ let mut align = dl.aggregate_align;
+ let mut size = Size::from_bytes(0);
+
+ // We're interested in the smallest alignment, so start large.
+ let mut start_align = Align::from_bytes(256, 256).unwrap();
+
+ // Create the set of structs that represent each variant
+ // Use the minimum integer type we figured out above
+ let discr = Some(Scalar { value: Int(min_ity), non_zero: false });
+ let mut variants = variants.into_iter().map(|fields| {
+ let mut found_start = false;
+ let fields = fields.into_iter().map(|field| {
+ let field = field.layout(infcx)?;
+ if !found_start {
+ // Find the first field we can't move later
+ // to make room for a larger discriminant.
+ let field_align = field.align(dl);
+ if field.size(dl).bytes() != 0 || field_align.abi() != 1 {
+ start_align = start_align.min(field_align);
+ found_start = true;
+ }
+ }
+ Ok(field)
});
+ let mut st = Struct::new(dl, false);
+ st.extend(dl, discr.iter().map(Ok).chain(fields), ty)?;
+ size = cmp::max(size, st.min_size());
+ align = align.max(st.align);
+ Ok(st)
+ }).collect::<Result<Vec<_>, _>>()?;
+
+ // Align the maximum variant size to the largest alignment.
+ size = size.abi_align(align);
+
+ if size.bytes() >= dl.obj_size_bound() {
+ return Err(LayoutError::SizeOverflow(ty));
}
- }
- // The general case.
- let discr_max = (variants.len() - 1) as i64;
- assert!(discr_max >= 0);
- let (min_ity, _) = Integer::repr_discr(tcx, hint, 0, discr_max);
-
- let mut align = dl.aggregate_align;
- let mut size = Size::from_bytes(0);
-
- // We're interested in the smallest alignment, so start large.
- let mut start_align = Align::from_bytes(256, 256).unwrap();
-
- // Create the set of structs that represent each variant
- // Use the minimum integer type we figured out above
- let discr = Some(Scalar { value: Int(min_ity), non_zero: false });
- let mut variants = variants.into_iter().map(|fields| {
- let mut found_start = false;
- let fields = fields.into_iter().map(|field| {
- let field = field.layout(infcx)?;
- if !found_start {
- // Find the first field we can't move later
- // to make room for a larger discriminant.
- let field_align = field.align(dl);
- if field.size(dl).bytes() != 0 || field_align.abi() != 1 {
- start_align = start_align.min(field_align);
- found_start = true;
- }
+ // Check to see if we should use a different type for the
+ // discriminant. We can safely use a type with the same size
+ // as the alignment of the first field of each variant.
+ // We increase the size of the discriminant to avoid LLVM copying
+ // padding when it doesn't need to. This normally causes unaligned
+ // load/stores and excessive memcpy/memset operations. By using a
+ // bigger integer size, LLVM can be sure about it's contents and
+ // won't be so conservative.
+
+ // Use the initial field alignment
+ let wanted = start_align.abi();
+ let mut ity = min_ity;
+ for &candidate in &[I16, I32, I64] {
+ let ty = Int(candidate);
+ if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
+ ity = candidate;
+ break;
}
- Ok(field)
- });
- let mut st = Struct::new(dl, false);
- st.extend(dl, discr.iter().map(Ok).chain(fields), ty)?;
- size = cmp::max(size, st.min_size());
- align = align.max(st.align);
- Ok(st)
- }).collect::<Result<Vec<_>, _>>()?;
-
- // Align the maximum variant size to the largest alignment.
- size = size.abi_align(align);
-
- if size.bytes() >= dl.obj_size_bound() {
- return Err(LayoutError::SizeOverflow(ty));
- }
-
- // Check to see if we should use a different type for the
- // discriminant. We can safely use a type with the same size
- // as the alignment of the first field of each variant.
- // We increase the size of the discriminant to avoid LLVM copying
- // padding when it doesn't need to. This normally causes unaligned
- // load/stores and excessive memcpy/memset operations. By using a
- // bigger integer size, LLVM can be sure about it's contents and
- // won't be so conservative.
-
- // Use the initial field alignment
- let wanted = start_align.abi();
- let mut ity = min_ity;
- for &candidate in &[I16, I32, I64] {
- let ty = Int(candidate);
- if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
- ity = candidate;
- break;
}
- }
- // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
- if align.abi() != start_align.abi() {
- ity = min_ity;
- }
+ // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
+ if align.abi() != start_align.abi() {
+ ity = min_ity;
+ }
- // If the alignment is not larger than the chosen discriminant size,
- // don't use the alignment as the final size.
- if ity <= min_ity {
- ity = min_ity;
- } else {
- // Patch up the variants' first few fields.
- let old_ity_size = Int(min_ity).size(dl);
- let new_ity_size = Int(ity).size(dl);
- for variant in &mut variants {
- for offset in &mut variant.offset_after_field {
- if *offset > old_ity_size {
- break;
+ // If the alignment is not larger than the chosen discriminant size,
+ // don't use the alignment as the final size.
+ if ity <= min_ity {
+ ity = min_ity;
+ } else {
+ // Patch up the variants' first few fields.
+ let old_ity_size = Int(min_ity).size(dl);
+ let new_ity_size = Int(ity).size(dl);
+ for variant in &mut variants {
+ for offset in &mut variant.offset_after_field {
+ if *offset > old_ity_size {
+ break;
+ }
+ *offset = new_ity_size;
}
- *offset = new_ity_size;
}
}
- }
- General {
- discr: ity,
- variants: variants,
- size: size,
- align: align
+ General {
+ discr: ity,
+ variants: variants,
+ size: size,
+ align: align
+ }
}
- }
+ },
// Types with no meaningful known layout.
ty::TyProjection(_) | ty::TyAnon(..) => {
}
}
- ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
// Only newtypes and enums w/ nullable pointer optimization.
- if def.variants.is_empty() || def.variants.len() > 2 {
+ if def.is_union() || def.variants.is_empty() || def.variants.len() > 2 {
return Err(err);
}
self.input_types()
.flat_map(|t| t.walk())
.filter_map(|t| match t.sty {
- ty::TyStruct(adt_def, _) |
- ty::TyUnion(adt_def, _) |
- ty::TyEnum(adt_def, _) =>
+ ty::TyAdt(adt_def, _) =>
Some(adt_def.did),
_ =>
None
self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
}
+ #[inline]
+ pub fn is_struct(&self) -> bool {
+ !self.is_union() && !self.is_enum()
+ }
+
+ #[inline]
+ pub fn is_union(&self) -> bool {
+ self.flags.get().intersects(AdtFlags::IS_UNION)
+ }
+
+ #[inline]
+ pub fn is_enum(&self) -> bool {
+ self.flags.get().intersects(AdtFlags::IS_ENUM)
+ }
+
/// Returns the kind of the ADT - Struct or Enum.
#[inline]
pub fn adt_kind(&self) -> AdtKind {
- if self.flags.get().intersects(AdtFlags::IS_ENUM) {
+ if self.is_enum() {
AdtKind::Enum
- } else if self.flags.get().intersects(AdtFlags::IS_UNION) {
+ } else if self.is_union() {
AdtKind::Union
} else {
AdtKind::Struct
}
}
+ pub fn descr(&self) -> &'static str {
+ match self.adt_kind() {
+ AdtKind::Struct => "struct",
+ AdtKind::Union => "union",
+ AdtKind::Enum => "enum",
+ }
+ }
+
+ pub fn variant_descr(&self) -> &'static str {
+ match self.adt_kind() {
+ AdtKind::Struct => "struct",
+ AdtKind::Union => "union",
+ AdtKind::Enum => "variant",
+ }
+ }
+
/// Returns whether this is a dtorck type. If this returns
/// true, this type being safe for destruction requires it to be
/// alive; Otherwise, only the contents are required to be.
/// Asserts this is a struct and returns the struct's unique
/// variant.
pub fn struct_variant(&self) -> &VariantDefData<'gcx, 'container> {
- let adt_kind = self.adt_kind();
- assert!(adt_kind == AdtKind::Struct || adt_kind == AdtKind::Union);
+ assert!(!self.is_enum());
&self.variants[0]
}
}
}
- TyEnum(adt, substs) | TyStruct(adt, substs) | TyUnion(adt, substs) => {
+ TyAdt(adt, substs) => {
// recursive case
let adt = tcx.lookup_adt_def_master(adt.did);
adt.calculate_sized_constraint_inner(tcx, stack);
ty::TyUint(..) | // OutlivesScalar
ty::TyFloat(..) | // OutlivesScalar
ty::TyNever | // ...
- ty::TyEnum(..) | // OutlivesNominalType
- ty::TyStruct(..) | // OutlivesNominalType
- ty::TyUnion(..) | // OutlivesNominalType
+ ty::TyAdt(..) | // OutlivesNominalType
ty::TyBox(..) | // OutlivesNominalType (ish)
ty::TyAnon(..) | // OutlivesNominalType (ish)
ty::TyStr | // OutlivesScalar (ish)
Ok(a)
}
- (&ty::TyEnum(a_def, a_substs), &ty::TyEnum(b_def, b_substs))
+ (&ty::TyAdt(a_def, a_substs), &ty::TyAdt(b_def, b_substs))
if a_def == b_def =>
{
let substs = relate_item_substs(relation, a_def.did, a_substs, b_substs)?;
- Ok(tcx.mk_enum(a_def, substs))
+ Ok(tcx.mk_adt(a_def, substs))
}
(&ty::TyTrait(ref a_obj), &ty::TyTrait(ref b_obj)) =>
}))
}
- (&ty::TyStruct(a_def, a_substs), &ty::TyStruct(b_def, b_substs))
- if a_def == b_def =>
- {
- let substs = relate_item_substs(relation, a_def.did, a_substs, b_substs)?;
- Ok(tcx.mk_struct(a_def, substs))
- }
-
- (&ty::TyUnion(a_def, a_substs), &ty::TyUnion(b_def, b_substs))
- if a_def == b_def =>
- {
- let substs = relate_item_substs(relation, a_def.did, a_substs, b_substs)?;
- Ok(tcx.mk_union(a_def, substs))
- }
-
(&ty::TyClosure(a_id, a_substs),
&ty::TyClosure(b_id, b_substs))
if a_id == b_id =>
ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)),
ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz),
ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)),
- ty::TyEnum(tid, substs) => ty::TyEnum(tid, substs.fold_with(folder)),
+ ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
ty::TyTrait(ref trait_ty) => ty::TyTrait(trait_ty.fold_with(folder)),
ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)),
ty::TyFnDef(def_id, substs, f) => {
ty::TyRef(ref r, tm) => {
ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
}
- ty::TyStruct(did, substs) => ty::TyStruct(did, substs.fold_with(folder)),
- ty::TyUnion(did, substs) => ty::TyUnion(did, substs.fold_with(folder)),
ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)),
ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
ty::TyRawPtr(ref tm) => tm.visit_with(visitor),
ty::TyArray(typ, _sz) => typ.visit_with(visitor),
ty::TySlice(typ) => typ.visit_with(visitor),
- ty::TyEnum(_tid, ref substs) => substs.visit_with(visitor),
+ ty::TyAdt(_, substs) => substs.visit_with(visitor),
ty::TyTrait(ref trait_ty) => trait_ty.visit_with(visitor),
ty::TyTuple(ts) => ts.visit_with(visitor),
ty::TyFnDef(_, substs, ref f) => {
}
ty::TyFnPtr(ref f) => f.visit_with(visitor),
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
- ty::TyStruct(_did, ref substs) => substs.visit_with(visitor),
- ty::TyUnion(_did, ref substs) => substs.visit_with(visitor),
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
ty::TyProjection(ref data) => data.visit_with(visitor),
ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
/// A primitive floating-point type. For example, `f64`.
TyFloat(ast::FloatTy),
- /// An enumerated type, defined with `enum`.
+ /// Structures, enumerations and unions.
///
/// Substs here, possibly against intuition, *may* contain `TyParam`s.
/// That is, even after substitution it is possible that there are type
- /// variables. This happens when the `TyEnum` corresponds to an enum
- /// definition and not a concrete use of it. This is true for `TyStruct`
- /// and `TyUnion` as well.
- TyEnum(AdtDef<'tcx>, &'tcx Substs<'tcx>),
-
- /// A structure type, defined with `struct`.
- ///
- /// See warning about substitutions for enumerated types.
- TyStruct(AdtDef<'tcx>, &'tcx Substs<'tcx>),
-
- /// A union type, defined with `union`.
- ///
- /// See warning about substitutions for enumerated types.
- TyUnion(AdtDef<'tcx>, &'tcx Substs<'tcx>),
+ /// variables. This happens when the `TyAdt` corresponds to an ADT
+ /// definition and not a concrete use of it.
+ TyAdt(AdtDef<'tcx>, &'tcx Substs<'tcx>),
/// `Box<T>`; this is nominally a struct in the documentation, but is
/// special-cased internally. For example, it is possible to implicitly
// FIXME(#24885): be smarter here, the AdtDefData::is_empty method could easily be made
// more complete.
match self.sty {
- TyEnum(def, _) | TyStruct(def, _) | TyUnion(def, _) => def.is_empty(),
+ TyAdt(def, _) => def.is_empty(),
// FIXME(canndrew): There's no reason why these can't be uncommented, they're tested
// and they don't break anything. But I'm keeping my changes small for now.
}
pub fn is_phantom_data(&self) -> bool {
- if let TyStruct(def, _) = self.sty {
+ if let TyAdt(def, _) = self.sty {
def.is_phantom_data()
} else {
false
pub fn is_structural(&self) -> bool {
match self.sty {
- TyStruct(..) | TyUnion(..) | TyTuple(..) | TyEnum(..) |
- TyArray(..) | TyClosure(..) => true,
+ TyAdt(..) | TyTuple(..) | TyArray(..) | TyClosure(..) => true,
_ => self.is_slice() | self.is_trait()
}
}
#[inline]
pub fn is_simd(&self) -> bool {
match self.sty {
- TyStruct(def, _) => def.is_simd(),
+ TyAdt(def, _) => def.is_simd(),
_ => false
}
}
pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
match self.sty {
- TyStruct(def, substs) => {
+ TyAdt(def, substs) => {
def.struct_variant().fields[0].ty(tcx, substs)
}
_ => bug!("simd_type called on invalid type")
pub fn simd_size(&self, _cx: TyCtxt) -> usize {
match self.sty {
- TyStruct(def, _) => def.struct_variant().fields.len(),
+ TyAdt(def, _) => def.struct_variant().fields.len(),
_ => bug!("simd_size called on invalid type")
}
}
pub fn ty_to_def_id(&self) -> Option<DefId> {
match self.sty {
TyTrait(ref tt) => Some(tt.principal.def_id()),
- TyStruct(def, _) |
- TyUnion(def, _) |
- TyEnum(def, _) => Some(def.did),
+ TyAdt(def, _) => Some(def.did),
TyClosure(id, _) => Some(id),
_ => None
}
pub fn ty_adt_def(&self) -> Option<AdtDef<'tcx>> {
match self.sty {
- TyStruct(adt, _) | TyUnion(adt, _) | TyEnum(adt, _) => Some(adt),
+ TyAdt(adt, _) => Some(adt),
_ => None
}
}
v.extend(obj.principal.skip_binder().substs.regions());
v
}
- TyEnum(_, substs) |
- TyStruct(_, substs) |
- TyUnion(_, substs) |
- TyAnon(_, substs) => {
+ TyAdt(_, substs) | TyAnon(_, substs) => {
substs.regions().collect()
}
TyClosure(_, ref substs) => {
use infer::InferCtxt;
use hir::pat_util;
use traits::{self, Reveal};
-use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
+use ty::{self, Ty, AdtKind, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
use ty::{Disr, ParameterEnvironment};
use ty::fold::TypeVisitor;
use ty::layout::{Layout, LayoutError};
// FIXME: (@jroesch) float this code up
tcx.infer_ctxt(None, Some(self.clone()), Reveal::ExactMatch).enter(|infcx| {
let adt = match self_type.sty {
- ty::TyStruct(struct_def, substs) | ty::TyUnion(struct_def, substs) => {
- for field in struct_def.all_fields() {
- let field_ty = field.ty(tcx, substs);
- if infcx.type_moves_by_default(field_ty, span) {
- return Err(CopyImplementationError::InfrigingField(
- field.name))
- }
- }
- struct_def
- }
- ty::TyEnum(enum_def, substs) => {
- for variant in &enum_def.variants {
- for field in &variant.fields {
+ ty::TyAdt(adt, substs) => match adt.adt_kind() {
+ AdtKind::Struct | AdtKind::Union => {
+ for field in adt.all_fields() {
let field_ty = field.ty(tcx, substs);
if infcx.type_moves_by_default(field_ty, span) {
- return Err(CopyImplementationError::InfrigingVariant(
- variant.name))
+ return Err(CopyImplementationError::InfrigingField(
+ field.name))
}
}
+ adt
}
- enum_def
- }
+ AdtKind::Enum => {
+ for variant in &adt.variants {
+ for field in &variant.fields {
+ let field_ty = field.ty(tcx, substs);
+ if infcx.type_moves_by_default(field_ty, span) {
+ return Err(CopyImplementationError::InfrigingVariant(
+ variant.name))
+ }
+ }
+ }
+ adt
+ }
+ },
_ => return Err(CopyImplementationError::NotAnAdt)
};
pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
match ty.sty {
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
for field in def.all_fields() {
let field_ty = field.ty(self, substs);
if let TyError = field_ty.sty {
i: usize,
variant: Option<DefId>) -> Option<Ty<'tcx>> {
match (&ty.sty, variant) {
- (&TyStruct(def, substs), None) |
- (&TyUnion(def, substs), None) => {
- def.struct_variant().fields.get(i).map(|f| f.ty(self, substs))
+ (&TyAdt(adt, substs), Some(vid)) => {
+ adt.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
}
- (&TyEnum(def, substs), Some(vid)) => {
- def.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
- }
- (&TyEnum(def, substs), None) => {
- assert!(def.is_univariant());
- def.variants[0].fields.get(i).map(|f| f.ty(self, substs))
+ (&TyAdt(adt, substs), None) => {
+ // Don't use `struct_variant`, this may be a univariant enum.
+ adt.variants[0].fields.get(i).map(|f| f.ty(self, substs))
}
(&TyTuple(ref v), None) => v.get(i).cloned(),
_ => None
n: Name,
variant: Option<DefId>) -> Option<Ty<'tcx>> {
match (&ty.sty, variant) {
- (&TyStruct(def, substs), None) |
- (&TyUnion(def, substs), None) => {
- def.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
+ (&TyAdt(adt, substs), Some(vid)) => {
+ adt.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
}
- (&TyEnum(def, substs), Some(vid)) => {
- def.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
+ (&TyAdt(adt, substs), None) => {
+ adt.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
}
_ => return None
}
/// if not a structure at all. Corresponds to the only possible unsized
/// field, and its type can be used to determine unsizing strategy.
pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
- while let TyStruct(def, substs) = ty.sty {
- match def.struct_variant().fields.last() {
- Some(f) => ty = f.ty(self, substs),
- None => break
+ loop {
+ match ty.sty {
+ TyAdt(def, substs) if def.is_struct() => {
+ match def.struct_variant().fields.last() {
+ Some(f) => ty = f.ty(self, substs),
+ None => break
+ }
+ }
+ _ => break
}
}
ty
target: Ty<'tcx>)
-> (Ty<'tcx>, Ty<'tcx>) {
let (mut a, mut b) = (source, target);
- while let (&TyStruct(a_def, a_substs), &TyStruct(b_def, b_substs)) = (&a.sty, &b.sty) {
- if a_def != b_def {
- break;
- }
- if let Some(f) = a_def.struct_variant().fields.last() {
- a = f.ty(self, a_substs);
- b = f.ty(self, b_substs);
- } else {
- break;
+ loop {
+ match (&a.sty, &b.sty) {
+ (&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs))
+ if a_def == b_def && a_def.is_struct() => {
+ match a_def.struct_variant().fields.last() {
+ Some(f) => {
+ a = f.ty(self, a_substs);
+ b = f.ty(self, b_substs);
+ }
+ _ => break
+ }
+ }
+ _ => break
}
}
(a, b)
TyInt(i) => self.hash(i),
TyUint(u) => self.hash(u),
TyFloat(f) => self.hash(f),
- TyStruct(d, _) |
- TyUnion(d, _) |
- TyEnum(d, _) => self.def_id(d.did),
+ TyAdt(d, _) => self.def_id(d.did),
TyArray(_, n) => self.hash(n),
TyRawPtr(m) |
TyRef(_, m) => self.hash(m.mutbl),
mutbl: hir::MutMutable, ..
}) => Some(true),
- TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
- TyClosure(..) | TyEnum(..) | TyStruct(..) | TyUnion(..) | TyAnon(..) |
+ TyArray(..) | TySlice(..) | TyTrait(..) | TyTuple(..) |
+ TyClosure(..) | TyAdt(..) | TyAnon(..) |
TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
}.unwrap_or_else(|| !self.impls_bound(tcx, param_env, ty::BoundCopy, span));
TyStr | TyTrait(..) | TySlice(_) => Some(false),
- TyEnum(..) | TyStruct(..) | TyUnion(..) | TyProjection(..) | TyParam(..) |
+ TyAdt(..) | TyProjection(..) | TyParam(..) |
TyInfer(..) | TyAnon(..) | TyError => None
}.unwrap_or_else(|| self.impls_bound(tcx, param_env, ty::BoundSized, span));
TyArray(ty, _) => {
is_type_structurally_recursive(tcx, sp, seen, ty)
}
- TyStruct(def, substs) | TyUnion(def, substs) | TyEnum(def, substs) => {
+ TyAdt(def, substs) => {
find_nonrepresentable(tcx,
sp,
seen,
fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
match ty.sty {
- TyStruct(ty_def, _) | TyUnion(ty_def, _) | TyEnum(ty_def, _) => {
+ TyAdt(ty_def, _) => {
ty_def == def
}
_ => false
fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
match (&a.sty, &b.sty) {
- (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
- (&TyUnion(did_a, ref substs_a), &TyUnion(did_b, ref substs_b)) |
- (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
+ (&TyAdt(did_a, substs_a), &TyAdt(did_b, substs_b)) => {
if did_a != did_b {
return false;
}
debug!("is_type_structurally_recursive: {:?}", ty);
match ty.sty {
- TyStruct(def, _) | TyUnion(def, _) | TyEnum(def, _) => {
+ TyAdt(def, _) => {
{
// Iterate through stack of previously seen types.
let mut iter = seen.iter();
pred.0.ty
}).rev());
}
- ty::TyEnum(_, ref substs) |
- ty::TyStruct(_, ref substs) |
- ty::TyUnion(_, ref substs) |
- ty::TyAnon(_, ref substs) => {
+ ty::TyAdt(_, substs) | ty::TyAnon(_, substs) => {
stack.extend(substs.types().rev());
}
ty::TyClosure(_, ref substs) => {
self.compute_projection(data);
}
- ty::TyEnum(def, substs) |
- ty::TyStruct(def, substs) |
- ty::TyUnion(def, substs) => {
+ ty::TyAdt(def, substs) => {
// WfNominalType
let obligations = self.nominal_obligations(def.did, substs);
self.out.extend(obligations);
use hir::def_id::DefId;
use ty::subst::{self, Subst, Substs};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
-use ty::{TyBool, TyChar, TyStruct, TyUnion, TyEnum};
+use ty::{TyBool, TyChar, TyAdt};
use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
use ty::TyClosure;
TyInfer(infer_ty) => write!(f, "{}", infer_ty),
TyError => write!(f, "[type error]"),
TyParam(ref param_ty) => write!(f, "{}", param_ty),
- TyEnum(def, substs) | TyStruct(def, substs) | TyUnion(def, substs) => {
+ TyAdt(def, substs) => {
ty::tls::with(|tcx| {
if def.did.is_local() &&
!tcx.tcache.borrow().contains_key(&def.did) {
}
LpExtend(ref lp_base, _, LpInterior(_, InteriorField(_))) => {
match lp_base.to_type().sty {
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) |
- ty::TyEnum(def, _) if def.has_dtor() => {
+ ty::TyAdt(def, _) if def.has_dtor() => {
// In the case where the owner implements drop, then
// the path must be initialized to prevent a case of
// partial reinitialization
use borrowck::move_data::InvalidMovePathIndex;
use borrowck::move_data::{MoveData, MovePathIndex};
use rustc::hir::def_id::{DefId};
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, AdtKind, TyCtxt};
use rustc::middle::mem_categorization as mc;
use std::mem;
variant_did);
};
- match (&parent_ty.sty, enum_variant_info) {
- (&ty::TyTuple(ref v), None) => {
+ match parent_ty.sty {
+ ty::TyTuple(ref v) => {
let tuple_idx = match *origin_field_name {
mc::PositionalField(tuple_idx) => tuple_idx,
mc::NamedField(_) =>
}
}
- (&ty::TyStruct(def, _), None) => {
- match *origin_field_name {
- mc::NamedField(ast_name) => {
- for f in &def.struct_variant().fields {
- if f.name == ast_name {
- continue;
+ ty::TyAdt(def, ..) => match def.adt_kind() {
+ AdtKind::Struct => {
+ match *origin_field_name {
+ mc::NamedField(ast_name) => {
+ for f in &def.struct_variant().fields {
+ if f.name == ast_name {
+ continue;
+ }
+ let field_name = mc::NamedField(f.name);
+ add_fragment_sibling_local(field_name, None);
}
- let field_name = mc::NamedField(f.name);
- add_fragment_sibling_local(field_name, None);
}
- }
- mc::PositionalField(tuple_idx) => {
- for (i, _f) in def.struct_variant().fields.iter().enumerate() {
- if i == tuple_idx {
- continue
+ mc::PositionalField(tuple_idx) => {
+ for (i, _f) in def.struct_variant().fields.iter().enumerate() {
+ if i == tuple_idx {
+ continue
+ }
+ let field_name = mc::PositionalField(i);
+ add_fragment_sibling_local(field_name, None);
}
- let field_name = mc::PositionalField(i);
- add_fragment_sibling_local(field_name, None);
}
}
}
- }
-
- (&ty::TyUnion(..), None) => {
- // Do nothing, all union fields are moved/assigned together.
- }
-
- (&ty::TyEnum(def, _), ref enum_variant_info) => {
- let variant = match *enum_variant_info {
- Some((vid, ref _lp2)) => def.variant_with_id(vid),
- None => {
- assert!(def.is_univariant());
- &def.variants[0]
- }
- };
- match *origin_field_name {
- mc::NamedField(ast_name) => {
- for field in &variant.fields {
- if field.name == ast_name {
- continue;
+ AdtKind::Union => {
+ // Do nothing, all union fields are moved/assigned together.
+ }
+ AdtKind::Enum => {
+ let variant = match enum_variant_info {
+ Some((vid, ref _lp2)) => def.variant_with_id(vid),
+ None => {
+ assert!(def.is_univariant());
+ &def.variants[0]
+ }
+ };
+ match *origin_field_name {
+ mc::NamedField(ast_name) => {
+ for field in &variant.fields {
+ if field.name == ast_name {
+ continue;
+ }
+ let field_name = mc::NamedField(field.name);
+ add_fragment_sibling_local(field_name, Some(variant.did));
}
- let field_name = mc::NamedField(field.name);
- add_fragment_sibling_local(field_name, Some(variant.did));
}
- }
- mc::PositionalField(tuple_idx) => {
- for (i, _f) in variant.fields.iter().enumerate() {
- if tuple_idx == i {
- continue;
+ mc::PositionalField(tuple_idx) => {
+ for (i, _f) in variant.fields.iter().enumerate() {
+ if tuple_idx == i {
+ continue;
+ }
+ let field_name = mc::PositionalField(i);
+ add_fragment_sibling_local(field_name, None);
}
- let field_name = mc::PositionalField(i);
- add_fragment_sibling_local(field_name, None);
}
}
}
- }
+ },
- ref sty_and_variant_info => {
+ ref ty => {
let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id));
span_bug!(opt_span.unwrap_or(DUMMY_SP),
"type {:?} ({:?}) is not fragmentable",
- parent_ty,
- sty_and_variant_info);
+ parent_ty, ty);
}
}
}
Categorization::Interior(ref b, mc::InteriorField(_)) |
Categorization::Interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
match b.ty.sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) | ty::TyEnum(def, _) => {
+ ty::TyAdt(def, _) => {
if def.has_dtor() {
Some(cmt.clone())
} else {
Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, mc::InteriorField(_)) => {
match b.ty.sty {
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) |
- ty::TyEnum(def, _) if def.has_dtor() => {
+ ty::TyAdt(def, _) if def.has_dtor() => {
let mut err = struct_span_err!(bccx, move_from.span, E0509,
"cannot move out of type `{}`, \
which implements the `Drop` trait",
let base_ty = cmt_base.ty;
let result = self.restrict(cmt_base);
// Borrowing one union field automatically borrows all its fields.
- if let ty::TyUnion(ref adt_def, _) = base_ty.sty {
- match result {
+ match base_ty.sty {
+ ty::TyAdt(adt_def, _) if adt_def.is_union() => match result {
RestrictionResult::Safe => RestrictionResult::Safe,
RestrictionResult::SafeIf(base_lp, mut base_vec) => {
for field in &adt_def.struct_variant().fields {
LpInterior(opt_variant_id, interior)));
RestrictionResult::SafeIf(lp, base_vec)
}
- }
- } else {
- self.extend(result, &cmt, LpInterior(opt_variant_id, interior))
+ },
+ _ => self.extend(result, &cmt, LpInterior(opt_variant_id, interior))
}
}
fn open_drop<'a>(&mut self, c: &DropCtxt<'a, 'tcx>) -> BasicBlock {
let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
match ty.sty {
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
self.open_drop_for_adt(c, def, substs)
}
ty::TyTuple(tys) | ty::TyClosure(_, ty::ClosureSubsts {
let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
match ty.sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) | ty::TyEnum(def, _) => {
+ ty::TyAdt(def, _) => {
if def.has_dtor() {
self.tcx.sess.span_warn(
c.source_info.span,
lv, ty);
true
}
- ty::TyStruct(def, _) | ty::TyUnion(def, _) | ty::TyEnum(def, _) if def.has_dtor() => {
+ ty::TyAdt(def, _) if def.has_dtor() => {
debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => false",
lv, ty);
true
kind: MoveKind) {
// Moving one union field automatically moves all its fields.
if let LpExtend(ref base_lp, mutbl, LpInterior(opt_variant_id, interior)) = lp.kind {
- if let ty::TyUnion(ref adt_def, _) = base_lp.ty.sty {
- for field in &adt_def.struct_variant().fields {
- let field = InteriorKind::InteriorField(mc::NamedField(field.name));
- let field_ty = if field == interior {
- lp.ty
- } else {
- tcx.types.err // Doesn't matter
- };
- let sibling_lp_kind = LpExtend(base_lp.clone(), mutbl,
- LpInterior(opt_variant_id, field));
- let sibling_lp = Rc::new(LoanPath::new(sibling_lp_kind, field_ty));
- self.add_move_helper(tcx, sibling_lp, id, kind);
+ if let ty::TyAdt(adt_def, _) = base_lp.ty.sty {
+ if adt_def.is_union() {
+ for field in &adt_def.struct_variant().fields {
+ let field = InteriorKind::InteriorField(mc::NamedField(field.name));
+ let field_ty = if field == interior {
+ lp.ty
+ } else {
+ tcx.types.err // Doesn't matter
+ };
+ let sibling_lp_kind = LpExtend(base_lp.clone(), mutbl,
+ LpInterior(opt_variant_id, field));
+ let sibling_lp = Rc::new(LoanPath::new(sibling_lp_kind, field_ty));
+ self.add_move_helper(tcx, sibling_lp, id, kind);
+ }
+ return;
}
- return;
}
}
mode: euv::MutateMode) {
// Assigning to one union field automatically assigns to all its fields.
if let LpExtend(ref base_lp, mutbl, LpInterior(opt_variant_id, interior)) = lp.kind {
- if let ty::TyUnion(ref adt_def, _) = base_lp.ty.sty {
- for field in &adt_def.struct_variant().fields {
- let field = InteriorKind::InteriorField(mc::NamedField(field.name));
- let field_ty = if field == interior {
- lp.ty
- } else {
- tcx.types.err // Doesn't matter
- };
- let sibling_lp_kind = LpExtend(base_lp.clone(), mutbl,
- LpInterior(opt_variant_id, field));
- let sibling_lp = Rc::new(LoanPath::new(sibling_lp_kind, field_ty));
- self.add_assignment_helper(tcx, sibling_lp, assign_id, span, assignee_id, mode);
+ if let ty::TyAdt(adt_def, _) = base_lp.ty.sty {
+ if adt_def.is_union() {
+ for field in &adt_def.struct_variant().fields {
+ let field = InteriorKind::InteriorField(mc::NamedField(field.name));
+ let field_ty = if field == interior {
+ lp.ty
+ } else {
+ tcx.types.err // Doesn't matter
+ };
+ let sibling_lp_kind = LpExtend(base_lp.clone(), mutbl,
+ LpInterior(opt_variant_id, field));
+ let sibling_lp = Rc::new(LoanPath::new(sibling_lp_kind, field_ty));
+ self.add_assignment_helper(tcx, sibling_lp, assign_id,
+ span, assignee_id, mode);
+ }
+ return;
}
- return;
}
}
pat.walk(|p| {
if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node {
let pat_ty = cx.tcx.pat_ty(p);
- if let ty::TyEnum(edef, _) = pat_ty.sty {
- if let Def::Local(..) = cx.tcx.expect_def(p.id) {
- if edef.variants.iter().any(|variant| {
- variant.name == name.node && variant.kind == VariantKind::Unit
- }) {
- let ty_path = cx.tcx.item_path_str(edef.did);
- let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
- "pattern binding `{}` is named the same as one \
- of the variants of the type `{}`",
- name.node, ty_path);
- help!(err,
- "if you meant to match on a variant, \
- consider making the path in the pattern qualified: `{}::{}`",
- ty_path, name.node);
- err.emit();
+ if let ty::TyAdt(edef, _) = pat_ty.sty {
+ if edef.is_enum() {
+ if let Def::Local(..) = cx.tcx.expect_def(p.id) {
+ if edef.variants.iter().any(|variant| {
+ variant.name == name.node && variant.kind == VariantKind::Unit
+ }) {
+ let ty_path = cx.tcx.item_path_str(edef.did);
+ let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
+ "pattern binding `{}` is named the same as one \
+ of the variants of the type `{}`",
+ name.node, ty_path);
+ help!(err,
+ "if you meant to match on a variant, \
+ consider making the path in the pattern qualified: `{}::{}`",
+ ty_path, name.node);
+ err.emit();
+ }
}
}
}
let pat = match left_ty.sty {
ty::TyTuple(..) => PatKind::Tuple(pats.collect(), None),
- ty::TyEnum(adt, _) | ty::TyStruct(adt, _) | ty::TyUnion(adt, _) => {
+ ty::TyAdt(adt, _) => {
let v = ctor.variant_for_adt(adt);
match v.kind {
VariantKind::Struct => {
[true, false].iter().map(|b| ConstantValue(ConstVal::Bool(*b))).collect(),
ty::TySlice(_) =>
(0..max_slice_length+1).map(|length| Slice(length)).collect(),
- ty::TyEnum(def, _) => def.variants.iter().map(|v| Variant(v.did)).collect(),
+ ty::TyAdt(def, _) if def.is_enum() =>
+ def.variants.iter().map(|v| Variant(v.did)).collect(),
_ => vec![Single]
}
}
_ => bug!()
},
ty::TyRef(..) => 1,
- ty::TyEnum(adt, _) | ty::TyStruct(adt, _) | ty::TyUnion(adt, _) => {
+ ty::TyAdt(adt, _) => {
ctor.variant_for_adt(adt).fields.len()
}
ty::TyArray(_, n) => n,
span,
format!("floating point constants cannot be used in patterns"));
}
- ty::TyEnum(adt_def, _) |
- ty::TyStruct(adt_def, _) => {
+ ty::TyAdt(adt_def, _) if adt_def.is_union() => {
+ // Matching on union fields is unsafe, we can't hide it in constants
+ tcx.sess.span_err(span, "cannot use unions in constant patterns");
+ }
+ ty::TyAdt(adt_def, _) => {
if !tcx.has_attr(adt_def.did, "structural_match") {
tcx.sess.add_lint(
lint::builtin::ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
tcx.item_path_str(adt_def.did)));
}
}
- ty::TyUnion(..) => {
- // Matching on union fields is unsafe, we can't hide it in constants
- tcx.sess.span_err(span, "cannot use unions in constant patterns");
- }
_ => { }
}
let pat = match expr.node {
(&ty::TyInt(ity), i) => Err(TypeMismatch(ity.to_string(), i)),
(&ty::TyUint(ity), i) => Err(TypeMismatch(ity.to_string(), i)),
- (&ty::TyEnum(ref adt, _), i) => {
+ (&ty::TyAdt(adt, _), i) if adt.is_enum() => {
let hints = tcx.lookup_repr_hints(adt.did);
let int_ty = tcx.enum_repr_type(hints.iter().next());
infer(i, tcx, &int_ty.to_ty(tcx).sty)
infer(Infer(n), tcx, &ty::TyUint(uty)).map(Integral)
},
None => Ok(Integral(Infer(n))),
- Some(&ty::TyEnum(ref adt, _)) => {
+ Some(&ty::TyAdt(adt, _)) => {
let hints = tcx.lookup_repr_hints(adt.did);
let int_ty = tcx.enum_repr_type(hints.iter().next());
infer(Infer(n), tcx, &int_ty.to_ty(tcx).sty).map(Integral)
return;
}
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
- (def, cx.tcx.mk_struct(def, Substs::empty(cx.tcx)))
+ (def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx)))
}
hir::ItemUnion(_, ref ast_generics) => {
if ast_generics.is_parameterized() {
return;
}
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
- (def, cx.tcx.mk_union(def, Substs::empty(cx.tcx)))
+ (def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx)))
}
hir::ItemEnum(_, ref ast_generics) => {
if ast_generics.is_parameterized() {
return;
}
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
- (def, cx.tcx.mk_enum(def, Substs::empty(cx.tcx)))
+ (def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx)))
}
_ => return,
};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, Ty, TyCtxt};
use rustc::ty::layout::{Layout, Primitive};
use rustc::traits::Reveal;
use middle::const_val::ConstVal;
}
match ty.sty {
- ty::TyStruct(def, substs) => {
- if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
- return FfiUnsafe(
- "found struct without foreign-function-safe \
- representation annotation in foreign module, \
- consider adding a #[repr(C)] attribute to \
- the type");
- }
+ ty::TyAdt(def, substs) => match def.adt_kind() {
+ AdtKind::Struct => {
+ if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
+ return FfiUnsafe(
+ "found struct without foreign-function-safe \
+ representation annotation in foreign module, \
+ consider adding a #[repr(C)] attribute to \
+ the type");
+ }
- // We can't completely trust repr(C) markings; make sure the
- // fields are actually safe.
- if def.struct_variant().fields.is_empty() {
- return FfiUnsafe(
- "found zero-size struct in foreign module, consider \
- adding a member to this struct");
- }
+ // We can't completely trust repr(C) markings; make sure the
+ // fields are actually safe.
+ if def.struct_variant().fields.is_empty() {
+ return FfiUnsafe(
+ "found zero-size struct in foreign module, consider \
+ adding a member to this struct");
+ }
- for field in &def.struct_variant().fields {
- let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
- let r = self.check_type_for_ffi(cache, field_ty);
- match r {
- FfiSafe => {}
- FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
- FfiUnsafe(s) => { return FfiBadStruct(def.did, s); }
+ for field in &def.struct_variant().fields {
+ let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
+ let r = self.check_type_for_ffi(cache, field_ty);
+ match r {
+ FfiSafe => {}
+ FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+ FfiUnsafe(s) => { return FfiBadStruct(def.did, s); }
+ }
}
+ FfiSafe
}
- FfiSafe
- }
- ty::TyUnion(def, substs) => {
- if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
- return FfiUnsafe(
- "found union without foreign-function-safe \
- representation annotation in foreign module, \
- consider adding a #[repr(C)] attribute to \
- the type");
- }
+ AdtKind::Union => {
+ if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
+ return FfiUnsafe(
+ "found union without foreign-function-safe \
+ representation annotation in foreign module, \
+ consider adding a #[repr(C)] attribute to \
+ the type");
+ }
- for field in &def.struct_variant().fields {
- let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
- let r = self.check_type_for_ffi(cache, field_ty);
- match r {
- FfiSafe => {}
- FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
- FfiUnsafe(s) => { return FfiBadUnion(def.did, s); }
+ for field in &def.struct_variant().fields {
+ let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
+ let r = self.check_type_for_ffi(cache, field_ty);
+ match r {
+ FfiSafe => {}
+ FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+ FfiUnsafe(s) => { return FfiBadUnion(def.did, s); }
+ }
}
+ FfiSafe
}
- FfiSafe
- }
- ty::TyEnum(def, substs) => {
- if def.variants.is_empty() {
- // Empty enums are okay... although sort of useless.
- return FfiSafe
- }
+ AdtKind::Enum => {
+ if def.variants.is_empty() {
+ // Empty enums are okay... although sort of useless.
+ return FfiSafe
+ }
- // Check for a repr() attribute to specify the size of the
- // discriminant.
- let repr_hints = cx.lookup_repr_hints(def.did);
- match &repr_hints[..] {
- &[] => {
- // Special-case types like `Option<extern fn()>`.
- if !is_repr_nullable_ptr(cx, def, substs) {
- return FfiUnsafe(
- "found enum without foreign-function-safe \
- representation annotation in foreign module, \
- consider adding a #[repr(...)] attribute to \
- the type")
+ // Check for a repr() attribute to specify the size of the
+ // discriminant.
+ let repr_hints = cx.lookup_repr_hints(def.did);
+ match &repr_hints[..] {
+ &[] => {
+ // Special-case types like `Option<extern fn()>`.
+ if !is_repr_nullable_ptr(cx, def, substs) {
+ return FfiUnsafe(
+ "found enum without foreign-function-safe \
+ representation annotation in foreign module, \
+ consider adding a #[repr(...)] attribute to \
+ the type")
+ }
}
- }
- &[ref hint] => {
- if !hint.is_ffi_safe() {
+ &[ref hint] => {
+ if !hint.is_ffi_safe() {
+ // FIXME: This shouldn't be reachable: we should check
+ // this earlier.
+ return FfiUnsafe(
+ "enum has unexpected #[repr(...)] attribute")
+ }
+
+ // Enum with an explicitly sized discriminant; either
+ // a C-style enum or a discriminated union.
+
+ // The layout of enum variants is implicitly repr(C).
+ // FIXME: Is that correct?
+ }
+ _ => {
// FIXME: This shouldn't be reachable: we should check
// this earlier.
return FfiUnsafe(
- "enum has unexpected #[repr(...)] attribute")
+ "enum has too many #[repr(...)] attributes");
}
-
- // Enum with an explicitly sized discriminant; either
- // a C-style enum or a discriminated union.
-
- // The layout of enum variants is implicitly repr(C).
- // FIXME: Is that correct?
- }
- _ => {
- // FIXME: This shouldn't be reachable: we should check
- // this earlier.
- return FfiUnsafe(
- "enum has too many #[repr(...)] attributes");
}
- }
- // Check the contained variants.
- for variant in &def.variants {
- for field in &variant.fields {
- let arg = cx.normalize_associated_type(&field.ty(cx, substs));
- let r = self.check_type_for_ffi(cache, arg);
- match r {
- FfiSafe => {}
- FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
- FfiUnsafe(s) => { return FfiBadEnum(def.did, s); }
+ // Check the contained variants.
+ for variant in &def.variants {
+ for field in &variant.fields {
+ let arg = cx.normalize_associated_type(&field.ty(cx, substs));
+ let r = self.check_type_for_ffi(cache, arg);
+ match r {
+ FfiSafe => {}
+ FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+ FfiUnsafe(s) => { return FfiBadEnum(def.did, s); }
+ }
}
}
+ FfiSafe
}
- FfiSafe
- }
+ },
ty::TyChar => {
FfiUnsafe("found Rust type `char` in foreign module, while \
ty::TyTuple(ref tys) if tys.is_empty() => return,
ty::TyNever => return,
ty::TyBool => return,
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) |
- ty::TyEnum(def, _) => {
+ ty::TyAdt(def, _) => {
let attrs = cx.tcx.get_attrs(def.did);
check_must_use(cx, &attrs[..], s.span)
}
use rustc::hir::def_id::{DefId, DefIndex};
use middle::lang_items;
use rustc::ty::{ImplContainer, TraitContainer};
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, VariantKind};
+use rustc::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, VariantKind};
use rustc_const_math::ConstInt;
let mut ctor_did = None;
let (kind, variants) = match item_family(doc) {
Enum => {
- (ty::AdtKind::Enum,
- get_enum_variants(cdata, doc))
+ (AdtKind::Enum, get_enum_variants(cdata, doc))
}
Struct(..) => {
// Use separate constructor id for unit/tuple structs and reuse did for braced structs.
ctor_did = reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).map(|ctor_doc| {
translated_def_id(cdata, ctor_doc)
});
- (ty::AdtKind::Struct,
- vec![get_struct_variant(cdata, doc, ctor_did.unwrap_or(did))])
+ (AdtKind::Struct, vec![get_struct_variant(cdata, doc, ctor_did.unwrap_or(did))])
}
Union => {
- (ty::AdtKind::Union,
- vec![get_struct_variant(cdata, doc, did)])
+ (AdtKind::Union, vec![get_struct_variant(cdata, doc, did)])
}
- _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}",
- item_family(doc), did)
+ _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}", item_family(doc), did)
};
let adt = tcx.intern_adt_def(did, kind, variants);
// this needs to be done *after* the variant is interned,
// to support recursive structures
for variant in &adt.variants {
- if variant.kind == ty::VariantKind::Tuple &&
- adt.adt_kind() == ty::AdtKind::Enum {
+ if variant.kind == ty::VariantKind::Tuple && adt.is_enum() {
// tuple-like enum variant fields aren't real items - get the types
// from the ctor.
debug!("evaluating the ctor-type of {:?}",
}
}
'c' => return tcx.types.char,
- 't' => {
- assert_eq!(self.next(), '[');
- let did = self.parse_def();
- let substs = self.parse_substs();
- assert_eq!(self.next(), ']');
- let def = self.tcx.lookup_adt_def(did);
- return tcx.mk_enum(def, substs);
- }
'x' => {
assert_eq!(self.next(), '[');
let trait_ref = ty::Binder(self.parse_existential_trait_ref());
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did);
- return self.tcx.mk_struct(def, substs);
- }
- 'U' => {
- assert_eq!(self.next(), '[');
- let did = self.parse_def();
- let substs = self.parse_substs();
- assert_eq!(self.next(), ']');
- let def = self.tcx.lookup_adt_def(did);
- return self.tcx.mk_union(def, substs);
+ return self.tcx.mk_adt(def, substs);
}
'k' => {
assert_eq!(self.next(), '[');
ast::FloatTy::F64 => write!(w, "MF"),
};
}
- ty::TyEnum(def, substs) => {
- write!(w, "t[{}|", (cx.ds)(cx.tcx, def.did));
- enc_substs(w, cx, substs);
- write!(w, "]");
- }
ty::TyTrait(ref obj) => {
write!(w, "x[");
enc_existential_trait_ref(w, cx, obj.principal.0);
ty::TyParam(p) => {
write!(w, "p[{}|{}]", p.idx, p.name);
}
- ty::TyStruct(def, substs) => {
+ ty::TyAdt(def, substs) => {
write!(w, "a[{}|", (cx.ds)(cx.tcx, def.did));
enc_substs(w, cx, substs);
write!(w, "]");
}
- ty::TyUnion(def, substs) => {
- write!(w, "U[{}|", (cx.ds)(cx.tcx, def.did));
- enc_substs(w, cx, substs);
- write!(w, "]");
- }
ty::TyClosure(def, substs) => {
write!(w, "k[{}|", (cx.ds)(cx.tcx, def));
enc_substs(w, cx, substs.func_substs);
ExprKind::Adt {
adt_def, variant_index, substs, fields, base
} => { // see (*) above
- let is_union = adt_def.adt_kind() == ty::AdtKind::Union;
+ let is_union = adt_def.is_union();
let active_field_index = if is_union { Some(fields[0].name.index()) } else { None };
// first process the set of fields that were provided
use rustc::middle::const_val::ConstVal;
use rustc_const_eval as const_eval;
use rustc::middle::region::CodeExtent;
-use rustc::ty::{self, VariantDef, Ty};
+use rustc::ty::{self, AdtKind, VariantDef, Ty};
use rustc::ty::cast::CastKind as TyCastKind;
use rustc::mir::repr::*;
use rustc::hir;
hir::ExprStruct(_, ref fields, ref base) => {
match expr_ty.sty {
- ty::TyStruct(adt, substs) | ty::TyUnion(adt, substs) => {
- let field_refs = field_refs(&adt.variants[0], fields);
- ExprKind::Adt {
- adt_def: adt,
- variant_index: 0,
- substs: substs,
- fields: field_refs,
- base: base.as_ref().map(|base| {
- FruInfo {
- base: base.to_ref(),
- field_types: cx.tcx.tables
- .borrow()
- .fru_field_types[&expr.id]
- .clone()
- }
- })
+ ty::TyAdt(adt, substs) => match adt.adt_kind() {
+ AdtKind::Struct | AdtKind::Union => {
+ let field_refs = field_refs(&adt.variants[0], fields);
+ ExprKind::Adt {
+ adt_def: adt,
+ variant_index: 0,
+ substs: substs,
+ fields: field_refs,
+ base: base.as_ref().map(|base| {
+ FruInfo {
+ base: base.to_ref(),
+ field_types: cx.tcx.tables
+ .borrow()
+ .fru_field_types[&expr.id]
+ .clone()
+ }
+ })
+ }
}
- }
- ty::TyEnum(adt, substs) => {
- match cx.tcx.expect_def(expr.id) {
- Def::Variant(enum_id, variant_id) => {
- debug_assert!(adt.did == enum_id);
- assert!(base.is_none());
-
- let index = adt.variant_index_with_id(variant_id);
- let field_refs = field_refs(&adt.variants[index], fields);
- ExprKind::Adt {
- adt_def: adt,
- variant_index: index,
- substs: substs,
- fields: field_refs,
- base: None
+ AdtKind::Enum => {
+ match cx.tcx.expect_def(expr.id) {
+ Def::Variant(enum_id, variant_id) => {
+ debug_assert!(adt.did == enum_id);
+ assert!(base.is_none());
+
+ let index = adt.variant_index_with_id(variant_id);
+ let field_refs = field_refs(&adt.variants[index], fields);
+ ExprKind::Adt {
+ adt_def: adt,
+ variant_index: index,
+ substs: substs,
+ fields: field_refs,
+ base: None
+ }
+ }
+ ref def => {
+ span_bug!(
+ expr.span,
+ "unexpected def: {:?}",
+ def);
}
- }
- ref def => {
- span_bug!(
- expr.span,
- "unexpected def: {:?}",
- def);
}
}
- }
+ },
_ => {
span_bug!(
expr.span,
body: block::to_expr_ref(cx, body) },
hir::ExprField(ref source, name) => {
let index = match cx.tcx.expr_ty_adjusted(source).sty {
- ty::TyStruct(adt_def, _) | ty::TyUnion(adt_def, _) =>
+ ty::TyAdt(adt_def, _) =>
adt_def.variants[0].index_of_field_named(name.node),
ref ty =>
- span_bug!(
- expr.span,
- "field of non-struct: {:?}",
- ty),
+ span_bug!(expr.span, "field of non-ADT: {:?}", ty),
};
let index = index.unwrap_or_else(|| {
span_bug!(
ty::TyFnDef(..) => def_id,
// A unit struct which is used as a value. We return a completely different ExprKind
// here to account for this special case.
- ty::TyStruct(adt_def, substs) => return ExprKind::Adt {
+ ty::TyAdt(adt_def, substs) => return ExprKind::Adt {
adt_def: adt_def,
variant_index: 0,
substs: substs,
// expression.
ty::TyFnDef(..) => variant_id,
// A unit variant, similar special case to the struct case above.
- ty::TyEnum(adt_def, substs) => {
+ ty::TyAdt(adt_def, substs) => {
debug_assert!(adt_def.did == enum_id);
let index = adt_def.variant_index_with_id(variant_id);
return ExprKind::Adt {
PatKind::TupleStruct(_, ref subpatterns, ddpos) => {
let pat_ty = self.cx.tcx.node_id_to_type(pat.id);
let adt_def = match pat_ty.sty {
- ty::TyStruct(adt_def, _) | ty::TyEnum(adt_def, _) => adt_def,
- _ => span_bug!(pat.span, "tuple struct pattern not applied to struct or enum"),
+ ty::TyAdt(adt_def, _) => adt_def,
+ _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"),
};
let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id));
PatKind::Struct(_, ref fields, _) => {
let pat_ty = self.cx.tcx.node_id_to_type(pat.id);
let adt_def = match pat_ty.sty {
- ty::TyStruct(adt_def, _) |
- ty::TyUnion(adt_def, _) |
- ty::TyEnum(adt_def, _) => adt_def,
+ ty::TyAdt(adt_def, _) => adt_def,
_ => {
span_bug!(
pat.span,
- "struct pattern not applied to struct or enum");
+ "struct pattern not applied to an ADT");
}
};
let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id));
}
ProjectionElem::Downcast(adt_def1, index) =>
match base_ty.sty {
- ty::TyEnum(adt_def, substs) if adt_def == adt_def1 => {
+ ty::TyAdt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
if index >= adt_def.variants.len() {
LvalueTy::Ty {
ty: span_mirbug_and_err!(
(&adt_def.variants[variant_index], substs)
}
LvalueTy::Ty { ty } => match ty.sty {
- ty::TyStruct(adt_def, substs) |
- ty::TyUnion(adt_def, substs) |
- ty::TyEnum(adt_def, substs)
- if adt_def.is_univariant() => {
+ ty::TyAdt(adt_def, substs) if adt_def.is_univariant() => {
(&adt_def.variants[0], substs)
}
ty::TyTuple(tys) | ty::TyClosure(_, ty::ClosureSubsts {
StatementKind::SetDiscriminant{ ref lvalue, variant_index } => {
let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx);
let adt = match lvalue_type.sty {
- TypeVariants::TyEnum(adt, _) => adt,
+ TypeVariants::TyAdt(adt, _) if adt.is_enum() => adt,
_ => {
span_bug!(stmt.source_info.span,
"bad set discriminant ({:?} = {:?}): lhs is not an enum",
TerminatorKind::Switch { ref discr, adt_def, ref targets } => {
let discr_ty = discr.ty(mir, tcx).to_ty(tcx);
match discr_ty.sty {
- ty::TyEnum(def, _)
- if def == adt_def && adt_def.variants.len() == targets.len()
- => {},
+ ty::TyAdt(def, _) if def.is_enum() &&
+ def == adt_def &&
+ adt_def.variants.len() == targets.len()
+ => {},
_ => {
span_mirbug!(self, term, "bad Switch ({:?} on {:?})",
adt_def, discr_ty);
/// instead of producing errors.
fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node_ty: Ty<'tcx>) {
match node_ty.sty {
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) |
- ty::TyEnum(def, _) if def.has_dtor() => {
+ ty::TyAdt(def, _) if def.has_dtor() => {
v.add_qualif(ConstQualif::NEEDS_DROP);
}
_ => {}
// Checks that a field is in scope.
fn check_field(&mut self, span: Span, def: ty::AdtDef<'tcx>, field: ty::FieldDef<'tcx>) {
- if def.adt_kind() != ty::AdtKind::Enum &&
- !field.vis.is_accessible_from(self.curitem, &self.tcx.map) {
- let kind_descr = if def.adt_kind() == ty::AdtKind::Union { "union" } else { "struct" };
+ if !def.is_enum() && !field.vis.is_accessible_from(self.curitem, &self.tcx.map) {
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
- field.name, kind_descr, self.tcx.item_path_str(def.did))
+ field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
.span_label(span, &format!("field `{}` is private", field.name))
.emit();
}
// (i.e. `all_fields - fields`), just check them all,
// unless the ADT is a union, then unmentioned fields
// are not checked.
- if adt.adt_kind() == ty::AdtKind::Union {
+ if adt.is_union() {
for expr_field in expr_fields {
self.check_field(expr.span, adt, variant.field_named(expr_field.name.node));
}
}
PatKind::TupleStruct(_, ref fields, ddpos) => {
match self.tcx.pat_ty(pattern).sty {
- ty::TyStruct(def, _) => {
+ // enum fields have no privacy at this time
+ ty::TyAdt(def, _) if !def.is_enum() => {
let expected_len = def.struct_variant().fields.len();
for (i, field) in fields.iter().enumerate_and_adjust(expected_len, ddpos) {
if let PatKind::Wild = field.node {
self.check_field(field.span, def, &def.struct_variant().fields[i]);
}
}
- ty::TyEnum(..) => {
- // enum fields have no privacy at this time
- }
_ => {}
}
}
};
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
match *ty {
- ty::TyStruct(def, _) => {
+ ty::TyAdt(def, _) => {
let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);
if !self.span.filter_generated(sub_span, ex.span) {
self.dumper.variable_ref(VariableRefData {
}
};
match self.tcx.expr_ty_adjusted(&hir_node).sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) if !def.is_enum() => {
let f = def.struct_variant().field_named(ident.node.name);
let sub_span = self.span_utils.span_for_last_ident(expr.span);
filter!(self.span_utils, sub_span, expr.span, None);
}));
}
_ => {
- debug!("Expected struct type, found {:?}", ty);
+ debug!("Expected struct or union type, found {:?}", ty);
None
}
}
}
ast::ExprKind::Struct(ref path, ..) => {
match self.tcx.expr_ty_adjusted(&hir_node).sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) if !def.is_enum() => {
let sub_span = self.span_utils.span_for_last_ident(path.span);
filter!(self.span_utils, sub_span, path.span, None);
Some(Data::TypeRefData(TypeRefData {
}))
}
_ => {
- // FIXME ty could legitimately be a TyEnum, but then we will fail
+ // FIXME ty could legitimately be an enum, but then we will fail
// later if we try to look up the fields.
- debug!("expected TyStruct, found {:?}", ty);
+ debug!("expected struct or union, found {:?}", ty);
None
}
}
use llvm::{ValueRef, True, IntEQ, IntNE};
use rustc::ty::subst::Substs;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, Ty, TyCtxt};
use syntax::ast;
use syntax::attr;
use syntax::attr::IntType;
ty::TyTuple(ref elems) => {
Univariant(mk_struct(cx, &elems[..], false, t))
}
- ty::TyStruct(def, substs) => {
- let ftys = def.struct_variant().fields.iter().map(|field| {
- monomorphize::field_ty(cx.tcx(), substs, field)
- }).collect::<Vec<_>>();
- let packed = cx.tcx().lookup_packed(def.did);
-
- Univariant(mk_struct(cx, &ftys[..], packed, t))
- }
- ty::TyUnion(def, substs) => {
- let ftys = def.struct_variant().fields.iter().map(|field| {
- monomorphize::field_ty(cx.tcx(), substs, field)
- }).collect::<Vec<_>>();
- let packed = cx.tcx().lookup_packed(def.did);
- UntaggedUnion(mk_union(cx, &ftys[..], packed, t))
- }
ty::TyClosure(_, ref substs) => {
Univariant(mk_struct(cx, &substs.upvar_tys, false, t))
}
- ty::TyEnum(def, substs) => {
- let cases = get_cases(cx.tcx(), def, substs);
- let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
- .unwrap_or(&attr::ReprAny);
-
- if cases.is_empty() {
- // Uninhabitable; represent as unit
- // (Typechecking will reject discriminant-sizing attrs.)
- assert_eq!(hint, attr::ReprAny);
- return Univariant(mk_struct(cx, &[], false, t));
+ ty::TyAdt(def, substs) => match def.adt_kind() {
+ AdtKind::Struct => {
+ let ftys = def.struct_variant().fields.iter().map(|field| {
+ monomorphize::field_ty(cx.tcx(), substs, field)
+ }).collect::<Vec<_>>();
+ let packed = cx.tcx().lookup_packed(def.did);
+
+ Univariant(mk_struct(cx, &ftys[..], packed, t))
}
-
- if cases.iter().all(|c| c.tys.is_empty()) {
- // All bodies empty -> intlike
- let discrs: Vec<_> = cases.iter().map(|c| Disr::from(c.discr)).collect();
- let bounds = IntBounds {
- ulo: discrs.iter().min().unwrap().0,
- uhi: discrs.iter().max().unwrap().0,
- slo: discrs.iter().map(|n| n.0 as i64).min().unwrap(),
- shi: discrs.iter().map(|n| n.0 as i64).max().unwrap()
- };
- return mk_cenum(cx, hint, &bounds);
+ AdtKind::Union => {
+ let ftys = def.struct_variant().fields.iter().map(|field| {
+ monomorphize::field_ty(cx.tcx(), substs, field)
+ }).collect::<Vec<_>>();
+ let packed = cx.tcx().lookup_packed(def.did);
+ UntaggedUnion(mk_union(cx, &ftys[..], packed, t))
}
+ AdtKind::Enum => {
+ let cases = get_cases(cx.tcx(), def, substs);
+ let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
+ .unwrap_or(&attr::ReprAny);
+
+ if cases.is_empty() {
+ // Uninhabitable; represent as unit
+ // (Typechecking will reject discriminant-sizing attrs.)
+ assert_eq!(hint, attr::ReprAny);
+ return Univariant(mk_struct(cx, &[], false, t));
+ }
- // Since there's at least one
- // non-empty body, explicit discriminants should have
- // been rejected by a checker before this point.
- if !cases.iter().enumerate().all(|(i,c)| c.discr == Disr::from(i)) {
- bug!("non-C-like enum {} with specified discriminants",
- cx.tcx().item_path_str(def.did));
- }
+ if cases.iter().all(|c| c.tys.is_empty()) {
+ // All bodies empty -> intlike
+ let discrs: Vec<_> = cases.iter().map(|c| Disr::from(c.discr)).collect();
+ let bounds = IntBounds {
+ ulo: discrs.iter().min().unwrap().0,
+ uhi: discrs.iter().max().unwrap().0,
+ slo: discrs.iter().map(|n| n.0 as i64).min().unwrap(),
+ shi: discrs.iter().map(|n| n.0 as i64).max().unwrap()
+ };
+ return mk_cenum(cx, hint, &bounds);
+ }
- if cases.len() == 1 && hint == attr::ReprAny {
- // Equivalent to a struct/tuple/newtype.
- return Univariant(mk_struct(cx, &cases[0].tys, false, t));
- }
+ // Since there's at least one
+ // non-empty body, explicit discriminants should have
+ // been rejected by a checker before this point.
+ if !cases.iter().enumerate().all(|(i,c)| c.discr == Disr::from(i)) {
+ bug!("non-C-like enum {} with specified discriminants",
+ cx.tcx().item_path_str(def.did));
+ }
- if cases.len() == 2 && hint == attr::ReprAny {
- // Nullable pointer optimization
- let mut discr = 0;
- while discr < 2 {
- if cases[1 - discr].is_zerolen(cx, t) {
- let st = mk_struct(cx, &cases[discr].tys,
- false, t);
- match cases[discr].find_ptr(cx) {
- Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
- return RawNullablePointer {
- nndiscr: Disr::from(discr),
- nnty: st.fields[0],
- nullfields: cases[1 - discr].tys.clone()
- };
- }
- Some(mut discrfield) => {
- discrfield.push(0);
- discrfield.reverse();
- return StructWrappedNullablePointer {
- nndiscr: Disr::from(discr),
- nonnull: st,
- discrfield: discrfield,
- nullfields: cases[1 - discr].tys.clone()
- };
+ if cases.len() == 1 && hint == attr::ReprAny {
+ // Equivalent to a struct/tuple/newtype.
+ return Univariant(mk_struct(cx, &cases[0].tys, false, t));
+ }
+
+ if cases.len() == 2 && hint == attr::ReprAny {
+ // Nullable pointer optimization
+ let mut discr = 0;
+ while discr < 2 {
+ if cases[1 - discr].is_zerolen(cx, t) {
+ let st = mk_struct(cx, &cases[discr].tys,
+ false, t);
+ match cases[discr].find_ptr(cx) {
+ Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
+ return RawNullablePointer {
+ nndiscr: Disr::from(discr),
+ nnty: st.fields[0],
+ nullfields: cases[1 - discr].tys.clone()
+ };
+ }
+ Some(mut discrfield) => {
+ discrfield.push(0);
+ discrfield.reverse();
+ return StructWrappedNullablePointer {
+ nndiscr: Disr::from(discr),
+ nonnull: st,
+ discrfield: discrfield,
+ nullfields: cases[1 - discr].tys.clone()
+ };
+ }
+ None => {}
}
- None => {}
}
+ discr += 1;
}
- discr += 1;
}
- }
- // The general case.
- assert!((cases.len() - 1) as i64 >= 0);
- let bounds = IntBounds { ulo: 0, uhi: (cases.len() - 1) as u64,
- slo: 0, shi: (cases.len() - 1) as i64 };
- let min_ity = range_to_inttype(cx, hint, &bounds);
-
- // Create the set of structs that represent each variant
- // Use the minimum integer type we figured out above
- let fields : Vec<_> = cases.iter().map(|c| {
- let mut ftys = vec!(ty_of_inttype(cx.tcx(), min_ity));
- ftys.extend_from_slice(&c.tys);
- mk_struct(cx, &ftys, false, t)
- }).collect();
-
-
- // Check to see if we should use a different type for the
- // discriminant. If the overall alignment of the type is
- // the same as the first field in each variant, we can safely use
- // an alignment-sized type.
- // We increase the size of the discriminant to avoid LLVM copying
- // padding when it doesn't need to. This normally causes unaligned
- // load/stores and excessive memcpy/memset operations. By using a
- // bigger integer size, LLVM can be sure about it's contents and
- // won't be so conservative.
- // This check is needed to avoid increasing the size of types when
- // the alignment of the first field is smaller than the overall
- // alignment of the type.
- let (_, align) = union_size_and_align(&fields);
- let mut use_align = true;
- for st in &fields {
- // Get the first non-zero-sized field
- let field = st.fields.iter().skip(1).filter(|ty| {
- let t = type_of::sizing_type_of(cx, **ty);
- machine::llsize_of_real(cx, t) != 0 ||
- // This case is only relevant for zero-sized types with large alignment
- machine::llalign_of_min(cx, t) != 1
- }).next();
-
- if let Some(field) = field {
- let field_align = type_of::align_of(cx, *field);
- if field_align != align {
- use_align = false;
- break;
+ // The general case.
+ assert!((cases.len() - 1) as i64 >= 0);
+ let bounds = IntBounds { ulo: 0, uhi: (cases.len() - 1) as u64,
+ slo: 0, shi: (cases.len() - 1) as i64 };
+ let min_ity = range_to_inttype(cx, hint, &bounds);
+
+ // Create the set of structs that represent each variant
+ // Use the minimum integer type we figured out above
+ let fields : Vec<_> = cases.iter().map(|c| {
+ let mut ftys = vec!(ty_of_inttype(cx.tcx(), min_ity));
+ ftys.extend_from_slice(&c.tys);
+ mk_struct(cx, &ftys, false, t)
+ }).collect();
+
+
+ // Check to see if we should use a different type for the
+ // discriminant. If the overall alignment of the type is
+ // the same as the first field in each variant, we can safely use
+ // an alignment-sized type.
+ // We increase the size of the discriminant to avoid LLVM copying
+ // padding when it doesn't need to. This normally causes unaligned
+ // load/stores and excessive memcpy/memset operations. By using a
+ // bigger integer size, LLVM can be sure about it's contents and
+ // won't be so conservative.
+ // This check is needed to avoid increasing the size of types when
+ // the alignment of the first field is smaller than the overall
+ // alignment of the type.
+ let (_, align) = union_size_and_align(&fields);
+ let mut use_align = true;
+ for st in &fields {
+ // Get the first non-zero-sized field
+ let field = st.fields.iter().skip(1).filter(|ty| {
+ let t = type_of::sizing_type_of(cx, **ty);
+ machine::llsize_of_real(cx, t) != 0 ||
+ // This case is only relevant for zero-sized types with large alignment
+ machine::llalign_of_min(cx, t) != 1
+ }).next();
+
+ if let Some(field) = field {
+ let field_align = type_of::align_of(cx, *field);
+ if field_align != align {
+ use_align = false;
+ break;
+ }
}
}
- }
- // If the alignment is smaller than the chosen discriminant size, don't use the
- // alignment as the final size.
- let min_ty = ll_inttype(&cx, min_ity);
- let min_size = machine::llsize_of_real(cx, min_ty);
- if (align as u64) < min_size {
- use_align = false;
- }
-
- let ity = if use_align {
- // Use the overall alignment
- match align {
- 1 => attr::UnsignedInt(ast::UintTy::U8),
- 2 => attr::UnsignedInt(ast::UintTy::U16),
- 4 => attr::UnsignedInt(ast::UintTy::U32),
- 8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
- attr::UnsignedInt(ast::UintTy::U64),
- _ => min_ity // use min_ity as a fallback
+ // If the alignment is smaller than the chosen discriminant size, don't use the
+ // alignment as the final size.
+ let min_ty = ll_inttype(&cx, min_ity);
+ let min_size = machine::llsize_of_real(cx, min_ty);
+ if (align as u64) < min_size {
+ use_align = false;
}
- } else {
- min_ity
- };
- let fields : Vec<_> = cases.iter().map(|c| {
- let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
- ftys.extend_from_slice(&c.tys);
- mk_struct(cx, &ftys[..], false, t)
- }).collect();
+ let ity = if use_align {
+ // Use the overall alignment
+ match align {
+ 1 => attr::UnsignedInt(ast::UintTy::U8),
+ 2 => attr::UnsignedInt(ast::UintTy::U16),
+ 4 => attr::UnsignedInt(ast::UintTy::U32),
+ 8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
+ attr::UnsignedInt(ast::UintTy::U64),
+ _ => min_ity // use min_ity as a fallback
+ }
+ } else {
+ min_ity
+ };
- ensure_enum_fits_in_address_space(cx, &fields[..], t);
+ let fields : Vec<_> = cases.iter().map(|c| {
+ let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
+ ftys.extend_from_slice(&c.tys);
+ mk_struct(cx, &ftys[..], false, t)
+ }).collect();
- General(ity, fields)
- }
+ ensure_enum_fits_in_address_space(cx, &fields[..], t);
+
+ General(ity, fields)
+ }
+ },
_ => bug!("adt::represent_type called on non-ADT type: {}", t)
}
}
ty::TyFnPtr(_) => Some(path),
// Is this the NonZero lang item wrapping a pointer or integer type?
- ty::TyStruct(def, substs) if Some(def.did) == tcx.lang_items.non_zero() => {
+ ty::TyAdt(def, substs) if Some(def.did) == tcx.lang_items.non_zero() => {
let nonzero_fields = &def.struct_variant().fields;
assert_eq!(nonzero_fields.len(), 1);
let field_ty = monomorphize::field_ty(tcx, substs, &nonzero_fields[0]);
// Perhaps one of the fields of this struct is non-zero
// let's recurse and find out
- ty::TyStruct(def, substs) => {
+ ty::TyAdt(def, substs) if def.is_struct() => {
for (j, field) in def.struct_variant().fields.iter().enumerate() {
let field_ty = monomorphize::field_ty(tcx, substs, field);
if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) {
}
// This can be extended to enums and tuples in the future.
- // (&ty::TyEnum(def_id_a, _), &ty::TyEnum(def_id_b, _)) |
- (&ty::TyStruct(def_a, _), &ty::TyStruct(def_b, _)) => {
+ (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => {
assert_eq!(def_a, def_b);
let src_repr = adt::represent_type(bcx.ccx(), src_ty);
// If the type implements Drop, also add a translation item for the
// monomorphized Drop::drop() implementation.
let destructor_did = match ty.sty {
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) |
- ty::TyEnum(def, _) => def.destructor(),
+ ty::TyAdt(def, _) => def.destructor(),
_ => None
};
ty::TyTrait(_) => {
/* nothing to do */
}
- ty::TyStruct(ref adt_def, substs) |
- ty::TyUnion(ref adt_def, substs) |
- ty::TyEnum(ref adt_def, substs) => {
+ ty::TyAdt(adt_def, substs) => {
for field in adt_def.all_fields() {
let field_type = monomorphize::apply_param_substs(scx,
substs,
}
}
- (&ty::TyStruct(source_adt_def, source_substs),
- &ty::TyStruct(target_adt_def, target_substs)) => {
+ (&ty::TyAdt(source_adt_def, source_substs),
+ &ty::TyAdt(target_adt_def, target_substs)) => {
assert_eq!(source_adt_def, target_adt_def);
let kind = custom_coerce_unsize_info(scx, source_ty, target_ty);
return false;
}
match ty.sty {
- ty::TyStruct(..) | ty::TyUnion(..) | ty::TyEnum(..) |
- ty::TyTuple(..) | ty::TyArray(..) | ty::TyClosure(..) => {
+ ty::TyAdt(..) | ty::TyTuple(..) | ty::TyArray(..) | ty::TyClosure(..) => {
let llty = sizing_type_of(ccx, ty);
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
}
pub fn type_pair_fields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
-> Option<[Ty<'tcx>; 2]> {
match ty.sty {
- ty::TyEnum(adt, substs) | ty::TyStruct(adt, substs) => {
+ ty::TyAdt(adt, substs) => {
assert_eq!(adt.variants.len(), 1);
let fields = &adt.variants[0].fields;
if fields.len() != 2 {
-> Self
{
match ty.sty {
- ty::TyStruct(adt, substs) | ty::TyUnion(adt, substs) | ty::TyEnum(adt, substs) => {
+ ty::TyAdt(adt, substs) => {
let variant = match opt_def {
None => adt.struct_variant(),
Some(def) => adt.variant_of_def(def)
let def_ids: Vec<DefId> =
key.walk()
.filter_map(|t| match t.sty {
- ty::TyStruct(adt_def, _) |
- ty::TyEnum(adt_def, _) =>
- Some(adt_def.did),
- ty::TyProjection(ref proj) =>
- Some(proj.trait_ref.def_id),
- _ =>
- None
+ ty::TyAdt(adt_def, _) => Some(adt_def.did),
+ ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
+ _ => None,
})
.collect();
DepNode::TraitSelect(def_ids)
use {type_of, adt, machine, monomorphize};
use common::CrateContext;
use type_::Type;
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, AdtKind, Ty};
use session::config;
use util::nodemap::FnvHashMap;
use util::common::path2cstr;
ty::TyFloat(_) => {
push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
},
- ty::TyEnum(def, substs) => {
- unique_type_id.push_str("enum ");
+ ty::TyAdt(def, substs) => {
+ unique_type_id.push_str(&(String::from(def.descr()) + " "));
from_def_id_and_substs(self, cx, def.did, substs, &mut unique_type_id);
- },
- ty::TyStruct(def, substs) => {
- unique_type_id.push_str("struct ");
- from_def_id_and_substs(self, cx, def.did, substs, &mut unique_type_id);
- },
- ty::TyUnion(def, substs) => {
- unique_type_id.push_str("union ");
- from_def_id_and_substs(self, cx, def.did, substs, &mut unique_type_id);
- },
+ }
ty::TyTuple(component_types) if component_types.is_empty() => {
push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
},
ty::TyTuple(ref elements) if elements.is_empty() => {
MetadataCreationResult::new(basic_type_metadata(cx, t), false)
}
- ty::TyEnum(def, _) => {
- prepare_enum_metadata(cx,
- t,
- def.did,
- unique_type_id,
- usage_site_span).finalize(cx)
- }
ty::TyArray(typ, len) => {
fixed_vec_metadata(cx, unique_type_id, typ, Some(len as u64), usage_site_span)
}
unique_type_id,
usage_site_span).finalize(cx)
}
- ty::TyStruct(..) => {
- prepare_struct_metadata(cx,
+ ty::TyAdt(def, ..) => match def.adt_kind() {
+ AdtKind::Struct => {
+ prepare_struct_metadata(cx,
+ t,
+ unique_type_id,
+ usage_site_span).finalize(cx)
+ }
+ AdtKind::Union => {
+ prepare_union_metadata(cx,
t,
unique_type_id,
usage_site_span).finalize(cx)
- }
- ty::TyUnion(..) => {
- prepare_union_metadata(cx,
- t,
- unique_type_id,
- usage_site_span).finalize(cx)
- }
+ }
+ AdtKind::Enum => {
+ prepare_enum_metadata(cx,
+ t,
+ def.did,
+ unique_type_id,
+ usage_site_span).finalize(cx)
+ }
+ },
ty::TyTuple(ref elements) => {
prepare_tuple_metadata(cx,
t,
let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);
let (struct_def_id, variant, substs) = match struct_type.sty {
- ty::TyStruct(def, substs) => (def.did, def.struct_variant(), substs),
- _ => bug!("prepare_struct_metadata on a non-struct")
+ ty::TyAdt(def, substs) => (def.did, def.struct_variant(), substs),
+ _ => bug!("prepare_struct_metadata on a non-ADT")
};
let (containing_scope, _) = get_namespace_and_span_for_item(cx, struct_def_id);
let union_llvm_type = type_of::in_memory_type_of(cx, union_type);
let (union_def_id, variant, substs) = match union_type.sty {
- ty::TyUnion(def, substs) => (def.did, def.struct_variant(), substs),
- _ => bug!("prepare_union_metadata on a non-union")
+ ty::TyAdt(def, substs) => (def.did, def.struct_variant(), substs),
+ _ => bug!("prepare_union_metadata on a non-ADT")
};
let (containing_scope, _) = get_namespace_and_span_for_item(cx, union_def_id);
// Only "class" methods are generally understood by LLVM,
// so avoid methods on other types (e.g. `<*mut T>::null`).
match impl_self_ty.sty {
- ty::TyStruct(..) | ty::TyUnion(..) | ty::TyEnum(..) => {
+ ty::TyAdt(..) => {
Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP))
}
_ => None
ty::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
- ty::TyStruct(def, substs) |
- ty::TyUnion(def, substs) |
- ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
push_item_name(cx, def.did, qualified, output);
push_type_params(cx, substs, output);
},
use middle::lang_items::ExchangeFreeFnLangItem;
use rustc::ty::subst::{Substs};
use rustc::traits;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
use adt;
use base::*;
use build::*;
return (C_undef(llty), C_undef(llty));
}
match t.sty {
- ty::TyStruct(def, substs) => {
+ ty::TyAdt(def, substs) => {
let ccx = bcx.ccx();
// First get the size of all statically known fields.
// Don't use type_of::sizing_type_of because that expects t to be sized,
DebugLoc::None);
bcx
}
- ty::TyStruct(def, _) | ty::TyEnum(def, _)
- if def.dtor_kind().is_present() && !skip_dtor => {
- trans_custom_dtor(bcx, t, v0, false)
+ ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => {
+ trans_custom_dtor(bcx, t, v0, def.is_union())
}
- ty::TyUnion(def, _) => {
- if def.dtor_kind().is_present() && !skip_dtor {
- trans_custom_dtor(bcx, t, v0, true)
- } else {
- bcx
- }
+ ty::TyAdt(def, ..) if def.is_union() => {
+ bcx
}
_ => {
if bcx.fcx.type_needs_drop(t) {
let mut cx = cx;
match t.sty {
- ty::TyStruct(..) => {
- let repr = adt::represent_type(cx.ccx(), t);
- let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
- for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
- let llfld_a = adt::trans_field_ptr(cx, &repr, value, Disr::from(discr), i);
-
- let val = if type_is_sized(cx.tcx(), field_ty) {
- llfld_a
- } else {
- let scratch = alloc_ty(cx, field_ty, "__fat_ptr_iter");
- Store(cx, llfld_a, get_dataptr(cx, scratch));
- Store(cx, value.meta, get_meta(cx, scratch));
- scratch
- };
- cx = drop_ty(cx, val, field_ty, DebugLoc::None);
- }
- }
ty::TyClosure(_, ref substs) => {
let repr = adt::represent_type(cx.ccx(), t);
for (i, upvar_ty) in substs.upvar_tys.iter().enumerate() {
cx = drop_ty(cx, llfld_a, *arg, DebugLoc::None);
}
}
- ty::TyEnum(en, substs) => {
- let fcx = cx.fcx;
- let ccx = fcx.ccx;
-
- let repr = adt::represent_type(ccx, t);
- let n_variants = en.variants.len();
-
- // NB: we must hit the discriminant first so that structural
- // comparison know not to proceed when the discriminants differ.
-
- match adt::trans_switch(cx, &repr, av, false) {
- (adt::BranchKind::Single, None) => {
- if n_variants != 0 {
- assert!(n_variants == 1);
- cx = iter_variant(cx, &repr, adt::MaybeSizedValue::sized(av),
- &en.variants[0], substs);
- }
+ ty::TyAdt(adt, substs) => match adt.adt_kind() {
+ AdtKind::Struct => {
+ let repr = adt::represent_type(cx.ccx(), t);
+ let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
+ for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
+ let llfld_a = adt::trans_field_ptr(cx, &repr, value, Disr::from(discr), i);
+
+ let val = if type_is_sized(cx.tcx(), field_ty) {
+ llfld_a
+ } else {
+ let scratch = alloc_ty(cx, field_ty, "__fat_ptr_iter");
+ Store(cx, llfld_a, get_dataptr(cx, scratch));
+ Store(cx, value.meta, get_meta(cx, scratch));
+ scratch
+ };
+ cx = drop_ty(cx, val, field_ty, DebugLoc::None);
}
- (adt::BranchKind::Switch, Some(lldiscrim_a)) => {
- cx = drop_ty(cx, lldiscrim_a, cx.tcx().types.isize, DebugLoc::None);
-
- // Create a fall-through basic block for the "else" case of
- // the switch instruction we're about to generate. Note that
- // we do **not** use an Unreachable instruction here, even
- // though most of the time this basic block will never be hit.
- //
- // When an enum is dropped it's contents are currently
- // overwritten to DTOR_DONE, which means the discriminant
- // could have changed value to something not within the actual
- // range of the discriminant. Currently this function is only
- // used for drop glue so in this case we just return quickly
- // from the outer function, and any other use case will only
- // call this for an already-valid enum in which case the `ret
- // void` will never be hit.
- let ret_void_cx = fcx.new_block("enum-iter-ret-void");
- RetVoid(ret_void_cx, DebugLoc::None);
- let llswitch = Switch(cx, lldiscrim_a, ret_void_cx.llbb, n_variants);
- let next_cx = fcx.new_block("enum-iter-next");
-
- for variant in &en.variants {
- let variant_cx = fcx.new_block(&format!("enum-iter-variant-{}",
- &variant.disr_val
- .to_string()));
- let case_val = adt::trans_case(cx, &repr, Disr::from(variant.disr_val));
- AddCase(llswitch, case_val, variant_cx.llbb);
- let variant_cx = iter_variant(variant_cx,
- &repr,
- value,
- variant,
- substs);
- Br(variant_cx, next_cx.llbb, DebugLoc::None);
+ }
+ AdtKind::Union => {
+ bug!("Union in `glue::drop_structural_ty`");
+ }
+ AdtKind::Enum => {
+ let fcx = cx.fcx;
+ let ccx = fcx.ccx;
+
+ let repr = adt::represent_type(ccx, t);
+ let n_variants = adt.variants.len();
+
+ // NB: we must hit the discriminant first so that structural
+ // comparison know not to proceed when the discriminants differ.
+
+ match adt::trans_switch(cx, &repr, av, false) {
+ (adt::BranchKind::Single, None) => {
+ if n_variants != 0 {
+ assert!(n_variants == 1);
+ cx = iter_variant(cx, &repr, adt::MaybeSizedValue::sized(av),
+ &adt.variants[0], substs);
+ }
}
- cx = next_cx;
+ (adt::BranchKind::Switch, Some(lldiscrim_a)) => {
+ cx = drop_ty(cx, lldiscrim_a, cx.tcx().types.isize, DebugLoc::None);
+
+ // Create a fall-through basic block for the "else" case of
+ // the switch instruction we're about to generate. Note that
+ // we do **not** use an Unreachable instruction here, even
+ // though most of the time this basic block will never be hit.
+ //
+ // When an enum is dropped it's contents are currently
+ // overwritten to DTOR_DONE, which means the discriminant
+ // could have changed value to something not within the actual
+ // range of the discriminant. Currently this function is only
+ // used for drop glue so in this case we just return quickly
+ // from the outer function, and any other use case will only
+ // call this for an already-valid enum in which case the `ret
+ // void` will never be hit.
+ let ret_void_cx = fcx.new_block("enum-iter-ret-void");
+ RetVoid(ret_void_cx, DebugLoc::None);
+ let llswitch = Switch(cx, lldiscrim_a, ret_void_cx.llbb, n_variants);
+ let next_cx = fcx.new_block("enum-iter-next");
+
+ for variant in &adt.variants {
+ let variant_cx = fcx.new_block(&format!("enum-iter-variant-{}",
+ &variant.disr_val
+ .to_string()));
+ let case_val = adt::trans_case(cx, &repr, Disr::from(variant.disr_val));
+ AddCase(llswitch, case_val, variant_cx.llbb);
+ let variant_cx = iter_variant(variant_cx,
+ &repr,
+ value,
+ variant,
+ substs);
+ Br(variant_cx, next_cx.llbb, DebugLoc::None);
+ }
+ cx = next_cx;
+ }
+ _ => ccx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
}
- _ => ccx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
}
- }
+ },
+
_ => {
cx.sess().unimpl(&format!("type in drop_structural_ty: {}", t))
}
(_, "discriminant_value") => {
let val_ty = substs.type_at(0);
match val_ty.sty {
- ty::TyEnum(..) => {
+ ty::TyAdt(adt, ..) if adt.is_enum() => {
let repr = adt::represent_type(ccx, val_ty);
adt::trans_get_discr(bcx, &repr, llargs[0],
Some(llret_ty), true)
ty::TyUint(ast::UintTy::U64) => output.push_str("u64"),
ty::TyFloat(ast::FloatTy::F32) => output.push_str("f32"),
ty::TyFloat(ast::FloatTy::F64) => output.push_str("f64"),
- ty::TyStruct(adt_def, substs) |
- ty::TyUnion(adt_def, substs) |
- ty::TyEnum(adt_def, substs) => {
+ ty::TyAdt(adt_def, substs) => {
push_item_name(tcx, adt_def.did, output);
push_type_params(tcx, substs, &[], output);
},
Type::nil(cx)
}
- ty::TyStruct(..) if t.is_simd() => {
+ ty::TyAdt(..) if t.is_simd() => {
let e = t.simd_type(cx.tcx());
if !e.is_machine() {
cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \
Type::vector(&llet, n)
}
- ty::TyTuple(..) | ty::TyStruct(..) | ty::TyUnion(..) |
- ty::TyEnum(..) | ty::TyClosure(..) => {
+ ty::TyTuple(..) | ty::TyAdt(..) | ty::TyClosure(..) => {
let repr = adt::represent_type(cx, t);
adt::sizing_type_of(cx, &repr, false)
}
let repr = adt::represent_type(cx, t);
adt::type_of(cx, &repr)
}
- ty::TyStruct(..) if t.is_simd() => {
+ ty::TyAdt(..) if t.is_simd() => {
let e = t.simd_type(cx.tcx());
if !e.is_machine() {
cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \
ensure_array_fits_in_address_space(cx, llet, n, t);
Type::vector(&llet, n)
}
- ty::TyStruct(def, ref substs) |
- ty::TyUnion(def, ref substs) |
- ty::TyEnum(def, ref substs) => {
+ ty::TyAdt(def, substs) => {
// Only create the named struct, but don't fill it in. We
// fill it in *after* placing it into the type cache. This
// avoids creating more than one copy of the enum when one
// If this was an enum or struct, fill in the type now.
match t.sty {
- ty::TyEnum(..) | ty::TyStruct(..) | ty::TyUnion(..) | ty::TyClosure(..)
- if !t.is_simd() => {
+ ty::TyAdt(..) | ty::TyClosure(..) if !t.is_simd() => {
let repr = adt::represent_type(cx, t);
adt::finish_type_of(cx, &repr, &mut llty);
}
if subpats.len() == variant.fields.len() ||
subpats.len() < variant.fields.len() && ddpos.is_some() {
let substs = match pat_ty.sty {
- ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
+ ty::TyAdt(_, substs) => substs,
ref ty => bug!("unexpected pattern type {:?}", ty),
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
let tcx = self.tcx;
let (substs, kind_name) = match adt_ty.sty {
- ty::TyEnum(_, substs) => (substs, "variant"),
- ty::TyStruct(_, substs) => (substs, "struct"),
- ty::TyUnion(_, substs) => (substs, "union"),
+ ty::TyAdt(adt, substs) => (substs, adt.variant_descr()),
_ => span_bug!(span, "struct pattern is not an ADT")
};
match t.sty {
ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length),
ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal.def_id())),
- ty::TyStruct(def, substs) => {
+ ty::TyAdt(def, substs) if def.is_struct() => {
// FIXME(arielb1): do some kind of normalization
match def.struct_variant().fields.last() {
None => None,
use rustc::infer;
use middle::region;
use rustc::ty::subst::{Subst, Substs};
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, Ty, TyCtxt};
use rustc::traits::{self, Reveal};
use util::nodemap::FnvHashSet;
let dtor_self_type = ccx.tcx.lookup_item_type(drop_impl_did).ty;
let dtor_predicates = ccx.tcx.lookup_predicates(drop_impl_did);
match dtor_self_type.sty {
- ty::TyEnum(adt_def, self_to_impl_substs) |
- ty::TyUnion(adt_def, self_to_impl_substs) |
- ty::TyStruct(adt_def, self_to_impl_substs) => {
+ ty::TyAdt(adt_def, self_to_impl_substs) => {
ensure_drop_params_and_item_params_correspond(ccx,
drop_impl_did,
dtor_self_type,
TypeContext::ADT { def_id, variant, field } => {
let adt = tcx.lookup_adt_def(def_id);
let variant_name = match adt.adt_kind() {
- ty::AdtKind::Enum => format!("enum {} variant {}",
- tcx.item_path_str(def_id),
- variant),
- ty::AdtKind::Struct => format!("struct {}",
- tcx.item_path_str(def_id)),
- ty::AdtKind::Union => format!("union {}",
- tcx.item_path_str(def_id)),
+ AdtKind::Enum => format!("enum {} variant {}",
+ tcx.item_path_str(def_id),
+ variant),
+ AdtKind::Struct => format!("struct {}",
+ tcx.item_path_str(def_id)),
+ AdtKind::Union => format!("union {}",
+ tcx.item_path_str(def_id)),
};
span_note!(
&mut err,
cx, context, ity, depth+1)
}
- ty::TyStruct(def, substs) if def.is_phantom_data() => {
+ ty::TyAdt(def, substs) if def.is_phantom_data() => {
// PhantomData<T> - behaves identically to T
let ity = substs.type_at(0);
iterate_over_potentially_unsafe_regions_in_type(
cx, context, ity, depth+1)
}
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
let did = def.did;
for variant in &def.variants {
for field in variant.fields.iter() {
fn has_dtor_of_interest<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty: Ty<'tcx>) -> bool {
match ty.sty {
- ty::TyEnum(def, _) | ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
def.is_dtorck(tcx)
}
ty::TyTrait(..) | ty::TyProjection(..) | ty::TyAnon(..) => {
self.assemble_inherent_candidates_from_object(self_ty, data.principal);
self.assemble_inherent_impl_candidates_for_type(data.principal.def_id());
}
- ty::TyEnum(def, _) |
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
self.assemble_inherent_impl_candidates_for_type(def.did);
}
ty::TyBox(_) => {
if let Some(expr) = rcvr_expr {
for (ty, _) in self.autoderef(span, rcvr_ty) {
match ty.sty {
- ty::TyStruct(def, substs) | ty::TyUnion(def, substs) => {
+ ty::TyAdt(def, substs) if !def.is_enum() => {
if let Some(field) = def.struct_variant().
find_field_named(item_name) {
let snippet = tcx.sess.codemap().span_to_snippet(expr.span);
rcvr_expr: Option<&hir::Expr>) -> bool {
fn is_local(ty: Ty) -> bool {
match ty.sty {
- ty::TyEnum(def, _) | ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
- def.did.is_local()
- }
+ ty::TyAdt(def, _) => def.did.is_local(),
ty::TyTrait(ref tr) => tr.principal.def_id().is_local(),
pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) {
let t = tcx.node_id_to_type(id);
match t.sty {
- ty::TyStruct(def, substs) => {
+ ty::TyAdt(def, substs) if def.is_struct() => {
let fields = &def.struct_variant().fields;
if fields.is_empty() {
span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
let mut autoderef = self.autoderef(expr.span, expr_t);
while let Some((base_t, autoderefs)) = autoderef.next() {
match base_t.sty {
- ty::TyStruct(base_def, substs) | ty::TyUnion(base_def, substs) => {
+ ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
debug!("struct named {:?}", base_t);
if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
let field_ty = self.field_ty(expr.span, field, substs);
field.node, actual)
}, expr_t);
match expr_t.sty {
- ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) if !def.is_enum() => {
if let Some(suggested_field_name) =
Self::suggest_field_name(def.struct_variant(), field, vec![]) {
err.span_help(field.span,
let mut autoderef = self.autoderef(expr.span, expr_t);
while let Some((base_t, autoderefs)) = autoderef.next() {
let field = match base_t.sty {
- ty::TyStruct(base_def, substs) => {
+ ty::TyAdt(base_def, substs) if base_def.is_struct() => {
tuple_like = base_def.struct_variant().kind == ty::VariantKind::Tuple;
if !tuple_like { continue }
kind_name: &str) {
let mut err = self.type_error_struct_with_diag(
field.name.span,
- |actual| if let ty::TyEnum(..) = ty.sty {
- struct_span_err!(self.tcx.sess, field.name.span, E0559,
- "{} `{}::{}` has no field named `{}`",
- kind_name, actual, variant.name.as_str(), field.name.node)
- } else {
- struct_span_err!(self.tcx.sess, field.name.span, E0560,
- "{} `{}` has no field named `{}`",
- kind_name, actual, field.name.node)
+ |actual| match ty.sty {
+ ty::TyAdt(adt, ..) if adt.is_enum() => {
+ struct_span_err!(self.tcx.sess, field.name.span, E0559,
+ "{} `{}::{}` has no field named `{}`",
+ kind_name, actual, variant.name.as_str(), field.name.node)
+ }
+ _ => {
+ struct_span_err!(self.tcx.sess, field.name.span, E0560,
+ "{} `{}` has no field named `{}`",
+ kind_name, actual, field.name.node)
+ }
},
ty);
// prevent all specified fields from being suggested
check_completeness: bool) {
let tcx = self.tcx;
let (substs, kind_name) = match adt_ty.sty {
- ty::TyEnum(_, substs) => (substs, "variant"),
- ty::TyStruct(_, substs) => (substs, "struct"),
- ty::TyUnion(_, substs) => (substs, "union"),
+ ty::TyAdt(adt, substs) => (substs, adt.variant_descr()),
_ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
};
}
Def::TyAlias(did) => {
match self.tcx.opt_lookup_item_type(did).map(|scheme| &scheme.ty.sty) {
- Some(&ty::TyStruct(adt, _)) |
- Some(&ty::TyUnion(adt, _)) => Some((did, adt.struct_variant())),
+ Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => {
+ Some((did, adt.struct_variant()))
+ }
_ => None,
}
}
if let &Some(ref base_expr) = base_expr {
self.check_expr_has_type(base_expr, struct_ty);
match struct_ty.sty {
- ty::TyStruct(adt, substs) => {
+ ty::TyAdt(adt, substs) if adt.is_struct() => {
self.tables.borrow_mut().fru_field_types.insert(
expr.id,
adt.struct_variant().fields.iter().map(|f| {
use rustc::traits::{self, Reveal};
use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId};
use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
-use rustc::ty::{Ty, TyBool, TyChar, TyEnum, TyError};
+use rustc::ty::{Ty, TyBool, TyChar, TyError};
use rustc::ty::{TyParam, TyRawPtr};
-use rustc::ty::{TyRef, TyStruct, TyUnion, TyTrait, TyNever, TyTuple};
+use rustc::ty::{TyRef, TyAdt, TyTrait, TyNever, TyTuple};
use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt};
use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr};
use rustc::ty::{TyProjection, TyAnon};
// Returns the def ID of the base type, if there is one.
fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
match ty.sty {
- TyEnum(def, _) |
- TyStruct(def, _) |
- TyUnion(def, _) => {
+ TyAdt(def, _) => {
Some(def.did)
}
let self_type = tcx.lookup_item_type(impl_did);
match self_type.ty.sty {
- ty::TyEnum(type_def, _) |
- ty::TyStruct(type_def, _) |
- ty::TyUnion(type_def, _) => {
+ ty::TyAdt(type_def, _) => {
type_def.set_destructor(method_def_id.def_id());
}
_ => {
check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
}
- (&ty::TyStruct(def_a, substs_a), &ty::TyStruct(def_b, substs_b)) => {
+ (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b))
+ if def_a.is_struct() && def_b.is_struct() => {
if def_a != def_b {
let source_path = tcx.item_path_str(def_a.did);
let target_path = tcx.item_path_str(def_b.did);
self.tcx.map.node_to_string(item.id));
let self_ty = self.tcx.lookup_item_type(def_id).ty;
match self_ty.sty {
- ty::TyEnum(def, _) |
- ty::TyStruct(def, _) |
- ty::TyUnion(def, _) => {
+ ty::TyAdt(def, _) => {
self.check_def_id(item, def.did);
}
ty::TyTrait(ref data) => {
{
let self_ty = trait_ref.self_ty();
let opt_self_def_id = match self_ty.sty {
- ty::TyStruct(self_def, _) |
- ty::TyUnion(self_def, _) |
- ty::TyEnum(self_def, _) =>
- Some(self_def.did),
- ty::TyBox(..) =>
- self.tcx.lang_items.owned_box(),
- _ =>
- None
+ ty::TyAdt(self_def, _) => Some(self_def.did),
+ ty::TyBox(..) => self.tcx.lang_items.owned_box(),
+ _ => None,
};
let msg = match opt_self_def_id {
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::Substs;
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
-use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
+use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
use rustc::ty::util::IntTypeExt;
use rscope::*;
let ctor_id = if !def.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) } else { None };
let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
ConstInt::Infer(0), def)];
- let adt = ccx.tcx.intern_adt_def(did, ty::AdtKind::Struct, variants);
+ let adt = ccx.tcx.intern_adt_def(did, AdtKind::Struct, variants);
if let Some(ctor_id) = ctor_id {
// Make adt definition available through constructor id as well.
ccx.tcx.insert_adt_def(ctor_id, adt);
{
let did = ccx.tcx.map.local_def_id(it.id);
let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
- ccx.tcx.intern_adt_def(did, ty::AdtKind::Union, variants)
+ ccx.tcx.intern_adt_def(did, AdtKind::Union, variants)
}
fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
let did = tcx.map.local_def_id(v.node.data.id());
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
}).collect();
- tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
+ tcx.intern_adt_def(tcx.map.local_def_id(it.id), AdtKind::Enum, variants)
}
/// Ensures that the super-predicates of the trait with def-id
ItemEnum(ref ei, ref generics) => {
let def = convert_enum_def(ccx, item, ei);
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
- ccx.tcx.mk_enum(def, substs)
+ ccx.tcx.mk_adt(def, substs)
}
ItemStruct(ref si, ref generics) => {
let def = convert_struct_def(ccx, item, si);
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
- ccx.tcx.mk_struct(def, substs)
+ ccx.tcx.mk_adt(def, substs)
}
ItemUnion(ref un, ref generics) => {
let def = convert_union_def(ccx, item, un);
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
- ccx.tcx.mk_union(def, substs)
+ ccx.tcx.mk_adt(def, substs)
}
ItemDefaultImpl(..) |
ItemTrait(..) |
}
}
- ty::TyEnum(def, substs) |
- ty::TyStruct(def, substs) |
- ty::TyUnion(def, substs) => {
+ ty::TyAdt(def, substs) => {
let item_type = self.tcx().lookup_item_type(def.did);
// This edge is actually implied by the call to
let t = tcx.lookup_item_type(did);
let predicates = tcx.lookup_predicates(did);
match t.ty.sty {
- ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
+ ty::TyAdt(edef, _) if edef.is_enum() && !tcx.sess.cstore.is_typedef(did) => {
return clean::EnumItem(clean::Enum {
generics: (t.generics, &predicates).clean(cx),
variants_stripped: false,
use rustc::hir::fold::Folder;
use rustc::hir::print as pprust;
use rustc::ty::subst::Substs;
-use rustc::ty;
+use rustc::ty::{self, AdtKind};
use rustc::middle::stability;
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
decl: (cx.map.local_def_id(0), &fty.sig).clean(cx),
abi: fty.abi,
}),
- ty::TyStruct(def, substs) |
- ty::TyUnion(def, substs) |
- ty::TyEnum(def, substs) => {
+ ty::TyAdt(def, substs) => {
let did = def.did;
- let kind = match self.sty {
- ty::TyStruct(..) => TypeStruct,
- ty::TyUnion(..) => TypeUnion,
- _ => TypeEnum,
+ let kind = match def.adt_kind() {
+ AdtKind::Struct => TypeStruct,
+ AdtKind::Union => TypeUnion,
+ AdtKind::Enum => TypeEnum,
};
inline::record_extern_fqn(cx, did, kind);
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
fn foo_method(&self) -> usize;
}
- // Tests TyStruct
+ // Tests struct
pub struct FooStruct {
pub pub_foo_field: usize,
foo_field: usize
}
- // Tests TyEnum
+ // Tests enum
pub enum FooEnum {
VarA(usize),
VarB(usize, usize)