Skip to content

Commit

Permalink
Properly encode/decode structural variants.
Browse files Browse the repository at this point in the history
  • Loading branch information
SiegeLord committed Sep 11, 2013
1 parent f711650 commit 8c5402f
Show file tree
Hide file tree
Showing 19 changed files with 92 additions and 64 deletions.
21 changes: 14 additions & 7 deletions src/librustc/metadata/decoder.rs
Expand Up @@ -115,7 +115,8 @@ enum Family {
Mod, // m
ForeignMod, // n
Enum, // t
Variant, // v
TupleVariant, // v
StructVariant, // V
Impl, // i
Trait, // I
Struct, // S
Expand All @@ -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,
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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 => {}
}
}

Expand Down Expand Up @@ -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",
Expand Down
52 changes: 34 additions & 18 deletions src/librustc/metadata/encoder.rs
Expand Up @@ -307,6 +307,27 @@ fn encode_parent_item(ebml_w: &mut writer::Encoder, id: DefId) {
ebml_w.end_tag();
}

fn encode_struct_field_names(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,
Expand All @@ -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);
Expand All @@ -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_field_names(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);
Expand Down Expand Up @@ -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_field_names(ecx, ebml_w, struct_def);

// Encode inherent implementations for this structure.
encode_inherent_implementations(ecx, ebml_w, def_id);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/astencode.rs
Expand Up @@ -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)),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/check_const.rs
Expand Up @@ -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) => {
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/middle/check_match.rs
Expand Up @@ -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)))
Expand All @@ -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)
}
}
Expand All @@ -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 }
}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(*) => {
Expand All @@ -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| {
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/const_eval.rs
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/kind.rs
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/mem_categorization.rs
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/privacy.rs
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 \
Expand Down
18 changes: 12 additions & 6 deletions src/librustc/middle/resolve.rs
Expand Up @@ -1474,15 +1474,15 @@ 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(_) => {
let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
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));
}
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/trans/_match.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
_ => {
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/callee.rs
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/consts.rs
Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 8c5402f

Please sign in to comment.