Auto merge of #36331 - petrochenkov:tyadt, r=eddyb

Refactor `TyStruct`/`TyEnum`/`TyUnion` into `TyAdt`

r? @eddyb
This commit is contained in:
bors 2016-09-09 04:57:11 -07:00 committed by GitHub
commit f1f40f850e
77 changed files with 925 additions and 1072 deletions

View File

@ -488,10 +488,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// 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);
},
_ => ()

View File

@ -156,7 +156,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
ty::TyInt(..) |
ty::TyUint(..) |
ty::TyFloat(..) |
ty::TyEnum(..) |
ty::TyAdt(..) |
ty::TyBox(..) |
ty::TyStr |
ty::TyError |
@ -167,8 +167,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyTrait(..) |
ty::TyStruct(..) |
ty::TyUnion(..) |
ty::TyClosure(..) |
ty::TyNever |
ty::TyTuple(..) |

View File

@ -86,8 +86,6 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
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`
@ -95,11 +93,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
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);
}
}
}
@ -133,23 +128,27 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
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")

View File

@ -200,8 +200,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
}
}
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");
}
}
}
_ => {}
@ -212,9 +214,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
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");
}
}
}
}

View File

@ -671,28 +671,31 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
// 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");
}
}
}

View File

@ -223,8 +223,7 @@ fn deref_kind(t: Ty, context: DerefKindContext) -> McResult<deref_kind> {
Ok(deref_ptr(UnsafePtr(mt.mutbl)))
}
ty::TyEnum(..) |
ty::TyStruct(..) => { // newtype
ty::TyAdt(..) => { // newtype
Ok(deref_interior(InteriorField(PositionalField(0))))
}
@ -1154,7 +1153,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}
Def::Struct(..) => {
match self.pat_ty(&pat)?.sty {
ty::TyStruct(adt_def, _) => {
ty::TyAdt(adt_def, _) => {
adt_def.struct_variant().fields.len()
}
ref ty => {

View File

@ -20,7 +20,7 @@ use lint;
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};
@ -561,17 +561,19 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr,
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 \
@ -579,31 +581,28 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr,
}
}
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
@ -648,10 +647,9 @@ pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,
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)

View File

@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
LvalueTy::Ty { ty } =>
ty,
LvalueTy::Downcast { adt_def, substs, variant_index: _ } =>
tcx.mk_enum(adt_def, substs),
tcx.mk_adt(adt_def, substs),
}
}
@ -75,7 +75,8 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
}
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,
@ -83,7 +84,7 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
variant_index: index }
}
_ => {
bug!("cannot downcast non-enum type: `{:?}`", self)
bug!("cannot downcast non-ADT type: `{:?}`", self)
}
},
ProjectionElem::Field(_, fty) => LvalueTy::Ty { ty: fty }

View File

@ -224,7 +224,7 @@ fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool {
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"),
@ -260,9 +260,7 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)->
infer_is_local.0
}
ty::TyEnum(def, _) |
ty::TyStruct(def, _) |
ty::TyUnion(def, _) => {
ty::TyAdt(def, _) => {
def.did.is_local()
}

View File

@ -27,7 +27,7 @@ use super::{
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;
@ -151,32 +151,30 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
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

View File

@ -1638,7 +1638,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
(&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
}
@ -1780,8 +1780,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
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 {
@ -1837,8 +1836,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
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
}
@ -1930,11 +1928,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
// 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()
@ -2566,7 +2564,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
// 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())
@ -2621,7 +2619,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
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)

View File

@ -65,7 +65,7 @@ impl<'tcx> CastTy<'tcx> {
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)),

View File

@ -224,8 +224,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|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| {

View File

@ -27,7 +27,7 @@ use ty::subst::Substs;
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};
@ -620,7 +620,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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);
@ -1032,8 +1032,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
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());
@ -1227,9 +1227,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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> {
@ -1316,16 +1316,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, '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>,

View File

@ -216,7 +216,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'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(),
@ -244,12 +244,6 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
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(),

View File

@ -22,15 +22,13 @@ pub enum SimplifiedType {
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),
@ -57,19 +55,13 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
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
@ -79,7 +71,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
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),
}
}

View File

@ -102,7 +102,7 @@ impl FlagComputation {
}
}
&ty::TyEnum(_, substs) | &ty::TyStruct(_, substs) | &ty::TyUnion(_, substs) => {
&ty::TyAdt(_, substs) => {
self.add_substs(substs);
}

View File

@ -262,9 +262,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// 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 {
@ -320,9 +318,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// 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()),

View File

@ -555,7 +555,7 @@ impl<'a, 'gcx, 'tcx> Struct {
}
// 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)) => {
let fields = &def.struct_variant().fields;
assert_eq!(fields.len(), 1);
match *fields[0].ty(tcx, substs).layout(infcx)? {
@ -573,7 +573,7 @@ impl<'a, 'gcx, 'tcx> Struct {
// 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)
@ -694,7 +694,7 @@ pub enum Layout {
non_zero: bool
},
/// SIMD vectors, from TyStruct marked with #[repr(simd)].
/// SIMD vectors, from structs marked with #[repr(simd)].
Vector {
element: Primitive,
count: u64
@ -715,7 +715,7 @@ pub enum Layout {
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 {
@ -918,47 +918,26 @@ impl<'a, 'gcx, 'tcx> Layout {
Univariant { variant: st, non_zero: false }
}
// 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));
}
// SIMD vector types.
ty::TyAdt(def, ..) if def.is_simd() => {
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) => {
// ADTs.
ty::TyAdt(def, substs) => {
let hint = *tcx.lookup_repr_hints(def.did).get(0)
.unwrap_or(&attr::ReprAny);
@ -973,7 +952,7 @@ impl<'a, 'gcx, 'tcx> Layout {
});
}
if def.variants.iter().all(|v| v.fields.is_empty()) {
if def.is_enum() && 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 {
@ -991,28 +970,37 @@ impl<'a, 'gcx, 'tcx> Layout {
});
}
if def.variants.len() == 1 {
// Struct, or union, or univariant enum equivalent to a struct.
// (Typechecking will reject discriminant-sizing attrs.)
assert!(!def.is_enum() || hint == attr::ReprAny);
let fields = def.variants[0].fields.iter().map(|field| {
field.ty(tcx, substs).layout(infcx)
});
let packed = tcx.lookup_packed(def.did);
let layout = if def.is_union() {
let mut un = Union::new(dl, packed);
un.extend(dl, fields, ty)?;
UntaggedUnion { variants: un }
} else {
let mut st = Struct::new(dl, packed);
st.extend(dl, fields, ty)?;
let non_zero = Some(def.did) == tcx.lang_items.non_zero();
Univariant { variant: st, non_zero: non_zero }
};
return success(layout);
}
// 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));
tcx.item_path_str(def.did));
}
}
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<_>>()
@ -1042,8 +1030,8 @@ impl<'a, 'gcx, 'tcx> Layout {
}
_ => {
bug!("Layout::compute: `{}`'s non-zero \
`{}` field not scalar?!",
ty, variants[discr][0])
`{}` field not scalar?!",
ty, variants[discr][0])
}
}
}
@ -1317,9 +1305,9 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
}
}
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);
}

View File

@ -952,9 +952,7 @@ impl<'tcx> TraitPredicate<'tcx> {
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
@ -1573,18 +1571,49 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
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.
@ -1622,8 +1651,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
/// 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]
}
@ -1832,7 +1860,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
}
}
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);

View File

@ -172,9 +172,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
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)

View File

@ -414,11 +414,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
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)) =>
@ -440,20 +440,6 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
}))
}
(&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 =>

View File

@ -482,7 +482,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
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) => {
@ -494,8 +494,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
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)),
@ -516,7 +514,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
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) => {
@ -524,8 +522,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
}
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),

View File

@ -106,24 +106,13 @@ pub enum TypeVariants<'tcx> {
/// 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
@ -922,7 +911,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
// 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.
@ -950,7 +939,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
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
@ -985,8 +974,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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()
}
}
@ -994,7 +982,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
#[inline]
pub fn is_simd(&self) -> bool {
match self.sty {
TyStruct(def, _) => def.is_simd(),
TyAdt(def, _) => def.is_simd(),
_ => false
}
}
@ -1009,7 +997,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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")
@ -1018,7 +1006,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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")
}
}
@ -1203,9 +1191,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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
}
@ -1213,7 +1199,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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
}
}
@ -1231,10 +1217,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
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) => {

View File

@ -14,7 +14,7 @@ use hir::def_id::DefId;
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};
@ -138,28 +138,30 @@ impl<'tcx> ParameterEnvironment<'tcx> {
// 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)
};
@ -183,7 +185,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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 {
@ -203,16 +205,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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
@ -226,12 +224,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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
}
@ -256,7 +253,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// 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 {
while let TyAdt(def, substs) = ty.sty {
if !def.is_struct() {
break
}
match def.struct_variant().fields.last() {
Some(f) => ty = f.ty(self, substs),
None => break
@ -275,15 +275,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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;
while let (&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs)) = (&a.sty, &b.sty) {
if a_def != b_def || !a_def.is_struct() {
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;
match a_def.struct_variant().fields.last() {
Some(f) => {
a = f.ty(self, a_substs);
b = f.ty(self, b_substs);
}
_ => break
}
}
(a, b)
@ -431,9 +432,7 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
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),
@ -560,8 +559,8 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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));
@ -601,7 +600,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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));
@ -663,7 +662,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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,
@ -680,7 +679,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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
@ -689,9 +688,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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;
}
@ -713,7 +710,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
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();

View File

@ -93,10 +93,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
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) => {

View File

@ -336,9 +336,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
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);

View File

@ -11,7 +11,7 @@
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;
@ -868,7 +868,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
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) {

View File

@ -796,9 +796,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
}
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

View File

@ -21,7 +21,7 @@ use borrowck::LoanPathElem::{LpDeref, LpInterior};
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;
@ -422,8 +422,8 @@ fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
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(_) =>
@ -438,69 +438,68 @@ fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
}
}
(&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;
}
let field_name = mc::NamedField(field.name);
add_fragment_sibling_local(field_name, Some(variant.did));
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]
}
}
mc::PositionalField(tuple_idx) => {
for (i, _f) in variant.fields.iter().enumerate() {
if tuple_idx == i {
continue;
};
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));
}
}
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);
}
}
}

View File

@ -178,7 +178,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
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 {

View File

@ -148,9 +148,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
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",

View File

@ -103,8 +103,8 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
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 {
@ -124,9 +124,8 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
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))
}
}

View File

@ -709,7 +709,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
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 {
@ -893,7 +893,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
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,

View File

@ -261,7 +261,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
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

View File

@ -367,20 +367,22 @@ impl<'a, 'tcx> MoveData<'tcx> {
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;
}
}
@ -422,20 +424,23 @@ impl<'a, 'tcx> MoveData<'tcx> {
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;
}
}

View File

@ -245,21 +245,23 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
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();
}
}
}
}
@ -566,7 +568,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
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 => {
@ -659,7 +661,8 @@ fn all_constructors(_cx: &MatchCheckCtxt, left_ty: Ty,
[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]
}
}
@ -837,7 +840,7 @@ pub fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> us
_ => 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,

View File

@ -257,8 +257,11 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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,
@ -271,10 +274,6 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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 {
@ -1039,7 +1038,7 @@ fn infer<'a, 'tcx>(i: ConstInt,
(&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)
@ -1230,7 +1229,7 @@ fn lit_to_const<'a, 'tcx>(lit: &ast::LitKind,
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)

View File

@ -468,21 +468,21 @@ impl LateLintPass for MissingCopyImplementations {
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,
};

View File

@ -12,7 +12,7 @@
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;
@ -431,110 +431,112 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
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");
}
// 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); }
}
}
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");
}
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
}
ty::TyEnum(def, substs) => {
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")
}
}
&[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.
ty::TyAdt(def, substs) => match def.adt_kind() {
AdtKind::Struct => {
if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
return FfiUnsafe(
"enum has too many #[repr(...)] attributes");
"found struct without foreign-function-safe \
representation annotation in foreign module, \
consider adding a #[repr(C)] attribute to \
the type");
}
}
// 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);
// 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 FfiBadEnum(def.did, s); }
FfiUnsafe(s) => { return FfiBadStruct(def.did, s); }
}
}
FfiSafe
}
FfiSafe
}
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); }
}
}
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")
}
}
&[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 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); }
}
}
}
FfiSafe
}
},
ty::TyChar => {
FfiUnsafe("found Rust type `char` in foreign module, while \

View File

@ -136,9 +136,7 @@ impl LateLintPass for UnusedResults {
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)
}

View File

@ -36,7 +36,7 @@ use rustc::hir::def::Def;
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;
@ -453,23 +453,19 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
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);
@ -481,8 +477,7 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
// 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 {:?}",

View File

@ -358,14 +358,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
'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());
@ -470,15 +462,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
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(), '[');

View File

@ -97,11 +97,6 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
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);
@ -165,16 +160,11 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
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);

View File

@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
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

View File

@ -19,7 +19,7 @@ use rustc::hir::def::Def;
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;
@ -459,48 +459,50 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
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());
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
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,
@ -579,13 +581,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
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!(
@ -680,7 +679,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
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,
@ -694,7 +693,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// 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 {

View File

@ -198,8 +198,8 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
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));
@ -217,13 +217,11 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
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));

View File

@ -218,7 +218,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}
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!(
@ -281,10 +281,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
(&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 {
@ -364,7 +361,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
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",
@ -444,9 +441,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
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);

View File

@ -439,9 +439,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
/// 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);
}
_ => {}

View File

@ -384,11 +384,9 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// 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();
}
@ -438,7 +436,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
// (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));
}
@ -511,7 +509,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
}
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 {
@ -520,9 +519,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
self.check_field(field.span, def, &def.struct_variant().fields[i]);
}
}
ty::TyEnum(..) => {
// enum fields have no privacy at this time
}
_ => {}
}
}

View File

@ -1356,7 +1356,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
};
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 {

View File

@ -431,7 +431,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
};
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);
@ -443,14 +443,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}));
}
_ => {
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 {
@ -461,9 +461,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}))
}
_ => {
// 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
}
}

View File

@ -49,7 +49,7 @@ use std::rc::Rc;
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;
@ -179,172 +179,174 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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);
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);
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));
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);
// 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.is_empty() {
// Uninhabitable; represent as unit
// (Typechecking will reject discriminant-sizing attrs.)
assert_eq!(hint, attr::ReprAny);
return Univariant(mk_struct(cx, &[], false, t));
}
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.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() == 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()
};
// 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() == 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 => {}
}
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 => {}
}
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;
}
}
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);
// 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;
}
// 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;
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
};
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();
ensure_enum_fits_in_address_space(cx, &fields[..], t);
General(ity, fields)
}
// 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
}
} 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();
ensure_enum_fits_in_address_space(cx, &fields[..], t);
General(ity, fields)
}
},
_ => bug!("adt::represent_type called on non-ADT type: {}", t)
}
}
@ -376,7 +378,7 @@ fn find_discr_field_candidate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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]);
@ -395,7 +397,7 @@ fn find_discr_field_candidate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// 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()) {

View File

@ -467,8 +467,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
// 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);

View File

@ -743,9 +743,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// 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
};
@ -798,9 +796,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
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,
@ -989,8 +985,8 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
}
}
(&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);

View File

@ -88,8 +88,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
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())
}
@ -101,7 +100,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
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 {
@ -205,7 +204,7 @@ impl<'a, 'tcx> VariantInfo<'tcx> {
-> 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)

View File

@ -223,13 +223,9 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
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)

View File

@ -30,7 +30,7 @@ use rustc::hir;
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;
@ -176,18 +176,10 @@ impl<'tcx> TypeMap<'tcx> {
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);
},
@ -705,13 +697,6 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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)
}
@ -779,18 +764,27 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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,
@ -1134,8 +1128,8 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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);
@ -1250,8 +1244,8 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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);

View File

@ -421,7 +421,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// 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

View File

@ -44,9 +44,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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);
},

View File

@ -19,7 +19,7 @@ use llvm::{ValueRef, get_param};
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::*;
@ -338,7 +338,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
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,
@ -487,16 +487,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
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) {
@ -544,23 +539,6 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
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() {
@ -587,63 +565,86 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
cx = drop_ty(cx, llfld_a, *arg, DebugLoc::None);
}
}
ty::TyEnum(en, substs) => {
let fcx = cx.fcx;
let ccx = fcx.ccx;
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 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);
}
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);
}
cx = next_cx;
}
_ => ccx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
}
}
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);
}
}
(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"),
}
}
},
_ => {
cx.sess().unimpl(&format!("type in drop_structural_ty: {}", t))
}

View File

@ -408,7 +408,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "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)

View File

@ -396,9 +396,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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);
},

View File

@ -89,7 +89,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
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 \
@ -102,8 +102,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
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)
}
@ -294,7 +293,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
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 \
@ -306,9 +305,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
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
@ -331,8 +328,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// 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);
}

View File

@ -617,7 +617,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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) {
@ -657,9 +657,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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")
};

View File

@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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,

View File

@ -16,7 +16,7 @@ use middle::free_region::FreeRegionMap;
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;
@ -44,9 +44,7 @@ pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()>
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,
@ -301,13 +299,13 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
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,
@ -435,14 +433,14 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
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() {
@ -497,7 +495,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
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(..) => {

View File

@ -292,9 +292,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
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(_) => {

View File

@ -165,7 +165,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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);
@ -359,9 +359,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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(),

View File

@ -1200,7 +1200,7 @@ fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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");
@ -2911,7 +2911,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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);
@ -2957,7 +2957,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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,
@ -3009,7 +3009,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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 }
@ -3074,14 +3074,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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
@ -3102,9 +3105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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")
};
@ -3199,8 +3200,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
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,
}
}
@ -3246,7 +3248,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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| {

View File

@ -22,9 +22,9 @@ use rustc::ty::{self, TyCtxt, TypeFoldable};
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};
@ -69,9 +69,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
// 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)
}
@ -241,9 +239,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
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());
}
_ => {
@ -426,7 +422,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
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);

View File

@ -75,9 +75,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
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) => {
@ -294,14 +292,9 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
{
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 {

View File

@ -67,7 +67,7 @@ use rustc_const_eval::EvalHint::UncheckedExprHint;
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::*;
@ -1062,7 +1062,7 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
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);
@ -1077,7 +1077,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
{
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)
@ -1157,7 +1157,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
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
@ -1581,17 +1581,17 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
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(..) |

View File

@ -344,9 +344,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}
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

View File

@ -238,7 +238,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
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,

View File

@ -41,7 +41,7 @@ use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
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};
@ -1811,14 +1811,12 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
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(),

View File

@ -75,13 +75,13 @@ pub mod testtypes {
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)