Skip to content

Commit 7f0d261

Browse files
committed
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.
2 parents c8f69dd + 0766c89 commit 7f0d261

21 files changed

+128
-64
lines changed

src/librustc/metadata/decoder.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ enum Family {
115115
Mod, // m
116116
ForeignMod, // n
117117
Enum, // t
118-
Variant, // v
118+
TupleVariant, // v
119+
StructVariant, // V
119120
Impl, // i
120121
Trait, // I
121122
Struct, // S
@@ -139,7 +140,8 @@ fn item_family(item: ebml::Doc) -> Family {
139140
'm' => Mod,
140141
'n' => ForeignMod,
141142
't' => Enum,
142-
'v' => Variant,
143+
'v' => TupleVariant,
144+
'V' => StructVariant,
143145
'i' => Impl,
144146
'I' => Trait,
145147
'S' => Struct,
@@ -361,9 +363,13 @@ fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
361363
Type | ForeignType => DlDef(ast::DefTy(did)),
362364
Mod => DlDef(ast::DefMod(did)),
363365
ForeignMod => DlDef(ast::DefForeignMod(did)),
364-
Variant => {
366+
StructVariant => {
365367
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
366-
DlDef(ast::DefVariant(enum_did, did))
368+
DlDef(ast::DefVariant(enum_did, did, true))
369+
}
370+
TupleVariant => {
371+
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
372+
DlDef(ast::DefVariant(enum_did, did, false))
367373
}
368374
Trait => DlDef(ast::DefTrait(did)),
369375
Enum => DlDef(ast::DefTy(did)),
@@ -575,8 +581,8 @@ impl<'self> EachItemContext<'self> {
575581
}
576582
ImmStatic | MutStatic | Struct | UnsafeFn | Fn | ForeignFn |
577583
UnsafeStaticMethod | StaticMethod | Type | ForeignType |
578-
Variant | Enum | PublicField | PrivateField |
579-
InheritedField => {}
584+
TupleVariant | StructVariant | Enum | PublicField |
585+
PrivateField | InheritedField => {}
580586
}
581587
}
582588

@@ -1268,7 +1274,8 @@ fn item_family_to_str(fam: Family) -> ~str {
12681274
Mod => ~"mod",
12691275
ForeignMod => ~"foreign mod",
12701276
Enum => ~"enum",
1271-
Variant => ~"variant",
1277+
StructVariant => ~"struct variant",
1278+
TupleVariant => ~"tuple variant",
12721279
Impl => ~"impl",
12731280
Trait => ~"trait",
12741281
Struct => ~"struct",

src/librustc/metadata/encoder.rs

+34-18
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,27 @@ fn encode_parent_item(ebml_w: &mut writer::Encoder, id: DefId) {
307307
ebml_w.end_tag();
308308
}
309309

310+
fn encode_struct_fields(ecx: &EncodeContext,
311+
ebml_w: &mut writer::Encoder,
312+
def: @struct_def) {
313+
for f in def.fields.iter() {
314+
match f.node.kind {
315+
named_field(ident, vis) => {
316+
ebml_w.start_tag(tag_item_field);
317+
encode_struct_field_family(ebml_w, vis);
318+
encode_name(ecx, ebml_w, ident);
319+
encode_def_id(ebml_w, local_def(f.node.id));
320+
ebml_w.end_tag();
321+
}
322+
unnamed_field => {
323+
ebml_w.start_tag(tag_item_unnamed_field);
324+
encode_def_id(ebml_w, local_def(f.node.id));
325+
ebml_w.end_tag();
326+
}
327+
}
328+
}
329+
}
330+
310331
fn encode_enum_variant_info(ecx: &EncodeContext,
311332
ebml_w: &mut writer::Encoder,
312333
id: NodeId,
@@ -326,7 +347,10 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
326347
pos: ebml_w.writer.tell()});
327348
ebml_w.start_tag(tag_items_data_item);
328349
encode_def_id(ebml_w, def_id);
329-
encode_family(ebml_w, 'v');
350+
match variant.node.kind {
351+
ast::tuple_variant_kind(_) => encode_family(ebml_w, 'v'),
352+
ast::struct_variant_kind(_) => encode_family(ebml_w, 'V')
353+
}
330354
encode_name(ecx, ebml_w, variant.node.name);
331355
encode_parent_item(ebml_w, local_def(id));
332356
encode_visibility(ebml_w, variant.node.vis);
@@ -336,7 +360,14 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
336360
if args.len() > 0 && generics.ty_params.len() == 0 => {
337361
encode_symbol(ecx, ebml_w, variant.node.id);
338362
}
339-
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {}
363+
ast::tuple_variant_kind(_) => {},
364+
ast::struct_variant_kind(def) => {
365+
let idx = encode_info_for_struct(ecx, ebml_w, path,
366+
def.fields, index);
367+
encode_struct_fields(ecx, ebml_w, def);
368+
let bkts = create_index(idx);
369+
encode_index(ebml_w, bkts, write_i64);
370+
}
340371
}
341372
if vi[i].disr_val != disr_val {
342373
encode_disr_val(ecx, ebml_w, vi[i].disr_val);
@@ -986,22 +1017,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
9861017
/* Encode def_ids for each field and method
9871018
for methods, write all the stuff get_trait_method
9881019
needs to know*/
989-
for f in struct_def.fields.iter() {
990-
match f.node.kind {
991-
named_field(ident, vis) => {
992-
ebml_w.start_tag(tag_item_field);
993-
encode_struct_field_family(ebml_w, vis);
994-
encode_name(ecx, ebml_w, ident);
995-
encode_def_id(ebml_w, local_def(f.node.id));
996-
ebml_w.end_tag();
997-
}
998-
unnamed_field => {
999-
ebml_w.start_tag(tag_item_unnamed_field);
1000-
encode_def_id(ebml_w, local_def(f.node.id));
1001-
ebml_w.end_tag();
1002-
}
1003-
}
1004-
}
1020+
encode_struct_fields(ecx, ebml_w, struct_def);
10051021

10061022
// Encode inherent implementations for this structure.
10071023
encode_inherent_implementations(ecx, ebml_w, def_id);

src/librustc/middle/astencode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ impl tr for ast::Def {
396396
ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
397397
ast::DefArg(nid, b) => { ast::DefArg(xcx.tr_id(nid), b) }
398398
ast::DefLocal(nid, b) => { ast::DefLocal(xcx.tr_id(nid), b) }
399-
ast::DefVariant(e_did, v_did) => {
400-
ast::DefVariant(e_did.tr(xcx), v_did.tr(xcx))
399+
ast::DefVariant(e_did, v_did, is_s) => {
400+
ast::DefVariant(e_did.tr(xcx), v_did.tr(xcx), is_s)
401401
},
402402
ast::DefTrait(did) => ast::DefTrait(did.tr(xcx)),
403403
ast::DefTy(did) => ast::DefTy(did.tr(xcx)),

src/librustc/middle/check_const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
149149
match def_map.find(&e.id) {
150150
Some(&DefStatic(*)) |
151151
Some(&DefFn(_, _)) |
152-
Some(&DefVariant(_, _)) |
152+
Some(&DefVariant(_, _, _)) |
153153
Some(&DefStruct(_)) => { }
154154

155155
Some(&def) => {

src/librustc/middle/check_match.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
335335
PatWild => { None }
336336
PatIdent(_, _, _) | PatEnum(_, _) => {
337337
match cx.tcx.def_map.find(&pat.id) {
338-
Some(&DefVariant(_, id)) => Some(variant(id)),
338+
Some(&DefVariant(_, id, _)) => Some(variant(id)),
339339
Some(&DefStatic(did, false)) => {
340340
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
341341
Some(val(eval_const_expr(cx.tcx, const_expr)))
@@ -349,7 +349,7 @@ pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
349349
}
350350
PatStruct(*) => {
351351
match cx.tcx.def_map.find(&pat.id) {
352-
Some(&DefVariant(_, id)) => Some(variant(id)),
352+
Some(&DefVariant(_, id, _)) => Some(variant(id)),
353353
_ => Some(single)
354354
}
355355
}
@@ -371,7 +371,7 @@ pub fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool {
371371
PatWild => { true }
372372
PatIdent(_, _, _) => {
373373
match cx.tcx.def_map.find(&pat.id) {
374-
Some(&DefVariant(_, _)) | Some(&DefStatic(*)) => { false }
374+
Some(&DefVariant(_, _, _)) | Some(&DefStatic(*)) => { false }
375375
_ => { true }
376376
}
377377
}
@@ -547,7 +547,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
547547
}
548548
PatIdent(_, _, _) => {
549549
match cx.tcx.def_map.find(&pat_id) {
550-
Some(&DefVariant(_, id)) => {
550+
Some(&DefVariant(_, id, _)) => {
551551
if variant(id) == *ctor_id {
552552
Some(r.tail().to_owned())
553553
} else {
@@ -639,14 +639,14 @@ pub fn specialize(cx: &MatchCheckCtxt,
639639
None
640640
}
641641
}
642-
DefVariant(_, id) if variant(id) == *ctor_id => {
642+
DefVariant(_, id, _) if variant(id) == *ctor_id => {
643643
let args = match args {
644644
Some(args) => args,
645645
None => vec::from_elem(arity, wild())
646646
};
647647
Some(vec::append(args, r.tail()))
648648
}
649-
DefVariant(_, _) => None,
649+
DefVariant(_, _, _) => None,
650650

651651
DefFn(*) |
652652
DefStruct(*) => {
@@ -664,7 +664,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
664664
PatStruct(_, ref flds, _) => {
665665
// Is this a struct or an enum variant?
666666
match cx.tcx.def_map.get_copy(&pat_id) {
667-
DefVariant(_, variant_id) => {
667+
DefVariant(_, variant_id, _) => {
668668
if variant(variant_id) == *ctor_id {
669669
// FIXME #4731: Is this right? --pcw
670670
let args = flds.map(|ty_field| {
@@ -835,7 +835,7 @@ pub fn check_fn(v: &mut CheckMatchVisitor,
835835

836836
pub fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool {
837837
match cx.tcx.def_map.find(&pat.id) {
838-
Some(&DefVariant(enum_id, _)) => {
838+
Some(&DefVariant(enum_id, _, _)) => {
839839
if ty::enum_variants(cx.tcx, enum_id).len() != 1u {
840840
return true;
841841
}

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub fn classify(e: &Expr,
168168
pub fn lookup_const(tcx: ty::ctxt, e: &Expr) -> Option<@Expr> {
169169
match tcx.def_map.find(&e.id) {
170170
Some(&ast::DefStatic(def_id, false)) => lookup_const_by_id(tcx, def_id),
171-
Some(&ast::DefVariant(enum_def, variant_def)) => lookup_variant_by_id(tcx,
171+
Some(&ast::DefVariant(enum_def, variant_def, _)) => lookup_variant_by_id(tcx,
172172
enum_def,
173173
variant_def),
174174
_ => None

src/librustc/middle/kind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ fn is_nullary_variant(cx: Context, ex: @Expr) -> bool {
416416
match ex.node {
417417
ExprPath(_) => {
418418
match cx.tcx.def_map.get_copy(&ex.id) {
419-
DefVariant(edid, vdid) => {
419+
DefVariant(edid, vdid, _) => {
420420
ty::enum_variant_with_id(cx.tcx, edid, vdid).args.is_empty()
421421
}
422422
_ => false

src/librustc/middle/mem_categorization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ impl mem_categorization_ctxt {
889889
}
890890
ast::PatEnum(_, Some(ref subpats)) => {
891891
match self.tcx.def_map.find(&pat.id) {
892-
Some(&ast::DefVariant(enum_did, _)) => {
892+
Some(&ast::DefVariant(enum_did, _, _)) => {
893893
// variant(x, y, z)
894894

895895
let downcast_cmt = {
@@ -1074,7 +1074,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
10741074
}
10751075
ty::ty_enum(*) => {
10761076
match tcx.def_map.get_copy(&node_id) {
1077-
ast::DefVariant(_, variant_id) => {
1077+
ast::DefVariant(_, variant_id, _) => {
10781078
let r = ty::lookup_struct_fields(tcx, variant_id);
10791079
for fld in r.iter() {
10801080
if fld.ident == f_name {

src/librustc/middle/privacy.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
455455
if id.crate != LOCAL_CRATE ||
456456
!self.privileged_items.iter().any(|x| x == &(id.node)) {
457457
match self.tcx.def_map.get_copy(&expr.id) {
458-
DefVariant(_, variant_id) => {
458+
DefVariant(_, variant_id, _) => {
459459
for field in (*fields).iter() {
460460
debug!("(privacy checking) \
461461
checking field in \
@@ -522,7 +522,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
522522
if enum_id.crate != LOCAL_CRATE ||
523523
!self.privileged_items.iter().any(|x| x == &enum_id.node) {
524524
match self.tcx.def_map.find(&pattern.id) {
525-
Some(&DefVariant(_, variant_id)) => {
525+
Some(&DefVariant(_, variant_id, _)) => {
526526
for field in fields.iter() {
527527
debug!("(privacy checking) \
528528
checking field in \

src/librustc/middle/resolve.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -1474,15 +1474,15 @@ impl Resolver {
14741474
variant.span);
14751475
child.define_value(privacy,
14761476
DefVariant(item_id,
1477-
local_def(variant.node.id)),
1477+
local_def(variant.node.id), false),
14781478
variant.span);
14791479
}
14801480
struct_variant_kind(_) => {
14811481
let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
14821482
variant.span);
14831483
child.define_type(privacy,
14841484
DefVariant(item_id,
1485-
local_def(variant.node.id)),
1485+
local_def(variant.node.id), true),
14861486
variant.span);
14871487
self.structs.insert(local_def(variant.node.id));
14881488
}
@@ -1690,14 +1690,20 @@ impl Resolver {
16901690

16911691
match def {
16921692
DefMod(_) | DefForeignMod(_) => {}
1693-
DefVariant(*) => {
1693+
DefVariant(_, variant_id, is_struct) => {
16941694
debug!("(building reduced graph for external crate) building \
16951695
variant %s",
16961696
final_ident);
16971697
// We assume the parent is visible, or else we wouldn't have seen
16981698
// it.
16991699
let privacy = variant_visibility_to_privacy(visibility, true);
1700-
child_name_bindings.define_value(privacy, def, dummy_sp());
1700+
if is_struct {
1701+
child_name_bindings.define_type(privacy, def, dummy_sp());
1702+
self.structs.insert(variant_id);
1703+
}
1704+
else {
1705+
child_name_bindings.define_value(privacy, def, dummy_sp());
1706+
}
17011707
}
17021708
DefFn(*) | DefStaticMethod(*) | DefStatic(*) => {
17031709
debug!("(building reduced graph for external \
@@ -4507,7 +4513,7 @@ impl Resolver {
45074513
assert!(self.structs.contains(&class_id));
45084514
self.record_def(pattern.id, definition);
45094515
}
4510-
Some(definition @ DefVariant(_, variant_id))
4516+
Some(definition @ DefVariant(_, variant_id, _))
45114517
if self.structs.contains(&variant_id) => {
45124518
self.record_def(pattern.id, definition);
45134519
}
@@ -5123,7 +5129,7 @@ impl Resolver {
51235129
let class_def = DefStruct(class_id);
51245130
self.record_def(expr.id, class_def);
51255131
}
5126-
Some(definition @ DefVariant(_, class_id))
5132+
Some(definition @ DefVariant(_, class_id, _))
51275133
if self.structs.contains(&class_id) => {
51285134
self.record_def(expr.id, definition);
51295135
}

src/librustc/middle/trans/_match.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ fn variant_opt(bcx: @mut Block, pat_id: ast::NodeId)
347347
-> Opt {
348348
let ccx = bcx.ccx();
349349
match ccx.tcx.def_map.get_copy(&pat_id) {
350-
ast::DefVariant(enum_id, var_id) => {
350+
ast::DefVariant(enum_id, var_id, _) => {
351351
let variants = ty::enum_variants(ccx.tcx, enum_id);
352352
for v in (*variants).iter() {
353353
if var_id == v.id {
@@ -657,7 +657,7 @@ fn enter_opt<'r>(bcx: @mut Block,
657657
// Look up the struct variant ID.
658658
let struct_id;
659659
match tcx.def_map.get_copy(&p.id) {
660-
ast::DefVariant(_, found_struct_id) => {
660+
ast::DefVariant(_, found_struct_id, _) => {
661661
struct_id = found_struct_id;
662662
}
663663
_ => {
@@ -2113,7 +2113,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
21132113
}
21142114
ast::PatEnum(_, ref sub_pats) => {
21152115
match bcx.tcx().def_map.find(&pat.id) {
2116-
Some(&ast::DefVariant(enum_id, var_id)) => {
2116+
Some(&ast::DefVariant(enum_id, var_id, _)) => {
21172117
let repr = adt::represent_node(bcx, pat.id);
21182118
let vinfo = ty::enum_variant_with_id(ccx.tcx,
21192119
enum_id,

src/librustc/middle/trans/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub fn trans(bcx: @mut Block, expr: @ast::Expr) -> Callee {
128128
trait_did,
129129
ref_expr.id))
130130
}
131-
ast::DefVariant(tid, vid) => {
131+
ast::DefVariant(tid, vid, _) => {
132132
// nullary variants are not callable
133133
assert!(ty::enum_variant_with_id(bcx.tcx(),
134134
tid,

src/librustc/middle/trans/consts.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::Expr) -> ValueRef {
577577
Some(&ast::DefStatic(def_id, false)) => {
578578
get_const_val(cx, def_id)
579579
}
580-
Some(&ast::DefVariant(enum_did, variant_did)) => {
580+
Some(&ast::DefVariant(enum_did, variant_did, _)) => {
581581
let ety = ty::expr_ty(cx.tcx, e);
582582
let repr = adt::represent_type(cx, ety);
583583
let vinfo = ty::enum_variant_with_id(cx.tcx,
@@ -604,7 +604,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::Expr) -> ValueRef {
604604
let arg_vals = args.map(|a| const_expr(cx, *a));
605605
adt::trans_const(cx, repr, 0, arg_vals)
606606
}
607-
Some(&ast::DefVariant(enum_did, variant_did)) => {
607+
Some(&ast::DefVariant(enum_did, variant_did, _)) => {
608608
let ety = ty::expr_ty(cx.tcx, e);
609609
let repr = adt::represent_type(cx, ety);
610610
let vinfo = ty::enum_variant_with_id(cx.tcx,

0 commit comments

Comments
 (0)