From 58bd0ea73201747441a76c56a9b74252ef08e6ba Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 12:45:22 -0500 Subject: [PATCH] deduplicate ty::Instance constructors --- src/librustc/ty/instance.rs | 65 ++++++++++------- src/librustc_codegen_ssa/meth.rs | 4 +- src/librustc_codegen_ssa/mir/block.rs | 4 +- src/librustc_codegen_ssa/mir/rvalue.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 3 +- src/librustc_mir/interpret/traits.rs | 5 +- src/librustc_mir/monomorphize/collector.rs | 8 +- src/librustc_mir/monomorphize/mod.rs | 85 ---------------------- 8 files changed, 53 insertions(+), 125 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index be15b1e3cc9..f0251917074 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -4,6 +4,7 @@ use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; +use crate::middle::lang_items::DropInPlaceFnLangItem; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; @@ -325,11 +326,47 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { let actual_kind = substs.closure_kind(def_id, tcx); match needs_fn_once_adapter_shim(actual_kind, requested_kind) { - Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), + Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs), _ => Instance::new(def_id, substs.substs) } } + pub fn resolve_drop_in_place( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx>) + -> ty::Instance<'tcx> + { + let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); + let substs = tcx.intern_substs(&[ty.into()]); + Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap() + } + + pub fn fn_once_adapter_instance( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + closure_did: DefId, + substs: ty::ClosureSubsts<'tcx>) + -> Instance<'tcx> + { + debug!("fn_once_adapter_shim({:?}, {:?})", + closure_did, + substs); + let fn_once = tcx.lang_items().fn_once_trait().unwrap(); + let call_once = tcx.associated_items(fn_once) + .find(|it| it.kind == ty::AssocKind::Method) + .unwrap().def_id; + let def = ty::InstanceDef::ClosureOnceShim { call_once }; + + let self_ty = tcx.mk_closure(closure_did, substs); + + let sig = substs.closure_sig(closure_did, tcx); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + assert_eq!(sig.inputs().len(), 1); + let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); + + debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); + Instance { def, substs } + } + pub fn is_vtable_shim(&self) -> bool { if let InstanceDef::VtableShim(..) = self.def { true @@ -438,29 +475,3 @@ fn needs_fn_once_adapter_shim<'a, 'tcx>(actual_closure_kind: ty::ClosureKind, (ty::ClosureKind::FnOnce, _) => Err(()) } } - -fn fn_once_adapter_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - closure_did: DefId, - substs: ty::ClosureSubsts<'tcx>) - -> Instance<'tcx> -{ - debug!("fn_once_adapter_shim({:?}, {:?})", - closure_did, - substs); - let fn_once = tcx.lang_items().fn_once_trait().unwrap(); - let call_once = tcx.associated_items(fn_once) - .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; - let def = ty::InstanceDef::ClosureOnceShim { call_once }; - - let self_ty = tcx.mk_closure(closure_did, substs); - - let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); - - debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); - Instance { def, substs } -} diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 49f3c87ee2d..73065be9970 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -4,7 +4,7 @@ use rustc_mir::monomorphize; use crate::callee; use crate::traits::*; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; #[derive(Copy, Clone, Debug)] pub struct VirtualIndex(u64); @@ -103,7 +103,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( // `get_vtable` in rust_mir/interpret/traits.rs // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ - cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)), + cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)), cx.const_usize(layout.size.bytes()), cx.const_usize(layout.align.abi.bytes()) ].iter().cloned().chain(methods).collect(); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index c7dd019fc3e..f2d4cd33229 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,5 +1,5 @@ use rustc::middle::lang_items; -use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::InterpError; @@ -310,7 +310,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) { let ty = location.ty(self.mir, bx.tcx()).ty; let ty = self.monomorphize(&ty); - let drop_fn = monomorphize::resolve_drop_in_place(bx.tcx(), ty); + let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty); if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 586db5cfabe..b11fe236833 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -1,4 +1,4 @@ -use rustc::ty::{self, Ty, adjustment::{PointerCast}}; +use rustc::ty::{self, Ty, adjustment::{PointerCast}, Instance}; use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc::mir; @@ -196,7 +196,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => { match operand.layout.ty.sty { ty::Closure(def_id, substs) => { - let instance = monomorphize::resolve_closure( + let instance = Instance::resolve_closure( bx.cx().tcx(), def_id, substs, ty::ClosureKind::FnOnce); OperandValue::Immediate(bx.cx().get_fn(instance)) } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index ba48a28fc83..a39af9640ac 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use rustc::{mir, ty}; +use rustc::ty::Instance; use rustc::ty::layout::{self, TyLayout, LayoutOf}; use syntax::source_map::Span; use rustc_target::spec::abi::Abi; @@ -112,7 +113,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); - let instance = crate::monomorphize::resolve_drop_in_place(*self.tcx, ty); + let instance = Instance::resolve_drop_in_place(*self.tcx, ty); self.drop_in_place( place, instance, diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 208bba60bf2..33cb1a09717 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,4 +1,4 @@ -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; @@ -55,8 +55,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> ); let tcx = &*self.tcx; - let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty); + let drop = Instance::resolve_drop_in_place(*tcx, ty); let drop = self.memory.create_fn_alloc(drop); + // no need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index dae5f1b8cd2..b808f64b007 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -181,7 +181,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; -use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind}; +use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; @@ -189,7 +189,7 @@ use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::MonoItem; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; -use crate::monomorphize::{self, Instance}; +use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; @@ -580,7 +580,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ); match source_ty.sty { ty::Closure(def_id, substs) => { - let instance = monomorphize::resolve_closure( + let instance = Instance::resolve_closure( self.tcx, def_id, substs, ty::ClosureKind::FnOnce); if should_monomorphize_locally(self.tcx, &instance) { self.output.push(create_fn_mono_item(instance)); @@ -684,7 +684,7 @@ fn visit_drop_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, is_direct_call: bool, output: &mut Vec>) { - let instance = monomorphize::resolve_drop_in_place(tcx, ty); + let instance = Instance::resolve_drop_in_place(tcx, ty); visit_instance_use(tcx, instance, is_direct_call, output); } diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 5cf03a6a35b..8dda352d5e6 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -1,5 +1,3 @@ -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::DropInPlaceFnLangItem; use rustc::traits; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::ty::{self, Ty, TyCtxt, Instance}; @@ -54,89 +52,6 @@ pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mon } } -fn fn_once_adapter_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - closure_did: DefId, - substs: ty::ClosureSubsts<'tcx>, - ) -> Instance<'tcx> { - debug!("fn_once_adapter_shim({:?}, {:?})", - closure_did, - substs); - let fn_once = tcx.lang_items().fn_once_trait().unwrap(); - let call_once = tcx.associated_items(fn_once) - .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; - let def = ty::InstanceDef::ClosureOnceShim { call_once }; - - let self_ty = tcx.mk_closure(closure_did, substs); - - let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); - - debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); - Instance { def, substs } -} - -fn needs_fn_once_adapter_shim(actual_closure_kind: ty::ClosureKind, - trait_closure_kind: ty::ClosureKind) - -> Result -{ - match (actual_closure_kind, trait_closure_kind) { - (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | - (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => { - // No adapter needed. - Ok(false) - } - (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { - // The closure fn `llfn` is a `fn(&self, ...)`. We want a - // `fn(&mut self, ...)`. In fact, at codegen time, these are - // basically the same thing, so we can just return llfn. - Ok(false) - } - (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: - // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } - // - // These are both the same at codegen time. - Ok(true) - } - _ => Err(()), - } -} - -pub fn resolve_closure<'a, 'tcx> ( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - substs: ty::ClosureSubsts<'tcx>, - requested_kind: ty::ClosureKind) - -> Instance<'tcx> -{ - let actual_kind = substs.closure_kind(def_id, tcx); - - match needs_fn_once_adapter_shim(actual_kind, requested_kind) { - Ok(true) => fn_once_adapter_instance(tcx, def_id, substs), - _ => Instance::new(def_id, substs.substs) - } -} - -pub fn resolve_drop_in_place<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>) - -> ty::Instance<'tcx> -{ - let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); - let substs = tcx.intern_substs(&[ty.into()]); - Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap() -} - pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>)