mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
rustc: remove MethodOrigin::Object and use traits::VtableObject instead.
This commit is contained in:
parent
a5447e13aa
commit
96d24a5c58
@ -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)]
|
||||
|
@ -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"));
|
||||
|
@ -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))
|
||||
}
|
||||
};
|
||||
|
@ -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[..],
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user