]> git.lizzy.rs Git - rust.git/commitdiff
Refactor `TyStruct`/`TyEnum`/`TyUnion` into `TyAdt`
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Mon, 5 Sep 2016 22:26:02 +0000 (01:26 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Thu, 8 Sep 2016 19:17:53 +0000 (22:17 +0300)
77 files changed:
src/librustc/infer/error_reporting.rs
src/librustc/infer/freshen.rs
src/librustc/middle/dead.rs
src/librustc/middle/effect.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/stability.rs
src/librustc/mir/tcx.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/select.rs
src/librustc/ty/cast.rs
src/librustc/ty/contents.rs
src/librustc/ty/context.rs
src/librustc/ty/error.rs
src/librustc/ty/fast_reject.rs
src/librustc/ty/flags.rs
src/librustc/ty/item_path.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/outlives.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc/ty/walk.rs
src/librustc/ty/wf.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/fragments.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_borrowck/borrowck/mir/mod.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/eval.rs
src/librustc_lint/builtin.rs
src/librustc_lint/types.rs
src/librustc_lint/unused.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tyencode.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/pattern.rs
src/librustc_mir/transform/type_check.rs
src/librustc_passes/consts.rs
src/librustc_privacy/lib.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_trans/adt.rs
src/librustc_trans/base.rs
src/librustc_trans/collector.rs
src/librustc_trans/common.rs
src/librustc_trans/context.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/debuginfo/type_names.rs
src/librustc_trans/glue.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/trans_item.rs
src/librustc_trans/type_of.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/variance/constraints.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/test/run-pass/auxiliary/issue13507.rs

index 38f3f055cbb245d4cb3627bdd5df4b3f91a3c431..b8a3bdfcf25738ad44937886569cdf19796e04c2 100644 (file)
@@ -488,10 +488,7 @@ fn check_and_note_conflicting_crates(&self,
                 // 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);
                     },
                     _ => ()
index 8aeb0757f5de29a3d525b902f35b873c688a7f59..eea12b7f19712867b2ddbf3d750737a9f8b459fb 100644 (file)
@@ -156,7 +156,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
             ty::TyInt(..) |
             ty::TyUint(..) |
             ty::TyFloat(..) |
-            ty::TyEnum(..) |
+            ty::TyAdt(..) |
             ty::TyBox(..) |
             ty::TyStr |
             ty::TyError |
@@ -167,8 +167,6 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
             ty::TyFnDef(..) |
             ty::TyFnPtr(_) |
             ty::TyTrait(..) |
-            ty::TyStruct(..) |
-            ty::TyUnion(..) |
             ty::TyClosure(..) |
             ty::TyNever |
             ty::TyTuple(..) |
index 26a89feb2181f7ba5efeea5b8312c2c9b711d47c..9db6ac1dcefd00bb6ff70d314ca4014d53b4cbfb 100644 (file)
@@ -86,8 +86,6 @@ fn insert_def_id(&mut self, def_id: DefId) {
     }
 
     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 @@ fn lookup_and_handle_definition(&mut self, id: ast::NodeId) {
             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 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
 
     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")
index a7af0b50b849416f6c8902539c301b88b5cd4aa3..8b8d15b0b6ebf551abf4df444e651e83c327f07c 100644 (file)
@@ -178,8 +178,10 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
                 }
             }
             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");
+                    }
                 }
             }
             _ => {}
@@ -190,9 +192,11 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
 
     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");
+                    }
                 }
             }
         }
index d32954d3800ad5643e5490e41295dbdafde18e80..9f05dde4e66f44221a84fc365d1c3592bdbc7708 100644 (file)
@@ -671,28 +671,31 @@ fn walk_struct_expr(&mut self,
 
         // 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");
+                }
             }
         }
 
index f8eb0d4a0ece8dc1a46fb0d839413da28e72582d..39d5487e8beb159151e694081cca963c77fc239e 100644 (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 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResul
                 }
                 Def::Struct(..) => {
                     match self.pat_ty(&pat)?.sty {
-                        ty::TyStruct(adt_def, _) => {
+                        ty::TyAdt(adt_def, _) => {
                             adt_def.struct_variant().fields.len()
                         }
                         ref ty => {
index c62c99c3b70626bd1b11751ab8a18d7ae3857666..9a56959de38bc9a6bc5dccd8fa9dd8227dae798e 100644 (file)
@@ -20,7 +20,7 @@
 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)
index c82e723525b45d7b26fd6013687a70f07137f74d..74ad6c602f6cdf47f3bd59bb96d07d29dab6a579 100644 (file)
@@ -40,7 +40,7 @@ pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'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 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, '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 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, '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 }
index 0a7d3e6e76d8f0052cfb3baa65a8805decac0819..83774f0cf7ead24659c8829483cf0e98fb1a0852 100644 (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()
         }
 
index e5ebe96932d4f9eb77734e84985f915beb2bae7b..52ddd8ab5dac01f7dad1a7efd1ff6cab1191ed6e 100644 (file)
@@ -27,7 +27,7 @@
 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 @@ fn type_category<'tcx>(t: Ty<'tcx>) -> Option<u32> {
                 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
index 3f2bc8cbd13c5074a1ab3331d5d43644da5ea3a0..94dba7d12a8c762abd4016416b4600d3911f7cfd 100644 (file)
@@ -1638,7 +1638,7 @@ fn assemble_candidates_for_unsizing(&mut self,
             (&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 @@ fn sized_conditions(&mut self, obligation: &TraitObligation<'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 @@ fn copy_conditions(&mut self, obligation: &TraitObligation<'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 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'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 @@ fn confirm_builtin_unsize_candidate(&mut self,
             }
 
             // 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 @@ fn confirm_builtin_unsize_candidate(&mut self,
                         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)
index c8d282d18af1db0156c62070c91bb08ef7ea8388..0badb85e9e0956bcdd1ee9561c4d7221f82ba135 100644 (file)
@@ -65,7 +65,7 @@ pub fn from_ty(t: Ty<'tcx>) -> Option<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)),
index e0e8a329e6e1dc01026420f9399163160b2580d1..b499e1346e73c12afbffa50ac82be68cbce50b85 100644 (file)
@@ -224,8 +224,7 @@ fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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| {
index 0fc1641d31f705021016849f30e227fcf1ffebcd..20601493d68f3e16bf5ee5936fc6e754b2c02fa5 100644 (file)
@@ -27,7 +27,7 @@
 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 @@ pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
 
     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 @@ pub fn mk_static_str(self) -> Ty<'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 @@ pub fn mk_projection(self,
         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>,
index 0e33e396f7e187f7a8bfccceb58b64961d81c966..d820fddea3907d38a754d29cff3a620eaeeea6e1 100644 (file)
@@ -216,7 +216,7 @@ fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
             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 @@ fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
             ty::TyTrait(ref inner) => {
                 format!("trait {}", tcx.item_path_str(inner.principal.def_id()))
             }
-            ty::TyStruct(def, _) => {
-                format!("struct `{}`", tcx.item_path_str(def.did))
-            }
-            ty::TyUnion(def, _) => {
-                format!("union `{}`", tcx.item_path_str(def.did))
-            }
             ty::TyClosure(..) => "closure".to_string(),
             ty::TyTuple(_) => "tuple".to_string(),
             ty::TyInfer(ty::TyVar(_)) => "inferred type".to_string(),
index 84f34a640dd8e40ffe6e2370c24a965c796be2e9..ee1544d2d996d3df5905d29c6838ec2b4439e6e5 100644 (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),
             }
         }
index ce6e4d6516ec6977601588d2cd0baa0fb8288c86..cddd59fa83c1b80ec76aa68fe88f614657d2b3f2 100644 (file)
@@ -102,7 +102,7 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
                 }
             }
 
-            &ty::TyEnum(_, substs) | &ty::TyStruct(_, substs) | &ty::TyUnion(_, substs) => {
+            &ty::TyAdt(_, substs) => {
                 self.add_substs(substs);
             }
 
index ddb0a6970cba5227659cb0d2c1cb7d238c7ffca6..b6b55fc0e33ddc32e9f97b7b217eac66ca92de52 100644 (file)
@@ -262,9 +262,7 @@ fn push_impl_path<T>(self,
         // 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 @@ fn parent_def_id(&self, def_id: DefId) -> Option<DefId> {
 /// 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()),
 
index 276fc708eed1bad2350f9a2e5f575569892c55f8..3c0aa041d2dd3a62b3c3b297186e439176e8eee5 100644 (file)
@@ -15,7 +15,7 @@
 use infer::InferCtxt;
 use session::Session;
 use traits;
-use ty::{self, Ty, TyCtxt, TypeFoldable};
+use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
 
 use syntax::ast::{FloatTy, IntTy, UintTy};
 use syntax::attr;
@@ -555,7 +555,7 @@ pub fn non_zero_field_in_type(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
             }
 
             // Is this the NonZero lang item wrapping a pointer or integer type?
-            (&Univariant { non_zero: true, .. }, &ty::TyStruct(def, substs)) => {
+            (&Univariant { non_zero: true, .. }, &ty::TyAdt(def, substs)) if def.is_struct() => {
                 let fields = &def.struct_variant().fields;
                 assert_eq!(fields.len(), 1);
                 match *fields[0].ty(tcx, substs).layout(infcx)? {
@@ -573,7 +573,7 @@ pub fn non_zero_field_in_type(infcx: &InferCtxt<'a, 'gcx, '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() => {
                 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 {
@@ -919,240 +919,242 @@ pub fn compute_uncached(ty: Ty<'gcx>,
             }
 
             // ADTs.
-            ty::TyStruct(def, substs) => {
-                if ty.is_simd() {
-                    // SIMD vector types.
-                    let element = ty.simd_type(tcx);
-                    match *element.layout(infcx)? {
-                        Scalar { value, .. } => {
-                            return success(Vector {
-                                element: value,
-                                count: ty.simd_size(tcx) as u64
-                            });
-                        }
-                        _ => {
-                            tcx.sess.fatal(&format!("monomorphising SIMD type `{}` with \
-                                                     a non-machine element type `{}`",
-                                                    ty, element));
+            ty::TyAdt(def, substs) => match def.adt_kind() {
+                AdtKind::Struct => {
+                    if ty.is_simd() {
+                        // SIMD vector types.
+                        let element = ty.simd_type(tcx);
+                        match *element.layout(infcx)? {
+                            Scalar { value, .. } => {
+                                return success(Vector {
+                                    element: value,
+                                    count: ty.simd_size(tcx) as u64
+                                });
+                            }
+                            _ => {
+                                tcx.sess.fatal(&format!("monomorphising SIMD type `{}` with \
+                                                        a non-machine element type `{}`",
+                                                        ty, element));
+                            }
                         }
                     }
-                }
-                let fields = def.struct_variant().fields.iter().map(|field| {
-                    field.ty(tcx, substs).layout(infcx)
-                });
-                let packed = tcx.lookup_packed(def.did);
-                let mut st = Struct::new(dl, packed);
-                st.extend(dl, fields, ty)?;
-
-                Univariant {
-                    variant: st,
-                    non_zero: Some(def.did) == tcx.lang_items.non_zero()
-                }
-            }
-            ty::TyUnion(def, substs) => {
-                let fields = def.struct_variant().fields.iter().map(|field| {
-                    field.ty(tcx, substs).layout(infcx)
-                });
-                let packed = tcx.lookup_packed(def.did);
-                let mut un = Union::new(dl, packed);
-                un.extend(dl, fields, ty)?;
-                UntaggedUnion { variants: un }
-            }
-            ty::TyEnum(def, substs) => {
-                let hint = *tcx.lookup_repr_hints(def.did).get(0)
-                    .unwrap_or(&attr::ReprAny);
-
-                if def.variants.is_empty() {
-                    // Uninhabitable; represent as unit
-                    // (Typechecking will reject discriminant-sizing attrs.)
-                    assert_eq!(hint, attr::ReprAny);
-
-                    return success(Univariant {
-                        variant: Struct::new(dl, false),
-                        non_zero: false
-                    });
-                }
-
-                if def.variants.iter().all(|v| v.fields.is_empty()) {
-                    // All bodies empty -> intlike
-                    let (mut min, mut max) = (i64::MAX, i64::MIN);
-                    for v in &def.variants {
-                        let x = v.disr_val.to_u64_unchecked() as i64;
-                        if x < min { min = x; }
-                        if x > max { max = x; }
-                    }
-
-                    let (discr, signed) = Integer::repr_discr(tcx, hint, min, max);
-                    return success(CEnum {
-                        discr: discr,
-                        signed: signed,
-                        min: min as u64,
-                        max: max as u64
+                    let fields = def.struct_variant().fields.iter().map(|field| {
+                        field.ty(tcx, substs).layout(infcx)
                     });
-                }
+                    let packed = tcx.lookup_packed(def.did);
+                    let mut st = Struct::new(dl, packed);
+                    st.extend(dl, fields, ty)?;
 
-                // Since there's at least one
-                // non-empty body, explicit discriminants should have
-                // been rejected by a checker before this point.
-                for (i, v) in def.variants.iter().enumerate() {
-                    if i as u64 != v.disr_val.to_u64_unchecked() {
-                        bug!("non-C-like enum {} with specified discriminants",
-                             tcx.item_path_str(def.did));
+                    Univariant {
+                        variant: st,
+                        non_zero: Some(def.did) == tcx.lang_items.non_zero()
                     }
                 }
-
-                if def.variants.len() == 1 {
-                    // Equivalent to a struct/tuple/newtype.
-                    // (Typechecking will reject discriminant-sizing attrs.)
-                    assert_eq!(hint, attr::ReprAny);
-                    let fields = def.variants[0].fields.iter().map(|field| {
+                AdtKind::Union => {
+                    let fields = def.struct_variant().fields.iter().map(|field| {
                         field.ty(tcx, substs).layout(infcx)
                     });
-                    let mut st = Struct::new(dl, false);
-                    st.extend(dl, fields, ty)?;
-                    return success(Univariant { variant: st, non_zero: false });
+                    let packed = tcx.lookup_packed(def.did);
+                    let mut un = Union::new(dl, packed);
+                    un.extend(dl, fields, ty)?;
+                    UntaggedUnion { variants: un }
                 }
+                AdtKind::Enum => {
+                    let hint = *tcx.lookup_repr_hints(def.did).get(0)
+                        .unwrap_or(&attr::ReprAny);
+
+                    if def.variants.is_empty() {
+                        // Uninhabitable; represent as unit
+                        // (Typechecking will reject discriminant-sizing attrs.)
+                        assert_eq!(hint, attr::ReprAny);
+
+                        return success(Univariant {
+                            variant: Struct::new(dl, false),
+                            non_zero: false
+                        });
+                    }
 
-                // Cache the substituted and normalized variant field types.
-                let variants = def.variants.iter().map(|v| {
-                    v.fields.iter().map(|field| field.ty(tcx, substs)).collect::<Vec<_>>()
-                }).collect::<Vec<_>>();
+                    if def.variants.iter().all(|v| v.fields.is_empty()) {
+                        // All bodies empty -> intlike
+                        let (mut min, mut max) = (i64::MAX, i64::MIN);
+                        for v in &def.variants {
+                            let x = v.disr_val.to_u64_unchecked() as i64;
+                            if x < min { min = x; }
+                            if x > max { max = x; }
+                        }
 
-                if variants.len() == 2 && hint == attr::ReprAny {
-                    // Nullable pointer optimization
-                    for discr in 0..2 {
-                        let other_fields = variants[1 - discr].iter().map(|ty| {
-                            ty.layout(infcx)
+                        let (discr, signed) = Integer::repr_discr(tcx, hint, min, max);
+                        return success(CEnum {
+                            discr: discr,
+                            signed: signed,
+                            min: min as u64,
+                            max: max as u64
                         });
-                        if !Struct::would_be_zero_sized(dl, other_fields)? {
-                            continue;
+                    }
+
+                    // Since there's at least one
+                    // non-empty body, explicit discriminants should have
+                    // been rejected by a checker before this point.
+                    for (i, v) in def.variants.iter().enumerate() {
+                        if i as u64 != v.disr_val.to_u64_unchecked() {
+                            bug!("non-C-like enum {} with specified discriminants",
+                                tcx.item_path_str(def.did));
                         }
-                        let path = Struct::non_zero_field_path(infcx,
-                            variants[discr].iter().cloned())?;
-                        let mut path = if let Some(p) = path { p } else { continue };
-
-                        // FIXME(eddyb) should take advantage of a newtype.
-                        if path == &[0] && variants[discr].len() == 1 {
-                            match *variants[discr][0].layout(infcx)? {
-                                Scalar { value, .. } => {
-                                    return success(RawNullablePointer {
-                                        nndiscr: discr as u64,
-                                        value: value
-                                    });
-                                }
-                                _ => {
-                                    bug!("Layout::compute: `{}`'s non-zero \
-                                          `{}` field not scalar?!",
-                                         ty, variants[discr][0])
+                    }
+
+                    if def.variants.len() == 1 {
+                        // Equivalent to a struct/tuple/newtype.
+                        // (Typechecking will reject discriminant-sizing attrs.)
+                        assert_eq!(hint, attr::ReprAny);
+                        let fields = def.variants[0].fields.iter().map(|field| {
+                            field.ty(tcx, substs).layout(infcx)
+                        });
+                        let mut st = Struct::new(dl, false);
+                        st.extend(dl, fields, ty)?;
+                        return success(Univariant { variant: st, non_zero: false });
+                    }
+
+                    // Cache the substituted and normalized variant field types.
+                    let variants = def.variants.iter().map(|v| {
+                        v.fields.iter().map(|field| field.ty(tcx, substs)).collect::<Vec<_>>()
+                    }).collect::<Vec<_>>();
+
+                    if variants.len() == 2 && hint == attr::ReprAny {
+                        // Nullable pointer optimization
+                        for discr in 0..2 {
+                            let other_fields = variants[1 - discr].iter().map(|ty| {
+                                ty.layout(infcx)
+                            });
+                            if !Struct::would_be_zero_sized(dl, other_fields)? {
+                                continue;
+                            }
+                            let path = Struct::non_zero_field_path(infcx,
+                                variants[discr].iter().cloned())?;
+                            let mut path = if let Some(p) = path { p } else { continue };
+
+                            // FIXME(eddyb) should take advantage of a newtype.
+                            if path == &[0] && variants[discr].len() == 1 {
+                                match *variants[discr][0].layout(infcx)? {
+                                    Scalar { value, .. } => {
+                                        return success(RawNullablePointer {
+                                            nndiscr: discr as u64,
+                                            value: value
+                                        });
+                                    }
+                                    _ => {
+                                        bug!("Layout::compute: `{}`'s non-zero \
+                                            `{}` field not scalar?!",
+                                            ty, variants[discr][0])
+                                    }
                                 }
                             }
+
+                            path.push(0); // For GEP through a pointer.
+                            path.reverse();
+                            let mut st = Struct::new(dl, false);
+                            st.extend(dl, variants[discr].iter().map(|ty| ty.layout(infcx)), ty)?;
+                            return success(StructWrappedNullablePointer {
+                                nndiscr: discr as u64,
+                                nonnull: st,
+                                discrfield: path
+                            });
                         }
+                    }
 
-                        path.push(0); // For GEP through a pointer.
-                        path.reverse();
-                        let mut st = Struct::new(dl, false);
-                        st.extend(dl, variants[discr].iter().map(|ty| ty.layout(infcx)), ty)?;
-                        return success(StructWrappedNullablePointer {
-                            nndiscr: discr as u64,
-                            nonnull: st,
-                            discrfield: path
+                    // The general case.
+                    let discr_max = (variants.len() - 1) as i64;
+                    assert!(discr_max >= 0);
+                    let (min_ity, _) = Integer::repr_discr(tcx, hint, 0, discr_max);
+
+                    let mut align = dl.aggregate_align;
+                    let mut size = Size::from_bytes(0);
+
+                    // We're interested in the smallest alignment, so start large.
+                    let mut start_align = Align::from_bytes(256, 256).unwrap();
+
+                    // Create the set of structs that represent each variant
+                    // Use the minimum integer type we figured out above
+                    let discr = Some(Scalar { value: Int(min_ity), non_zero: false });
+                    let mut variants = variants.into_iter().map(|fields| {
+                        let mut found_start = false;
+                        let fields = fields.into_iter().map(|field| {
+                            let field = field.layout(infcx)?;
+                            if !found_start {
+                                // Find the first field we can't move later
+                                // to make room for a larger discriminant.
+                                let field_align = field.align(dl);
+                                if field.size(dl).bytes() != 0 || field_align.abi() != 1 {
+                                    start_align = start_align.min(field_align);
+                                    found_start = true;
+                                }
+                            }
+                            Ok(field)
                         });
+                        let mut st = Struct::new(dl, false);
+                        st.extend(dl, discr.iter().map(Ok).chain(fields), ty)?;
+                        size = cmp::max(size, st.min_size());
+                        align = align.max(st.align);
+                        Ok(st)
+                    }).collect::<Result<Vec<_>, _>>()?;
+
+                    // Align the maximum variant size to the largest alignment.
+                    size = size.abi_align(align);
+
+                    if size.bytes() >= dl.obj_size_bound() {
+                        return Err(LayoutError::SizeOverflow(ty));
                     }
-                }
 
-                // The general case.
-                let discr_max = (variants.len() - 1) as i64;
-                assert!(discr_max >= 0);
-                let (min_ity, _) = Integer::repr_discr(tcx, hint, 0, discr_max);
-
-                let mut align = dl.aggregate_align;
-                let mut size = Size::from_bytes(0);
-
-                // We're interested in the smallest alignment, so start large.
-                let mut start_align = Align::from_bytes(256, 256).unwrap();
-
-                // Create the set of structs that represent each variant
-                // Use the minimum integer type we figured out above
-                let discr = Some(Scalar { value: Int(min_ity), non_zero: false });
-                let mut variants = variants.into_iter().map(|fields| {
-                    let mut found_start = false;
-                    let fields = fields.into_iter().map(|field| {
-                        let field = field.layout(infcx)?;
-                        if !found_start {
-                            // Find the first field we can't move later
-                            // to make room for a larger discriminant.
-                            let field_align = field.align(dl);
-                            if field.size(dl).bytes() != 0 || field_align.abi() != 1 {
-                                start_align = start_align.min(field_align);
-                                found_start = true;
-                            }
+                    // Check to see if we should use a different type for the
+                    // discriminant. We can safely use a type with the same size
+                    // as the alignment of the first field of each variant.
+                    // We increase the size of the discriminant to avoid LLVM copying
+                    // padding when it doesn't need to. This normally causes unaligned
+                    // load/stores and excessive memcpy/memset operations. By using a
+                    // bigger integer size, LLVM can be sure about it's contents and
+                    // won't be so conservative.
+
+                    // Use the initial field alignment
+                    let wanted = start_align.abi();
+                    let mut ity = min_ity;
+                    for &candidate in &[I16, I32, I64] {
+                        let ty = Int(candidate);
+                        if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
+                            ity = candidate;
+                            break;
                         }
-                        Ok(field)
-                    });
-                    let mut st = Struct::new(dl, false);
-                    st.extend(dl, discr.iter().map(Ok).chain(fields), ty)?;
-                    size = cmp::max(size, st.min_size());
-                    align = align.max(st.align);
-                    Ok(st)
-                }).collect::<Result<Vec<_>, _>>()?;
-
-                // Align the maximum variant size to the largest alignment.
-                size = size.abi_align(align);
-
-                if size.bytes() >= dl.obj_size_bound() {
-                    return Err(LayoutError::SizeOverflow(ty));
-                }
-
-                // Check to see if we should use a different type for the
-                // discriminant. We can safely use a type with the same size
-                // as the alignment of the first field of each variant.
-                // We increase the size of the discriminant to avoid LLVM copying
-                // padding when it doesn't need to. This normally causes unaligned
-                // load/stores and excessive memcpy/memset operations. By using a
-                // bigger integer size, LLVM can be sure about it's contents and
-                // won't be so conservative.
-
-                // Use the initial field alignment
-                let wanted = start_align.abi();
-                let mut ity = min_ity;
-                for &candidate in &[I16, I32, I64] {
-                    let ty = Int(candidate);
-                    if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
-                        ity = candidate;
-                        break;
                     }
-                }
 
-                // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
-                if align.abi() != start_align.abi() {
-                    ity = min_ity;
-                }
+                    // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
+                    if align.abi() != start_align.abi() {
+                        ity = min_ity;
+                    }
 
-                // If the alignment is not larger than the chosen discriminant size,
-                // don't use the alignment as the final size.
-                if ity <= min_ity {
-                    ity = min_ity;
-                } else {
-                    // Patch up the variants' first few fields.
-                    let old_ity_size = Int(min_ity).size(dl);
-                    let new_ity_size = Int(ity).size(dl);
-                    for variant in &mut variants {
-                        for offset in &mut variant.offset_after_field {
-                            if *offset > old_ity_size {
-                                break;
+                    // If the alignment is not larger than the chosen discriminant size,
+                    // don't use the alignment as the final size.
+                    if ity <= min_ity {
+                        ity = min_ity;
+                    } else {
+                        // Patch up the variants' first few fields.
+                        let old_ity_size = Int(min_ity).size(dl);
+                        let new_ity_size = Int(ity).size(dl);
+                        for variant in &mut variants {
+                            for offset in &mut variant.offset_after_field {
+                                if *offset > old_ity_size {
+                                    break;
+                                }
+                                *offset = new_ity_size;
                             }
-                            *offset = new_ity_size;
                         }
                     }
-                }
 
-                General {
-                    discr: ity,
-                    variants: variants,
-                    size: size,
-                    align: align
+                    General {
+                        discr: ity,
+                        variants: variants,
+                        size: size,
+                        align: align
+                    }
                 }
-            }
+            },
 
             // Types with no meaningful known layout.
             ty::TyProjection(_) | ty::TyAnon(..) => {
@@ -1317,9 +1319,9 @@ pub fn compute(ty: Ty<'gcx>, infcx: &InferCtxt<'a, 'gcx, 'tcx>)
                 }
             }
 
-            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);
                 }
 
index dfe24d5627bf19c9f1550e4b331f9f17d3ea2ed4..91e3950745089177d53f533cc56efeb879a07322 100644 (file)
@@ -952,9 +952,7 @@ fn dep_node(&self) -> DepNode<DefId> {
             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 @@ fn calculate_dtorck(&'gcx self, tcx: TyCtxt) {
         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 @@ pub fn has_dtor(&self) -> bool {
     /// 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 @@ fn sized_constraint_for_ty(
                 }
             }
 
-            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);
index a7bb0374b75bf3810f49ff514d2ed9ca095d4e8f..a4edd3b93c949535a38a55465093635225a7af3e 100644 (file)
@@ -172,9 +172,7 @@ fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'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)
index dfae19487b6f0ccb8bb38c0ac413de69bfa67f16..b10c731fe27d00881faff1757c7cef9299eb2333 100644 (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 =>
index 952641f6832f90b373f9fd46966e4a0ea0a78822..6c3dabfe113fe37d824bd37a353aaaeb70187809 100644 (file)
@@ -482,7 +482,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
             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 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
             ty::TyRef(ref r, tm) => {
                 ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
             }
-            ty::TyStruct(did, substs) => ty::TyStruct(did, substs.fold_with(folder)),
-            ty::TyUnion(did, substs) => ty::TyUnion(did, substs.fold_with(folder)),
             ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
             ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)),
             ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
@@ -516,7 +514,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             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 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             }
             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),
index 7ded2b05f3b5b3e19dfdbdcdf6980d91da28528a..a755dd056cd8483a07ca03ef0498ed690f14de11 100644 (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 @@ pub fn is_uninhabited(&self, _cx: TyCtxt) -> bool {
         // 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 @@ pub fn is_ty_var(&self) -> bool {
     }
 
     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 @@ pub fn is_slice(&self) -> bool {
 
     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 @@ pub fn is_structural(&self) -> bool {
     #[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 @@ pub fn sequence_element_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'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 @@ pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'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 @@ pub fn is_fn(&self) -> bool {
     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 @@ pub fn ty_to_def_id(&self) -> Option<DefId> {
 
     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 @@ pub fn regions(&self) -> Vec<&'tcx ty::Region> {
                 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) => {
index 51ca6bfeb5affc4a11b8fe8c5330f5811f077f40..68de8d96f33dcbfd56399869d0608c91c5237222 100644 (file)
@@ -14,7 +14,7 @@
 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 @@ pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, '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 @@ pub fn arm_contains_ref_binding(self, arm: &hir::Arm) -> Option<hir::Mutability>
 
     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 @@ pub fn positional_element_ty(self,
                                  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 @@ pub fn named_element_ty(self,
                             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,10 +253,15 @@ pub fn enum_repr_type(self, opt_hint: Option<&attr::ReprAttr>) -> attr::IntType
     /// if not a structure at all. Corresponds to the only possible unsized
     /// field, and its type can be used to determine unsizing strategy.
     pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
-        while let TyStruct(def, substs) = ty.sty {
-            match def.struct_variant().fields.last() {
-                Some(f) => ty = f.ty(self, substs),
-                None => break
+        loop {
+            match ty.sty {
+                TyAdt(def, substs) if def.is_struct() => {
+                    match def.struct_variant().fields.last() {
+                        Some(f) => ty = f.ty(self, substs),
+                        None => break
+                    }
+                }
+                _ => break
             }
         }
         ty
@@ -275,15 +277,19 @@ pub fn struct_lockstep_tails(self,
                                  target: Ty<'tcx>)
                                  -> (Ty<'tcx>, Ty<'tcx>) {
         let (mut a, mut b) = (source, target);
-        while let (&TyStruct(a_def, a_substs), &TyStruct(b_def, b_substs)) = (&a.sty, &b.sty) {
-            if a_def != b_def {
-                break;
-            }
-            if let Some(f) = a_def.struct_variant().fields.last() {
-                a = f.ty(self, a_substs);
-                b = f.ty(self, b_substs);
-            } else {
-                break;
+        loop {
+            match (&a.sty, &b.sty) {
+                (&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs))
+                        if a_def == b_def && a_def.is_struct() => {
+                    match a_def.struct_variant().fields.last() {
+                        Some(f) => {
+                            a = f.ty(self, a_substs);
+                            b = f.ty(self, b_substs);
+                        }
+                        _ => break
+                    }
+                }
+                _ => break
             }
         }
         (a, b)
@@ -431,9 +437,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
             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 +564,8 @@ pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, '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 +605,7 @@ fn is_sized_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, '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 +667,7 @@ fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
                 TyArray(ty, _) => {
                     is_type_structurally_recursive(tcx, sp, seen, ty)
                 }
-                TyStruct(def, substs) | TyUnion(def, substs) | TyEnum(def, substs) => {
+                TyAdt(def, substs) => {
                     find_nonrepresentable(tcx,
                                           sp,
                                           seen,
@@ -680,7 +684,7 @@ fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
 
         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 +693,7 @@ fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
 
         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 +715,7 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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();
index cea3bd6348dbe9bb5927839076dc0232ad79eb32..dd3a62f7cd2dd0d5ee4071520c037cb259a68710 100644 (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) => {
index 599e2be4db247f0e4e133375749eafdfc2b79cf0..0557660e98c2f7d0a7890f6617598492c3302529 100644 (file)
@@ -336,9 +336,7 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
                     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);
index d0e02f2e8acdd05cdf95baf5695609b4bc72e3fc..3b84ff86ab9fbaa8cd20e316975713330cf19c0c 100644 (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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             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) {
index 6f4c48d632a7a64ca24bdcf515dde7ff8d81de73..089733da536d8d4c602727971784e21d22546dc4 100644 (file)
@@ -796,9 +796,7 @@ fn check_if_assigned_path_is_moved(&self,
             }
             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
index 45f5c3288a6d063eca5ba97dddffa651fbbbf185..515868c460d071571639eb9395014fc1a4f5370b 100644 (file)
@@ -21,7 +21,7 @@
 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;
+            AdtKind::Union => {
+                // Do nothing, all union fields are moved/assigned together.
+            }
+            AdtKind::Enum => {
+                let variant = match enum_variant_info {
+                    Some((vid, ref _lp2)) => def.variant_with_id(vid),
+                    None => {
+                        assert!(def.is_univariant());
+                        &def.variants[0]
+                    }
+                };
+                match *origin_field_name {
+                    mc::NamedField(ast_name) => {
+                        for field in &variant.fields {
+                            if field.name == ast_name {
+                                continue;
+                            }
+                            let field_name = mc::NamedField(field.name);
+                            add_fragment_sibling_local(field_name, Some(variant.did));
                         }
-                        let field_name = mc::NamedField(field.name);
-                        add_fragment_sibling_local(field_name, Some(variant.did));
                     }
-                }
-                mc::PositionalField(tuple_idx) => {
-                    for (i, _f) in variant.fields.iter().enumerate() {
-                        if tuple_idx == i {
-                            continue;
+                    mc::PositionalField(tuple_idx) => {
+                        for (i, _f) in variant.fields.iter().enumerate() {
+                            if tuple_idx == i {
+                                continue;
+                            }
+                            let field_name = mc::PositionalField(i);
+                            add_fragment_sibling_local(field_name, None);
                         }
-                        let field_name = mc::PositionalField(i);
-                        add_fragment_sibling_local(field_name, None);
                     }
                 }
             }
-        }
+        },
 
-        ref sty_and_variant_info => {
+        ref ty => {
             let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id));
             span_bug!(opt_span.unwrap_or(DUMMY_SP),
                       "type {:?} ({:?}) is not fragmentable",
-                      parent_ty,
-                      sty_and_variant_info);
+                      parent_ty, ty);
         }
     }
 }
index 5f2d6c406c4b99187ecbd84383e099cdc83704ec..3e335dacc8ed9f7a6698159cbc6ec4ef7ea9ebca 100644 (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 {
index bda68a1cd1ceb9e8c5d512d634ac44d02d0c9ff4..3fa7c252b842ce886701397c0301316eb0eda71f 100644 (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",
index c08dc9330b8fd0a877ab5634694483c0bba13698..fdcefdc0d43073f4d91f0b56dff5756f0adc2116 100644 (file)
@@ -103,8 +103,8 @@ fn restrict(&self,
                 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 @@ fn restrict(&self,
                                                      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))
                 }
             }
 
index c5d103453798927c044f4594b10a731714b6b005..71274b7e0218a976c6932c9c8fda970c531dc799 100644 (file)
@@ -709,7 +709,7 @@ fn open_drop_for_adt<'a>(&mut self, c: &DropCtxt<'a, '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 @@ fn must_complete_drop<'a>(&self, c: &DropCtxt<'a, 'tcx>) -> bool {
         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,
index 9c462feeaadd7f0a7967b20433d4df0c8c8c1201..e035e268b1c4cdb74dfbd536b9484e9ce4dd9d21 100644 (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
index 0c9261df54870055df825021a49d8201bcd5dd02..e9ba406389f88ae022b5512aa16518a1403a1963 100644 (file)
@@ -367,20 +367,22 @@ pub fn add_move(&self, tcx: TyCtxt<'a, 'tcx, '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 @@ pub fn add_assignment(&self, tcx: TyCtxt<'a, 'tcx, '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;
             }
         }
 
index e49011d88737063ee901f8c0121a499fd630c4e9..da4445ef68947c7db45d627a96eff76e0b65d0b8 100644 (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,
index 30e5a0cacf551654b60d4096aeab8628c15ac331..4f4c16d3f6a61af18be6959093a5f28956a4ca36 100644 (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)
index a73930fa52517d058b4e46b115d7b84fea53bbdb..b610a924a339666e264c515538af7a7a32ffc0f8 100644 (file)
@@ -468,21 +468,21 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
                     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,
         };
index 54cec3fd7e135b04a4775d92d4eeb0294a99ef03..a6049acdb10d431e75bf87d130915c23644c907e 100644 (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 @@ fn check_type_for_ffi(&self,
         }
 
         match ty.sty {
-            ty::TyStruct(def, substs) => {
-                if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
-                    return FfiUnsafe(
-                        "found struct without foreign-function-safe \
-                         representation annotation in foreign module, \
-                         consider adding a #[repr(C)] attribute to \
-                         the type");
-                }
+            ty::TyAdt(def, substs) => match def.adt_kind() {
+                AdtKind::Struct => {
+                    if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
+                        return FfiUnsafe(
+                            "found struct without foreign-function-safe \
+                            representation annotation in foreign module, \
+                            consider adding a #[repr(C)] attribute to \
+                            the type");
+                    }
 
-                // We can't completely trust repr(C) markings; make sure the
-                // fields are actually safe.
-                if def.struct_variant().fields.is_empty() {
-                    return FfiUnsafe(
-                        "found zero-size struct in foreign module, consider \
-                         adding a member to this struct");
-                }
+                    // We can't completely trust repr(C) markings; make sure the
+                    // fields are actually safe.
+                    if def.struct_variant().fields.is_empty() {
+                        return FfiUnsafe(
+                            "found zero-size struct in foreign module, consider \
+                            adding a member to this struct");
+                    }
 
-                for field in &def.struct_variant().fields {
-                    let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
-                    let r = self.check_type_for_ffi(cache, field_ty);
-                    match r {
-                        FfiSafe => {}
-                        FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
-                        FfiUnsafe(s) => { return FfiBadStruct(def.did, s); }
+                    for field in &def.struct_variant().fields {
+                        let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
+                        let r = self.check_type_for_ffi(cache, field_ty);
+                        match r {
+                            FfiSafe => {}
+                            FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+                            FfiUnsafe(s) => { return FfiBadStruct(def.did, s); }
+                        }
                     }
+                    FfiSafe
                 }
-                FfiSafe
-            }
-            ty::TyUnion(def, substs) => {
-                if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
-                    return FfiUnsafe(
-                        "found union without foreign-function-safe \
-                         representation annotation in foreign module, \
-                         consider adding a #[repr(C)] attribute to \
-                         the type");
-                }
+                AdtKind::Union => {
+                    if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
+                        return FfiUnsafe(
+                            "found union without foreign-function-safe \
+                            representation annotation in foreign module, \
+                            consider adding a #[repr(C)] attribute to \
+                            the type");
+                    }
 
-                for field in &def.struct_variant().fields {
-                    let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
-                    let r = self.check_type_for_ffi(cache, field_ty);
-                    match r {
-                        FfiSafe => {}
-                        FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
-                        FfiUnsafe(s) => { return FfiBadUnion(def.did, s); }
+                    for field in &def.struct_variant().fields {
+                        let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
+                        let r = self.check_type_for_ffi(cache, field_ty);
+                        match r {
+                            FfiSafe => {}
+                            FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+                            FfiUnsafe(s) => { return FfiBadUnion(def.did, s); }
+                        }
                     }
+                    FfiSafe
                 }
-                FfiSafe
-            }
-            ty::TyEnum(def, substs) => {
-                if def.variants.is_empty() {
-                    // Empty enums are okay... although sort of useless.
-                    return FfiSafe
-                }
+                AdtKind::Enum => {
+                    if def.variants.is_empty() {
+                        // Empty enums are okay... although sort of useless.
+                        return FfiSafe
+                    }
 
-                // Check for a repr() attribute to specify the size of the
-                // discriminant.
-                let repr_hints = cx.lookup_repr_hints(def.did);
-                match &repr_hints[..] {
-                    &[] => {
-                        // Special-case types like `Option<extern fn()>`.
-                        if !is_repr_nullable_ptr(cx, def, substs) {
-                            return FfiUnsafe(
-                                "found enum without foreign-function-safe \
-                                 representation annotation in foreign module, \
-                                 consider adding a #[repr(...)] attribute to \
-                                 the type")
+                    // Check for a repr() attribute to specify the size of the
+                    // discriminant.
+                    let repr_hints = cx.lookup_repr_hints(def.did);
+                    match &repr_hints[..] {
+                        &[] => {
+                            // Special-case types like `Option<extern fn()>`.
+                            if !is_repr_nullable_ptr(cx, def, substs) {
+                                return FfiUnsafe(
+                                    "found enum without foreign-function-safe \
+                                    representation annotation in foreign module, \
+                                    consider adding a #[repr(...)] attribute to \
+                                    the type")
+                            }
                         }
-                    }
-                    &[ref hint] => {
-                        if !hint.is_ffi_safe() {
+                        &[ref hint] => {
+                            if !hint.is_ffi_safe() {
+                                // FIXME: This shouldn't be reachable: we should check
+                                // this earlier.
+                                return FfiUnsafe(
+                                    "enum has unexpected #[repr(...)] attribute")
+                            }
+
+                            // Enum with an explicitly sized discriminant; either
+                            // a C-style enum or a discriminated union.
+
+                            // The layout of enum variants is implicitly repr(C).
+                            // FIXME: Is that correct?
+                        }
+                        _ => {
                             // FIXME: This shouldn't be reachable: we should check
                             // this earlier.
                             return FfiUnsafe(
-                                "enum has unexpected #[repr(...)] attribute")
+                                "enum has too many #[repr(...)] attributes");
                         }
-
-                        // Enum with an explicitly sized discriminant; either
-                        // a C-style enum or a discriminated union.
-
-                        // The layout of enum variants is implicitly repr(C).
-                        // FIXME: Is that correct?
-                    }
-                    _ => {
-                        // FIXME: This shouldn't be reachable: we should check
-                        // this earlier.
-                        return FfiUnsafe(
-                            "enum has too many #[repr(...)] attributes");
                     }
-                }
 
-                // Check the contained variants.
-                for variant in &def.variants {
-                    for field in &variant.fields {
-                        let arg = cx.normalize_associated_type(&field.ty(cx, substs));
-                        let r = self.check_type_for_ffi(cache, arg);
-                        match r {
-                            FfiSafe => {}
-                            FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
-                            FfiUnsafe(s) => { return FfiBadEnum(def.did, s); }
+                    // Check the contained variants.
+                    for variant in &def.variants {
+                        for field in &variant.fields {
+                            let arg = cx.normalize_associated_type(&field.ty(cx, substs));
+                            let r = self.check_type_for_ffi(cache, arg);
+                            match r {
+                                FfiSafe => {}
+                                FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; }
+                                FfiUnsafe(s) => { return FfiBadEnum(def.did, s); }
+                            }
                         }
                     }
+                    FfiSafe
                 }
-                FfiSafe
-            }
+            },
 
             ty::TyChar => {
                 FfiUnsafe("found Rust type `char` in foreign module, while \
index f07720f5202bd15b8cb69e38ab6da7b18f1c7d47..d31f16df693569ed1a5270d3508901e86d859337 100644 (file)
@@ -136,9 +136,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
             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)
             }
index 6b48b4dfabcfd2d5eb418ba9fcb03a4bae489641..4dc06f0d024967e69983e89346c500a671955b4b 100644 (file)
@@ -36,7 +36,7 @@
 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 @@ fn get_struct_variant<'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 @@ fn get_struct_variant<'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 {:?}",
index 55ff4817683de523072f78987c21f87e44628649..bcaf1640bc41b0cd8a4efeb28fbce235dedcae0f 100644 (file)
@@ -358,14 +358,6 @@ pub fn parse_ty(&mut self) -> Ty<'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 @@ pub fn parse_ty(&mut self) -> Ty<'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(), '[');
index bef3cf3a1940f965ec472504327f0c5ab1c5eee9..8030abf6330e76a63b47f150b3b75fcb524a0868 100644 (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);
index 6ea1fb5036065285b4faf0cf25d5fff4c8a12372..a40571c5d859784125c247ea19cf785b6e8d1622 100644 (file)
@@ -181,7 +181,7 @@ fn expr_as_rvalue(&mut self,
             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
index 8812287c34294ba9dd49844bd852dab99ff9d4e0..4518f8cb373fab70fe023cce5e665c03d5ae77d6 100644 (file)
@@ -19,7 +19,7 @@
 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());
-
-                            let index = adt.variant_index_with_id(variant_id);
-                            let field_refs = field_refs(&adt.variants[index], fields);
-                            ExprKind::Adt {
-                                adt_def: adt,
-                                variant_index: index,
-                                substs: substs,
-                                fields: field_refs,
-                                base: None
+                    AdtKind::Enum => {
+                        match cx.tcx.expect_def(expr.id) {
+                            Def::Variant(enum_id, variant_id) => {
+                                debug_assert!(adt.did == enum_id);
+                                assert!(base.is_none());
+
+                                let index = adt.variant_index_with_id(variant_id);
+                                let field_refs = field_refs(&adt.variants[index], fields);
+                                ExprKind::Adt {
+                                    adt_def: adt,
+                                    variant_index: index,
+                                    substs: substs,
+                                    fields: field_refs,
+                                    base: None
+                                }
+                            }
+                            ref def => {
+                                span_bug!(
+                                    expr.span,
+                                    "unexpected def: {:?}",
+                                    def);
                             }
-                        }
-                        ref def => {
-                            span_bug!(
-                                expr.span,
-                                "unexpected def: {:?}",
-                                def);
                         }
                     }
-                }
+                },
                 _ => {
                     span_bug!(
                         expr.span,
@@ -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 {
index 30f79796aaa6de8f2aea395ce1961afe15be4ca1..3639b165eb5abb33cc09a44087acc8f7b5b4e4fb 100644 (file)
@@ -198,8 +198,8 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'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 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'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));
index e260b1d262aed17e2b633d22f9dab2b02171acd8..7fda658185e0700f727c70eb0753b9c291f19828 100644 (file)
@@ -218,7 +218,7 @@ fn sanitize_projection(&mut self,
             }
             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 @@ fn field_ty(&mut self,
                 (&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 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'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 @@ fn check_terminator(&mut self,
             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);
index d4e8eb51cde27b30d96febcb91c9e627dc5c6726..f919e42b6bd7d38d6de6f483f002192ee80ae70f 100644 (file)
@@ -439,9 +439,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
 /// 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);
         }
         _ => {}
index 8c72933c4ce46a4d3d508372ff6385eef27703ec..4012c1cb348895ef34f845594e5a65e411b6e6a7 100644 (file)
@@ -384,11 +384,9 @@ fn item_is_accessible(&self, did: DefId) -> bool {
 
     // 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 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
                 // (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 @@ fn visit_pat(&mut self, pattern: &hir::Pat) {
             }
             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 @@ fn visit_pat(&mut self, pattern: &hir::Pat) {
                             self.check_field(field.span, def, &def.struct_variant().fields[i]);
                         }
                     }
-                    ty::TyEnum(..) => {
-                        // enum fields have no privacy at this time
-                    }
                     _ => {}
                 }
             }
index ebd0bdc71d7f0bc64be688bc5f3f6b5544b09fb8..27ee5765c99faab013c8861458c52b2444e6fc11 100644 (file)
@@ -1338,7 +1338,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                 };
                 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 {
index 04cd72ac2d3647de31dc91b94bc15fc5762b2b89..868e3bb1f1b73e3e1de46a87c822a59ee0d806ac 100644 (file)
@@ -420,7 +420,7 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                     }
                 };
                 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);
@@ -432,14 +432,14 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                         }));
                     }
                     _ => {
-                        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 {
@@ -450,9 +450,9 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                         }))
                     }
                     _ => {
-                        // 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
                     }
                 }
index 9eeefa079fb634614c1e516a5cbb4d3933b949b0..e8498363e45a31fe126fd0f4683f05f46bf5d501 100644 (file)
@@ -49,7 +49,7 @@
 
 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);
-
-            if cases.is_empty() {
-                // Uninhabitable; represent as unit
-                // (Typechecking will reject discriminant-sizing attrs.)
-                assert_eq!(hint, attr::ReprAny);
-                return Univariant(mk_struct(cx, &[], false, t));
+        ty::TyAdt(def, substs) => match def.adt_kind() {
+            AdtKind::Struct => {
+                let ftys = def.struct_variant().fields.iter().map(|field| {
+                    monomorphize::field_ty(cx.tcx(), substs, field)
+                }).collect::<Vec<_>>();
+                let packed = cx.tcx().lookup_packed(def.did);
+
+                Univariant(mk_struct(cx, &ftys[..], packed, t))
             }
-
-            if cases.iter().all(|c| c.tys.is_empty()) {
-                // All bodies empty -> intlike
-                let discrs: Vec<_> = cases.iter().map(|c| Disr::from(c.discr)).collect();
-                let bounds = IntBounds {
-                    ulo: discrs.iter().min().unwrap().0,
-                    uhi: discrs.iter().max().unwrap().0,
-                    slo: discrs.iter().map(|n| n.0 as i64).min().unwrap(),
-                    shi: discrs.iter().map(|n| n.0 as i64).max().unwrap()
-                };
-                return mk_cenum(cx, hint, &bounds);
+            AdtKind::Union => {
+                let ftys = def.struct_variant().fields.iter().map(|field| {
+                    monomorphize::field_ty(cx.tcx(), substs, field)
+                }).collect::<Vec<_>>();
+                let packed = cx.tcx().lookup_packed(def.did);
+                UntaggedUnion(mk_union(cx, &ftys[..], packed, t))
             }
+            AdtKind::Enum => {
+                let cases = get_cases(cx.tcx(), def, substs);
+                let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
+                    .unwrap_or(&attr::ReprAny);
+
+                if cases.is_empty() {
+                    // Uninhabitable; represent as unit
+                    // (Typechecking will reject discriminant-sizing attrs.)
+                    assert_eq!(hint, attr::ReprAny);
+                    return Univariant(mk_struct(cx, &[], false, t));
+                }
 
-            // Since there's at least one
-            // non-empty body, explicit discriminants should have
-            // been rejected by a checker before this point.
-            if !cases.iter().enumerate().all(|(i,c)| c.discr == Disr::from(i)) {
-                bug!("non-C-like enum {} with specified discriminants",
-                     cx.tcx().item_path_str(def.did));
-            }
+                if cases.iter().all(|c| c.tys.is_empty()) {
+                    // All bodies empty -> intlike
+                    let discrs: Vec<_> = cases.iter().map(|c| Disr::from(c.discr)).collect();
+                    let bounds = IntBounds {
+                        ulo: discrs.iter().min().unwrap().0,
+                        uhi: discrs.iter().max().unwrap().0,
+                        slo: discrs.iter().map(|n| n.0 as i64).min().unwrap(),
+                        shi: discrs.iter().map(|n| n.0 as i64).max().unwrap()
+                    };
+                    return mk_cenum(cx, hint, &bounds);
+                }
 
-            if cases.len() == 1 && hint == attr::ReprAny {
-                // Equivalent to a struct/tuple/newtype.
-                return Univariant(mk_struct(cx, &cases[0].tys, false, t));
-            }
+                // Since there's at least one
+                // non-empty body, explicit discriminants should have
+                // been rejected by a checker before this point.
+                if !cases.iter().enumerate().all(|(i,c)| c.discr == Disr::from(i)) {
+                    bug!("non-C-like enum {} with specified discriminants",
+                        cx.tcx().item_path_str(def.did));
+                }
 
-            if cases.len() == 2 && hint == attr::ReprAny {
-                // Nullable pointer optimization
-                let mut discr = 0;
-                while discr < 2 {
-                    if cases[1 - discr].is_zerolen(cx, t) {
-                        let st = mk_struct(cx, &cases[discr].tys,
-                                           false, t);
-                        match cases[discr].find_ptr(cx) {
-                            Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
-                                return RawNullablePointer {
-                                    nndiscr: Disr::from(discr),
-                                    nnty: st.fields[0],
-                                    nullfields: cases[1 - discr].tys.clone()
-                                };
-                            }
-                            Some(mut discrfield) => {
-                                discrfield.push(0);
-                                discrfield.reverse();
-                                return StructWrappedNullablePointer {
-                                    nndiscr: Disr::from(discr),
-                                    nonnull: st,
-                                    discrfield: discrfield,
-                                    nullfields: cases[1 - discr].tys.clone()
-                                };
+                if cases.len() == 1 && hint == attr::ReprAny {
+                    // Equivalent to a struct/tuple/newtype.
+                    return Univariant(mk_struct(cx, &cases[0].tys, false, t));
+                }
+
+                if cases.len() == 2 && hint == attr::ReprAny {
+                    // Nullable pointer optimization
+                    let mut discr = 0;
+                    while discr < 2 {
+                        if cases[1 - discr].is_zerolen(cx, t) {
+                            let st = mk_struct(cx, &cases[discr].tys,
+                                            false, t);
+                            match cases[discr].find_ptr(cx) {
+                                Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
+                                    return RawNullablePointer {
+                                        nndiscr: Disr::from(discr),
+                                        nnty: st.fields[0],
+                                        nullfields: cases[1 - discr].tys.clone()
+                                    };
+                                }
+                                Some(mut discrfield) => {
+                                    discrfield.push(0);
+                                    discrfield.reverse();
+                                    return StructWrappedNullablePointer {
+                                        nndiscr: Disr::from(discr),
+                                        nonnull: st,
+                                        discrfield: discrfield,
+                                        nullfields: cases[1 - discr].tys.clone()
+                                    };
+                                }
+                                None => {}
                             }
-                            None => {}
                         }
+                        discr += 1;
                     }
-                    discr += 1;
                 }
-            }
 
-            // The general case.
-            assert!((cases.len() - 1) as i64 >= 0);
-            let bounds = IntBounds { ulo: 0, uhi: (cases.len() - 1) as u64,
-                                     slo: 0, shi: (cases.len() - 1) as i64 };
-            let min_ity = range_to_inttype(cx, hint, &bounds);
-
-            // Create the set of structs that represent each variant
-            // Use the minimum integer type we figured out above
-            let fields : Vec<_> = cases.iter().map(|c| {
-                let mut ftys = vec!(ty_of_inttype(cx.tcx(), min_ity));
-                ftys.extend_from_slice(&c.tys);
-                mk_struct(cx, &ftys, false, t)
-            }).collect();
-
-
-            // Check to see if we should use a different type for the
-            // discriminant. If the overall alignment of the type is
-            // the same as the first field in each variant, we can safely use
-            // an alignment-sized type.
-            // We increase the size of the discriminant to avoid LLVM copying
-            // padding when it doesn't need to. This normally causes unaligned
-            // load/stores and excessive memcpy/memset operations. By using a
-            // bigger integer size, LLVM can be sure about it's contents and
-            // won't be so conservative.
-            // This check is needed to avoid increasing the size of types when
-            // the alignment of the first field is smaller than the overall
-            // alignment of the type.
-            let (_, align) = union_size_and_align(&fields);
-            let mut use_align = true;
-            for st in &fields {
-                // Get the first non-zero-sized field
-                let field = st.fields.iter().skip(1).filter(|ty| {
-                    let t = type_of::sizing_type_of(cx, **ty);
-                    machine::llsize_of_real(cx, t) != 0 ||
-                    // This case is only relevant for zero-sized types with large alignment
-                    machine::llalign_of_min(cx, t) != 1
-                }).next();
-
-                if let Some(field) = field {
-                    let field_align = type_of::align_of(cx, *field);
-                    if field_align != align {
-                        use_align = false;
-                        break;
+                // The general case.
+                assert!((cases.len() - 1) as i64 >= 0);
+                let bounds = IntBounds { ulo: 0, uhi: (cases.len() - 1) as u64,
+                                        slo: 0, shi: (cases.len() - 1) as i64 };
+                let min_ity = range_to_inttype(cx, hint, &bounds);
+
+                // Create the set of structs that represent each variant
+                // Use the minimum integer type we figured out above
+                let fields : Vec<_> = cases.iter().map(|c| {
+                    let mut ftys = vec!(ty_of_inttype(cx.tcx(), min_ity));
+                    ftys.extend_from_slice(&c.tys);
+                    mk_struct(cx, &ftys, false, t)
+                }).collect();
+
+
+                // Check to see if we should use a different type for the
+                // discriminant. If the overall alignment of the type is
+                // the same as the first field in each variant, we can safely use
+                // an alignment-sized type.
+                // We increase the size of the discriminant to avoid LLVM copying
+                // padding when it doesn't need to. This normally causes unaligned
+                // load/stores and excessive memcpy/memset operations. By using a
+                // bigger integer size, LLVM can be sure about it's contents and
+                // won't be so conservative.
+                // This check is needed to avoid increasing the size of types when
+                // the alignment of the first field is smaller than the overall
+                // alignment of the type.
+                let (_, align) = union_size_and_align(&fields);
+                let mut use_align = true;
+                for st in &fields {
+                    // Get the first non-zero-sized field
+                    let field = st.fields.iter().skip(1).filter(|ty| {
+                        let t = type_of::sizing_type_of(cx, **ty);
+                        machine::llsize_of_real(cx, t) != 0 ||
+                        // This case is only relevant for zero-sized types with large alignment
+                        machine::llalign_of_min(cx, t) != 1
+                    }).next();
+
+                    if let Some(field) = field {
+                        let field_align = type_of::align_of(cx, *field);
+                        if field_align != align {
+                            use_align = false;
+                            break;
+                        }
                     }
                 }
-            }
 
-            // If the alignment is smaller than the chosen discriminant size, don't use the
-            // alignment as the final size.
-            let min_ty = ll_inttype(&cx, min_ity);
-            let min_size = machine::llsize_of_real(cx, min_ty);
-            if (align as u64) < min_size {
-                use_align = false;
-            }
-
-            let ity = if use_align {
-                // Use the overall alignment
-                match align {
-                    1 => attr::UnsignedInt(ast::UintTy::U8),
-                    2 => attr::UnsignedInt(ast::UintTy::U16),
-                    4 => attr::UnsignedInt(ast::UintTy::U32),
-                    8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
-                        attr::UnsignedInt(ast::UintTy::U64),
-                    _ => min_ity // use min_ity as a fallback
+                // If the alignment is smaller than the chosen discriminant size, don't use the
+                // alignment as the final size.
+                let min_ty = ll_inttype(&cx, min_ity);
+                let min_size = machine::llsize_of_real(cx, min_ty);
+                if (align as u64) < min_size {
+                    use_align = false;
                 }
-            } else {
-                min_ity
-            };
 
-            let fields : Vec<_> = cases.iter().map(|c| {
-                let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
-                ftys.extend_from_slice(&c.tys);
-                mk_struct(cx, &ftys[..], false, t)
-            }).collect();
+                let ity = if use_align {
+                    // Use the overall alignment
+                    match align {
+                        1 => attr::UnsignedInt(ast::UintTy::U8),
+                        2 => attr::UnsignedInt(ast::UintTy::U16),
+                        4 => attr::UnsignedInt(ast::UintTy::U32),
+                        8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
+                            attr::UnsignedInt(ast::UintTy::U64),
+                        _ => min_ity // use min_ity as a fallback
+                    }
+                } else {
+                    min_ity
+                };
 
-            ensure_enum_fits_in_address_space(cx, &fields[..], t);
+                let fields : Vec<_> = cases.iter().map(|c| {
+                    let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
+                    ftys.extend_from_slice(&c.tys);
+                    mk_struct(cx, &ftys[..], false, t)
+                }).collect();
 
-            General(ity, fields)
-        }
+                ensure_enum_fits_in_address_space(cx, &fields[..], t);
+
+                General(ity, fields)
+            }
+        },
         _ => bug!("adt::represent_type called on non-ADT type: {}", t)
     }
 }
@@ -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()) {
index ec8ab33c4ca54878091ba5e1544f1779ffa75232..a6581ae605b56600e26d91482b2651ca2b0b1824 100644 (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);
index 704fac5ce7e5391b3a21b618c365cc25ce52ef7d..5a8ab62a2aa2d4f18d09b65b8e940996617365c4 100644 (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);
index bd98eee8869b17f957d67218f061d58928cefb6e..e0de04d150ca7446adba00b9ab1b5fafe4851a3d 100644 (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 @@ pub fn from_ty(tcx: TyCtxt<'a, 'tcx, '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)
index 2422b9f30069b16a38bbc0fa1817bf4c0b86ce85..b10129d1019aefc2b5ba4e6c5c75d57e4272201e 100644 (file)
@@ -223,13 +223,9 @@ fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
         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)
index 1bf1023dcd895104be750811bcbf90ab05a1ad44..31df49609cb8bf360afceb6d2594f9dc3a9a4f0d 100644 (file)
@@ -30,7 +30,7 @@
 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 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, '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);
index 20a33498475a2c920ce99fe54b07730afeedd166..bcd288671bc1915370b2c35ee767960611243e21 100644 (file)
@@ -421,7 +421,7 @@ fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, '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
index 8291f84054d0ccd4190c73d6493d67744ef80067..7f021bee371990d6ce82ff13b3500318d7b89353 100644 (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);
         },
index 34c92f334d0ac6d387eebcfeecc45e3cfddf21aa..6c1c5ac2d10e8efcd0609e2086d1fe91188d219a 100644 (file)
@@ -19,7 +19,7 @@
 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 iter_variant<'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 iter_variant<'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;
-
-            let repr = adt::represent_type(ccx, t);
-            let n_variants = en.variants.len();
-
-            // NB: we must hit the discriminant first so that structural
-            // comparison know not to proceed when the discriminants differ.
-
-            match adt::trans_switch(cx, &repr, av, false) {
-                (adt::BranchKind::Single, None) => {
-                    if n_variants != 0 {
-                        assert!(n_variants == 1);
-                        cx = iter_variant(cx, &repr, adt::MaybeSizedValue::sized(av),
-                                          &en.variants[0], substs);
-                    }
+        ty::TyAdt(adt, substs) => match adt.adt_kind() {
+            AdtKind::Struct => {
+                let repr = adt::represent_type(cx.ccx(), t);
+                let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
+                for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
+                    let llfld_a = adt::trans_field_ptr(cx, &repr, value, Disr::from(discr), i);
+
+                    let val = if type_is_sized(cx.tcx(), field_ty) {
+                        llfld_a
+                    } else {
+                        let scratch = alloc_ty(cx, field_ty, "__fat_ptr_iter");
+                        Store(cx, llfld_a, get_dataptr(cx, scratch));
+                        Store(cx, value.meta, get_meta(cx, scratch));
+                        scratch
+                    };
+                    cx = drop_ty(cx, val, field_ty, DebugLoc::None);
                 }
-                (adt::BranchKind::Switch, Some(lldiscrim_a)) => {
-                    cx = drop_ty(cx, lldiscrim_a, cx.tcx().types.isize, DebugLoc::None);
-
-                    // Create a fall-through basic block for the "else" case of
-                    // the switch instruction we're about to generate. Note that
-                    // we do **not** use an Unreachable instruction here, even
-                    // though most of the time this basic block will never be hit.
-                    //
-                    // When an enum is dropped it's contents are currently
-                    // overwritten to DTOR_DONE, which means the discriminant
-                    // could have changed value to something not within the actual
-                    // range of the discriminant. Currently this function is only
-                    // used for drop glue so in this case we just return quickly
-                    // from the outer function, and any other use case will only
-                    // call this for an already-valid enum in which case the `ret
-                    // void` will never be hit.
-                    let ret_void_cx = fcx.new_block("enum-iter-ret-void");
-                    RetVoid(ret_void_cx, DebugLoc::None);
-                    let llswitch = Switch(cx, lldiscrim_a, ret_void_cx.llbb, n_variants);
-                    let next_cx = fcx.new_block("enum-iter-next");
-
-                    for variant in &en.variants {
-                        let variant_cx = fcx.new_block(&format!("enum-iter-variant-{}",
-                                                                     &variant.disr_val
-                                                                             .to_string()));
-                        let case_val = adt::trans_case(cx, &repr, Disr::from(variant.disr_val));
-                        AddCase(llswitch, case_val, variant_cx.llbb);
-                        let variant_cx = iter_variant(variant_cx,
-                                                      &repr,
-                                                      value,
-                                                      variant,
-                                                      substs);
-                        Br(variant_cx, next_cx.llbb, DebugLoc::None);
+            }
+            AdtKind::Union => {
+                bug!("Union in `glue::drop_structural_ty`");
+            }
+            AdtKind::Enum => {
+                let fcx = cx.fcx;
+                let ccx = fcx.ccx;
+
+                let repr = adt::represent_type(ccx, t);
+                let n_variants = adt.variants.len();
+
+                // NB: we must hit the discriminant first so that structural
+                // comparison know not to proceed when the discriminants differ.
+
+                match adt::trans_switch(cx, &repr, av, false) {
+                    (adt::BranchKind::Single, None) => {
+                        if n_variants != 0 {
+                            assert!(n_variants == 1);
+                            cx = iter_variant(cx, &repr, adt::MaybeSizedValue::sized(av),
+                                            &adt.variants[0], substs);
+                        }
                     }
-                    cx = next_cx;
+                    (adt::BranchKind::Switch, Some(lldiscrim_a)) => {
+                        cx = drop_ty(cx, lldiscrim_a, cx.tcx().types.isize, DebugLoc::None);
+
+                        // Create a fall-through basic block for the "else" case of
+                        // the switch instruction we're about to generate. Note that
+                        // we do **not** use an Unreachable instruction here, even
+                        // though most of the time this basic block will never be hit.
+                        //
+                        // When an enum is dropped it's contents are currently
+                        // overwritten to DTOR_DONE, which means the discriminant
+                        // could have changed value to something not within the actual
+                        // range of the discriminant. Currently this function is only
+                        // used for drop glue so in this case we just return quickly
+                        // from the outer function, and any other use case will only
+                        // call this for an already-valid enum in which case the `ret
+                        // void` will never be hit.
+                        let ret_void_cx = fcx.new_block("enum-iter-ret-void");
+                        RetVoid(ret_void_cx, DebugLoc::None);
+                        let llswitch = Switch(cx, lldiscrim_a, ret_void_cx.llbb, n_variants);
+                        let next_cx = fcx.new_block("enum-iter-next");
+
+                        for variant in &adt.variants {
+                            let variant_cx = fcx.new_block(&format!("enum-iter-variant-{}",
+                                                                        &variant.disr_val
+                                                                                .to_string()));
+                            let case_val = adt::trans_case(cx, &repr, Disr::from(variant.disr_val));
+                            AddCase(llswitch, case_val, variant_cx.llbb);
+                            let variant_cx = iter_variant(variant_cx,
+                                                        &repr,
+                                                        value,
+                                                        variant,
+                                                        substs);
+                            Br(variant_cx, next_cx.llbb, DebugLoc::None);
+                        }
+                        cx = next_cx;
+                    }
+                    _ => ccx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
                 }
-                _ => ccx.sess().unimpl("value from adt::trans_switch in drop_structural_ty"),
             }
-        }
+        },
+
         _ => {
             cx.sess().unimpl(&format!("type in drop_structural_ty: {}", t))
         }
index c0ff6c508bf3e02ebc4e117ec436b5948bebdb19..2049696ee4f717ba704210c6aa4ed123c77022a8 100644 (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)
index e078d46274d3ede579e0fb937e4b4ea38668837e..44e613c4c2b043ab40539722f5a3b13ff879ed8d 100644 (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);
         },
index b5565109306b4d57321729cadae3d11bd1352052..3873c24a9f676971b1c9cadd5e517331ef8d45f3 100644 (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);
         }
index 17fb68339198242133bcdc7dfd5e98a7288cd086..dd3ac6ff2d457838be93c8ebeddecd4008a1d6c7 100644 (file)
@@ -617,7 +617,7 @@ fn check_pat_tuple_struct(&self,
         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 @@ fn check_struct_pat_fields(&self,
         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")
         };
 
index 0c9da86563ab21af6f8be9965a4e3776852050f2..51a9b18392dcf332f93eaca5b7fa9e632f6fcd9a 100644 (file)
@@ -79,7 +79,7 @@ fn unsize_kind(&self, t: Ty<'tcx>) -> Option<UnsizeKind<'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,
index 88add66b7dcb0a2059a20e94f7172a12417b9d94..cc958fb3b2343042152e41dc98804e8192882c06 100644 (file)
@@ -16,7 +16,7 @@
 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(..) => {
index 058049992dc00b21f56b42846048b092722496f3..81e95c91e7ff94e0657b5225be12e2acdb766ace 100644 (file)
@@ -292,9 +292,7 @@ fn assemble_probe(&mut self, self_ty: Ty<'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(_) => {
index e4ea9bb407d96e26332a74f3ef93d8324e3c89ae..3692d6fbf73d6a9069ebb472ad5bb8cda3cae1c4 100644 (file)
@@ -165,7 +165,7 @@ pub fn report_method_error(&self,
                 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 @@ fn type_derefs_to_local(&self,
                             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(),
 
index b059c2ab9f3a8d0f6f41b45d5c9b4f941275749e..005cd2e46b89f71b9ce4f32c6babe1c65dd88595 100644 (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 @@ fn check_field(&self,
         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 @@ fn check_field(&self,
                         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 @@ fn check_tup_field(&self,
         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 @@ fn report_unknown_field(&self,
                             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 @@ fn check_expr_struct_fields(&self,
                                 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 @@ pub fn check_struct_path(&self,
             }
             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 @@ fn check_expr_struct(&self,
         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| {
index d2b7f07b9ce6ca0102dc44c79afa444d16e3ddce..046ba5fb4523c86076be20eada5e2004ec230f62 100644 (file)
@@ -22,9 +22,9 @@
 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 @@ fn populate_destructors(&self) {
 
             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 @@ fn check_implementations_of_coerce_unsized(&self) {
                         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);
index cb424eb48e9328057e34ed1ebf2e6c87db6f9529..d1eb0f995de133b82a6d1e8a79616844c4440429 100644 (file)
@@ -75,9 +75,7 @@ fn check_item(&self, item: &hir::Item) {
                        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 @@ fn check_item(&self, item: &hir::Item) {
                 {
                     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 {
index fcc0b09e31acf158db22235f004e7910f3c464d8..082690149c9d1216c169a3bb6ba3e03bdca18be4 100644 (file)
@@ -67,7 +67,7 @@
 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(..) |
index 1e38f464651b9a008c1cc4394e5282c333638f09..b18792d894287844dab3c65854b8fee268e7b417 100644 (file)
@@ -344,9 +344,7 @@ fn add_constraints_from_ty(&mut self,
                 }
             }
 
-            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
index 18c12f98fb428cd1f939d263c3367f273d1f6475..f1b907e70d74e0324e7b8023d80405c2fe8e2190 100644 (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,
index 79c66be5e57d79fafbf06da56d6b4e7bce94aea4..b9dc75cdd9f12dda6084e2e50a56df6bdfb36667 100644 (file)
@@ -41,7 +41,7 @@
 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 @@ fn clean(&self, cx: &DocContext) -> Type {
                 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(),
index 4cb846b51868fc9d62ded630170e5a3e62d817af..ca1027b11adce26a27549f0eb4f975a79ae0041d 100644 (file)
@@ -75,13 +75,13 @@ pub trait FooTrait {
         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)