about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-01-13 09:17:07 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-01-13 09:17:07 -0500
commitd3cecbf6f6aaeb7defdfb2e5d9e2b82d02fa7528 (patch)
tree956775208a0ab58a4378bc5d218e4bd00c6de2a9 /src
parenta6408fa1d80191032bebfa0047bc597b746886a5 (diff)
downloadrust-d3cecbf6f6aaeb7defdfb2e5d9e2b82d02fa7528.tar.gz
rust-d3cecbf6f6aaeb7defdfb2e5d9e2b82d02fa7528.zip
Support UFCS style calls to a method defined in `Trait` where `Self`
is bound to a trait object. Fixes #20676.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/trans/meth.rs17
-rw-r--r--src/test/run-pass/issue-20676.rs20
-rw-r--r--src/test/run-pass/ufcs-trait-object.rs25
3 files changed, 59 insertions, 3 deletions
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 7ac062108f3..72c5e9f9d09 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -288,6 +288,17 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                      param_substs,
                                      callee_substs)
         }
+        traits::VtableObject(ref data) => {
+            let trait_item_def_ids =
+                ty::trait_item_def_ids(ccx.tcx(), trait_id);
+            let method_offset_in_trait =
+                trait_item_def_ids.iter()
+                                  .position(|item| item.def_id() == method_id)
+                                  .unwrap();
+            let (llfn, ty) =
+                trans_object_shim(ccx, data.object_ty, trait_id, method_offset_in_trait);
+            immediate_rvalue(llfn, ty)
+        }
         _ => {
             tcx.sess.bug(&format!("static call to invalid vtable: {}",
                                  vtbl.repr(tcx))[]);
@@ -371,7 +382,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             Callee { bcx: bcx, data: Fn(llfn) }
         }
         traits::VtableObject(ref data) => {
-            let llfn = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method);
+            let (llfn, _) = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method);
             Callee { bcx: bcx, data: Fn(llfn) }
         }
         traits::VtableBuiltin(..) |
@@ -540,7 +551,7 @@ pub fn trans_object_shim<'a, 'tcx>(
     object_ty: Ty<'tcx>,
     trait_id: ast::DefId,
     method_offset_in_trait: uint)
-    -> ValueRef
+    -> (ValueRef, Ty<'tcx>)
 {
     let _icx = push_ctxt("trans_object_shim");
     let tcx = ccx.tcx();
@@ -667,7 +678,7 @@ pub fn trans_object_shim<'a, 'tcx>(
 
     finish_fn(&fcx, bcx, sig.output);
 
-    llfn
+    (llfn, method_bare_fn_ty)
 }
 
 /// Creates a returns a dynamic vtable for the given type and vtable origin.
diff --git a/src/test/run-pass/issue-20676.rs b/src/test/run-pass/issue-20676.rs
new file mode 100644
index 00000000000..fd99fc01a23
--- /dev/null
+++ b/src/test/run-pass/issue-20676.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// Regression test for #20676. Error was that we didn't support
+// UFCS-style calls to a method in `Trait` where `Self` was bound to a
+// trait object of type `Trait`. See also `ufcs-trait-object.rs`.
+
+use std::fmt;
+
+fn main() {
+    let a: &fmt::Show = &1_i32;
+    format!("{:?}", a);
+}
diff --git a/src/test/run-pass/ufcs-trait-object.rs b/src/test/run-pass/ufcs-trait-object.rs
new file mode 100644
index 00000000000..2ae63040d17
--- /dev/null
+++ b/src/test/run-pass/ufcs-trait-object.rs
@@ -0,0 +1,25 @@
+// Copyright 2015 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 that when you use ufcs form to invoke a trait method (on a
+// trait object) everything works fine.
+
+trait Foo {
+    fn test(&self) -> i32;
+}
+
+impl Foo for i32 {
+    fn test(&self) -> i32 { *self }
+}
+
+fn main() {
+    let a: &Foo = &22_i32;
+    assert_eq!(Foo::test(a), 22);
+}