about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-26 02:56:03 -0700
committerbors <bors@rust-lang.org>2013-09-26 02:56:03 -0700
commita8a69ec15dce8bed5827d02e92cdb9fe2857b829 (patch)
tree983b168964d34754854dbefdff38e62943bdeb05
parenta268a1c4bb3867e4f8b050e07fd216e561b50521 (diff)
parent56d415aa60b41e171890cb76a323cb95d617b077 (diff)
downloadrust-a8a69ec15dce8bed5827d02e92cdb9fe2857b829.tar.gz
rust-a8a69ec15dce8bed5827d02e92cdb9fe2857b829.zip
auto merge of #9464 : bmaxa/rust/master, r=cmr
I have tried this fix and it seems to work either with single or multiple trait inheritance.

trait Base:Base2 + Base3{
fn foo(&self);
}

trait Base2 {
fn baz(&self);
}

trait Base3{
fn root(&self);
}

trait Super: Base{
fn bar(&self);
}

struct X;

impl Base for X {
fn foo(&self) {
println("base foo");
}

}
impl Base2 for X {
fn baz(&self) {
println("base2 baz");
}

}
impl Base3 for X {
fn root(&self) {
println("base3 root");
}

}
impl Super for X {
fn bar(&self) {
println("super bar");
}
}

fn main() {
let n = X;
let s = &n as &Super;
s.bar();
s.foo(); // super bar
s.baz();
s.root();
}

bmaxa@maxa:~/examples/rust$ rustc error.rs
bmaxa@maxa:~/examples/rust$ ./error 
super bar
base foo
base2 baz
base3 root
-rw-r--r--src/librustc/middle/typeck/check/method.rs11
-rw-r--r--src/test/run-pass/issue-9394-inherited-trait-calls.rs61
2 files changed, 66 insertions, 6 deletions
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 48d630b4aa9..60712769de5 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -372,7 +372,7 @@ impl<'self> LookupContext<'self> {
     // to a trait and its supertraits.
     fn get_method_index(&self,
                         trait_ref: @TraitRef,
-                        subtrait_id: ast::DefId,
+                        subtrait: @TraitRef,
                         n_method: uint) -> uint {
         let tcx = self.tcx();
 
@@ -382,15 +382,14 @@ impl<'self> LookupContext<'self> {
         // we find the trait the method came from, counting up the
         // methods from them.
         let mut method_count = 0;
-        do ty::each_bound_trait_and_supertraits(tcx, &[trait_ref])
+        do ty::each_bound_trait_and_supertraits(tcx, &[subtrait])
             |bound_ref| {
-            if bound_ref.def_id == subtrait_id { false }
+            if bound_ref.def_id == trait_ref.def_id { false }
                 else {
                 method_count += ty::trait_methods(tcx, bound_ref.def_id).len();
                 true
             }
         };
-
         return method_count + n_method;
     }
 
@@ -418,9 +417,9 @@ impl<'self> LookupContext<'self> {
         let trait_ref = @TraitRef { def_id: did, substs: rcvr_substs.clone() };
 
         do self.push_inherent_candidates_from_bounds_inner(&[trait_ref])
-            |trait_ref, m, method_num, _bound_num| {
+            |new_trait_ref, m, method_num, _bound_num| {
             let vtable_index =
-                self.get_method_index(trait_ref, trait_ref.def_id, method_num);
+                self.get_method_index(new_trait_ref, trait_ref, method_num);
             // We need to fix up the transformed self type.
             let transformed_self_ty =
                 self.construct_transformed_self_ty_for_object(
diff --git a/src/test/run-pass/issue-9394-inherited-trait-calls.rs b/src/test/run-pass/issue-9394-inherited-trait-calls.rs
new file mode 100644
index 00000000000..e60f8d4c888
--- /dev/null
+++ b/src/test/run-pass/issue-9394-inherited-trait-calls.rs
@@ -0,0 +1,61 @@
+// Copyright 2012 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.
+
+trait Base: Base2 + Base3{
+    fn foo(&self) -> ~str;
+}
+
+trait Base2: Base3{
+    fn baz(&self) -> ~str;
+}
+
+trait Base3{
+    fn root(&self) -> ~str;
+}
+
+trait Super: Base{
+    fn bar(&self) -> ~str;
+}
+
+struct X;
+
+impl Base for X {
+    fn foo(&self) -> ~str{
+        ~"base foo"
+    }
+
+}
+
+impl Base2 for X {
+    fn baz(&self) -> ~str{
+        ~"base2 baz"
+    }
+}
+
+impl Base3 for X {
+    fn root(&self) -> ~str{
+        ~"base3 root"
+    }
+}
+
+impl Super for X {
+    fn bar(&self) -> ~str{
+        ~"super bar"
+    }
+}
+
+pub fn main() {
+    let n = X;
+    let s = &n as &Super;
+    assert_eq!(s.bar(),~"super bar");
+    assert_eq!(s.foo(),~"base foo");
+    assert_eq!(s.baz(),~"base2 baz");
+    assert_eq!(s.root(),~"base3 root");
+}