rustc: remove MethodOrigin::Object and use traits::VtableObject instead.

This commit is contained in:
Eduard Burtescu 2015-07-03 05:22:54 +03:00
parent a5447e13aa
commit 96d24a5c58
9 changed files with 144 additions and 227 deletions

View File

@ -630,15 +630,8 @@ pub enum MethodOrigin {
/// Inherent impl method call.
Inherent,
/// Statically dispatched trait method call.
Trait,
/// Dynamically dispatched trait method call.
/// The usize is the index into the actual runtime vtable.
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits; this is the index into
/// that vtable.
Object(usize)
/// Trait method call.
Trait
}
#[derive(Clone, Debug)]

View File

@ -852,7 +852,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
}
// Trait methods are always all public. The only controlling factor
// is whether the trait itself is accessible or not.
ty::MethodOrigin::Trait | ty::MethodOrigin::Object(_) => {
ty::MethodOrigin::Trait => {
let method = self.tcx.impl_or_trait_item(callee.def_id);
self.report_error(self.ensure_public(span, method.container().id(),
None, "source trait"));

View File

@ -892,7 +892,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
ty::MethodOrigin::Inherent => {
(Some(method_callee.def_id), None)
}
ty::MethodOrigin::Trait | ty::MethodOrigin::Object(_) => {
ty::MethodOrigin::Trait => {
(None, Some(method_callee.def_id))
}
};

View File

@ -22,7 +22,6 @@ use arena::TypedArena;
use back::link;
use session;
use llvm::{self, ValueRef, get_params};
use metadata::csearch;
use middle::def;
use middle::subst;
use middle::subst::{Subst, Substs};
@ -66,7 +65,7 @@ pub struct MethodData {
pub enum CalleeData<'tcx> {
// Constructor for enum variant/tuple-like-struct
// i.e. Some, Ok
NamedTupleConstructor(subst::Substs<'tcx>, ty::Disr),
NamedTupleConstructor(ty::Disr),
// Represents a (possibly monomorphized) top-level fn item or method
// item. Note that this is just the fn-ptr and is not a Rust closure
@ -81,6 +80,7 @@ pub enum CalleeData<'tcx> {
pub struct Callee<'blk, 'tcx: 'blk> {
pub bcx: Block<'blk, 'tcx>,
pub data: CalleeData<'tcx>,
pub ty: Ty<'tcx>
}
fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
@ -104,11 +104,11 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
let DatumBlock { bcx, datum, .. } = expr::trans(bcx, expr);
match datum.ty.sty {
ty::TyBareFn(..) => {
let llval = datum.to_llscalarish(bcx);
return Callee {
Callee {
bcx: bcx,
data: Fn(llval),
};
ty: datum.ty,
data: Fn(datum.to_llscalarish(bcx))
}
}
_ => {
bcx.tcx().sess.span_bug(
@ -119,12 +119,13 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
}
}
fn fn_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, llfn: ValueRef)
fn fn_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, datum: Datum<'tcx, Rvalue>)
-> Callee<'blk, 'tcx> {
return Callee {
Callee {
bcx: bcx,
data: Fn(llfn),
};
data: Fn(datum.val),
ty: datum.ty
}
}
fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@ -143,12 +144,10 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
_ => false
}
} => {
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
Callee {
bcx: bcx,
data: NamedTupleConstructor(substs, 0)
data: NamedTupleConstructor(0),
ty: expr_ty
}
}
def::DefFn(did, _) if match expr_ty.sty {
@ -159,40 +158,36 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
ExprId(ref_expr.id),
bcx.fcx.param_substs);
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs), ty: expr_ty }
}
def::DefFn(did, _) | def::DefMethod(did, def::FromImpl(_)) => {
fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
bcx.fcx.param_substs).val)
bcx.fcx.param_substs))
}
def::DefMethod(meth_did, def::FromTrait(trait_did)) => {
fn_callee(bcx, meth::trans_static_method_callee(bcx.ccx(),
meth_did,
trait_did,
ref_expr.id,
bcx.fcx.param_substs).val)
bcx.fcx.param_substs))
}
def::DefVariant(tid, vid, _) => {
let vinfo = bcx.tcx().enum_variant_with_id(tid, vid);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
// Nullary variants are not callable
assert!(!vinfo.args.is_empty());
Callee {
bcx: bcx,
data: NamedTupleConstructor(substs, vinfo.disr_val)
data: NamedTupleConstructor(vinfo.disr_val),
ty: expr_ty
}
}
def::DefStruct(_) => {
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
Callee {
bcx: bcx,
data: NamedTupleConstructor(substs, 0)
data: NamedTupleConstructor(0),
ty: expr_ty
}
}
def::DefStatic(..) |
@ -232,21 +227,6 @@ pub fn trans_fn_ref<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trans_fn_ref_with_substs(ccx, def_id, node, param_substs, substs)
}
fn trans_fn_ref_with_substs_to_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
def_id: ast::DefId,
ref_id: ast::NodeId,
substs: subst::Substs<'tcx>)
-> Callee<'blk, 'tcx> {
Callee {
bcx: bcx,
data: Fn(trans_fn_ref_with_substs(bcx.ccx(),
def_id,
ExprId(ref_id),
bcx.fcx.param_substs,
substs).val),
}
}
/// Translates an adapter that implements the `Fn` trait for a fn
/// pointer. This is basically the equivalent of something like:
///
@ -356,12 +336,13 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
expr::SaveIn(fcx.get_ret_slot(bcx, sig.output, "ret_slot"))
);
bcx = trans_call_inner(bcx,
DebugLoc::None,
bare_fn_ty,
|bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
ArgVals(&llargs[(self_idx + 1)..]),
dest).bcx;
bcx = trans_call_inner(bcx, DebugLoc::None, |bcx, _| {
Callee {
bcx: bcx,
data: Fn(llfnpointer),
ty: bare_fn_ty
}
}, ArgVals(&llargs[(self_idx + 1)..]), dest).bcx;
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
@ -586,17 +567,16 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// ______________________________________________________________________
// Translating calls
pub fn trans_call<'a, 'blk, 'tcx>(in_cx: Block<'blk, 'tcx>,
pub fn trans_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
call_expr: &ast::Expr,
f: &ast::Expr,
args: CallArgs<'a, 'tcx>,
dest: expr::Dest)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_call");
trans_call_inner(in_cx,
trans_call_inner(bcx,
call_expr.debug_loc(),
common::expr_ty_adjusted(in_cx, f),
|cx, _| trans(cx, f),
|bcx, _| trans(bcx, f),
args,
Some(dest)).bcx
}
@ -610,22 +590,9 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_expr={:?})", call_expr);
let method_call = MethodCall::expr(call_expr.id);
let method_ty = match bcx.tcx().tables.borrow().method_map.get(&method_call) {
Some(method) => match method.origin {
ty::MethodOrigin::Object(_) => match method.ty.sty {
ty::TyBareFn(_, ref fty) => {
bcx.tcx().mk_fn(None, meth::opaque_method_ty(bcx.tcx(), fty))
}
_ => method.ty
},
_ => method.ty
},
None => panic!("method not found in trans_method_call")
};
trans_call_inner(
bcx,
call_expr.debug_loc(),
common::monomorphize_type(bcx, method_ty),
|cx, arg_cleanup_scope| {
meth::trans_method_callee(cx, method_call, Some(rcvr), arg_cleanup_scope)
},
@ -639,22 +606,18 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
dest: Option<expr::Dest>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let fty = if did.krate == ast::LOCAL_CRATE {
bcx.tcx().node_id_to_type(did.node)
} else {
csearch::get_type(bcx.tcx(), did).ty
};
callee::trans_call_inner(bcx,
debug_loc,
fty,
|bcx, _| {
trans_fn_ref_with_substs_to_callee(bcx,
did,
0,
subst::Substs::trans_empty())
},
ArgVals(args),
dest)
callee::trans_call_inner(bcx, debug_loc, |bcx, _| {
let datum = trans_fn_ref_with_substs(bcx.ccx(),
did,
ExprId(0),
bcx.fcx.param_substs,
subst::Substs::trans_empty());
Callee {
bcx: bcx,
data: Fn(datum.val),
ty: datum.ty
}
}, ArgVals(args), dest)
}
/// This behemoth of a function translates function calls. Unfortunately, in order to generate more
@ -669,7 +632,6 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// somewhere. Nonetheless we return the actual return value of the function.
pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
debug_loc: DebugLoc,
callee_ty: Ty<'tcx>,
get_callee: F,
args: CallArgs<'a, 'tcx>,
dest: Option<expr::Dest>)
@ -690,7 +652,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
let mut bcx = callee.bcx;
let (abi, ret_ty) = match callee_ty.sty {
let (abi, ret_ty) = match callee.ty.sty {
ty::TyBareFn(_, ref f) => {
let output = bcx.tcx().erase_late_bound_regions(&f.sig.output());
(f.abi, output)
@ -716,18 +678,17 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
}
};
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
return intrinsic::trans_intrinsic_call(bcx, node, callee.ty,
arg_cleanup_scope, args,
dest.unwrap(), substs,
call_info);
}
NamedTupleConstructor(substs, disr) => {
NamedTupleConstructor(disr) => {
assert!(dest.is_some());
fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
let ctor_ty = callee_ty.subst(bcx.tcx(), &substs);
return base::trans_named_tuple_constructor(bcx,
ctor_ty,
callee.ty,
disr,
args,
dest.unwrap(),
@ -802,7 +763,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
// Push the arguments.
bcx = trans_args(bcx,
args,
callee_ty,
callee.ty,
&mut llargs,
cleanup::CustomScope(arg_cleanup_scope),
llself.is_some(),
@ -814,7 +775,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let (llret, b) = base::invoke(bcx,
llfn,
&llargs[..],
callee_ty,
callee.ty,
debug_loc);
bcx = b;
llresult = llret;
@ -843,7 +804,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
};
bcx = trans_args(bcx,
args,
callee_ty,
callee.ty,
&mut llargs,
cleanup::CustomScope(arg_cleanup_scope),
false,
@ -851,7 +812,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
bcx = foreign::trans_native_call(bcx,
callee_ty,
callee.ty,
llfn,
opt_llretslot.unwrap(),
&llargs[..],

View File

@ -429,12 +429,13 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let callee_data = TraitItem(MethodData { llfn: llreffn,
llself: env_datum.val });
bcx = callee::trans_call_inner(bcx,
DebugLoc::None,
llref_fn_ty,
|bcx, _| Callee { bcx: bcx, data: callee_data },
ArgVals(&llargs[(self_idx + 1)..]),
dest).bcx;
bcx = callee::trans_call_inner(bcx, DebugLoc::None, |bcx, _| {
Callee {
bcx: bcx,
data: callee_data,
ty: llref_fn_ty
}
}, ArgVals(&llargs[(self_idx + 1)..]), dest).bcx;
fcx.pop_custom_cleanup_scope(self_scope);

View File

@ -1947,15 +1947,8 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
dest: Option<Dest>,
autoref: bool)
-> Result<'blk, 'tcx> {
let method_ty = bcx.tcx()
.tables
.borrow()
.method_map
.get(&method_call).unwrap().ty;
callee::trans_call_inner(bcx,
expr.debug_loc(),
monomorphize_type(bcx, method_ty),
|bcx, arg_cleanup_scope| {
meth::trans_method_callee(bcx,
method_call,
@ -1974,20 +1967,11 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
-> Block<'blk, 'tcx> {
debug!("trans_overloaded_call {}", expr.id);
let method_call = MethodCall::expr(expr.id);
let method_type = bcx.tcx()
.tables
.borrow()
.method_map
.get(&method_call)
.unwrap()
.ty;
let mut all_args = vec!(callee);
all_args.extend(args.iter().map(|e| &**e));
unpack_result!(bcx,
callee::trans_call_inner(bcx,
expr.debug_loc(),
monomorphize_type(bcx,
method_type),
|bcx, arg_cleanup_scope| {
meth::trans_method_callee(
bcx,

View File

@ -39,7 +39,6 @@ use trans::type_of::*;
use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty::MethodCall;
use syntax::abi::{Rust, RustCall};
use syntax::parse::token;
use syntax::{ast, attr, visit};
use syntax::codemap::DUMMY_SP;
@ -119,12 +118,14 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match origin {
ty::MethodOrigin::Inherent => {
debug!("trans_method_callee: static, {:?}", method_id);
let datum = callee::trans_fn_ref(bcx.ccx(),
method_id,
MethodCallKey(method_call),
bcx.fcx.param_substs);
Callee {
bcx: bcx,
data: Fn(callee::trans_fn_ref(bcx.ccx(),
method_id,
MethodCallKey(method_call),
bcx.fcx.param_substs).val),
data: Fn(datum.val),
ty: datum.ty
}
}
@ -149,26 +150,27 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
debug!("origin = {:?}", origin);
trans_monomorphized_callee(bcx,
method_call,
self_expr,
trait_def_id,
method_id,
origin)
method_ty,
origin,
arg_cleanup_scope)
}
}
}
ty::MethodOrigin::Object(vtable_index) => {
let self_expr = match self_expr {
Some(self_expr) => self_expr,
None => {
bcx.sess().span_bug(bcx.tcx().map.span(method_call.expr_id),
"self expr wasn't provided for trait object \
callee (trying to call overloaded op?)")
}
};
trans_trait_callee(bcx,
monomorphize_type(bcx, method_ty),
vtable_index,
self_expr,
arg_cleanup_scope)
}
fn method_offset_in_object_vtable<'tcx>(tcx: &ty::ctxt<'tcx>,
object_ty: Ty<'tcx>,
method_id: ast::DefId)
-> usize {
if let ty::TyTrait(ref data) = object_ty.sty {
let trait_ref = data.principal_trait_ref_with_self_ty(tcx, object_ty);
traits::get_vtable_index_of_object_method(tcx, trait_ref, method_id)
} else {
tcx.sess.bug(&format!(
"trans::methd::object_ty_to_trait_ref() called on non-object: {:?}",
object_ty));
}
}
@ -237,8 +239,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
Vec::new()));
let trait_substs = tcx.mk_substs(trait_substs);
debug!("trait_substs={:?}", trait_substs);
let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id,
substs: trait_substs });
let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, trait_substs));
let vtbl = fulfill_obligation(ccx,
DUMMY_SP,
trait_ref);
@ -284,12 +285,11 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
callee_substs)
}
traits::VtableObject(ref data) => {
let (llfn, ty) =
trans_object_shim(ccx,
data.object_ty,
data.upcast_trait_ref.clone(),
method_id);
immediate_rvalue(llfn, ty)
let idx = method_offset_in_object_vtable(tcx, data.object_ty, method_id);
trans_object_shim(ccx,
data.upcast_trait_ref.clone(),
method_id,
idx)
}
_ => {
tcx.sess.bug(&format!("static call to invalid vtable: {:?}",
@ -322,9 +322,12 @@ fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name)
fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
method_call: MethodCall,
self_expr: Option<&ast::Expr>,
trait_id: ast::DefId,
method_id: ast::DefId,
vtable: traits::Vtable<'tcx, ()>)
method_ty: Ty<'tcx>,
vtable: traits::Vtable<'tcx, ()>,
arg_cleanup_scope: cleanup::ScopeId)
-> Callee<'blk, 'tcx> {
let _icx = push_ctxt("meth::trans_monomorphized_callee");
match vtable {
@ -347,13 +350,13 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx, MethodCallKey(method_call), vtable_impl.substs);
// translate the function
let llfn = trans_fn_ref_with_substs(bcx.ccx(),
mth_id,
MethodCallKey(method_call),
bcx.fcx.param_substs,
callee_substs).val;
let datum = trans_fn_ref_with_substs(bcx.ccx(),
mth_id,
MethodCallKey(method_call),
bcx.fcx.param_substs,
callee_substs);
Callee { bcx: bcx, data: Fn(llfn) }
Callee { bcx: bcx, data: Fn(datum.val), ty: datum.ty }
}
traits::VtableClosure(vtable_closure) => {
// The substitutions should have no type parameters remaining
@ -368,19 +371,31 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Callee {
bcx: bcx,
data: Fn(llfn),
ty: monomorphize_type(bcx, method_ty)
}
}
traits::VtableFnPointer(fn_ty) => {
let trait_closure_kind = bcx.tcx().lang_items.fn_trait_kind(trait_id).unwrap();
let llfn = trans_fn_pointer_shim(bcx.ccx(), trait_closure_kind, fn_ty);
Callee { bcx: bcx, data: Fn(llfn) }
Callee {
bcx: bcx,
data: Fn(llfn),
ty: monomorphize_type(bcx, method_ty)
}
}
traits::VtableObject(ref data) => {
let (llfn, _) = trans_object_shim(bcx.ccx(),
data.object_ty,
data.upcast_trait_ref.clone(),
method_id);
Callee { bcx: bcx, data: Fn(llfn) }
let idx = method_offset_in_object_vtable(bcx.tcx(), data.object_ty, method_id);
if let Some(self_expr) = self_expr {
if let ty::TyBareFn(_, ref fty) = monomorphize_type(bcx, method_ty).sty {
let ty = bcx.tcx().mk_fn(None, opaque_method_ty(bcx.tcx(), fty));
return trans_trait_callee(bcx, ty, idx, self_expr, arg_cleanup_scope);
}
}
let datum = trans_object_shim(bcx.ccx(),
data.upcast_trait_ref.clone(),
method_id,
idx);
Callee { bcx: bcx, data: Fn(datum.val), ty: datum.ty }
}
traits::VtableBuiltin(..) |
traits::VtableDefaultImpl(..) |
@ -434,7 +449,7 @@ fn combine_impl_and_methods_tps<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// object. Objects are represented as a pair, so we first evaluate the self expression and then
/// extract the self data and vtable out of the pair.
fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
method_ty: Ty<'tcx>,
opaque_fn_ty: Ty<'tcx>,
vtable_index: usize,
self_expr: &ast::Expr,
arg_cleanup_scope: cleanup::ScopeId)
@ -467,51 +482,39 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let llself = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_ADDR]));
let llvtable = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_EXTRA]));
trans_trait_callee_from_llval(bcx, method_ty, vtable_index, llself, llvtable)
trans_trait_callee_from_llval(bcx, opaque_fn_ty, vtable_index, llself, llvtable)
}
/// Same as `trans_trait_callee()` above, except that it is given a by-ref pointer to the object
/// pair.
pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
callee_ty: Ty<'tcx>,
vtable_index: usize,
llself: ValueRef,
llvtable: ValueRef)
-> Callee<'blk, 'tcx> {
fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
opaque_fn_ty: Ty<'tcx>,
vtable_index: usize,
llself: ValueRef,
llvtable: ValueRef)
-> Callee<'blk, 'tcx> {
let _icx = push_ctxt("meth::trans_trait_callee");
let ccx = bcx.ccx();
// Load the data pointer from the object.
debug!("trans_trait_callee_from_llval(callee_ty={}, vtable_index={}, llself={}, llvtable={})",
callee_ty,
opaque_fn_ty,
vtable_index,
bcx.val_to_string(llself),
bcx.val_to_string(llvtable));
// Replace the self type (&Self or Box<Self>) with an opaque pointer.
let llcallee_ty = match callee_ty.sty {
ty::TyBareFn(_, ref f) if f.abi == Rust || f.abi == RustCall => {
let fake_sig =
ty::Binder(ty::FnSig {
inputs: f.sig.0.inputs[1..].to_vec(),
output: f.sig.0.output,
variadic: f.sig.0.variadic,
});
type_of_rust_fn(ccx, Some(Type::i8p(ccx)), &fake_sig, f.abi)
}
_ => {
ccx.sess().bug("meth::trans_trait_callee given non-bare-rust-fn");
}
};
let mptr = Load(bcx, GEPi(bcx, llvtable, &[vtable_index + VTABLE_OFFSET]));
let llcallee_ty = type_of_fn_from_ty(ccx, opaque_fn_ty);
return Callee {
Callee {
bcx: bcx,
data: TraitItem(MethodData {
llfn: PointerCast(bcx, mptr, llcallee_ty.ptr_to()),
llself: PointerCast(bcx, llself, Type::i8p(ccx)),
})
};
}),
ty: opaque_fn_ty
}
}
/// Generate a shim function that allows an object type like `SomeTrait` to
@ -538,30 +541,18 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// that go through this shim function.
fn trans_object_shim<'a, 'tcx>(
ccx: &'a CrateContext<'a, 'tcx>,
object_ty: Ty<'tcx>,
upcast_trait_ref: ty::PolyTraitRef<'tcx>,
method_id: ast::DefId)
-> (ValueRef, Ty<'tcx>)
method_id: ast::DefId,
vtable_index: usize)
-> Datum<'tcx, Rvalue>
{
let _icx = push_ctxt("trans_object_shim");
let tcx = ccx.tcx();
debug!("trans_object_shim(object_ty={:?}, upcast_trait_ref={:?}, method_id={:?})",
object_ty,
debug!("trans_object_shim(upcast_trait_ref={:?}, method_id={:?})",
upcast_trait_ref,
method_id);
let object_trait_ref =
match object_ty.sty {
ty::TyTrait(ref data) => {
data.principal_trait_ref_with_self_ty(tcx, object_ty)
}
_ => {
tcx.sess.bug(&format!("trans_object_shim() called on non-object: {:?}",
object_ty));
}
};
// Upcast to the trait in question and extract out the substitutions.
let upcast_trait_ref = tcx.erase_late_bound_regions(&upcast_trait_ref);
let object_substs = upcast_trait_ref.substs.clone().erase_regions();
@ -617,26 +608,21 @@ fn trans_object_shim<'a, 'tcx>(
fcx.llretslotptr.get().map(
|_| expr::SaveIn(fcx.get_ret_slot(bcx, sig.output, "ret_slot")));
let method_offset_in_vtable =
traits::get_vtable_index_of_object_method(bcx.tcx(),
object_trait_ref.clone(),
method_id);
debug!("trans_object_shim: method_offset_in_vtable={}",
method_offset_in_vtable);
vtable_index);
bcx = trans_call_inner(bcx,
DebugLoc::None,
method_bare_fn_ty,
|bcx, _| trans_trait_callee_from_llval(bcx,
method_bare_fn_ty,
method_offset_in_vtable,
vtable_index,
llself, llvtable),
ArgVals(&llargs[(self_idx + 2)..]),
dest).bcx;
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
(llfn, method_bare_fn_ty)
immediate_rvalue(llfn, shim_fn_ty)
}
/// Creates a returns a dynamic vtable for the given type and vtable origin.
@ -819,8 +805,8 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
/// Replace the self type (&Self or Box<Self>) with an opaque pointer.
pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
-> &'tcx ty::BareFnTy<'tcx> {
fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
-> &'tcx ty::BareFnTy<'tcx> {
let mut inputs = method_ty.sig.0.inputs.clone();
inputs[0] = tcx.mk_mut_ptr(tcx.mk_mach_int(ast::TyI8));

View File

@ -59,7 +59,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let item_ty = ccx.tcx().lookup_item_type(fn_id).ty;
debug!("monomorphic_fn about to subst into {:?}", item_ty);
let mono_ty = item_ty.subst(ccx.tcx(), psubsts);
let mono_ty = apply_param_substs(ccx.tcx(), psubsts, &item_ty);
debug!("mono_ty = {:?} (post-substitution)", mono_ty);
match ccx.monomorphized().borrow().get(&hash_id) {
Some(&val) => {
@ -96,11 +97,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
debug!("mono_ty = {:?} (post-substitution)", mono_ty);
let mono_ty = normalize_associated_type(ccx.tcx(), &mono_ty);
debug!("mono_ty = {:?} (post-normalization)", mono_ty);
ccx.stats().n_monos.set(ccx.stats().n_monos.get() + 1);
let depth;

View File

@ -230,11 +230,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
trait_def_id);
let substs = upcast_trait_ref.substs.clone();
let vtable_index =
traits::get_vtable_index_of_object_method(this.tcx(),
original_poly_trait_ref,
pick.item.def_id());
(substs, ty::MethodOrigin::Object(vtable_index))
(substs, ty::MethodOrigin::Trait)
})
}