about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-08-22 17:21:29 -0700
committerbors <bors@rust-lang.org>2013-08-22 17:21:29 -0700
commit23bfa600a0f91f1ea62ea3f3783c358a7cb7da45 (patch)
tree5cbc5e327157d1fc25e40c5445b59dbe83850636 /src
parentf858452391c63bfbf46678c4ea9fd584adf1c28e (diff)
parent7b08b2c838c440d03e3e01f090e648e14ebfa083 (diff)
downloadrust-23bfa600a0f91f1ea62ea3f3783c358a7cb7da45.tar.gz
rust-23bfa600a0f91f1ea62ea3f3783c358a7cb7da45.zip
auto merge of #8659 : msullivan/rust/default-methods, r=alexcrichton
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/liveness.rs2
-rw-r--r--src/librustc/middle/trans/meth.rs19
-rw-r--r--src/librustc/middle/typeck/check/method.rs15
-rw-r--r--src/librustc/middle/typeck/check/mod.rs4
-rw-r--r--src/librustc/middle/typeck/collect.rs10
-rw-r--r--src/librustpkg/tests.rs1
-rw-r--r--src/libsyntax/ast_map.rs16
-rw-r--r--src/test/run-pass/trait-object-generics.rs46
8 files changed, 92 insertions, 21 deletions
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index edb805cfc40..a18fffda32e 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1617,7 +1617,7 @@ impl Liveness {
 
     pub fn should_warn(&self, var: Variable) -> Option<@str> {
         let name = self.ir.variable_name(var);
-        if name[0] == ('_' as u8) { None } else { Some(name) }
+        if name.len() == 0 || name[0] == ('_' as u8) { None } else { Some(name) }
     }
 
     pub fn warn_about_unused_args(&self, decl: &fn_decl, entry_ln: LiveNode) {
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index f4451d9c53f..c0534b89f79 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -577,20 +577,23 @@ fn emit_vtable_methods(bcx: @mut Block,
 
     let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
     do trait_method_def_ids.map |method_def_id| {
-        let im = ty::method(tcx, *method_def_id);
+        let ident = ty::method(tcx, *method_def_id).ident;
+        // The substitutions we have are on the impl, so we grab
+        // the method type from the impl to substitute into.
+        let m_id = method_with_name(ccx, impl_id, ident);
+        let m = ty::method(tcx, m_id);
+        debug!("(making impl vtable) emitting method %s at subst %s",
+               m.repr(tcx),
+               substs.repr(tcx));
         let fty = ty::subst_tps(tcx,
                                 substs,
                                 None,
-                                ty::mk_bare_fn(tcx, im.fty.clone()));
-        if im.generics.has_type_params() || ty::type_has_self(fty) {
+                                ty::mk_bare_fn(tcx, m.fty.clone()));
+        if m.generics.has_type_params() || ty::type_has_self(fty) {
             debug!("(making impl vtable) method has self or type params: %s",
-                   tcx.sess.str_of(im.ident));
+                   tcx.sess.str_of(ident));
             C_null(Type::nil().ptr_to())
         } else {
-            debug!("(making impl vtable) adding method to vtable: %s",
-                   tcx.sess.str_of(im.ident));
-            let m_id = method_with_name(ccx, impl_id, im.ident);
-
             trans_fn_ref_with_vtables(bcx, m_id, 0,
                                       substs, Some(vtables)).llfn
         }
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index c8d3bdaab28..c15f6a25445 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -938,9 +938,18 @@ impl<'self> LookupContext<'self> {
 
         // static methods should never have gotten this far:
         assert!(candidate.method_ty.explicit_self != sty_static);
-        let transformed_self_ty =
-            ty::subst(tcx, &candidate.rcvr_substs,
-                      candidate.method_ty.transformed_self_ty.unwrap());
+
+        let transformed_self_ty = match candidate.origin {
+            method_object(*) => {
+                // For annoying reasons, we've already handled the
+                // substitution for object calls.
+                candidate.method_ty.transformed_self_ty.unwrap()
+            }
+            _ => {
+                ty::subst(tcx, &candidate.rcvr_substs,
+                          candidate.method_ty.transformed_self_ty.unwrap())
+            }
+        };
 
         // Determine the values for the type parameters of the method.
         // If they were not explicitly supplied, just construct fresh
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 7d1b5f7e93f..5ce82ad6e2c 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3092,7 +3092,6 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
                                       sp: span,
                                       defn: ast::def)
                                    -> ty_param_bounds_and_ty {
-
     match defn {
       ast::def_arg(nid, _) | ast::def_local(nid, _) | ast::def_self(nid, _) |
       ast::def_binding(nid, _) => {
@@ -3149,7 +3148,8 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
     let ty_param_count = tpt.generics.type_param_defs.len();
     let ty_substs_len = pth.types.len();
 
-    debug!("ty_param_count=%? ty_substs_len=%?",
+    debug!("tpt=%s ty_param_count=%? ty_substs_len=%?",
+           tpt.repr(fcx.tcx()),
            ty_param_count,
            ty_substs_len);
 
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 987b5949f98..cb0244bb610 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -346,9 +346,10 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
         let substd_type_param_defs = m.generics.type_param_defs.subst(tcx, &substs);
         new_type_param_defs.push_all(*substd_type_param_defs);
 
-        debug!("static method %s type_param_defs=%s substs=%s",
+        debug!("static method %s type_param_defs=%s ty=%s, substs=%s",
                m.def_id.repr(tcx),
                new_type_param_defs.repr(tcx),
+               ty.repr(tcx),
                substs.repr(tcx));
 
         tcx.tcache.insert(m.def_id,
@@ -893,8 +894,8 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
       }
       ast::item_trait(ref generics, _, ref trait_methods) => {
           let _trait_def = trait_def_of_item(ccx, it);
-          ensure_trait_methods(ccx, it.id);
 
+          // Run convert_methods on the provided methods.
           let (_, provided_methods) =
               split_trait_methods(*trait_methods);
           let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
@@ -904,6 +905,11 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
                                   untransformed_rcvr_ty,
                                   &ty_generics, generics,
                                   it.vis);
+
+          // We need to do this *after* converting methods, since
+          // convert_methods produces a tcache entry that is wrong for
+          // static trait methods. This is somewhat unfortunate.
+          ensure_trait_methods(ccx, it.id);
       }
       ast::item_struct(struct_def, ref generics) => {
         ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index d130ef249ef..0efa0782da9 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -678,6 +678,7 @@ fn rustpkg_local_pkg() {
 }
 
 #[test]
+#[ignore (reason = "test makes bogus assumptions about build directory layout: issue #8690")]
 fn package_script_with_default_build() {
     let dir = create_local_package(&PkgId::new("fancy-lib"));
     debug!("dir = %s", dir.to_str());
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 6c3fb82965d..9c9d19ba46b 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -238,12 +238,18 @@ impl Visitor<()> for Ctx {
                     self.map.insert(p.ref_id, node_item(i, item_path));
                 }
                 for tm in methods.iter() {
-                    let id = ast_util::trait_method_to_ty_method(tm).id;
+                    let ext = { self.extend(i.ident) };
                     let d_id = ast_util::local_def(i.id);
-                    self.map.insert(id,
-                                    node_trait_method(@(*tm).clone(),
-                                                      d_id,
-                                                      item_path));
+                    match *tm {
+                        required(ref m) => {
+                            let entry =
+                                node_trait_method(@(*tm).clone(), d_id, ext);
+                            self.map.insert(m.id, entry);
+                        }
+                        provided(m) => {
+                            self.map_method(d_id, ext, m, true);
+                        }
+                    }
                 }
             }
             _ => {}
diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs
new file mode 100644
index 00000000000..12b6af29520
--- /dev/null
+++ b/src/test/run-pass/trait-object-generics.rs
@@ -0,0 +1,46 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// test for #8664
+
+pub trait Trait2<A> {
+    fn doit(&self);
+}
+
+pub struct Impl<A1, A2, A3> {
+    /*
+     * With A2 we get the ICE:
+     * task <unnamed> failed at 'index out of bounds: the len is 1 but the index is 1', /home/tortue/rust_compiler_newest/src/librustc/middle/subst.rs:58
+     */
+    t: ~Trait2<A2>
+}
+
+impl<A1, A2, A3> Impl<A1, A2, A3> {
+    pub fn step(&self) {
+        self.t.doit()
+    }
+}
+
+// test for #8601
+
+enum Type<T> { Constant }
+
+trait Trait<K,V> {
+    fn method(&self,Type<(K,V)>) -> int;
+}
+
+impl<V> Trait<u8,V> for () {
+    fn method(&self, _x: Type<(u8,V)>) -> int { 0 }
+}
+
+fn main () {
+    let a = @() as @Trait<u8, u8>;
+    assert_eq!(a.method(Constant), 0);
+}