about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2013-07-11 15:08:43 -0700
committerMichael Sullivan <sully@msully.net>2013-07-11 15:51:10 -0700
commit186f6faf1e6f4b507d97fefcb02fd8a7cf8d716f (patch)
treeb5b0c24a133e581034649a3498699e5d68d61a2b
parent1bbb4348806dab6d9b4c280d4cfd324645969eca (diff)
downloadrust-186f6faf1e6f4b507d97fefcb02fd8a7cf8d716f.tar.gz
rust-186f6faf1e6f4b507d97fefcb02fd8a7cf8d716f.zip
Get cross crate static default methods working. Closes #7569.
-rw-r--r--src/librustc/metadata/encoder.rs19
-rw-r--r--src/librustc/middle/astencode.rs6
-rw-r--r--src/librustc/middle/trans/inline.rs2
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_map.rs13
-rw-r--r--src/libsyntax/ast_util.rs6
-rw-r--r--src/test/auxiliary/trait_default_method_xc_aux.rs4
-rw-r--r--src/test/run-pass/trait-default-method-xc.rs19
8 files changed, 40 insertions, 31 deletions
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index a9f3200af12..b2fefdd97b8 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -791,7 +791,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
     if len > 0u || should_inline {
         (ecx.encode_inlined_item)(
            ecx, ebml_w, impl_path,
-           ii_method(local_def(parent_id), m));
+           ii_method(local_def(parent_id), false, m));
     } else {
         encode_symbol(ecx, ebml_w, m.id);
     }
@@ -1123,21 +1123,16 @@ fn encode_info_for_item(ecx: &EncodeContext,
                 }
 
                 provided(m) => {
-                    // This is obviously a bogus assert but I don't think this
-                    // ever worked before anyhow...near as I can tell, before
-                    // we would emit two items.
-                    if method_ty.explicit_self == sty_static {
-                        tcx.sess.span_unimpl(
-                            item.span,
-                            fmt!("Method %s is both provided and static",
-                                 token::ident_to_str(&method_ty.ident)));
+                    // If this is a static method, we've already encoded
+                    // this.
+                    if method_ty.explicit_self != sty_static {
+                        encode_type_param_bounds(ebml_w, ecx,
+                                                 &m.generics.ty_params);
                     }
-                    encode_type_param_bounds(ebml_w, ecx,
-                                             &m.generics.ty_params);
                     encode_method_sort(ebml_w, 'p');
                     (ecx.encode_inlined_item)(
                         ecx, ebml_w, path,
-                        ii_method(local_def(item.id), m));
+                        ii_method(local_def(item.id), true, m));
                 }
             }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 7412eba1156..2e0090f7dda 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -319,7 +319,8 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
     match *ii {
         //hack: we're not dropping items
         ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
-        ast::ii_method(d, m) => ast::ii_method(d, fld.fold_method(m)),
+        ast::ii_method(d, is_provided, m) =>
+          ast::ii_method(d, is_provided, fld.fold_method(m)),
         ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
     }
 }
@@ -340,7 +341,8 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
 
     match ii {
         ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
-        ast::ii_method(d, m) => ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m)),
+        ast::ii_method(d, is_provided, m) =>
+          ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)),
         ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),
     }
 }
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index 893ef3feb56..1f7b2bd4663 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -88,7 +88,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id,
             ccx.sess.bug("maybe_get_item_ast returned a found_parent \
              with a non-item parent");
         }
-        csearch::found(ast::ii_method(impl_did, mth)) => {
+        csearch::found(ast::ii_method(impl_did, _is_provided, mth)) => {
           ccx.stats.n_inlines += 1;
           ccx.external.insert(fn_id, Some(mth.id));
           // If this is a default method, we can't look up the
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8c37c1510cf..b6275ed186c 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1033,7 +1033,7 @@ pub enum foreign_item_ {
 #[deriving(Eq, Encodable, Decodable,IterBytes)]
 pub enum inlined_item {
     ii_item(@item),
-    ii_method(def_id /* impl id */, @method),
+    ii_method(def_id /* impl id */, bool /* is provided */, @method),
     ii_foreign(@foreign_item),
 }
 
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 59020e9d183..e7eedcaa62e 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -165,8 +165,8 @@ pub fn map_decoded_item(diag: @span_handler,
                                               i.vis,    // Wrong but OK
                                               @path));
       }
-      ii_method(impl_did, m) => {
-        map_method(impl_did, @path, m, cx);
+      ii_method(impl_did, is_provided, m) => {
+        map_method(impl_did, @path, m, is_provided, cx);
       }
     }
 
@@ -207,8 +207,11 @@ pub fn map_pat(pat: @pat, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) {
 }
 
 pub fn map_method(impl_did: def_id, impl_path: @path,
-                  m: @method, cx: @mut Ctx) {
-    cx.map.insert(m.id, node_method(m, impl_did, impl_path));
+                  m: @method, is_provided: bool, cx: @mut Ctx) {
+    let entry = if is_provided {
+        node_trait_method(@provided(m), impl_did, impl_path)
+    } else { node_method(m, impl_did, impl_path) };
+    cx.map.insert(m.id, entry);
     cx.map.insert(m.self_id, node_local(special_idents::self_));
 }
 
@@ -219,7 +222,7 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) {
         item_impl(_, _, _, ref ms) => {
             let impl_did = ast_util::local_def(i.id);
             for ms.iter().advance |m| {
-                map_method(impl_did, extend(cx, i.ident), *m, cx);
+                map_method(impl_did, extend(cx, i.ident), *m, false, cx);
             }
         }
         item_enum(ref enum_definition, _) => {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 78be8e6f180..d87955a484c 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -298,7 +298,7 @@ impl inlined_item_utils for inlined_item {
         match *self {
             ii_item(i) => /* FIXME (#2543) */ copy i.ident,
             ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
-            ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
+            ii_method(_, _, m) => /* FIXME (#2543) */ copy m.ident,
         }
     }
 
@@ -306,7 +306,7 @@ impl inlined_item_utils for inlined_item {
         match *self {
             ii_item(i) => i.id,
             ii_foreign(i) => i.id,
-            ii_method(_, m) => m.id,
+            ii_method(_, _, m) => m.id,
         }
     }
 
@@ -314,7 +314,7 @@ impl inlined_item_utils for inlined_item {
         match *self {
             ii_item(i) => (v.visit_item)(i, (e, v)),
             ii_foreign(i) => (v.visit_foreign_item)(i, (e, v)),
-            ii_method(_, m) => visit::visit_method_helper(m, (e, v)),
+            ii_method(_, _, m) => visit::visit_method_helper(m, (e, v)),
         }
     }
 }
diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs
index 7ae648f113a..6bd679f1304 100644
--- a/src/test/auxiliary/trait_default_method_xc_aux.rs
+++ b/src/test/auxiliary/trait_default_method_xc_aux.rs
@@ -5,7 +5,8 @@ pub struct Something { x: int }
 pub trait A {
     fn f(&self) -> int;
     fn g(&self) -> int { 10 }
-    fn h(&self) -> int { 10 }
+    fn h(&self) -> int { 11 }
+    fn lurr(x: &Self, y: &Self) -> int { x.g() + y.h() }
 }
 
 
@@ -19,6 +20,7 @@ impl A for Something {
 
 trait B<T> {
     fn thing<U>(&self, x: T, y: U) -> (T, U) { (x, y) }
+    fn staticthing<U>(z: &Self, x: T, y: U) -> (T, U) { (x, y) }
 }
 
 impl<T> B<T> for int { }
diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs
index 4eac1a1e730..f31b46c3339 100644
--- a/src/test/run-pass/trait-default-method-xc.rs
+++ b/src/test/run-pass/trait-default-method-xc.rs
@@ -4,13 +4,17 @@
 #[allow(default_methods)];
 
 extern mod aux(name = "trait_default_method_xc_aux");
-use aux::{A, B, TestEquality, Something};
-
+use aux::{A, TestEquality, Something};
+use aux::B;
 
 fn f<T: aux::A>(i: T) {
     assert_eq!(i.g(), 10);
 }
 
+fn welp<T>(i: int, x: &T) -> int {
+    i.g()
+}
+
 mod stuff {
     pub struct thing { x: int }
 }
@@ -43,23 +47,26 @@ fn main () {
     // Some tests of random things
     f(0);
 
+    assert_eq!(A::lurr(&0, &1), 21);
+
     let a = stuff::thing { x: 0 };
     let b = stuff::thing { x: 1 };
     let c = Something { x: 1 };
 
     assert_eq!(0i.g(), 10);
     assert_eq!(a.g(), 10);
-    assert_eq!(a.h(), 10);
-    assert_eq!(c.h(), 10);
+    assert_eq!(a.h(), 11);
+    assert_eq!(c.h(), 11);
 
-    0i.thing(3.14, 1);
     assert_eq!(0i.thing(3.14, 1), (3.14, 1));
+    assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1));
+    assert_eq!(B::staticthing::<float, int, int>(&0i, 3.14, 1), (3.14, 1));
 
     assert_eq!(g(0i, 3.14, 1), (3.14, 1));
     assert_eq!(g(false, 3.14, 1), (3.14, 1));
 
     let obj = @0i as @A;
-    assert_eq!(obj.h(), 10);
+    assert_eq!(obj.h(), 11);
 
 
     // Trying out a real one