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
|
|
@ -744,12 +744,21 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_name(ebml_w, item.ident);
|
||||
let mut i = 0u;
|
||||
for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
|
||||
ebml_w.start_tag(tag_item_trait_method);
|
||||
encode_name(ebml_w, mty.ident);
|
||||
encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
|
||||
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
|
||||
encode_family(ebml_w, purity_fn_family(mty.purity));
|
||||
ebml_w.end_tag();
|
||||
alt ms[i] {
|
||||
required(ty_m) {
|
||||
ebml_w.start_tag(tag_item_trait_method);
|
||||
encode_name(ebml_w, mty.ident);
|
||||
encode_type_param_bounds(ebml_w, ecx, ty_m.tps);
|
||||
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;
|
||||
}
|
||||
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::*;
|
||||
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,
|
||||
class_item_ident, path_to_ident};
|
||||
import pat_util::*;
|
||||
|
|
@ -566,12 +567,8 @@ fn visit_item_with_scope(e: @env, i: @ast::item,
|
|||
}
|
||||
ast::item_trait(tps, methods) {
|
||||
v.visit_ty_params(tps, sc, v);
|
||||
let isc = @cons(scope_method(i.id, tps), sc);
|
||||
for methods.each |m| {
|
||||
v.visit_ty_params(m.tps, isc, 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);
|
||||
visit_trait_method(m, i, tps, sc, v);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
v: vt<scopes>) {
|
||||
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");
|
||||
}
|
||||
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");
|
||||
}
|
||||
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::{view_item_import, view_item_use, view_path_glob};
|
||||
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::{walk_pat};
|
||||
import syntax::attr::{attr_metas, contains_name};
|
||||
|
|
@ -2928,21 +2929,33 @@ class Resolver {
|
|||
//
|
||||
// XXX: Do we need a node ID here?
|
||||
|
||||
do self.with_type_parameter_rib
|
||||
(HasTypeParameters(&method.tps,
|
||||
alt method {
|
||||
required(ty_m) {
|
||||
do self.with_type_parameter_rib
|
||||
(HasTypeParameters(&ty_m.tps,
|
||||
item.id,
|
||||
type_parameters.len(),
|
||||
NormalRibKind))
|
||||
|| {
|
||||
|| {
|
||||
|
||||
// Resolve the method-specific type parameters.
|
||||
self.resolve_type_parameters(method.tps, visitor);
|
||||
// Resolve the method-specific type
|
||||
// parameters.
|
||||
self.resolve_type_parameters(ty_m.tps,
|
||||
visitor);
|
||||
|
||||
for method.decl.inputs.each |argument| {
|
||||
self.resolve_type(argument.ty, visitor);
|
||||
for ty_m.decl.inputs.each |argument| {
|
||||
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| {
|
||||
alt class_member.node {
|
||||
class_method(method) {
|
||||
let borrowed_method_type_parameters = &method.tps;
|
||||
let type_parameters =
|
||||
HasTypeParameters(borrowed_method_type_parameters,
|
||||
method.id,
|
||||
outer_type_parameter_count,
|
||||
NormalRibKind);
|
||||
self.resolve_function(NormalRibKind,
|
||||
some(@method.decl),
|
||||
type_parameters,
|
||||
method.body,
|
||||
HasSelfBinding(method.self_id),
|
||||
NoCaptureClause,
|
||||
visitor);
|
||||
self.resolve_method(NormalRibKind,
|
||||
method,
|
||||
outer_type_parameter_count,
|
||||
visitor);
|
||||
}
|
||||
instance_var(_, field_type, _, _, _) {
|
||||
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,
|
||||
span: span,
|
||||
type_parameters: ~[ty_param],
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ independently:
|
|||
import result::{result, extensions};
|
||||
import syntax::{ast, ast_util, ast_map};
|
||||
import ast::spanned;
|
||||
import ast::{required, provided};
|
||||
import syntax::ast_map::node_id_to_str;
|
||||
import syntax::ast_util::{local_def, respan, split_class_items};
|
||||
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);
|
||||
alt check tcx.items.get(id) {
|
||||
ast_map::node_item(@{node: ast::item_trait(_, ms), _}, _) {
|
||||
store_methods::<ast::ty_method>(ccx, id, ms, |m| {
|
||||
ty_of_ty_method(ccx, m, rp)
|
||||
store_methods::<ast::trait_method>(ccx, id, ms, |m| {
|
||||
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,_,_), _}, _) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue