rustc: Parse, serialize, and deserialize trait inheritance
This commit is contained in:
parent
a805a1fb37
commit
b65dd9d090
13 changed files with 69 additions and 21 deletions
|
@ -724,7 +724,7 @@ enum item_ {
|
||||||
/* dtor is optional */
|
/* dtor is optional */
|
||||||
option<class_dtor>
|
option<class_dtor>
|
||||||
),
|
),
|
||||||
item_trait(~[ty_param], ~[trait_method]),
|
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
|
||||||
item_impl(~[ty_param],
|
item_impl(~[ty_param],
|
||||||
~[@trait_ref], /* traits this impl implements */
|
~[@trait_ref], /* traits this impl implements */
|
||||||
@ty, /* self */
|
@ty, /* self */
|
||||||
|
|
|
@ -231,7 +231,15 @@ fn map_item(i: @item, cx: ctx, v: vt) {
|
||||||
// only need to handle methods
|
// only need to handle methods
|
||||||
do vec::iter(ms) |m| { map_method(d_id, p, m, cx); }
|
do vec::iter(ms) |m| { map_method(d_id, p, m, cx); }
|
||||||
}
|
}
|
||||||
item_trait(tps, methods) {
|
item_trait(tps, traits, methods) {
|
||||||
|
// Map trait refs to their parent classes. This is
|
||||||
|
// so we can find the self_ty
|
||||||
|
for traits.each |p| {
|
||||||
|
cx.map.insert(p.ref_id, node_item(i, item_path));
|
||||||
|
// This is so we can look up the right things when
|
||||||
|
// encoding/decoding
|
||||||
|
cx.map.insert(p.impl_id, node_item(i, item_path));
|
||||||
|
}
|
||||||
for methods.each |tm| {
|
for methods.each |tm| {
|
||||||
let id = ast_util::trait_method_to_ty_method(tm).id;
|
let id = ast_util::trait_method_to_ty_method(tm).id;
|
||||||
let d_id = ast_util::local_def(i.id);
|
let d_id = ast_util::local_def(i.id);
|
||||||
|
|
|
@ -279,8 +279,9 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||||
fld.fold_ty(ty),
|
fld.fold_ty(ty),
|
||||||
vec::map(methods, |x| fld.fold_method(x)))
|
vec::map(methods, |x| fld.fold_method(x)))
|
||||||
}
|
}
|
||||||
item_trait(tps, methods) {
|
item_trait(tps, traits, methods) {
|
||||||
item_trait(fold_ty_params(tps, fld),
|
item_trait(fold_ty_params(tps, fld),
|
||||||
|
vec::map(traits, |p| fold_trait_ref(p, fld)),
|
||||||
/* FIXME (#2543) */ copy methods)
|
/* FIXME (#2543) */ copy methods)
|
||||||
}
|
}
|
||||||
item_mac(m) {
|
item_mac(m) {
|
||||||
|
|
|
@ -2278,8 +2278,18 @@ class parser {
|
||||||
let ident = self.parse_ident();
|
let ident = self.parse_ident();
|
||||||
self.parse_region_param();
|
self.parse_region_param();
|
||||||
let tps = self.parse_ty_params();
|
let tps = self.parse_ty_params();
|
||||||
|
|
||||||
|
// Parse traits, if necessary.
|
||||||
|
let traits;
|
||||||
|
if self.token == token::COLON {
|
||||||
|
self.bump();
|
||||||
|
traits = self.parse_trait_ref_list(token::LBRACE);
|
||||||
|
} else {
|
||||||
|
traits = ~[];
|
||||||
|
}
|
||||||
|
|
||||||
let meths = self.parse_trait_methods();
|
let meths = self.parse_trait_methods();
|
||||||
(ident, item_trait(tps, meths), none)
|
(ident, item_trait(tps, traits, meths), none)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses four variants (with the region/type params always optional):
|
// Parses four variants (with the region/type params always optional):
|
||||||
|
|
|
@ -590,10 +590,15 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||||
}
|
}
|
||||||
bclose(s, item.span);
|
bclose(s, item.span);
|
||||||
}
|
}
|
||||||
ast::item_trait(tps, methods) {
|
ast::item_trait(tps, traits, methods) {
|
||||||
head(s, ~"trait");
|
head(s, ~"trait");
|
||||||
word(s.s, *item.ident);
|
word(s.s, *item.ident);
|
||||||
print_type_params(s, tps);
|
print_type_params(s, tps);
|
||||||
|
if vec::len(traits) != 0u {
|
||||||
|
word_space(s, ~":");
|
||||||
|
commasep(s, inconsistent, traits, |s, p|
|
||||||
|
print_path(s, p.path, false));
|
||||||
|
}
|
||||||
word(s.s, ~" ");
|
word(s.s, ~" ");
|
||||||
bopen(s);
|
bopen(s);
|
||||||
for methods.each |meth| { print_trait_method(s, meth); }
|
for methods.each |meth| { print_trait_method(s, meth); }
|
||||||
|
|
|
@ -162,8 +162,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
||||||
ast_util::local_def(i.id), e, v)
|
ast_util::local_def(i.id), e, v)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
item_trait(tps, methods) {
|
item_trait(tps, traits, methods) {
|
||||||
v.visit_ty_params(tps, e, v);
|
v.visit_ty_params(tps, e, v);
|
||||||
|
for traits.each |p| { visit_path(p.path, e, v); }
|
||||||
for methods.each |m| {
|
for methods.each |m| {
|
||||||
v.visit_trait_method(m, e, v);
|
v.visit_trait_method(m, e, v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -813,7 +813,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||||
vec::append(tps, m.tps));
|
vec::append(tps, m.tps));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_trait(tps, ms) {
|
item_trait(tps, traits, ms) {
|
||||||
add_to_index();
|
add_to_index();
|
||||||
ebml_w.start_tag(tag_items_data_item);
|
ebml_w.start_tag(tag_items_data_item);
|
||||||
encode_def_id(ebml_w, local_def(item.id));
|
encode_def_id(ebml_w, local_def(item.id));
|
||||||
|
@ -844,6 +844,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||||
|
for traits.each |associated_trait| {
|
||||||
|
encode_trait_ref(ebml_w, ecx, associated_trait)
|
||||||
|
}
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
item_mac(*) { fail ~"item macros unimplemented" }
|
item_mac(*) { fail ~"item macros unimplemented" }
|
||||||
|
|
|
@ -988,7 +988,7 @@ class Resolver {
|
||||||
visit_item(item, new_parent, visitor);
|
visit_item(item, new_parent, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_trait(_, methods) {
|
item_trait(_, _, methods) {
|
||||||
// Add the names of all the methods to the trait info.
|
// Add the names of all the methods to the trait info.
|
||||||
let method_names = @atom_hashmap();
|
let method_names = @atom_hashmap();
|
||||||
for methods.each |method| {
|
for methods.each |method| {
|
||||||
|
@ -3063,7 +3063,7 @@ class Resolver {
|
||||||
self_type, methods, visitor);
|
self_type, methods, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_trait(type_parameters, methods) {
|
item_trait(type_parameters, traits, methods) {
|
||||||
// Create a new rib for the self type.
|
// Create a new rib for the self type.
|
||||||
let self_type_rib = @Rib(NormalRibKind);
|
let self_type_rib = @Rib(NormalRibKind);
|
||||||
(*self.type_ribs).push(self_type_rib);
|
(*self.type_ribs).push(self_type_rib);
|
||||||
|
@ -3077,6 +3077,27 @@ class Resolver {
|
||||||
|
|
||||||
self.resolve_type_parameters(type_parameters, visitor);
|
self.resolve_type_parameters(type_parameters, visitor);
|
||||||
|
|
||||||
|
// Resolve derived traits.
|
||||||
|
for traits.each |trt| {
|
||||||
|
match self.resolve_path(trt.path, TypeNS, true,
|
||||||
|
visitor) {
|
||||||
|
none =>
|
||||||
|
self.session.span_err(trt.path.span,
|
||||||
|
~"attempt to derive a \
|
||||||
|
nonexistent trait"),
|
||||||
|
some(def) => {
|
||||||
|
// Write a mapping from the trait ID to the
|
||||||
|
// definition of the trait into the definition
|
||||||
|
// map.
|
||||||
|
|
||||||
|
debug!{"(resolving trait) found trait def: \
|
||||||
|
%?", def};
|
||||||
|
|
||||||
|
self.record_def(trt.ref_id, def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for methods.each |method| {
|
for methods.each |method| {
|
||||||
// Create a new rib for the method-specific type
|
// Create a new rib for the method-specific type
|
||||||
// parameters.
|
// parameters.
|
||||||
|
|
|
@ -419,7 +419,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
||||||
node_id: it.id };
|
node_id: it.id };
|
||||||
for ms.each |m| { check_method(ccx, m, self_info);}
|
for ms.each |m| { check_method(ccx, m, self_info);}
|
||||||
}
|
}
|
||||||
ast::item_trait(_, trait_methods) {
|
ast::item_trait(_, _, trait_methods) {
|
||||||
for trait_methods.each |trait_method| {
|
for trait_methods.each |trait_method| {
|
||||||
alt trait_method {
|
alt trait_method {
|
||||||
required(ty_m) {
|
required(ty_m) {
|
||||||
|
@ -434,7 +434,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_class(tps, traits, members, m_ctor, m_dtor) {
|
ast::item_class(tps, _, members, m_ctor, m_dtor) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let class_t = {self_ty: ty::node_id_to_type(tcx, it.id),
|
let class_t = {self_ty: ty::node_id_to_type(tcx, it.id),
|
||||||
node_id: it.id};
|
node_id: it.id};
|
||||||
|
|
|
@ -38,20 +38,19 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
|
||||||
let substs = {self_r: none, self_ty: none, tps: ~[]};
|
let substs = {self_r: none, self_ty: none, tps: ~[]};
|
||||||
|
|
||||||
alt intrinsic_item.node {
|
alt intrinsic_item.node {
|
||||||
|
ast::item_trait(*) => {
|
||||||
ast::item_trait(_, _) {
|
|
||||||
let ty = ty::mk_trait(ccx.tcx, def_id, substs);
|
let ty = ty::mk_trait(ccx.tcx, def_id, substs);
|
||||||
ccx.tcx.intrinsic_defs.insert
|
ccx.tcx.intrinsic_defs.insert
|
||||||
(intrinsic_item.ident, (def_id, ty));
|
(intrinsic_item.ident, (def_id, ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::item_enum(_, _) {
|
ast::item_enum(*) => {
|
||||||
let ty = ty::mk_enum(ccx.tcx, def_id, substs);
|
let ty = ty::mk_enum(ccx.tcx, def_id, substs);
|
||||||
ccx.tcx.intrinsic_defs.insert
|
ccx.tcx.intrinsic_defs.insert
|
||||||
(intrinsic_item.ident, (def_id, ty));
|
(intrinsic_item.ident, (def_id, ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ { }
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +146,7 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let rp = tcx.region_paramd_items.contains_key(id);
|
let rp = tcx.region_paramd_items.contains_key(id);
|
||||||
alt check tcx.items.get(id) {
|
alt check tcx.items.get(id) {
|
||||||
ast_map::node_item(@{node: ast::item_trait(_, ms), _}, _) {
|
ast_map::node_item(@{node: ast::item_trait(_, _, ms), _}, _) {
|
||||||
store_methods::<ast::trait_method>(ccx, id, ms, |m| {
|
store_methods::<ast::trait_method>(ccx, id, ms, |m| {
|
||||||
alt m {
|
alt m {
|
||||||
required(ty_m) {
|
required(ty_m) {
|
||||||
|
@ -339,7 +338,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
||||||
check_methods_against_trait(ccx, tps, rp, selfty, t, cms);
|
check_methods_against_trait(ccx, tps, rp, selfty, t, cms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_trait(tps, trait_methods) {
|
ast::item_trait(tps, _, trait_methods) {
|
||||||
let tpt = ty_of_item(ccx, it);
|
let tpt = ty_of_item(ccx, it);
|
||||||
debug!{"item_trait(it.id=%d, tpt.ty=%s)",
|
debug!{"item_trait(it.id=%d, tpt.ty=%s)",
|
||||||
it.id, ty_to_str(tcx, tpt.ty)};
|
it.id, ty_to_str(tcx, tpt.ty)};
|
||||||
|
@ -550,7 +549,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
|
||||||
tcx.tcache.insert(local_def(it.id), tpt);
|
tcx.tcache.insert(local_def(it.id), tpt);
|
||||||
return tpt;
|
return tpt;
|
||||||
}
|
}
|
||||||
ast::item_trait(tps, ms) {
|
ast::item_trait(tps, _, ms) {
|
||||||
let {bounds, substs} = mk_substs(ccx, tps, rp);
|
let {bounds, substs} = mk_substs(ccx, tps, rp);
|
||||||
let t = ty::mk_trait(tcx, local_def(it.id), substs);
|
let t = ty::mk_trait(tcx, local_def(it.id), substs);
|
||||||
let tpt = {bounds: bounds, rp: rp, ty: t};
|
let tpt = {bounds: bounds, rp: rp, ty: t};
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn merge_method_attrs(
|
||||||
let attrs: ~[(~str, option<~str>)] = do astsrv::exec(srv) |ctxt| {
|
let attrs: ~[(~str, option<~str>)] = do astsrv::exec(srv) |ctxt| {
|
||||||
alt ctxt.ast_map.get(item_id) {
|
alt ctxt.ast_map.get(item_id) {
|
||||||
ast_map::node_item(@{
|
ast_map::node_item(@{
|
||||||
node: ast::item_trait(_, methods), _
|
node: ast::item_trait(_, _, methods), _
|
||||||
}, _) {
|
}, _) {
|
||||||
vec::map(methods, |method| {
|
vec::map(methods, |method| {
|
||||||
alt method {
|
alt method {
|
||||||
|
|
|
@ -84,7 +84,7 @@ fn moddoc_from_mod(
|
||||||
enumdoc_from_enum(itemdoc, variants)
|
enumdoc_from_enum(itemdoc, variants)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ast::item_trait(_, methods) {
|
ast::item_trait(_, _, methods) {
|
||||||
some(doc::traittag(
|
some(doc::traittag(
|
||||||
traitdoc_from_trait(itemdoc, methods)
|
traitdoc_from_trait(itemdoc, methods)
|
||||||
))
|
))
|
||||||
|
|
|
@ -169,7 +169,7 @@ fn get_method_sig(
|
||||||
do astsrv::exec(srv) |ctxt| {
|
do astsrv::exec(srv) |ctxt| {
|
||||||
alt check ctxt.ast_map.get(item_id) {
|
alt check ctxt.ast_map.get(item_id) {
|
||||||
ast_map::node_item(@{
|
ast_map::node_item(@{
|
||||||
node: ast::item_trait(_, methods), _
|
node: ast::item_trait(_, _, methods), _
|
||||||
}, _) {
|
}, _) {
|
||||||
alt check vec::find(methods, |method| {
|
alt check vec::find(methods, |method| {
|
||||||
alt method {
|
alt method {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue