diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-02-23 21:21:50 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-03-17 17:52:30 +0200 |
| commit | 16201d45f16845cb5dc2fc0b48bcf34a6715ea14 (patch) | |
| tree | b2d6164dc3834a2027556547c5be41f7c3d8474f /src | |
| parent | 062a05dde8c3ea5386fa358d882e1eaca99a9ff0 (diff) | |
| download | rust-16201d45f16845cb5dc2fc0b48bcf34a6715ea14.tar.gz rust-16201d45f16845cb5dc2fc0b48bcf34a6715ea14.zip | |
trans: Get functions and do calls only through Callee.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_trans/trans/_match.rs | 11 | ||||
| -rw-r--r-- | src/librustc_trans/trans/base.rs | 54 | ||||
| -rw-r--r-- | src/librustc_trans/trans/callee.rs | 179 | ||||
| -rw-r--r-- | src/librustc_trans/trans/common.rs | 11 | ||||
| -rw-r--r-- | src/librustc_trans/trans/consts.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/trans/controlflow.rs | 21 | ||||
| -rw-r--r-- | src/librustc_trans/trans/expr.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/trans/glue.rs | 20 | ||||
| -rw-r--r-- | src/librustc_trans/trans/inline.rs | 79 | ||||
| -rw-r--r-- | src/librustc_trans/trans/intrinsic.rs | 19 | ||||
| -rw-r--r-- | src/librustc_trans/trans/meth.rs | 14 | ||||
| -rw-r--r-- | src/librustc_trans/trans/mir/block.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/trans/mir/rvalue.rs | 5 |
13 files changed, 197 insertions, 226 deletions
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index e277a535028..8aea2f1ec4f 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -200,12 +200,13 @@ use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; use middle::pat_util::*; +use middle::subst::Substs; use trans::adt; use trans::base::*; use trans::build::{AddCase, And, Br, CondBr, GEPi, InBoundsGEP, Load, PointerCast}; use trans::build::{Not, Store, Sub, add_comment}; use trans::build; -use trans::callee; +use trans::callee::{Callee, ArgVals}; use trans::cleanup::{self, CleanupMethods, DropHintMethods}; use trans::common::*; use trans::consts; @@ -881,7 +882,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, rhs_t: Ty<'tcx>, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { - fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>, + fn compare_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, lhs_data: ValueRef, lhs_len: ValueRef, rhs_data: ValueRef, @@ -889,11 +890,13 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, rhs_t: Ty<'tcx>, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { - let did = langcall(cx, + let did = langcall(bcx, None, &format!("comparison of `{}`", rhs_t), StrEqFnLangItem); - callee::trans_lang_call(cx, did, &[lhs_data, lhs_len, rhs_data, rhs_len], None, debug_loc) + let args = [lhs_data, lhs_len, rhs_data, rhs_len]; + Callee::def(bcx.ccx(), did, bcx.tcx().mk_substs(Substs::empty())) + .call(bcx, debug_loc, ArgVals(&args), None) } let _icx = push_ctxt("compare_values"); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 03f3671a6b1..b2d7b83887e 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -57,7 +57,7 @@ use trans::assert_dep_graph; use trans::attributes; use trans::build::*; use trans::builder::{Builder, noname}; -use trans::callee; +use trans::callee::{Callee, CallArgs, ArgExprs, ArgVals}; use trans::cleanup::{self, CleanupMethods, DropHint}; use trans::closure; use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_uint, C_integral}; @@ -280,11 +280,9 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("malloc_raw_exchange"); // Allocate space: - let r = callee::trans_lang_call(bcx, - require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem), - &[size, align], - None, - debug_loc); + let def_id = require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem); + let r = Callee::def(bcx.ccx(), def_id, bcx.tcx().mk_substs(Substs::empty())) + .call(bcx, debug_loc, ArgVals(&[size, align]), None); Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr)) } @@ -1219,9 +1217,8 @@ pub fn trans_unwind_resume(bcx: Block, lpval: ValueRef) { Resume(bcx, lpval); } else { let exc_ptr = ExtractValue(bcx, lpval, 0); - let llunwresume = bcx.fcx.eh_unwind_resume(); - Call(bcx, llunwresume, &[exc_ptr], None, DebugLoc::None); - Unreachable(bcx); + bcx.fcx.eh_unwind_resume() + .call(bcx, DebugLoc::None, ArgVals(&[exc_ptr]), None); } } @@ -2147,20 +2144,10 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, closure::ClosureEnv::NotClosure); } -pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - ctor_id: ast::NodeId, - disr: Disr, - param_substs: &'tcx Substs<'tcx>, - llfndecl: ValueRef) { - let _icx = push_ctxt("trans_enum_variant"); - - trans_enum_variant_or_tuple_like_struct(ccx, ctor_id, disr, param_substs, llfndecl); -} - pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, ctor_ty: Ty<'tcx>, disr: Disr, - args: callee::CallArgs, + args: CallArgs, dest: expr::Dest, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { @@ -2188,7 +2175,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, if !type_is_zero_size(ccx, result_ty) { match args { - callee::ArgExprs(exprs) => { + ArgExprs(exprs) => { let fields = exprs.iter().map(|x| &**x).enumerate().collect::<Vec<_>>(); bcx = expr::trans_adt(bcx, result_ty, @@ -2204,7 +2191,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // Just eval all the expressions (if any). Since expressions in Rust can have arbitrary // contents, there could be side-effects we need from them. match args { - callee::ArgExprs(exprs) => { + ArgExprs(exprs) => { for expr in exprs { bcx = expr::trans_into(bcx, expr, expr::Ignore); } @@ -2500,8 +2487,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { // compilation unit that references the item, so it will still get // translated everywhere it's needed. for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) { - let llfn = get_item_val(ccx, item.id); - let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); + let empty_substs = tcx.mk_substs(Substs::trans_empty()); + let def_id = tcx.map.local_def_id(item.id); + let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val; if abi != Abi::Rust { foreign::trans_rust_fn_with_foreign_abi(ccx, &decl, @@ -2536,9 +2524,8 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { // error in trans. This is used to write compile-fail tests // that actually test that compilation succeeds without // reporting an error. - let item_def_id = ccx.tcx().map.local_def_id(item.id); - if ccx.tcx().has_attr(item_def_id, "rustc_error") { - ccx.tcx().sess.span_fatal(item.span, "compilation successful"); + if tcx.has_attr(def_id, "rustc_error") { + tcx.sess.span_fatal(item.span, "compilation successful"); } } } @@ -2671,17 +2658,10 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) { let (start_fn, args) = if use_start_lang_item { let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) { Ok(id) => id, - Err(s) => { - ccx.sess().fatal(&s[..]); - } - }; - let start_fn = if let Some(start_node_id) = ccx.tcx() - .map - .as_local_node_id(start_def_id) { - get_item_val(ccx, start_node_id) - } else { - get_extern_fn(ccx, start_def_id).val + Err(s) => ccx.sess().fatal(&s) }; + let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); + let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx).val; let args = { let opaque_rust_main = llvm::LLVMBuildPointerCast(bld, diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 7e0e01c3150..318c968692c 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -97,26 +97,19 @@ impl<'tcx> Callee<'tcx> { pub fn method<'blk>(bcx: Block<'blk, 'tcx>, method: ty::MethodCallee<'tcx>) -> Callee<'tcx> { let substs = bcx.tcx().mk_substs(bcx.fcx.monomorphize(&method.substs)); - let ty = bcx.fcx.monomorphize(&method.ty); - Callee::def(bcx.ccx(), method.def_id, substs, ty) + Callee::def(bcx.ccx(), method.def_id, substs) } /// Function or method definition. pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, - substs: &'tcx subst::Substs<'tcx>, - ty: Ty<'tcx>) + substs: &'tcx subst::Substs<'tcx>) -> Callee<'tcx> { let tcx = ccx.tcx(); if substs.self_ty().is_some() { // Only trait methods can have a Self parameter. - let method_item = tcx.impl_or_trait_item(def_id); - let trait_id = method_item.container().id(); - let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id)); - let vtbl = common::fulfill_obligation(ccx, DUMMY_SP, trait_ref); - return meth::callee_for_trait_impl(ccx, def_id, substs, - trait_id, ty, vtbl); + return Callee::trait_method(ccx, def_id, substs); } let maybe_node_id = inline::get_local_instance(ccx, def_id) @@ -124,34 +117,95 @@ impl<'tcx> Callee<'tcx> { let maybe_ast_node = maybe_node_id.and_then(|node_id| { tcx.map.find(node_id) }); - match maybe_ast_node { + + let data = match maybe_ast_node { Some(hir_map::NodeStructCtor(_)) => { - return Callee { - data: NamedTupleConstructor(Disr(0)), - ty: ty - }; + NamedTupleConstructor(Disr(0)) } Some(hir_map::NodeVariant(_)) => { let vinfo = common::inlined_variant_def(ccx, maybe_node_id.unwrap()); - assert_eq!(vinfo.kind(), ty::VariantKind::Tuple); + NamedTupleConstructor(Disr::from(vinfo.disr_val)) + } + Some(hir_map::NodeForeignItem(fi)) if { + let abi = tcx.map.get_foreign_abi(fi.id); + abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic + } => Intrinsic, + + _ => return Callee::ptr(get_fn(ccx, def_id, substs)) + }; + + Callee { + data: data, + ty: def_ty(tcx, def_id, substs) + } + } + + /// Trait method, which has to be resolved to an impl method. + pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>, + def_id: DefId, + substs: &'tcx subst::Substs<'tcx>) + -> Callee<'tcx> { + let tcx = ccx.tcx(); - return Callee { - data: NamedTupleConstructor(Disr::from(vinfo.disr_val)), - ty: ty + let method_item = tcx.impl_or_trait_item(def_id); + let trait_id = method_item.container().id(); + let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id)); + match common::fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + traits::VtableImpl(vtable_impl) => { + let impl_did = vtable_impl.impl_def_id; + let mname = tcx.item_name(def_id); + // create a concatenated set of substitutions which includes + // those from the impl and those from the method: + let impl_substs = vtable_impl.substs.with_method_from(&substs); + let substs = tcx.mk_substs(impl_substs); + let mth = tcx.get_impl_method(impl_did, substs, mname); + + // Translate the function, bypassing Callee::def. + // That is because default methods have the same ID as the + // trait method used to look up the impl method that ended + // up here, so calling Callee::def would infinitely recurse. + Callee::ptr(get_fn(ccx, mth.method.def_id, mth.substs)) + } + traits::VtableClosure(vtable_closure) => { + // The substitutions should have no type parameters remaining + // after passing through fulfill_obligation + let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap(); + let llfn = closure::trans_closure_method(ccx, + vtable_closure.closure_def_id, + vtable_closure.substs, + trait_closure_kind); + + let method_ty = def_ty(tcx, def_id, substs); + let fn_ptr_ty = match method_ty.sty { + ty::TyFnDef(_, _, fty) => tcx.mk_ty(ty::TyFnPtr(fty)), + _ => unreachable!("expected fn item type, found {}", + method_ty) }; + Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty)) } - Some(hir_map::NodeForeignItem(fi)) => { - let abi = tcx.map.get_foreign_abi(fi.id); - if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - return Callee { - data: Intrinsic(fi.id, substs), - ty: ty - }; + traits::VtableFnPointer(fn_ty) => { + let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap(); + let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, fn_ty); + + let method_ty = def_ty(tcx, def_id, substs); + let fn_ptr_ty = match method_ty.sty { + ty::TyFnDef(_, _, fty) => tcx.mk_ty(ty::TyFnPtr(fty)), + _ => unreachable!("expected fn item type, found {}", + method_ty) + }; + Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty)) + } + traits::VtableObject(ref data) => { + Callee { + data: Virtual(traits::get_vtable_index_of_object_method( + tcx, data, def_id)), + ty: def_ty(tcx, def_id, substs) } } - _ => {} + vtable => { + unreachable!("resolved vtable bad vtable {:?} in trans", vtable); + } } - Callee::ptr(trans_fn_ref_with_substs(ccx, def_id, Some(ty), substs)) } /// This behemoth of a function translates function calls. Unfortunately, in @@ -187,7 +241,7 @@ impl<'tcx> Callee<'tcx> { Virtual(idx) => meth::trans_object_shim(ccx, self.ty, idx), NamedTupleConstructor(_) => match self.ty.sty { ty::TyFnDef(def_id, substs, _) => { - return trans_fn_ref_with_substs(ccx, def_id, Some(self.ty), substs); + return get_fn(ccx, def_id, substs); } _ => unreachable!("expected fn item type, found {}", self.ty) }, @@ -196,31 +250,13 @@ impl<'tcx> Callee<'tcx> { } } -/// Translates a reference (with id `ref_id`) to the fn/method with id `def_id` into a function -/// pointer. This may require monomorphization or inlining. -pub fn trans_fn_ref<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - def_id: DefId, - node: ExprOrMethodCall, - param_substs: &'tcx subst::Substs<'tcx>) - -> Datum<'tcx, Rvalue> { - let _icx = push_ctxt("trans_fn_ref"); - - let substs = common::node_id_substs(ccx, node, param_substs); - debug!("trans_fn_ref(def_id={:?}, node={:?}, substs={:?})", - def_id, - node, - substs); - let ref_ty = match node { - ExprId(0) => return trans_fn_ref_with_substs(ccx, def_id, None, substs), - ExprId(id) => ccx.tcx().node_id_to_type(id), - MethodCallKey(method_call) => { - ccx.tcx().tables.borrow().method_map[&method_call].ty - } - }; - let ref_ty = monomorphize::apply_param_substs(ccx.tcx(), - param_substs, - &ref_ty); - trans_fn_ref_with_substs(ccx, def_id, Some(ref_ty), substs) +/// Given a DefId and some Substs, produces the monomorphic item type. +fn def_ty<'tcx>(tcx: &TyCtxt<'tcx>, + def_id: DefId, + substs: &'tcx subst::Substs<'tcx>) + -> Ty<'tcx> { + let ty = tcx.lookup_item_type(def_id).ty; + monomorphize::apply_param_substs(tcx, substs, &ty) } /// Translates an adapter that implements the `Fn` trait for a fn @@ -323,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( let llfnpointer = match bare_fn_ty.sty { ty::TyFnDef(def_id, substs, _) => { // Function definitions have to be turned into a pointer. - Callee::def(ccx, def_id, substs, bare_fn_ty).reify(ccx).val + Callee::def(ccx, def_id, substs).reify(ccx).val } // the first argument (`self`) will be ptr to the fn pointer @@ -360,25 +396,14 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( /// /// - `ccx`: the crate context /// - `def_id`: def id of the fn or method item being referenced -/// - `node`: node id of the reference to the fn/method, if applicable. -/// This parameter may be zero; but, if so, the resulting value may not -/// have the right type, so it must be cast before being used. -/// - `ref_ty`: monotype of the reference to the fn/method, if applicable. -/// This parameter may be None; but, if so, the resulting value may not -/// have the right type, so it must be cast before being used. /// - `substs`: values for each of the fn/method's parameters -pub fn trans_fn_ref_with_substs<'a, 'tcx>( - ccx: &CrateContext<'a, 'tcx>, - def_id: DefId, - ref_ty: Option<Ty<'tcx>>, - substs: &'tcx subst::Substs<'tcx>) - -> Datum<'tcx, Rvalue> -{ - let _icx = push_ctxt("trans_fn_ref_with_substs"); +fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + def_id: DefId, + substs: &'tcx subst::Substs<'tcx>) + -> Datum<'tcx, Rvalue> { let tcx = ccx.tcx(); - debug!("trans_fn_ref_with_substs(def_id={:?}, ref_ty={:?}, substs={:?})", - def_id, ref_ty, substs); + debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs); assert!(!substs.types.needs_infer()); assert!(!substs.types.has_escaping_regions()); @@ -408,7 +433,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( let must_monomorphise = !substs.types.is_empty() || is_named_tuple_constructor(tcx, def_id); - debug!("trans_fn_ref_with_substs({:?}) must_monomorphise: {}", + debug!("get_fn({:?}) must_monomorphise: {}", def_id, must_monomorphise); // Create a monomorphic version of generic functions @@ -494,16 +519,6 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( // ______________________________________________________________________ // Translating calls -pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - did: DefId, - args: &[ValueRef], - dest: Option<expr::Dest>, - debug_loc: DebugLoc) - -> Result<'blk, 'tcx> { - let datum = trans_fn_ref(bcx.ccx(), did, ExprId(0), bcx.fcx.param_substs); - Callee::ptr(datum).call(bcx, debug_loc, ArgVals(args), dest) -} - fn trans_call_inner<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, debug_loc: DebugLoc, callee: Callee<'tcx>, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index ec24242a010..c974173f765 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -512,11 +512,12 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { // `rust_eh_personality` function, but rather we wired it up to the // CRT's custom personality function, which forces LLVM to consider // landing pads as "landing pads for SEH". - let target = &self.ccx.sess().target.target; - match self.ccx.tcx().lang_items.eh_personality() { - Some(def_id) if !base::wants_msvc_seh(self.ccx.sess()) => { - callee::trans_fn_ref(self.ccx, def_id, ExprId(0), - self.param_substs).val + let ccx = self.ccx; + let tcx = ccx.tcx(); + let target = &ccx.sess().target.target; + match tcx.lang_items.eh_personality() { + Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => { + Callee::def(ccx, def_id, tcx.mk_substs(Substs::empty())).reify(ccx).val } _ => { let mut personality = self.ccx.eh_personality().borrow_mut(); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 66fdc2056a3..ec550c680de 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -352,9 +352,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Some(AdjustReifyFnPointer) => { match ety.sty { ty::TyFnDef(def_id, substs, _) => { - let datum = Callee::def(cx, def_id, substs, ety).reify(cx); - llconst = datum.val; - ety_adjusted = datum.ty; + llconst = Callee::def(cx, def_id, substs).reify(cx).val; } _ => { unreachable!("{} cannot be reified to a fn ptr", ety) diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index 805c1388627..ef8d4cfff9d 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -11,10 +11,11 @@ use llvm::ValueRef; use middle::def::Def; use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem}; +use middle::subst::Substs; use trans::base::*; use trans::basic_block::BasicBlock; use trans::build::*; -use trans::callee; +use trans::callee::{Callee, ArgVals}; use trans::cleanup::CleanupMethods; use trans::cleanup; use trans::common::*; @@ -405,13 +406,8 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let expr_file_line = consts::addr_of(ccx, expr_file_line_const, align, "panic_loc"); let args = vec!(expr_file_line); let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem); - let bcx = callee::trans_lang_call(bcx, - did, - &args[..], - Some(expr::Ignore), - call_info.debug_loc()).bcx; - Unreachable(bcx); - return bcx; + Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty())) + .call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx } pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, @@ -438,11 +434,6 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let file_line = consts::addr_of(ccx, file_line_const, align, "panic_bounds_check_loc"); let args = vec!(file_line, index, len); let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem); - let bcx = callee::trans_lang_call(bcx, - did, - &args[..], - Some(expr::Ignore), - call_info.debug_loc()).bcx; - Unreachable(bcx); - return bcx; + Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty())) + .call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index beae363f968..63612cd1e1f 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -385,7 +385,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, AdjustReifyFnPointer => { match datum.ty.sty { ty::TyFnDef(def_id, substs, _) => { - datum = Callee::def(bcx.ccx(), def_id, substs, datum.ty) + datum = Callee::def(bcx.ccx(), def_id, substs) .reify(bcx.ccx()).to_expr_datum(); } _ => { @@ -1143,7 +1143,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let f = unpack_datum!(bcx, trans(bcx, f)); (match f.ty.sty { ty::TyFnDef(def_id, substs, _) => { - Callee::def(bcx.ccx(), def_id, substs, f.ty) + Callee::def(bcx.ccx(), def_id, substs) } ty::TyFnPtr(_) => { let f = unpack_datum!(bcx, diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index b899dbe47ca..c93548fe1c2 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -25,7 +25,7 @@ use trans::adt; use trans::adt::GetDtorType; // for tcx.dtor_type() use trans::base::*; use trans::build::*; -use trans::callee; +use trans::callee::{Callee, ArgVals}; use trans::cleanup; use trans::cleanup::CleanupMethods; use trans::collector::{self, TransItem}; @@ -44,19 +44,18 @@ use libc::c_uint; use syntax::ast; use syntax::codemap::DUMMY_SP; -pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>, +pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v: ValueRef, size: ValueRef, align: ValueRef, debug_loc: DebugLoc) -> Block<'blk, 'tcx> { let _icx = push_ctxt("trans_exchange_free"); - let ccx = cx.ccx(); - callee::trans_lang_call(cx, - langcall(cx, None, "", ExchangeFreeFnLangItem), - &[PointerCast(cx, v, Type::i8p(ccx)), size, align], - Some(expr::Ignore), - debug_loc).bcx + + let def_id = langcall(bcx, None, "", ExchangeFreeFnLangItem); + let args = [PointerCast(bcx, v, Type::i8p(bcx.ccx())), size, align]; + Callee::def(bcx.ccx(), def_id, bcx.tcx().mk_substs(Substs::empty())) + .call(bcx, debug_loc, ArgVals(&args), None).bcx } pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>, @@ -366,9 +365,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => tcx.sess.bug(&format!("dtor for {:?} is not an impl???", t)) }; let dtor_did = def.destructor().unwrap(); - bcx = callee::Callee::ptr(callee::trans_fn_ref_with_substs( - bcx.ccx(), dtor_did, None, vtbl.substs)) - .call(bcx, DebugLoc::None, callee::ArgVals(args), Some(expr::Ignore)).bcx; + bcx = Callee::def(bcx.ccx(), dtor_did, vtbl.substs) + .call(bcx, DebugLoc::None, ArgVals(args), None).bcx; bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, contents_scope) } diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 0dcb0c29faf..c260f77e887 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -12,7 +12,8 @@ use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage}; use middle::cstore::{CrateStore, FoundAst, InlinedItem}; use middle::def_id::DefId; use middle::subst::Substs; -use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn}; +use trans::base::{push_ctxt, trans_item, trans_fn}; +use trans::callee::Callee; use trans::common::*; use rustc::dep_graph::DepNode; @@ -21,14 +22,15 @@ use rustc_front::hir; fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { debug!("instantiate_inline({:?})", fn_id); let _icx = push_ctxt("instantiate_inline"); - let _task = ccx.tcx().dep_graph.in_task(DepNode::TransInlinedItem(fn_id)); + let tcx = ccx.tcx(); + let _task = tcx.dep_graph.in_task(DepNode::TransInlinedItem(fn_id)); match ccx.external().borrow().get(&fn_id) { Some(&Some(node_id)) => { // Already inline debug!("instantiate_inline({}): already inline as node id {}", - ccx.tcx().item_path_str(fn_id), node_id); - let node_def_id = ccx.tcx().map.local_def_id(node_id); + tcx.item_path_str(fn_id), node_id); + let node_def_id = tcx.map.local_def_id(node_id); return Some(node_def_id); } Some(&None) => { @@ -39,7 +41,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { } } - let inlined = ccx.tcx().sess.cstore.maybe_get_item_ast(ccx.tcx(), fn_id); + let inlined = tcx.sess.cstore.maybe_get_item_ast(tcx, fn_id); let inline_id = match inlined { FoundAst::NotFound => { ccx.external().borrow_mut().insert(fn_id, None); @@ -52,38 +54,27 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); trans_item(ccx, item); - let linkage = match item.node { - hir::ItemFn(_, _, _, _, ref generics, _) => { - if generics.is_type_parameterized() { - // Generics have no symbol, so they can't be given any - // linkage. - None + if let hir::ItemFn(_, _, _, _, ref generics, _) = item.node { + // Generics have no symbol, so they can't be given any linkage. + if !generics.is_type_parameterized() { + let linkage = if ccx.sess().opts.cg.codegen_units == 1 { + // We could use AvailableExternallyLinkage here, + // but InternalLinkage allows LLVM to optimize more + // aggressively (at the cost of sometimes + // duplicating code). + InternalLinkage } else { - if ccx.sess().opts.cg.codegen_units == 1 { - // We could use AvailableExternallyLinkage here, - // but InternalLinkage allows LLVM to optimize more - // aggressively (at the cost of sometimes - // duplicating code). - Some(InternalLinkage) - } else { - // With multiple compilation units, duplicated code - // is more of a problem. Also, `codegen_units > 1` - // means the user is okay with losing some - // performance. - Some(AvailableExternallyLinkage) - } - } - } - hir::ItemConst(..) => None, - _ => unreachable!(), - }; - - match linkage { - Some(linkage) => { - let g = get_item_val(ccx, item.id); - SetLinkage(g, linkage); + // With multiple compilation units, duplicated code + // is more of a problem. Also, `codegen_units > 1` + // means the user is okay with losing some + // performance. + AvailableExternallyLinkage + }; + let empty_substs = tcx.mk_substs(Substs::trans_empty()); + let def_id = tcx.map.local_def_id(item.id); + let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val; + SetLinkage(llfn, linkage); } - None => {} } item.id @@ -120,7 +111,6 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { _ => ccx.sess().bug("instantiate_inline: item has a \ non-enum, non-struct parent") } - trans_item(ccx, &item); my_id } FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => { @@ -133,10 +123,10 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { // the logic to do that already exists in `middle`. In order to // reuse that code, it needs to be able to look up the traits for // inlined items. - let ty_trait_item = ccx.tcx().impl_or_trait_item(fn_id).clone(); - let trait_item_def_id = ccx.tcx().map.local_def_id(trait_item.id); - ccx.tcx().impl_or_trait_items.borrow_mut() - .insert(trait_item_def_id, ty_trait_item); + let ty_trait_item = tcx.impl_or_trait_item(fn_id).clone(); + let trait_item_def_id = tcx.map.local_def_id(trait_item.id); + tcx.impl_or_trait_items.borrow_mut() + .insert(trait_item_def_id, ty_trait_item); // If this is a default method, we can't look up the // impl type. But we aren't going to translate anyways, so @@ -151,11 +141,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { // Translate monomorphic impl methods immediately. if let hir::ImplItemKind::Method(ref sig, ref body) = impl_item.node { - let impl_tpt = ccx.tcx().lookup_item_type(impl_did); + let impl_tpt = tcx.lookup_item_type(impl_did); if impl_tpt.generics.types.is_empty() && sig.generics.ty_params.is_empty() { - let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); - let llfn = get_item_val(ccx, impl_item.id); + let empty_substs = tcx.mk_substs(Substs::trans_empty()); + let def_id = tcx.map.local_def_id(impl_item.id); + let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val; trans_fn(ccx, &sig.decl, body, @@ -176,7 +167,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> { } }; - let inline_def_id = ccx.tcx().map.local_def_id(inline_id); + let inline_def_id = tcx.map.local_def_id(inline_id); Some(inline_def_id) } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index d246208ec1d..77df214d6dd 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -213,7 +213,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, if out_type_size != 0 { // FIXME #19925 Remove this hack after a release cycle. let _ = unpack_datum!(bcx, expr::trans(bcx, &arg_exprs[0])); - let llfn = Callee::def(ccx, def_id, substs, in_type).reify(ccx).val; + let llfn = Callee::def(ccx, def_id, substs).reify(ccx).val; let llfnty = val_ty(llfn); let llresult = match dest { expr::SaveIn(d) => d, @@ -1208,6 +1208,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, dloc: DebugLoc) -> Block<'blk, 'tcx> { let llfn = get_rust_try_fn(bcx.fcx, &mut |bcx| { let ccx = bcx.ccx(); + let tcx = ccx.tcx(); let dloc = DebugLoc::None; // Translates the shims described above: @@ -1228,10 +1229,11 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // managed by the standard library. attributes::emit_uwtable(bcx.fcx.llfn, true); - let catch_pers = match bcx.tcx().lang_items.eh_personality_catch() { - Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0), - bcx.fcx.param_substs).val, - None => bcx.tcx().sess.bug("eh_personality_catch not defined"), + let catch_pers = match tcx.lang_items.eh_personality_catch() { + Some(did) => { + Callee::def(ccx, did, tcx.mk_substs(Substs::empty())).reify(ccx).val + } + None => ccx.sess().bug("eh_personality_catch not defined"), }; let then = bcx.fcx.new_temp_block("then"); @@ -1341,9 +1343,10 @@ fn generate_filter_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, let tcx = ccx.tcx(); let dloc = DebugLoc::None; - let rust_try_filter = match ccx.tcx().lang_items.msvc_try_filter() { - Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0), - fcx.param_substs).val, + let rust_try_filter = match tcx.lang_items.msvc_try_filter() { + Some(did) => { + Callee::def(ccx, did, tcx.mk_substs(Substs::empty())).reify(ccx).val + } None => ccx.sess().bug("msvc_try_filter not defined"), }; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index da07a02bd3a..5b052a8e602 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -310,17 +310,9 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let nullptr = C_null(Type::nil(ccx).ptr_to()); get_vtable_methods(ccx, id, substs) .into_iter() - .map(|opt_mth| { - match opt_mth { - Some(mth) => { - trans_fn_ref_with_substs(ccx, - mth.method.def_id, - None, - &mth.substs).val - } - None => nullptr - } - }) + .map(|opt_mth| opt_mth.map_or(nullptr, |mth| { + Callee::def(ccx, mth.method.def_id, &mth.substs).reify(ccx).val + })) .collect::<Vec<_>>() .into_iter() } diff --git a/src/librustc_trans/trans/mir/block.rs b/src/librustc_trans/trans/mir/block.rs index 50283c0959c..1bbb2447e6a 100644 --- a/src/librustc_trans/trans/mir/block.rs +++ b/src/librustc_trans/trans/mir/block.rs @@ -163,7 +163,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let (callee, fty) = match callee.ty.sty { ty::TyFnDef(def_id, substs, f) => { - (Callee::def(bcx.ccx(), def_id, substs, callee.ty), f) + (Callee::def(bcx.ccx(), def_id, substs), f) } ty::TyFnPtr(f) => { (Callee { diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs index 4b5f1566380..99c388f604b 100644 --- a/src/librustc_trans/trans/mir/rvalue.rs +++ b/src/librustc_trans/trans/mir/rvalue.rs @@ -201,7 +201,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { match operand.ty.sty { ty::TyFnDef(def_id, substs, _) => { OperandValue::Immediate( - Callee::def(bcx.ccx(), def_id, substs, operand.ty) + Callee::def(bcx.ccx(), def_id, substs) .reify(bcx.ccx()).val) } _ => { @@ -511,8 +511,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { if use_fmod { let f64t = Type::f64(bcx.ccx()); let fty = Type::func(&[f64t, f64t], &f64t); - let llfn = declare::declare_cfn(bcx.ccx(), "fmod", fty, - tcx.types.f64); + let llfn = declare::declare_cfn(bcx.ccx(), "fmod", fty); if input_ty == tcx.types.f32 { let lllhs = bcx.fpext(lhs, f64t); let llrhs = bcx.fpext(rhs, f64t); |
