about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-09-06 17:44:42 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-09-07 10:27:29 -0700
commitc6b51547c14780a0473a5bcae90c8d4b0530b7c8 (patch)
tree1eee892474197e0e09b090d094e254864706ff6e /src/rustc
parentcd3cc6d17b68ef18199a54372963b00ba8a0a84f (diff)
downloadrust-c6b51547c14780a0473a5bcae90c8d4b0530b7c8.tar.gz
rust-c6b51547c14780a0473a5bcae90c8d4b0530b7c8.zip
In typeck, don't assume traits with default methods are in the same crate
But note that default methods still don't work cross-crate (see #2794) --
this just makes it so that when a method is missing in a cross-crate impl,
the right error message gets printed.

Closes #3344
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/ty.rs19
-rw-r--r--src/rustc/middle/typeck/collect.rs35
2 files changed, 31 insertions, 23 deletions
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index f95997c93e9..dd48c2183a7 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -190,6 +190,7 @@ export serialize_region_variance, deserialize_region_variance;
 export opt_region_variance;
 export serialize_opt_region_variance, deserialize_opt_region_variance;
 export determine_inherited_purity;
+export provided_trait_methods;
 
 // Data types
 
@@ -3069,6 +3070,24 @@ fn store_trait_methods(cx: ctxt, id: ast::node_id, ms: @~[method]) {
     cx.trait_method_cache.insert(ast_util::local_def(id), ms);
 }
 
+fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[@ast::method] {
+    if is_local(id) {
+        match cx.items.find(id.node) {
+            Some(ast_map::node_item(@{node: item_trait(_, _, ms),_}, _)) =>
+                match ast_util::split_trait_methods(ms) {
+                   (_, p) => p
+                },
+            _ => cx.sess.bug(#fmt("provided_trait_methods: %? is not a trait",
+                                  id))
+        }
+    }
+    else {
+        // FIXME #2794: default methods for traits don't work cross-crate
+        ~[]
+    }
+}
+
+
 fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
     match cx.trait_method_cache.find(id) {
       // Local traits are supposed to have been added explicitly.
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index 3b25e41d313..43d6cf14d93 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -343,33 +343,22 @@ fn check_methods_against_trait(ccx: @crate_ctxt,
               // implementation in the trait itself.  If not, raise a
               // "missing method" error.
 
-              match tcx.items.get(did.node) {
-                ast_map::node_item(
-                    @{node: ast::item_trait(_, _, trait_methods), _}, _) => {
-                  let (_, provided_methods) =
-                      split_trait_methods(trait_methods);
-
-                  match vec::find(provided_methods, |provided_method|
-                                provided_method.ident == trait_m.ident) {
-                    Some(_) => {
-                      // If there's a provided method with the name we
-                      // want, then we're fine; nothing else to do.
-                    }
-                    None => {
-                      tcx.sess.span_err(
-                          a_trait_ty.path.span,
-                          fmt!("missing method `%s`",
-                               tcx.sess.str_of(trait_m.ident)));
-                    }
-                  }
+              let provided_methods = ty::provided_trait_methods(tcx, did);
+              match vec::find(provided_methods, |provided_method|
+                              provided_method.ident == trait_m.ident) {
+                Some(_) => {
+                    // If there's a provided method with the name we
+                    // want, then we're fine; nothing else to do.
                 }
-                _ => {
-                    tcx.sess.bug(~"check_methods_against_trait(): trait_ref \
-                                   didn't refer to a trait");
+                None => {
+                    tcx.sess.span_err(
+                        a_trait_ty.path.span,
+                        fmt!("missing method `%s`",
+                             tcx.sess.str_of(trait_m.ident)));
                 }
               }
           }
-        } // alt
+        } // match
     } // |trait_m|
 } // fn