mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-13 15:33:53 +00:00
rollup merge of #21089: nikomatsakis/issue-20676-invalid-vtable-for-object
Support UFCS style calls to a method defined in `Trait` where `Self` is bound to a trait object. Fixes #20676. r? @alexcrichton
This commit is contained in:
commit
d11f2b3aea
@ -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.
|
||||
|
20
src/test/run-pass/issue-20676.rs
Normal file
20
src/test/run-pass/issue-20676.rs
Normal file
@ -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);
|
||||
}
|
25
src/test/run-pass/ufcs-trait-object.rs
Normal file
25
src/test/run-pass/ufcs-trait-object.rs
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user