about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-11 14:56:00 -0700
committerbors <bors@rust-lang.org>2013-09-11 14:56:00 -0700
commit7f0d261ae2d931a8a3e06d784840d85e25166d89 (patch)
treeb8bc39c2b74473ac60485d55539381fee9a29ffe
parentc8f69dd2a4cf80f98e1a1ad37febb4cc9948f5ee (diff)
parent0766c89b423d91e36d3f3ce0abcb3971a42d258e (diff)
downloadrust-7f0d261ae2d931a8a3e06d784840d85e25166d89.tar.gz
rust-7f0d261ae2d931a8a3e06d784840d85e25166d89.zip
auto merge of #9064 : SiegeLord/rust/external_struct_variants, r=luqmana
Fixes issues #5557 and #8746.

This patch adds an additional family for struct-like variants, and encodes some struct-like aspects of such variants that can then be properly decoded by resolve.

Note that I am not 100% sure how this fix works, but it fixes the issue without breaking any of the tests on my machine.
-rw-r--r--src/librustc/metadata/decoder.rs21
-rw-r--r--src/librustc/metadata/encoder.rs52
-rw-r--r--src/librustc/middle/astencode.rs4
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/check_match.rs16
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/kind.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs4
-rw-r--r--src/librustc/middle/privacy.rs4
-rw-r--r--src/librustc/middle/resolve.rs18
-rw-r--r--src/librustc/middle/trans/_match.rs6
-rw-r--r--src/librustc/middle/trans/callee.rs2
-rw-r--r--src/librustc/middle/trans/consts.rs4
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/ty.rs3
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustc/middle/typeck/check/mod.rs4
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/test/auxiliary/struct_variant_xc_aux.rs17
-rw-r--r--src/test/run-pass/struct_variant_xc.rs19
21 files changed, 128 insertions, 64 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 18446acfef6..debbc7591d4 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -115,7 +115,8 @@ enum Family {
     Mod,                   // m
     ForeignMod,            // n
     Enum,                  // t
-    Variant,               // v
+    TupleVariant,          // v
+    StructVariant,         // V
     Impl,                  // i
     Trait,                 // I
     Struct,                // S
@@ -139,7 +140,8 @@ fn item_family(item: ebml::Doc) -> Family {
       'm' => Mod,
       'n' => ForeignMod,
       't' => Enum,
-      'v' => Variant,
+      'v' => TupleVariant,
+      'V' => StructVariant,
       'i' => Impl,
       'I' => Trait,
       'S' => Struct,
@@ -361,9 +363,13 @@ fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         Type | ForeignType => DlDef(ast::DefTy(did)),
         Mod => DlDef(ast::DefMod(did)),
         ForeignMod => DlDef(ast::DefForeignMod(did)),
-        Variant => {
+        StructVariant => {
             let enum_did = item_reqd_and_translated_parent_item(cnum, item);
-            DlDef(ast::DefVariant(enum_did, did))
+            DlDef(ast::DefVariant(enum_did, did, true))
+        }
+        TupleVariant => {
+            let enum_did = item_reqd_and_translated_parent_item(cnum, item);
+            DlDef(ast::DefVariant(enum_did, did, false))
         }
         Trait => DlDef(ast::DefTrait(did)),
         Enum => DlDef(ast::DefTy(did)),
@@ -575,8 +581,8 @@ impl<'self> EachItemContext<'self> {
                 }
                 ImmStatic | MutStatic | Struct | UnsafeFn | Fn | ForeignFn |
                 UnsafeStaticMethod | StaticMethod | Type | ForeignType |
-                Variant | Enum | PublicField | PrivateField |
-                InheritedField => {}
+                TupleVariant | StructVariant | Enum | PublicField |
+                PrivateField | InheritedField => {}
             }
         }
 
@@ -1268,7 +1274,8 @@ fn item_family_to_str(fam: Family) -> ~str {
       Mod => ~"mod",
       ForeignMod => ~"foreign mod",
       Enum => ~"enum",
-      Variant => ~"variant",
+      StructVariant => ~"struct variant",
+      TupleVariant => ~"tuple variant",
       Impl => ~"impl",
       Trait => ~"trait",
       Struct => ~"struct",
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index d1eb959055b..98c7a7a126e 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -307,6 +307,27 @@ fn encode_parent_item(ebml_w: &mut writer::Encoder, id: DefId) {
     ebml_w.end_tag();
 }
 
+fn encode_struct_fields(ecx: &EncodeContext,
+                             ebml_w: &mut writer::Encoder,
+                             def: @struct_def) {
+    for f in def.fields.iter() {
+        match f.node.kind {
+            named_field(ident, vis) => {
+               ebml_w.start_tag(tag_item_field);
+               encode_struct_field_family(ebml_w, vis);
+               encode_name(ecx, ebml_w, ident);
+               encode_def_id(ebml_w, local_def(f.node.id));
+               ebml_w.end_tag();
+            }
+            unnamed_field => {
+                ebml_w.start_tag(tag_item_unnamed_field);
+                encode_def_id(ebml_w, local_def(f.node.id));
+                ebml_w.end_tag();
+            }
+        }
+    }
+}
+
 fn encode_enum_variant_info(ecx: &EncodeContext,
                             ebml_w: &mut writer::Encoder,
                             id: NodeId,
@@ -326,7 +347,10 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                           pos: ebml_w.writer.tell()});
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, def_id);
-        encode_family(ebml_w, 'v');
+        match variant.node.kind {
+            ast::tuple_variant_kind(_) => encode_family(ebml_w, 'v'),
+            ast::struct_variant_kind(_) => encode_family(ebml_w, 'V')
+        }
         encode_name(ecx, ebml_w, variant.node.name);
         encode_parent_item(ebml_w, local_def(id));
         encode_visibility(ebml_w, variant.node.vis);
@@ -336,7 +360,14 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                     if args.len() > 0 && generics.ty_params.len() == 0 => {
                 encode_symbol(ecx, ebml_w, variant.node.id);
             }
-            ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {}
+            ast::tuple_variant_kind(_) => {},
+            ast::struct_variant_kind(def) => {
+                let idx = encode_info_for_struct(ecx, ebml_w, path,
+                                         def.fields, index);
+                encode_struct_fields(ecx, ebml_w, def);
+                let bkts = create_index(idx);
+                encode_index(ebml_w, bkts, write_i64);
+            }
         }
         if vi[i].disr_val != disr_val {
             encode_disr_val(ecx, ebml_w, vi[i].disr_val);
@@ -986,22 +1017,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
         needs to know*/
-        for f in struct_def.fields.iter() {
-            match f.node.kind {
-                named_field(ident, vis) => {
-                   ebml_w.start_tag(tag_item_field);
-                   encode_struct_field_family(ebml_w, vis);
-                   encode_name(ecx, ebml_w, ident);
-                   encode_def_id(ebml_w, local_def(f.node.id));
-                   ebml_w.end_tag();
-                }
-                unnamed_field => {
-                    ebml_w.start_tag(tag_item_unnamed_field);
-                    encode_def_id(ebml_w, local_def(f.node.id));
-                    ebml_w.end_tag();
-                }
-            }
-        }
+        encode_struct_fields(ecx, ebml_w, struct_def);
 
         // Encode inherent implementations for this structure.
         encode_inherent_implementations(ecx, ebml_w, def_id);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index b6ccda5e1d1..bcc333afeec 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -396,8 +396,8 @@ impl tr for ast::Def {
           ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
           ast::DefArg(nid, b) => { ast::DefArg(xcx.tr_id(nid), b) }
           ast::DefLocal(nid, b) => { ast::DefLocal(xcx.tr_id(nid), b) }
-          ast::DefVariant(e_did, v_did) => {
-            ast::DefVariant(e_did.tr(xcx), v_did.tr(xcx))
+          ast::DefVariant(e_did, v_did, is_s) => {
+            ast::DefVariant(e_did.tr(xcx), v_did.tr(xcx), is_s)
           },
           ast::DefTrait(did) => ast::DefTrait(did.tr(xcx)),
           ast::DefTy(did) => ast::DefTy(did.tr(xcx)),
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 26427648674..fe5925f26f0 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -149,7 +149,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
             match def_map.find(&e.id) {
               Some(&DefStatic(*)) |
               Some(&DefFn(_, _)) |
-              Some(&DefVariant(_, _)) |
+              Some(&DefVariant(_, _, _)) |
               Some(&DefStruct(_)) => { }
 
               Some(&def) => {
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 581e203ae9a..16338b25bf4 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -335,7 +335,7 @@ pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
       PatWild => { None }
       PatIdent(_, _, _) | PatEnum(_, _) => {
         match cx.tcx.def_map.find(&pat.id) {
-          Some(&DefVariant(_, id)) => Some(variant(id)),
+          Some(&DefVariant(_, id, _)) => Some(variant(id)),
           Some(&DefStatic(did, false)) => {
             let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
             Some(val(eval_const_expr(cx.tcx, const_expr)))
@@ -349,7 +349,7 @@ pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
       }
       PatStruct(*) => {
         match cx.tcx.def_map.find(&pat.id) {
-          Some(&DefVariant(_, id)) => Some(variant(id)),
+          Some(&DefVariant(_, id, _)) => Some(variant(id)),
           _ => Some(single)
         }
       }
@@ -371,7 +371,7 @@ pub fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool {
       PatWild => { true }
       PatIdent(_, _, _) => {
         match cx.tcx.def_map.find(&pat.id) {
-          Some(&DefVariant(_, _)) | Some(&DefStatic(*)) => { false }
+          Some(&DefVariant(_, _, _)) | Some(&DefStatic(*)) => { false }
           _ => { true }
         }
       }
@@ -547,7 +547,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
             }
             PatIdent(_, _, _) => {
                 match cx.tcx.def_map.find(&pat_id) {
-                    Some(&DefVariant(_, id)) => {
+                    Some(&DefVariant(_, id, _)) => {
                         if variant(id) == *ctor_id {
                             Some(r.tail().to_owned())
                         } else {
@@ -639,14 +639,14 @@ pub fn specialize(cx: &MatchCheckCtxt,
                             None
                         }
                     }
-                    DefVariant(_, id) if variant(id) == *ctor_id => {
+                    DefVariant(_, id, _) if variant(id) == *ctor_id => {
                         let args = match args {
                             Some(args) => args,
                             None => vec::from_elem(arity, wild())
                         };
                         Some(vec::append(args, r.tail()))
                     }
-                    DefVariant(_, _) => None,
+                    DefVariant(_, _, _) => None,
 
                     DefFn(*) |
                     DefStruct(*) => {
@@ -664,7 +664,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
             PatStruct(_, ref flds, _) => {
                 // Is this a struct or an enum variant?
                 match cx.tcx.def_map.get_copy(&pat_id) {
-                    DefVariant(_, variant_id) => {
+                    DefVariant(_, variant_id, _) => {
                         if variant(variant_id) == *ctor_id {
                             // FIXME #4731: Is this right? --pcw
                             let args = flds.map(|ty_field| {
@@ -835,7 +835,7 @@ pub fn check_fn(v: &mut CheckMatchVisitor,
 
 pub fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool {
     match cx.tcx.def_map.find(&pat.id) {
-      Some(&DefVariant(enum_id, _)) => {
+      Some(&DefVariant(enum_id, _, _)) => {
         if ty::enum_variants(cx.tcx, enum_id).len() != 1u {
             return true;
         }
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index ad9a3b2f4e7..2e5e87f225a 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -168,7 +168,7 @@ pub fn classify(e: &Expr,
 pub fn lookup_const(tcx: ty::ctxt, e: &Expr) -> Option<@Expr> {
     match tcx.def_map.find(&e.id) {
         Some(&ast::DefStatic(def_id, false)) => lookup_const_by_id(tcx, def_id),
-        Some(&ast::DefVariant(enum_def, variant_def)) => lookup_variant_by_id(tcx,
+        Some(&ast::DefVariant(enum_def, variant_def, _)) => lookup_variant_by_id(tcx,
                                                                                enum_def,
                                                                                variant_def),
         _ => None
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index d3b94e9f7c6..6ca8086efc2 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -416,7 +416,7 @@ fn is_nullary_variant(cx: Context, ex: @Expr) -> bool {
     match ex.node {
       ExprPath(_) => {
         match cx.tcx.def_map.get_copy(&ex.id) {
-          DefVariant(edid, vdid) => {
+          DefVariant(edid, vdid, _) => {
               ty::enum_variant_with_id(cx.tcx, edid, vdid).args.is_empty()
           }
           _ => false
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index b284cd967a7..63b63d8d691 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -889,7 +889,7 @@ impl mem_categorization_ctxt {
           }
           ast::PatEnum(_, Some(ref subpats)) => {
             match self.tcx.def_map.find(&pat.id) {
-                Some(&ast::DefVariant(enum_did, _)) => {
+                Some(&ast::DefVariant(enum_did, _, _)) => {
                     // variant(x, y, z)
 
                     let downcast_cmt = {
@@ -1074,7 +1074,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
       }
       ty::ty_enum(*) => {
         match tcx.def_map.get_copy(&node_id) {
-          ast::DefVariant(_, variant_id) => {
+          ast::DefVariant(_, variant_id, _) => {
             let r = ty::lookup_struct_fields(tcx, variant_id);
             for fld in r.iter() {
                 if fld.ident == f_name {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index d6f61c6328a..085925f97a4 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -455,7 +455,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
                             if id.crate != LOCAL_CRATE ||
                                     !self.privileged_items.iter().any(|x| x == &(id.node)) {
                                 match self.tcx.def_map.get_copy(&expr.id) {
-                                    DefVariant(_, variant_id) => {
+                                    DefVariant(_, variant_id, _) => {
                                         for field in (*fields).iter() {
                                                 debug!("(privacy checking) \
                                                         checking field in \
@@ -522,7 +522,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
                             if enum_id.crate != LOCAL_CRATE ||
                                     !self.privileged_items.iter().any(|x| x == &enum_id.node) {
                                 match self.tcx.def_map.find(&pattern.id) {
-                                    Some(&DefVariant(_, variant_id)) => {
+                                    Some(&DefVariant(_, variant_id, _)) => {
                                         for field in fields.iter() {
                                             debug!("(privacy checking) \
                                                     checking field in \
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 335ea06eda9..3a9ef3cf06f 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1474,7 +1474,7 @@ impl Resolver {
                                                 variant.span);
                 child.define_value(privacy,
                                    DefVariant(item_id,
-                                               local_def(variant.node.id)),
+                                               local_def(variant.node.id), false),
                                    variant.span);
             }
             struct_variant_kind(_) => {
@@ -1482,7 +1482,7 @@ impl Resolver {
                                                 variant.span);
                 child.define_type(privacy,
                                   DefVariant(item_id,
-                                              local_def(variant.node.id)),
+                                              local_def(variant.node.id), true),
                                   variant.span);
                 self.structs.insert(local_def(variant.node.id));
             }
@@ -1690,14 +1690,20 @@ impl Resolver {
 
         match def {
           DefMod(_) | DefForeignMod(_) => {}
-          DefVariant(*) => {
+          DefVariant(_, variant_id, is_struct) => {
             debug!("(building reduced graph for external crate) building \
                     variant %s",
                    final_ident);
             // We assume the parent is visible, or else we wouldn't have seen
             // it.
             let privacy = variant_visibility_to_privacy(visibility, true);
-            child_name_bindings.define_value(privacy, def, dummy_sp());
+            if is_struct {
+                child_name_bindings.define_type(privacy, def, dummy_sp());
+                self.structs.insert(variant_id);
+            }
+            else {
+                child_name_bindings.define_value(privacy, def, dummy_sp());
+            }
           }
           DefFn(*) | DefStaticMethod(*) | DefStatic(*) => {
             debug!("(building reduced graph for external \
@@ -4507,7 +4513,7 @@ impl Resolver {
                             assert!(self.structs.contains(&class_id));
                             self.record_def(pattern.id, definition);
                         }
-                        Some(definition @ DefVariant(_, variant_id))
+                        Some(definition @ DefVariant(_, variant_id, _))
                                 if self.structs.contains(&variant_id) => {
                             self.record_def(pattern.id, definition);
                         }
@@ -5123,7 +5129,7 @@ impl Resolver {
                         let class_def = DefStruct(class_id);
                         self.record_def(expr.id, class_def);
                     }
-                    Some(definition @ DefVariant(_, class_id))
+                    Some(definition @ DefVariant(_, class_id, _))
                             if self.structs.contains(&class_id) => {
                         self.record_def(expr.id, definition);
                     }
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index d54a079a2bf..244e0e6e85d 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -347,7 +347,7 @@ fn variant_opt(bcx: @mut Block, pat_id: ast::NodeId)
     -> Opt {
     let ccx = bcx.ccx();
     match ccx.tcx.def_map.get_copy(&pat_id) {
-        ast::DefVariant(enum_id, var_id) => {
+        ast::DefVariant(enum_id, var_id, _) => {
             let variants = ty::enum_variants(ccx.tcx, enum_id);
             for v in (*variants).iter() {
                 if var_id == v.id {
@@ -657,7 +657,7 @@ fn enter_opt<'r>(bcx: @mut Block,
                     // Look up the struct variant ID.
                     let struct_id;
                     match tcx.def_map.get_copy(&p.id) {
-                        ast::DefVariant(_, found_struct_id) => {
+                        ast::DefVariant(_, found_struct_id, _) => {
                             struct_id = found_struct_id;
                         }
                         _ => {
@@ -2113,7 +2113,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
         }
         ast::PatEnum(_, ref sub_pats) => {
             match bcx.tcx().def_map.find(&pat.id) {
-                Some(&ast::DefVariant(enum_id, var_id)) => {
+                Some(&ast::DefVariant(enum_id, var_id, _)) => {
                     let repr = adt::represent_node(bcx, pat.id);
                     let vinfo = ty::enum_variant_with_id(ccx.tcx,
                                                          enum_id,
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 14be9bc2873..aa6e10a4a0d 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -128,7 +128,7 @@ pub fn trans(bcx: @mut Block, expr: @ast::Expr) -> Callee {
                                                                 trait_did,
                                                                 ref_expr.id))
             }
-            ast::DefVariant(tid, vid) => {
+            ast::DefVariant(tid, vid, _) => {
                 // nullary variants are not callable
                 assert!(ty::enum_variant_with_id(bcx.tcx(),
                                                       tid,
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 94f0b373570..78d2228ff04 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -577,7 +577,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::Expr) -> ValueRef {
                 Some(&ast::DefStatic(def_id, false)) => {
                     get_const_val(cx, def_id)
                 }
-                Some(&ast::DefVariant(enum_did, variant_did)) => {
+                Some(&ast::DefVariant(enum_did, variant_did, _)) => {
                     let ety = ty::expr_ty(cx.tcx, e);
                     let repr = adt::represent_type(cx, ety);
                     let vinfo = ty::enum_variant_with_id(cx.tcx,
@@ -604,7 +604,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::Expr) -> ValueRef {
                       let arg_vals = args.map(|a| const_expr(cx, *a));
                       adt::trans_const(cx, repr, 0, arg_vals)
                   }
-                  Some(&ast::DefVariant(enum_did, variant_did)) => {
+                  Some(&ast::DefVariant(enum_did, variant_did, _)) => {
                       let ety = ty::expr_ty(cx.tcx, e);
                       let repr = adt::represent_type(cx, ety);
                       let vinfo = ty::enum_variant_with_id(cx.tcx,
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index ea9e47416c1..b351fe91e6f 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -782,7 +782,7 @@ fn trans_def_dps_unadjusted(bcx: @mut Block, ref_expr: &ast::Expr,
     };
 
     match def {
-        ast::DefVariant(tid, vid) => {
+        ast::DefVariant(tid, vid, _) => {
             let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
             if variant_info.args.len() > 0u {
                 // N-ary variant.
@@ -1140,7 +1140,7 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
                 }
                 Some(node_id) => {
                     match tcx.def_map.get_copy(&node_id) {
-                        ast::DefVariant(enum_id, variant_id) => {
+                        ast::DefVariant(enum_id, variant_id, _) => {
                             let variant_info = ty::enum_variant_with_id(
                                 tcx, enum_id, variant_id);
                             op(variant_info.disr_val,
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index a438953be42..0e57bdc5321 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3630,7 +3630,7 @@ pub fn note_and_explain_type_err(cx: ctxt, err: &type_err) {
 
 pub fn def_has_ty_params(def: ast::Def) -> bool {
     match def {
-      ast::DefFn(_, _) | ast::DefVariant(_, _) | ast::DefStruct(_)
+      ast::DefFn(_, _) | ast::DefVariant(_, _, _) | ast::DefStruct(_)
         => true,
       _ => false
     }
@@ -3840,7 +3840,6 @@ impl VariantInfo {
     pub fn from_ast_variant(cx: ctxt,
                             ast_variant: &ast::variant,
                             discriminant: Disr) -> VariantInfo {
-
         let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
 
         match ast_variant.node.kind {
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index d813f973123..4c5ee1ca217 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -384,7 +384,7 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
 
     // Find the variant that was specified.
     match tcx.def_map.find(&pat_id) {
-        Some(&ast::DefVariant(found_enum_id, variant_id))
+        Some(&ast::DefVariant(found_enum_id, variant_id, _))
                 if found_enum_id == enum_id => {
             // Get the struct fields from this struct-like enum variant.
             let class_fields = ty::lookup_struct_fields(tcx, variant_id);
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 0c0326e9317..265e19fdaa7 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -2825,7 +2825,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                 check_struct_constructor(fcx, id, expr.span, type_def_id,
                                          *fields, base_expr);
             }
-            Some(&ast::DefVariant(enum_id, variant_id)) => {
+            Some(&ast::DefVariant(enum_id, variant_id, _)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, *fields);
             }
@@ -3256,7 +3256,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
           return no_params(typ);
       }
       ast::DefFn(id, _) | ast::DefStaticMethod(id, _, _) |
-      ast::DefStatic(id, _) | ast::DefVariant(_, id) |
+      ast::DefStatic(id, _) | ast::DefVariant(_, id, _) |
       ast::DefStruct(id) => {
         return ty::lookup_item_type(fcx.ccx.tcx, id);
       }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index ef2e557b6ea..f5de683cb97 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -233,7 +233,7 @@ pub enum Def {
     DefStatic(DefId, bool /* is_mutbl */),
     DefArg(NodeId, bool /* is_mutbl */),
     DefLocal(NodeId, bool /* is_mutbl */),
-    DefVariant(DefId /* enum */, DefId /* variant */),
+    DefVariant(DefId /* enum */, DefId /* variant */, bool /* is_structure */),
     DefTy(DefId),
     DefTrait(DefId),
     DefPrimTy(prim_ty),
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 040c4cda4c7..965f4a49aec 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -52,7 +52,7 @@ pub fn stmt_id(s: &Stmt) -> NodeId {
 
 pub fn variant_def_ids(d: Def) -> Option<(DefId, DefId)> {
     match d {
-      DefVariant(enum_id, var_id) => {
+      DefVariant(enum_id, var_id, _) => {
           Some((enum_id, var_id))
       }
       _ => None
@@ -63,7 +63,7 @@ pub fn def_id_of_def(d: Def) -> DefId {
     match d {
       DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
       DefForeignMod(id) | DefStatic(id, _) |
-      DefVariant(_, id) | DefTy(id) | DefTyParam(id, _) |
+      DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) |
       DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
         id
       }
diff --git a/src/test/auxiliary/struct_variant_xc_aux.rs b/src/test/auxiliary/struct_variant_xc_aux.rs
new file mode 100644
index 00000000000..6d2c77ffb0e
--- /dev/null
+++ b/src/test/auxiliary/struct_variant_xc_aux.rs
@@ -0,0 +1,17 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[link(name = "struct_variant_xc_aux",
+       vers = "0.1")];
+#[crate_type = "lib"];
+
+pub enum Enum {
+    Variant { arg: u8 }
+}
diff --git a/src/test/run-pass/struct_variant_xc.rs b/src/test/run-pass/struct_variant_xc.rs
new file mode 100644
index 00000000000..2dd7887cfcd
--- /dev/null
+++ b/src/test/run-pass/struct_variant_xc.rs
@@ -0,0 +1,19 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-fast - check-fast doesn't understand aux-build
+// aux-build:struct_variant_xc_aux.rs
+extern mod struct_variant_xc_aux;
+
+use struct_variant_xc_aux::Variant;
+
+fn main() {
+    let _ = Variant { arg: 1 };
+}