deduplicate ty::Instance constructors
This commit is contained in:
parent
8af151b30a
commit
58bd0ea732
8 changed files with 53 additions and 125 deletions
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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<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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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>,
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue