diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-09-06 17:44:42 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-09-07 10:27:29 -0700 |
| commit | c6b51547c14780a0473a5bcae90c8d4b0530b7c8 (patch) | |
| tree | 1eee892474197e0e09b090d094e254864706ff6e /src/rustc | |
| parent | cd3cc6d17b68ef18199a54372963b00ba8a0a84f (diff) | |
| download | rust-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.rs | 19 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/collect.rs | 35 |
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 |
