1
Fork 0

deduplicate ty::Instance constructors

This commit is contained in:
Mark Mansi 2019-05-23 12:45:22 -05:00
parent 8af151b30a
commit 58bd0ea732
8 changed files with 53 additions and 125 deletions

View file

@ -4,6 +4,7 @@ use crate::hir::def_id::DefId;
use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::print::{FmtPrinter, Printer};
use crate::traits; use crate::traits;
use crate::middle::lang_items::DropInPlaceFnLangItem;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use rustc_macros::HashStable; use rustc_macros::HashStable;
@ -325,11 +326,47 @@ impl<'a, 'b, 'tcx> Instance<'tcx> {
let actual_kind = substs.closure_kind(def_id, tcx); let actual_kind = substs.closure_kind(def_id, tcx);
match needs_fn_once_adapter_shim(actual_kind, requested_kind) { 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) _ => 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 { pub fn is_vtable_shim(&self) -> bool {
if let InstanceDef::VtableShim(..) = self.def { if let InstanceDef::VtableShim(..) = self.def {
true true
@ -438,29 +475,3 @@ fn needs_fn_once_adapter_shim<'a, 'tcx>(actual_closure_kind: ty::ClosureKind,
(ty::ClosureKind::FnOnce, _) => Err(()) (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 }
}

View file

@ -4,7 +4,7 @@ use rustc_mir::monomorphize;
use crate::callee; use crate::callee;
use crate::traits::*; use crate::traits::*;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty, Instance};
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct VirtualIndex(u64); pub struct VirtualIndex(u64);
@ -103,7 +103,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
// `get_vtable` in rust_mir/interpret/traits.rs // `get_vtable` in rust_mir/interpret/traits.rs
// ///////////////////////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////////////////////
let components: Vec<_> = [ 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.size.bytes()),
cx.const_usize(layout.align.abi.bytes()) cx.const_usize(layout.align.abi.bytes())
].iter().cloned().chain(methods).collect(); ].iter().cloned().chain(methods).collect();

View file

@ -1,5 +1,5 @@
use rustc::middle::lang_items; 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::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
use rustc::mir::interpret::InterpError; 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 = location.ty(self.mir, bx.tcx()).ty;
let ty = self.monomorphize(&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 { if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
// we don't actually need to drop anything. // we don't actually need to drop anything.

View file

@ -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::cast::{CastTy, IntTy};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir; use rustc::mir;
@ -196,7 +196,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => { mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
match operand.layout.ty.sty { match operand.layout.ty.sty {
ty::Closure(def_id, substs) => { ty::Closure(def_id, substs) => {
let instance = monomorphize::resolve_closure( let instance = Instance::resolve_closure(
bx.cx().tcx(), def_id, substs, ty::ClosureKind::FnOnce); bx.cx().tcx(), def_id, substs, ty::ClosureKind::FnOnce);
OperandValue::Immediate(bx.cx().get_fn(instance)) OperandValue::Immediate(bx.cx().get_fn(instance))
} }

View file

@ -1,6 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use rustc::{mir, ty}; use rustc::{mir, ty};
use rustc::ty::Instance;
use rustc::ty::layout::{self, TyLayout, LayoutOf}; use rustc::ty::layout::{self, TyLayout, LayoutOf};
use syntax::source_map::Span; use syntax::source_map::Span;
use rustc_target::spec::abi::Abi; 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; let ty = place.layout.ty;
trace!("TerminatorKind::drop: {:?}, type {}", location, 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( self.drop_in_place(
place, place,
instance, instance,

View file

@ -1,4 +1,4 @@
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty, Instance};
use rustc::ty::layout::{Size, Align, LayoutOf}; use rustc::ty::layout::{Size, Align, LayoutOf};
use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; 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 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); let drop = self.memory.create_fn_alloc(drop);
// no need to do any alignment checks on the memory accesses below, because we know the // 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 // 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`. // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.

View file

@ -181,7 +181,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::mir::interpret::{AllocId, ConstValue};
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
use rustc::ty::subst::{InternalSubsts, SubstsRef}; 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::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc::session::config::EntryFnType; use rustc::session::config::EntryFnType;
use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; 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::mono::MonoItem;
use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; 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::nodemap::{FxHashSet, FxHashMap, DefIdMap};
use rustc::util::common::time; use rustc::util::common::time;
@ -580,7 +580,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
); );
match source_ty.sty { match source_ty.sty {
ty::Closure(def_id, substs) => { ty::Closure(def_id, substs) => {
let instance = monomorphize::resolve_closure( let instance = Instance::resolve_closure(
self.tcx, def_id, substs, ty::ClosureKind::FnOnce); self.tcx, def_id, substs, ty::ClosureKind::FnOnce);
if should_monomorphize_locally(self.tcx, &instance) { if should_monomorphize_locally(self.tcx, &instance) {
self.output.push(create_fn_mono_item(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, is_direct_call: bool,
output: &mut Vec<MonoItem<'tcx>>) output: &mut Vec<MonoItem<'tcx>>)
{ {
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); visit_instance_use(tcx, instance, is_direct_call, output);
} }

View file

@ -1,5 +1,3 @@
use rustc::hir::def_id::DefId;
use rustc::middle::lang_items::DropInPlaceFnLangItem;
use rustc::traits; use rustc::traits;
use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::ty::adjustment::CustomCoerceUnsized;
use rustc::ty::{self, Ty, TyCtxt, Instance}; 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<bool, ()>
{
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>, pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source_ty: Ty<'tcx>, source_ty: Ty<'tcx>,
target_ty: Ty<'tcx>) target_ty: Ty<'tcx>)