about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorLindsey Kuper <lindsey@rockstargirl.org>2012-07-10 13:44:20 -0700
committerLindsey Kuper <lindsey@rockstargirl.org>2012-07-13 11:16:07 -0700
commitfc9c4c32451dadab4f8a81897e8fc83ae6473d95 (patch)
treed54e7d2d8ecce561fb04375e31516ccaf1521aa0 /src/rustc
parentd5563d732dfb4ebbf50ad221d8d4568319210a65 (diff)
Front-end support for default impls in traits.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/metadata/encoder.rs21
-rw-r--r--src/rustc/middle/resolve.rs39
-rw-r--r--src/rustc/middle/resolve3.rs69
-rw-r--r--src/rustc/middle/typeck.rs1
-rw-r--r--src/rustc/middle/typeck/collect.rs11
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,_,_), _}, _) {