Skip to content

Properly encode/decode structural variants. #9064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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_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);
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_fields(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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading