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::{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 }
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue