diff options
| author | Lindsey Kuper <lindsey@rockstargirl.org> | 2012-07-10 13:44:20 -0700 |
|---|---|---|
| committer | Lindsey Kuper <lindsey@rockstargirl.org> | 2012-07-13 11:16:07 -0700 |
| commit | fc9c4c32451dadab4f8a81897e8fc83ae6473d95 (patch) | |
| tree | d54e7d2d8ecce561fb04375e31516ccaf1521aa0 /src/rustc | |
| parent | d5563d732dfb4ebbf50ad221d8d4568319210a65 (diff) | |
Front-end support for default impls in traits.
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 21 | ||||
| -rw-r--r-- | src/rustc/middle/resolve.rs | 39 | ||||
| -rw-r--r-- | src/rustc/middle/resolve3.rs | 69 | ||||
| -rw-r--r-- | src/rustc/middle/typeck.rs | 1 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/collect.rs | 11 |
5 files changed, 105 insertions, 36 deletions
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 7539d2be00b..74fd9e1c17e 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -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)); diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index f2eea665522..8efdfac95ea 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -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) { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index ae1b4eebef4..138f021982a 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -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(method.decl.output, visitor); + self.resolve_type(ty_m.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], diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 3b10bb3bae3..d8db0533156 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -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; diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index fa5ffc61bae..30c5c04dc04 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -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,_,_), _}, _) { |
