Front-end support for default impls in traits.
This commit is contained in:
parent
d5563d732d
commit
fc9c4c3245
14 changed files with 252 additions and 68 deletions
|
@ -452,6 +452,15 @@ type ty_field = spanned<ty_field_>;
|
||||||
type ty_method = {ident: ident, attrs: ~[attribute],
|
type ty_method = {ident: ident, attrs: ~[attribute],
|
||||||
decl: fn_decl, tps: ~[ty_param], span: span};
|
decl: fn_decl, tps: ~[ty_param], span: span};
|
||||||
|
|
||||||
|
#[auto_serialize]
|
||||||
|
// A trait method is either required (meaning it doesn't have an
|
||||||
|
// implementation, just a signature) or provided (meaning it has a default
|
||||||
|
// implementation).
|
||||||
|
enum trait_method {
|
||||||
|
required(ty_method),
|
||||||
|
provided(@method),
|
||||||
|
}
|
||||||
|
|
||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
|
enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
|
||||||
|
|
||||||
|
@ -695,7 +704,7 @@ enum item_ {
|
||||||
/* dtor is optional */
|
/* dtor is optional */
|
||||||
option<class_dtor>
|
option<class_dtor>
|
||||||
),
|
),
|
||||||
item_trait(~[ty_param], ~[ty_method]),
|
item_trait(~[ty_param], ~[trait_method]),
|
||||||
item_impl(~[ty_param], option<@trait_ref> /* trait */,
|
item_impl(~[ty_param], option<@trait_ref> /* trait */,
|
||||||
@ty /* self */, ~[@method]),
|
@ty /* self */, ~[@method]),
|
||||||
item_mac(mac),
|
item_mac(mac),
|
||||||
|
|
|
@ -511,6 +511,9 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
|
||||||
visit_ty_method: fn@(_ty_m: ty_method) {
|
visit_ty_method: fn@(_ty_m: ty_method) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
visit_trait_method: fn@(_ty_m: trait_method) {
|
||||||
|
},
|
||||||
|
|
||||||
visit_class_item: fn@(c: @class_member) {
|
visit_class_item: fn@(c: @class_member) {
|
||||||
alt c.node {
|
alt c.node {
|
||||||
instance_var(_, _, _, id,_) {
|
instance_var(_, _, _, id,_) {
|
||||||
|
|
|
@ -42,14 +42,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
|
||||||
mtc_rep, mtc_tok, mul, mutability, neg, noreturn, not, pat,
|
mtc_rep, mtc_tok, mul, mutability, neg, noreturn, not, pat,
|
||||||
pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec,
|
pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec,
|
||||||
pat_tup, pat_uniq, pat_wild, path, private, proto, proto_any,
|
pat_tup, pat_uniq, pat_wild, path, private, proto, proto_any,
|
||||||
proto_bare, proto_block, proto_box, proto_uniq, public, pure_fn,
|
proto_bare, proto_block, proto_box, proto_uniq, provided, public,
|
||||||
purity, re_anon, re_named, region, rem, ret_style,
|
pure_fn, purity, re_anon, re_named, region, rem, required,
|
||||||
return_val, shl, shr, stmt, stmt_decl,
|
ret_style, return_val, shl, shr, stmt, stmt_decl, stmt_expr,
|
||||||
stmt_expr, stmt_semi, subtract, token_tree, trait_ref, tt_delim,
|
stmt_semi, subtract, token_tree, trait_method, trait_ref,
|
||||||
tt_dotdotdot, tt_flat, tt_interpolate, ty, ty_, ty_bot, ty_box,
|
tt_delim, tt_dotdotdot, tt_flat, tt_interpolate, ty, ty_, ty_bot,
|
||||||
ty_constr, ty_constr_, ty_constr_arg, ty_field, ty_fn, ty_infer,
|
ty_box, ty_constr, ty_constr_, ty_constr_arg, ty_field, ty_fn,
|
||||||
ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr, ty_rec,
|
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr,
|
||||||
ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec, ty_vstore,
|
ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec, ty_vstore,
|
||||||
unchecked_blk, uniq, unsafe_blk, unsafe_fn, variant, view_item,
|
unchecked_blk, uniq, unsafe_blk, unsafe_fn, variant, view_item,
|
||||||
view_item_, view_item_export, view_item_import, view_item_use,
|
view_item_, view_item_export, view_item_import, view_item_use,
|
||||||
view_path, view_path_glob, view_path_list, view_path_simple,
|
view_path, view_path_glob, view_path_list, view_path_simple,
|
||||||
|
@ -275,7 +275,7 @@ class parser {
|
||||||
constraints: constrs};
|
constraints: constrs};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ty_methods() -> ~[ty_method] {
|
fn parse_trait_methods() -> ~[trait_method] {
|
||||||
do self.parse_unspanned_seq(token::LBRACE, token::RBRACE,
|
do self.parse_unspanned_seq(token::LBRACE, token::RBRACE,
|
||||||
seq_sep_none()) |p| {
|
seq_sep_none()) |p| {
|
||||||
let attrs = p.parse_outer_attributes();
|
let attrs = p.parse_outer_attributes();
|
||||||
|
@ -284,12 +284,42 @@ class parser {
|
||||||
let ident = p.parse_method_name();
|
let ident = p.parse_method_name();
|
||||||
let tps = p.parse_ty_params();
|
let tps = p.parse_ty_params();
|
||||||
let d = p.parse_ty_fn_decl(pur), fhi = p.last_span.hi;
|
let d = p.parse_ty_fn_decl(pur), fhi = p.last_span.hi;
|
||||||
self.expect(token::SEMI);
|
#debug["parse_trait_methods(): trait method ends in %s",
|
||||||
{ident: ident, attrs: attrs, decl: {purity: pur with d}, tps: tps,
|
token_to_str(self.reader, self.token)];
|
||||||
span: mk_sp(flo, fhi)}
|
alt self.token {
|
||||||
|
token::SEMI {
|
||||||
|
self.bump();
|
||||||
|
required({ident: ident, attrs: attrs,
|
||||||
|
decl: {purity: pur with d}, tps: tps,
|
||||||
|
span: mk_sp(flo, fhi)})
|
||||||
|
}
|
||||||
|
token::LBRACE {
|
||||||
|
self.bump();
|
||||||
|
let (inner_attrs, body) =
|
||||||
|
self.parse_inner_attrs_and_block(true);
|
||||||
|
let attrs = vec::append(attrs, inner_attrs);
|
||||||
|
self.eat(token::RBRACE);
|
||||||
|
provided(@{ident: ident,
|
||||||
|
attrs: attrs,
|
||||||
|
tps: tps,
|
||||||
|
decl: d,
|
||||||
|
body: body,
|
||||||
|
id: self.get_id(),
|
||||||
|
span: mk_sp(flo, fhi),
|
||||||
|
self_id: self.get_id(),
|
||||||
|
// Provided traits methods always public for now
|
||||||
|
vis: public})
|
||||||
|
}
|
||||||
|
|
||||||
|
_ { self.fatal("expected ';' or '}` \
|
||||||
|
but found `"
|
||||||
|
+ token_to_str(self.reader, self.token) + "`");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_mt() -> mt {
|
fn parse_mt() -> mt {
|
||||||
let mutbl = self.parse_mutability();
|
let mutbl = self.parse_mutability();
|
||||||
let t = self.parse_ty(false);
|
let t = self.parse_ty(false);
|
||||||
|
@ -2127,7 +2157,7 @@ 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();
|
||||||
let meths = self.parse_ty_methods();
|
let meths = self.parse_trait_methods();
|
||||||
(ident, item_trait(tps, meths), none)
|
(ident, item_trait(tps, meths), none)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import pp::{break_offset, word, printer,
|
||||||
space, zerobreak, hardbreak, breaks, consistent,
|
space, zerobreak, hardbreak, breaks, consistent,
|
||||||
inconsistent, eof};
|
inconsistent, eof};
|
||||||
import diagnostic;
|
import diagnostic;
|
||||||
|
import ast::{required, provided};
|
||||||
import ast_util::operator_prec;
|
import ast_util::operator_prec;
|
||||||
import dvec::{dvec, extensions};
|
import dvec::{dvec, extensions};
|
||||||
import parse::classify::*;
|
import parse::classify::*;
|
||||||
|
@ -593,7 +594,7 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||||
print_type_params(s, tps);
|
print_type_params(s, tps);
|
||||||
word(s.s, " ");
|
word(s.s, " ");
|
||||||
bopen(s);
|
bopen(s);
|
||||||
for methods.each |meth| { print_ty_method(s, meth); }
|
for methods.each |meth| { print_trait_method(s, meth); }
|
||||||
bclose(s, item.span);
|
bclose(s, item.span);
|
||||||
}
|
}
|
||||||
ast::item_mac({node: ast::mac_invoc_tt(pth, tts), _}) {
|
ast::item_mac({node: ast::mac_invoc_tt(pth, tts), _}) {
|
||||||
|
@ -647,6 +648,13 @@ fn print_ty_method(s: ps, m: ast::ty_method) {
|
||||||
word(s.s, ";");
|
word(s.s, ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_trait_method(s: ps, m: ast::trait_method) {
|
||||||
|
alt m {
|
||||||
|
required(ty_m) { print_ty_method(s, ty_m) }
|
||||||
|
provided(m) { print_method(s, m) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn print_method(s: ps, meth: @ast::method) {
|
fn print_method(s: ps, meth: @ast::method) {
|
||||||
hardbreak_if_not_bol(s);
|
hardbreak_if_not_bol(s);
|
||||||
maybe_print_comment(s, meth.span.lo);
|
maybe_print_comment(s, meth.span.lo);
|
||||||
|
|
|
@ -62,6 +62,7 @@ type visitor<E> =
|
||||||
visit_constr: fn@(@path, span, node_id, E, vt<E>),
|
visit_constr: fn@(@path, span, node_id, E, vt<E>),
|
||||||
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
|
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
|
||||||
visit_ty_method: fn@(ty_method, E, vt<E>),
|
visit_ty_method: fn@(ty_method, E, vt<E>),
|
||||||
|
visit_trait_method: fn@(trait_method, E, vt<E>),
|
||||||
visit_class_item: fn@(@class_member, E, vt<E>)};
|
visit_class_item: fn@(@class_member, E, vt<E>)};
|
||||||
|
|
||||||
fn default_visitor<E>() -> visitor<E> {
|
fn default_visitor<E>() -> visitor<E> {
|
||||||
|
@ -81,6 +82,7 @@ fn default_visitor<E>() -> visitor<E> {
|
||||||
visit_constr: |a,b,c,d,e|visit_constr::<E>(a, b, c, d, e),
|
visit_constr: |a,b,c,d,e|visit_constr::<E>(a, b, c, d, e),
|
||||||
visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g),
|
visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g),
|
||||||
visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c),
|
visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c),
|
||||||
|
visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c),
|
||||||
visit_class_item: |a,b,c|visit_class_item::<E>(a, b, c)};
|
visit_class_item: |a,b,c|visit_class_item::<E>(a, b, c)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +162,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
||||||
item_trait(tps, methods) {
|
item_trait(tps, methods) {
|
||||||
v.visit_ty_params(tps, e, v);
|
v.visit_ty_params(tps, e, v);
|
||||||
for methods.each |m| {
|
for methods.each |m| {
|
||||||
v.visit_ty_method(m, e, v);
|
v.visit_trait_method(m, e, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_mac(m) { visit_mac(m, e, v) }
|
item_mac(m) { visit_mac(m, e, v) }
|
||||||
|
@ -317,6 +319,17 @@ fn visit_ty_method<E>(m: ty_method, e: E, v: vt<E>) {
|
||||||
v.visit_ty(m.decl.output, e, v);
|
v.visit_ty(m.decl.output, e, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_trait_method<E>(m: trait_method, e: E, v: vt<E>) {
|
||||||
|
alt m {
|
||||||
|
required(ty_m) {
|
||||||
|
v.visit_ty_method(ty_m, e, v)
|
||||||
|
}
|
||||||
|
provided(m) {
|
||||||
|
visit_method_helper(m, e, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) {
|
fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) {
|
||||||
for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); }
|
for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); }
|
||||||
for b.node.stmts.each |s| { v.visit_stmt(s, e, v); }
|
for b.node.stmts.each |s| { v.visit_stmt(s, e, v); }
|
||||||
|
@ -465,6 +478,7 @@ type simple_visitor =
|
||||||
visit_constr: fn@(@path, span, node_id),
|
visit_constr: fn@(@path, span, node_id),
|
||||||
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id),
|
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id),
|
||||||
visit_ty_method: fn@(ty_method),
|
visit_ty_method: fn@(ty_method),
|
||||||
|
visit_trait_method: fn@(trait_method),
|
||||||
visit_class_item: fn@(@class_member)};
|
visit_class_item: fn@(@class_member)};
|
||||||
|
|
||||||
fn simple_ignore_ty(_t: @ty) {}
|
fn simple_ignore_ty(_t: @ty) {}
|
||||||
|
@ -487,6 +501,7 @@ fn default_simple_visitor() -> simple_visitor {
|
||||||
visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span,
|
visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span,
|
||||||
_id: node_id) { },
|
_id: node_id) { },
|
||||||
visit_ty_method: fn@(_m: ty_method) { },
|
visit_ty_method: fn@(_m: ty_method) { },
|
||||||
|
visit_trait_method: fn@(_m: trait_method) { },
|
||||||
visit_class_item: fn@(_c: @class_member) {}
|
visit_class_item: fn@(_c: @class_member) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -546,6 +561,11 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
||||||
f(ty);
|
f(ty);
|
||||||
visit_ty_method(ty, e, v);
|
visit_ty_method(ty, e, v);
|
||||||
}
|
}
|
||||||
|
fn v_trait_method(f: fn@(trait_method), m: trait_method, &&e: (),
|
||||||
|
v: vt<()>) {
|
||||||
|
f(m);
|
||||||
|
visit_trait_method(m, e, v);
|
||||||
|
}
|
||||||
fn v_ty_params(f: fn@(~[ty_param]),
|
fn v_ty_params(f: fn@(~[ty_param]),
|
||||||
ps: ~[ty_param],
|
ps: ~[ty_param],
|
||||||
&&e: (), v: vt<()>) {
|
&&e: (), v: vt<()>) {
|
||||||
|
@ -596,6 +616,8 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
||||||
v_fn(v.visit_fn, a, b, c, d, e, f, g),
|
v_fn(v.visit_fn, a, b, c, d, e, f, g),
|
||||||
visit_ty_method: |a,b,c|
|
visit_ty_method: |a,b,c|
|
||||||
v_ty_method(v.visit_ty_method, a, b, c),
|
v_ty_method(v.visit_ty_method, a, b, c),
|
||||||
|
visit_trait_method: |a,b,c|
|
||||||
|
v_trait_method(v.visit_trait_method, a, b, c),
|
||||||
visit_class_item: |a,b,c|
|
visit_class_item: |a,b,c|
|
||||||
v_class_item(v.visit_class_item, a, b, c)
|
v_class_item(v.visit_class_item, a, b, c)
|
||||||
});
|
});
|
||||||
|
|
|
@ -744,12 +744,21 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||||
encode_name(ebml_w, item.ident);
|
encode_name(ebml_w, item.ident);
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
|
for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
|
||||||
ebml_w.start_tag(tag_item_trait_method);
|
alt ms[i] {
|
||||||
encode_name(ebml_w, mty.ident);
|
required(ty_m) {
|
||||||
encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
|
ebml_w.start_tag(tag_item_trait_method);
|
||||||
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
|
encode_name(ebml_w, mty.ident);
|
||||||
encode_family(ebml_w, purity_fn_family(mty.purity));
|
encode_type_param_bounds(ebml_w, ecx, ty_m.tps);
|
||||||
ebml_w.end_tag();
|
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
|
||||||
|
encode_family(ebml_w, purity_fn_family(mty.purity));
|
||||||
|
ebml_w.end_tag();
|
||||||
|
}
|
||||||
|
provided(m) {
|
||||||
|
encode_info_for_method(ecx, ebml_w, path,
|
||||||
|
should_inline(m.attrs), item.id,
|
||||||
|
m, m.tps);
|
||||||
|
}
|
||||||
|
}
|
||||||
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));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import syntax::{ast, ast_util, codemap, ast_map};
|
import syntax::{ast, ast_util, codemap, ast_map};
|
||||||
import syntax::ast::*;
|
import syntax::ast::*;
|
||||||
import ast::{ident, fn_ident, def, def_id, node_id};
|
import ast::{ident, fn_ident, def, def_id, node_id};
|
||||||
|
import ast::{required, provided};
|
||||||
import syntax::ast_util::{local_def, def_id_of_def, new_def_hash,
|
import syntax::ast_util::{local_def, def_id_of_def, new_def_hash,
|
||||||
class_item_ident, path_to_ident};
|
class_item_ident, path_to_ident};
|
||||||
import pat_util::*;
|
import pat_util::*;
|
||||||
|
@ -566,12 +567,8 @@ fn visit_item_with_scope(e: @env, i: @ast::item,
|
||||||
}
|
}
|
||||||
ast::item_trait(tps, methods) {
|
ast::item_trait(tps, methods) {
|
||||||
v.visit_ty_params(tps, sc, v);
|
v.visit_ty_params(tps, sc, v);
|
||||||
let isc = @cons(scope_method(i.id, tps), sc);
|
|
||||||
for methods.each |m| {
|
for methods.each |m| {
|
||||||
v.visit_ty_params(m.tps, isc, v);
|
visit_trait_method(m, i, tps, sc, v);
|
||||||
let msc = @cons(scope_method(i.id, vec::append(tps, m.tps)), sc);
|
|
||||||
for m.decl.inputs.each |a| { v.visit_ty(a.ty, msc, v); }
|
|
||||||
v.visit_ty(m.decl.output, msc, v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_class(tps, traits, members, ctor, m_dtor) {
|
ast::item_class(tps, traits, members, ctor, m_dtor) {
|
||||||
|
@ -618,6 +615,27 @@ fn visit_item_with_scope(e: @env, i: @ast::item,
|
||||||
e.resolve_unexported = old_resolve_unexported;
|
e.resolve_unexported = old_resolve_unexported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_trait_method(m: trait_method, i: @ast::item,
|
||||||
|
tps: ~[ast::ty_param], sc: scopes,
|
||||||
|
v: vt<scopes>) {
|
||||||
|
alt m {
|
||||||
|
required(ty_m) {
|
||||||
|
let isc = @cons(scope_method(i.id, tps), sc);
|
||||||
|
v.visit_ty_params(ty_m.tps, isc, v);
|
||||||
|
let msc = @cons(scope_method(i.id, vec::append(tps, ty_m.tps)), sc);
|
||||||
|
for ty_m.decl.inputs.each |a| { v.visit_ty(a.ty, msc, v); }
|
||||||
|
v.visit_ty(ty_m.decl.output, msc, v);
|
||||||
|
}
|
||||||
|
provided(m) {
|
||||||
|
v.visit_ty_params(m.tps, sc, v);
|
||||||
|
let msc = @cons(scope_method(m.self_id, vec::append(tps, m.tps)),
|
||||||
|
sc);
|
||||||
|
v.visit_fn(visit::fk_method(m.ident, ~[], m),
|
||||||
|
m.decl, m.body, m.span, m.id, msc, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_foreign_item_with_scope(ni: @ast::foreign_item, &&sc: scopes,
|
fn visit_foreign_item_with_scope(ni: @ast::foreign_item, &&sc: scopes,
|
||||||
v: vt<scopes>) {
|
v: vt<scopes>) {
|
||||||
visit::visit_foreign_item(ni, @cons(scope_foreign_item(ni), sc), v);
|
visit::visit_foreign_item(ni, @cons(scope_foreign_item(ni), sc), v);
|
||||||
|
@ -1785,7 +1803,16 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
|
||||||
"type parameter");
|
"type parameter");
|
||||||
}
|
}
|
||||||
ast::item_trait(_, methods) {
|
ast::item_trait(_, methods) {
|
||||||
ensure_unique(*e, i.span, methods, |m| m.ident,
|
ensure_unique(*e, i.span, methods, |m| {
|
||||||
|
alt m {
|
||||||
|
required(ty_m) {
|
||||||
|
ty_m.ident
|
||||||
|
}
|
||||||
|
provided(m) {
|
||||||
|
m.ident
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"method");
|
"method");
|
||||||
}
|
}
|
||||||
ast::item_impl(_, _, _, methods) {
|
ast::item_impl(_, _, _, methods) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import syntax::ast::{ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64};
|
||||||
import syntax::ast::{ty_u8, ty_uint, variant, view_item, view_item_export};
|
import syntax::ast::{ty_u8, ty_uint, variant, view_item, view_item_export};
|
||||||
import syntax::ast::{view_item_import, view_item_use, view_path_glob};
|
import syntax::ast::{view_item_import, view_item_use, view_path_glob};
|
||||||
import syntax::ast::{view_path_list, view_path_simple};
|
import syntax::ast::{view_path_list, view_path_simple};
|
||||||
|
import syntax::ast::{required, provided};
|
||||||
import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
|
import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
|
||||||
import syntax::ast_util::{walk_pat};
|
import syntax::ast_util::{walk_pat};
|
||||||
import syntax::attr::{attr_metas, contains_name};
|
import syntax::attr::{attr_metas, contains_name};
|
||||||
|
@ -2928,21 +2929,33 @@ class Resolver {
|
||||||
//
|
//
|
||||||
// XXX: Do we need a node ID here?
|
// XXX: Do we need a node ID here?
|
||||||
|
|
||||||
do self.with_type_parameter_rib
|
alt method {
|
||||||
(HasTypeParameters(&method.tps,
|
required(ty_m) {
|
||||||
|
do self.with_type_parameter_rib
|
||||||
|
(HasTypeParameters(&ty_m.tps,
|
||||||
item.id,
|
item.id,
|
||||||
type_parameters.len(),
|
type_parameters.len(),
|
||||||
NormalRibKind))
|
NormalRibKind))
|
||||||
|| {
|
|| {
|
||||||
|
|
||||||
// Resolve the method-specific type parameters.
|
// Resolve the method-specific type
|
||||||
self.resolve_type_parameters(method.tps, visitor);
|
// parameters.
|
||||||
|
self.resolve_type_parameters(ty_m.tps,
|
||||||
|
visitor);
|
||||||
|
|
||||||
for method.decl.inputs.each |argument| {
|
for ty_m.decl.inputs.each |argument| {
|
||||||
self.resolve_type(argument.ty, visitor);
|
self.resolve_type(argument.ty, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.resolve_type(ty_m.decl.output, visitor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.resolve_type(method.decl.output, visitor);
|
provided(m) {
|
||||||
|
self.resolve_method(NormalRibKind,
|
||||||
|
m,
|
||||||
|
type_parameters.len(),
|
||||||
|
visitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3242,19 +3255,10 @@ class Resolver {
|
||||||
for class_members.each |class_member| {
|
for class_members.each |class_member| {
|
||||||
alt class_member.node {
|
alt class_member.node {
|
||||||
class_method(method) {
|
class_method(method) {
|
||||||
let borrowed_method_type_parameters = &method.tps;
|
self.resolve_method(NormalRibKind,
|
||||||
let type_parameters =
|
method,
|
||||||
HasTypeParameters(borrowed_method_type_parameters,
|
outer_type_parameter_count,
|
||||||
method.id,
|
visitor);
|
||||||
outer_type_parameter_count,
|
|
||||||
NormalRibKind);
|
|
||||||
self.resolve_function(NormalRibKind,
|
|
||||||
some(@method.decl),
|
|
||||||
type_parameters,
|
|
||||||
method.body,
|
|
||||||
HasSelfBinding(method.self_id),
|
|
||||||
NoCaptureClause,
|
|
||||||
visitor);
|
|
||||||
}
|
}
|
||||||
instance_var(_, field_type, _, _, _) {
|
instance_var(_, field_type, _, _, _) {
|
||||||
self.resolve_type(field_type, visitor);
|
self.resolve_type(field_type, visitor);
|
||||||
|
@ -3291,6 +3295,27 @@ class Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does this really need to take a RibKind or is it always going
|
||||||
|
// to be NormalRibKind?
|
||||||
|
fn resolve_method(rib_kind: RibKind,
|
||||||
|
method: @method,
|
||||||
|
outer_type_parameter_count: uint,
|
||||||
|
visitor: ResolveVisitor) {
|
||||||
|
let borrowed_method_type_parameters = &method.tps;
|
||||||
|
let type_parameters =
|
||||||
|
HasTypeParameters(borrowed_method_type_parameters,
|
||||||
|
method.id,
|
||||||
|
outer_type_parameter_count,
|
||||||
|
rib_kind);
|
||||||
|
self.resolve_function(rib_kind,
|
||||||
|
some(@method.decl),
|
||||||
|
type_parameters,
|
||||||
|
method.body,
|
||||||
|
HasSelfBinding(method.self_id),
|
||||||
|
NoCaptureClause,
|
||||||
|
visitor);
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_implementation(id: node_id,
|
fn resolve_implementation(id: node_id,
|
||||||
span: span,
|
span: span,
|
||||||
type_parameters: ~[ty_param],
|
type_parameters: ~[ty_param],
|
||||||
|
|
|
@ -41,6 +41,7 @@ independently:
|
||||||
import result::{result, extensions};
|
import result::{result, extensions};
|
||||||
import syntax::{ast, ast_util, ast_map};
|
import syntax::{ast, ast_util, ast_map};
|
||||||
import ast::spanned;
|
import ast::spanned;
|
||||||
|
import ast::{required, provided};
|
||||||
import syntax::ast_map::node_id_to_str;
|
import syntax::ast_map::node_id_to_str;
|
||||||
import syntax::ast_util::{local_def, respan, split_class_items};
|
import syntax::ast_util::{local_def, respan, split_class_items};
|
||||||
import syntax::visit;
|
import syntax::visit;
|
||||||
|
|
|
@ -147,8 +147,15 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id) {
|
||||||
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::ty_method>(ccx, id, ms, |m| {
|
store_methods::<ast::trait_method>(ccx, id, ms, |m| {
|
||||||
ty_of_ty_method(ccx, m, rp)
|
alt m {
|
||||||
|
required(ty_m) {
|
||||||
|
ty_of_ty_method(ccx, ty_m, rp)
|
||||||
|
}
|
||||||
|
provided(m) {
|
||||||
|
ty_of_method(ccx, m, rp)
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ast_map::node_item(@{node: ast::item_class(_,_,its,_,_), _}, _) {
|
ast_map::node_item(@{node: ast::item_class(_,_,its,_,_), _}, _) {
|
||||||
|
|
|
@ -207,7 +207,14 @@ fn merge_method_attrs(
|
||||||
node: ast::item_trait(_, methods), _
|
node: ast::item_trait(_, methods), _
|
||||||
}, _) {
|
}, _) {
|
||||||
par::seqmap(methods, |method| {
|
par::seqmap(methods, |method| {
|
||||||
(*method.ident, attr_parser::parse_desc(method.attrs))
|
alt method {
|
||||||
|
ast::required(ty_m) {
|
||||||
|
(*ty_m.ident, attr_parser::parse_desc(ty_m.attrs))
|
||||||
|
}
|
||||||
|
ast::provided(m) {
|
||||||
|
(*m.ident, attr_parser::parse_desc(m.attrs))
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ast_map::node_item(@{
|
ast_map::node_item(@{
|
||||||
|
|
|
@ -11,6 +11,11 @@ enum page {
|
||||||
itempage(itemtag)
|
itempage(itemtag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum implementation {
|
||||||
|
required,
|
||||||
|
provided,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Most rustdocs can be parsed into 'sections' according to their markdown
|
* Most rustdocs can be parsed into 'sections' according to their markdown
|
||||||
* headers
|
* headers
|
||||||
|
@ -91,7 +96,8 @@ type methoddoc = {
|
||||||
brief: option<str>,
|
brief: option<str>,
|
||||||
desc: option<str>,
|
desc: option<str>,
|
||||||
sections: ~[section],
|
sections: ~[section],
|
||||||
sig: option<str>
|
sig: option<str>,
|
||||||
|
implementation: implementation,
|
||||||
};
|
};
|
||||||
|
|
||||||
type impldoc = {
|
type impldoc = {
|
||||||
|
|
|
@ -185,17 +185,32 @@ fn should_extract_enum_variants() {
|
||||||
|
|
||||||
fn traitdoc_from_trait(
|
fn traitdoc_from_trait(
|
||||||
itemdoc: doc::itemdoc,
|
itemdoc: doc::itemdoc,
|
||||||
methods: ~[ast::ty_method]
|
methods: ~[ast::trait_method]
|
||||||
) -> doc::traitdoc {
|
) -> doc::traitdoc {
|
||||||
{
|
{
|
||||||
item: itemdoc,
|
item: itemdoc,
|
||||||
methods: do par::seqmap(methods) |method| {
|
methods: do par::seqmap(methods) |method| {
|
||||||
{
|
alt method {
|
||||||
name: *method.ident,
|
ast::required(ty_m) {
|
||||||
brief: none,
|
{
|
||||||
desc: none,
|
name: *ty_m.ident,
|
||||||
sections: ~[],
|
brief: none,
|
||||||
sig: none
|
desc: none,
|
||||||
|
sections: ~[],
|
||||||
|
sig: none,
|
||||||
|
implementation: doc::required,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::provided(m) {
|
||||||
|
{
|
||||||
|
name: *m.ident,
|
||||||
|
brief: none,
|
||||||
|
desc: none,
|
||||||
|
sections: ~[],
|
||||||
|
sig: none,
|
||||||
|
implementation: doc::provided,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +242,8 @@ fn impldoc_from_impl(
|
||||||
brief: none,
|
brief: none,
|
||||||
desc: none,
|
desc: none,
|
||||||
sections: ~[],
|
sections: ~[],
|
||||||
sig: none
|
sig: none,
|
||||||
|
implementation: doc::provided,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,14 +171,28 @@ fn get_method_sig(
|
||||||
node: ast::item_trait(_, methods), _
|
node: ast::item_trait(_, methods), _
|
||||||
}, _) {
|
}, _) {
|
||||||
alt check vec::find(methods, |method| {
|
alt check vec::find(methods, |method| {
|
||||||
*method.ident == method_name
|
alt method {
|
||||||
|
ast::required(ty_m) { *ty_m.ident == method_name }
|
||||||
|
ast::provided(m) { *m.ident == method_name }
|
||||||
|
}
|
||||||
}) {
|
}) {
|
||||||
some(method) {
|
some(method) {
|
||||||
some(pprust::fun_to_str(
|
alt method {
|
||||||
method.decl,
|
ast::required(ty_m) {
|
||||||
method.ident,
|
some(pprust::fun_to_str(
|
||||||
method.tps
|
ty_m.decl,
|
||||||
))
|
ty_m.ident,
|
||||||
|
ty_m.tps
|
||||||
|
))
|
||||||
|
}
|
||||||
|
ast::provided(m) {
|
||||||
|
some(pprust::fun_to_str(
|
||||||
|
m.decl,
|
||||||
|
m.ident,
|
||||||
|
m.tps
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue