Querify fn_abi_of_{fn_ptr,instance}
.
This commit is contained in:
parent
e9b68304ef
commit
c1837ef1c5
19 changed files with 152 additions and 93 deletions
|
@ -53,7 +53,11 @@ pub(crate) fn get_function_sig<'tcx>(
|
|||
inst: Instance<'tcx>,
|
||||
) -> Signature {
|
||||
assert!(!inst.substs.needs_infer());
|
||||
clif_sig_from_fn_abi(tcx, triple, &RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, &[]))
|
||||
clif_sig_from_fn_abi(
|
||||
tcx,
|
||||
triple,
|
||||
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Instance must be monomorphized
|
||||
|
@ -350,14 +354,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||
};
|
||||
|
||||
let extra_args = &args[fn_sig.inputs().len()..];
|
||||
let extra_args = extra_args
|
||||
.iter()
|
||||
.map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))
|
||||
.collect::<Vec<_>>();
|
||||
let extra_args = fx
|
||||
.tcx
|
||||
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
|
||||
let fn_abi = if let Some(instance) = instance {
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, &extra_args)
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
|
||||
} else {
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), &extra_args)
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
|
||||
};
|
||||
|
||||
let is_cold = instance
|
||||
|
@ -525,7 +528,8 @@ pub(crate) fn codegen_drop<'tcx>(
|
|||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||
substs: drop_instance.substs,
|
||||
};
|
||||
let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, &[]);
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
|
||||
let sig = fx.bcx.import_signature(sig);
|
||||
|
@ -534,7 +538,8 @@ pub(crate) fn codegen_drop<'tcx>(
|
|||
_ => {
|
||||
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
|
||||
|
||||
let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, &[]);
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty());
|
||||
|
||||
let arg_value = drop_place.place_ref(
|
||||
fx,
|
||||
|
|
|
@ -61,7 +61,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||
instance,
|
||||
symbol_name,
|
||||
mir,
|
||||
fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, &[])),
|
||||
fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())),
|
||||
|
||||
bcx,
|
||||
block_map,
|
||||
|
|
|
@ -276,7 +276,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
|||
&self,
|
||||
err: FnAbiError<'tcx>,
|
||||
span: Span,
|
||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> ! {
|
||||
RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
|||
&self,
|
||||
err: FnAbiError<'tcx>,
|
||||
span: Span,
|
||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> ! {
|
||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||
self.0.sess.span_fatal(span, &err.to_string())
|
||||
|
|
|
@ -80,7 +80,10 @@ impl CommentWriter {
|
|||
vec![
|
||||
format!("symbol {}", tcx.symbol_name(instance).name),
|
||||
format!("instance {:?}", instance),
|
||||
format!("abi {:?}", RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, &[])),
|
||||
format!(
|
||||
"abi {:?}",
|
||||
RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())
|
||||
),
|
||||
String::new(),
|
||||
]
|
||||
} else {
|
||||
|
|
|
@ -107,7 +107,7 @@ impl FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
&self,
|
||||
err: FnAbiError<'tcx>,
|
||||
span: Span,
|
||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> ! {
|
||||
self.cx.handle_fn_abi_err(err, span, fn_abi_request)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
|
|||
sym
|
||||
);
|
||||
|
||||
let fn_abi = cx.fn_abi_of_instance(instance, &[]);
|
||||
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
|
||||
let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
|
||||
// Create a fn pointer with the new signature.
|
||||
|
|
|
@ -867,7 +867,7 @@ impl FnAbiOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
&self,
|
||||
err: FnAbiError<'tcx>,
|
||||
span: Span,
|
||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> ! {
|
||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||
self.sess().span_fatal(span, &err.to_string())
|
||||
|
|
|
@ -208,7 +208,7 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
|
|||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust,
|
||||
)),
|
||||
&[],
|
||||
ty::List::empty(),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ fn make_mir_scope(
|
|||
ty::ParamEnv::reveal_all(),
|
||||
callee,
|
||||
);
|
||||
let callee_fn_abi = cx.fn_abi_of_instance(callee, &[]);
|
||||
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
|
||||
cx.dbg_scope_fn(callee, &callee_fn_abi, None)
|
||||
}
|
||||
None => unsafe {
|
||||
|
|
|
@ -737,7 +737,7 @@ fn gen_fn<'ll, 'tcx>(
|
|||
rust_fn_sig: ty::PolyFnSig<'tcx>,
|
||||
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||
) -> (&'ll Type, &'ll Value) {
|
||||
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, &[]);
|
||||
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty());
|
||||
let llty = fn_abi.llvm_type(cx);
|
||||
let llfn = cx.declare_fn(name, &fn_abi);
|
||||
cx.set_frame_pointer_type(llfn);
|
||||
|
|
|
@ -52,7 +52,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
) {
|
||||
assert!(!instance.substs.needs_infer());
|
||||
|
||||
let fn_abi = self.fn_abi_of_instance(instance, &[]);
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let lldecl = self.declare_fn(symbol_name, &fn_abi);
|
||||
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
|
||||
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
|
||||
|
|
|
@ -230,7 +230,9 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
|||
ty::Adt(def, _) if def.is_box() => {
|
||||
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).llvm_type(cx))
|
||||
}
|
||||
ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, &[])),
|
||||
ty::FnPtr(sig) => {
|
||||
cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
|
||||
}
|
||||
_ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO),
|
||||
};
|
||||
cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
|
||||
|
|
|
@ -337,7 +337,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||
substs: drop_fn.substs,
|
||||
};
|
||||
let fn_abi = bx.fn_abi_of_instance(virtual_drop, &[]);
|
||||
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
let vtable = args[1];
|
||||
args = &args[..1];
|
||||
(
|
||||
|
@ -346,7 +346,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
fn_abi,
|
||||
)
|
||||
}
|
||||
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, &[])),
|
||||
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
|
||||
};
|
||||
helper.do_call(
|
||||
self,
|
||||
|
@ -433,7 +433,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// Obtain the panic entry point.
|
||||
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let fn_abi = bx.fn_abi_of_instance(instance, &[]);
|
||||
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let llfn = bx.get_fn_addr(instance);
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
|
@ -494,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let def_id =
|
||||
common::langcall(bx.tcx(), Some(source_info.span), "", LangItem::Panic);
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let fn_abi = bx.fn_abi_of_instance(instance, &[]);
|
||||
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let llfn = bx.get_fn_addr(instance);
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
|
@ -570,17 +570,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
};
|
||||
|
||||
let extra_args = &args[sig.inputs().skip_binder().len()..];
|
||||
let extra_args = extra_args
|
||||
.iter()
|
||||
.map(|op_arg| {
|
||||
let op_ty = op_arg.ty(self.mir, bx.tcx());
|
||||
self.monomorphize(op_ty)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let extra_args = bx.tcx().mk_type_list(extra_args.iter().map(|op_arg| {
|
||||
let op_ty = op_arg.ty(self.mir, bx.tcx());
|
||||
self.monomorphize(op_ty)
|
||||
}));
|
||||
|
||||
let fn_abi = match instance {
|
||||
Some(instance) => bx.fn_abi_of_instance(instance, &extra_args),
|
||||
None => bx.fn_abi_of_fn_ptr(sig, &extra_args),
|
||||
Some(instance) => bx.fn_abi_of_instance(instance, extra_args),
|
||||
None => bx.fn_abi_of_fn_ptr(sig, extra_args),
|
||||
};
|
||||
|
||||
if intrinsic == Some(sym::transmute) {
|
||||
|
|
|
@ -139,7 +139,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
let mir = cx.tcx().instance_mir(instance.def);
|
||||
|
||||
let fn_abi = cx.fn_abi_of_instance(instance, &[]);
|
||||
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
debug!("fn_abi: {:?}", fn_abi);
|
||||
|
||||
let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
|
||||
|
|
|
@ -1128,6 +1128,27 @@ rustc_queries! {
|
|||
desc { "computing layout of `{}`", key.value }
|
||||
}
|
||||
|
||||
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
|
||||
///
|
||||
/// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
|
||||
/// instead, where the instance is an `InstanceDef::Virtual`.
|
||||
query fn_abi_of_fn_ptr(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}` function pointers", key.value.0 }
|
||||
}
|
||||
|
||||
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
|
||||
/// direct calls to an `fn`.
|
||||
///
|
||||
/// NB: that includes virtual calls, which are represented by "direct calls"
|
||||
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
||||
query fn_abi_of_instance(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}`", key.value.0 }
|
||||
}
|
||||
|
||||
query dylib_dependency_formats(_: CrateNum)
|
||||
-> &'tcx [(CrateNum, LinkagePreference)] {
|
||||
desc { "dylib dependency formats of crate" }
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::ich::StableHashingContext;
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
|
||||
use crate::ty::subst::Subst;
|
||||
|
@ -6,7 +5,6 @@ use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
|
|||
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
|
@ -23,10 +21,14 @@ use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Targ
|
|||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::Bound;
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers =
|
||||
ty::query::Providers { layout_of, fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers };
|
||||
}
|
||||
|
||||
pub trait IntegerExt {
|
||||
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
|
||||
fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
|
||||
|
@ -191,7 +193,7 @@ pub const FAT_PTR_EXTRA: usize = 1;
|
|||
/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
|
||||
pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
|
||||
|
||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
|
||||
pub enum LayoutError<'tcx> {
|
||||
Unknown(Ty<'tcx>),
|
||||
SizeOverflow(Ty<'tcx>),
|
||||
|
@ -248,10 +250,6 @@ fn layout_of<'tcx>(
|
|||
})
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers { layout_of, ..*providers };
|
||||
}
|
||||
|
||||
pub struct LayoutCx<'tcx, C> {
|
||||
pub tcx: C,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -2537,18 +2535,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
|
||||
#[inline]
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
use crate::ty::layout::LayoutError::*;
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
Unknown(t) | SizeOverflow(t) => t.hash_stable(hcx, hasher),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::Instance<'tcx> {
|
||||
// NOTE(eddyb) this is private to avoid using it from outside of
|
||||
// `fn_abi_of_instance` - any other uses are either too high-level
|
||||
|
@ -2807,6 +2793,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
|
|||
}
|
||||
|
||||
/// Error produced by attempting to compute or adjust a `FnAbi`.
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub enum FnAbiError<'tcx> {
|
||||
/// Error produced by a `layout_of` call, while computing `FnAbi` initially.
|
||||
Layout(LayoutError<'tcx>),
|
||||
|
@ -2839,9 +2826,9 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> {
|
|||
// FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not
|
||||
// just for error handling.
|
||||
#[derive(Debug)]
|
||||
pub enum FnAbiRequest<'a, 'tcx> {
|
||||
OfFnPtr { sig: ty::PolyFnSig<'tcx>, extra_args: &'a [Ty<'tcx>] },
|
||||
OfInstance { instance: ty::Instance<'tcx>, extra_args: &'a [Ty<'tcx>] },
|
||||
pub enum FnAbiRequest<'tcx> {
|
||||
OfFnPtr { sig: ty::PolyFnSig<'tcx>, extra_args: &'tcx ty::List<Ty<'tcx>> },
|
||||
OfInstance { instance: ty::Instance<'tcx>, extra_args: &'tcx ty::List<Ty<'tcx>> },
|
||||
}
|
||||
|
||||
/// Trait for contexts that want to be able to compute `FnAbi`s.
|
||||
|
@ -2855,14 +2842,14 @@ pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> {
|
|||
/// `Self::FnAbiOfResult` (which does not need to be a `Result<...>`).
|
||||
///
|
||||
/// Most `impl`s, which propagate `FnAbiError`s, should simply return `err`,
|
||||
/// but this hook allows e.g. codegen to return only `&FnABi` from its
|
||||
/// but this hook allows e.g. codegen to return only `&FnAbi` from its
|
||||
/// `cx.fn_abi_of_*(...)`, without any `Result<...>` around it to deal with
|
||||
/// (and any `FnAbiError`s are turned into fatal errors or ICEs).
|
||||
fn handle_fn_abi_err(
|
||||
&self,
|
||||
err: FnAbiError<'tcx>,
|
||||
span: Span,
|
||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> <Self::FnAbiOfResult as MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>>::Error;
|
||||
}
|
||||
|
||||
|
@ -2876,18 +2863,15 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
|||
fn fn_abi_of_fn_ptr(
|
||||
&self,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>],
|
||||
extra_args: &'tcx ty::List<Ty<'tcx>>,
|
||||
) -> Self::FnAbiOfResult {
|
||||
// FIXME(eddyb) get a better `span` here.
|
||||
let span = self.layout_tcx_at_span();
|
||||
let cx = LayoutCx { tcx: self.tcx().at(span), param_env: self.param_env() };
|
||||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(
|
||||
cx.fn_abi_new_internal(sig, extra_args, None, CodegenFnAttrFlags::empty(), false)
|
||||
.map_err(|err| {
|
||||
self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args })
|
||||
}),
|
||||
)
|
||||
MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err(
|
||||
|err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
|
||||
))
|
||||
}
|
||||
|
||||
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
|
||||
|
@ -2899,36 +2883,19 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
|||
fn fn_abi_of_instance(
|
||||
&self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
extra_args: &[Ty<'tcx>],
|
||||
extra_args: &'tcx ty::List<Ty<'tcx>>,
|
||||
) -> Self::FnAbiOfResult {
|
||||
// FIXME(eddyb) get a better `span` here.
|
||||
let span = self.layout_tcx_at_span();
|
||||
let cx = LayoutCx { tcx: self.tcx().at(span), param_env: self.param_env() };
|
||||
|
||||
let sig = instance.fn_sig_for_fn_abi(cx.tcx());
|
||||
|
||||
let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
|
||||
Some(cx.tcx.caller_location_ty())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id()).flags;
|
||||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(
|
||||
cx.fn_abi_new_internal(
|
||||
sig,
|
||||
extra_args,
|
||||
caller_location,
|
||||
attrs,
|
||||
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
||||
)
|
||||
.map_err(|err| {
|
||||
tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| {
|
||||
// HACK(eddyb) at least for definitions of/calls to `Instance`s,
|
||||
// we can get some kind of span even if one wasn't provided.
|
||||
// However, we don't do this early in order to avoid calling
|
||||
// `def_span` unconditionally (which may have a perf penalty).
|
||||
let span = if !span.is_dummy() { span } else { cx.tcx.def_span(instance.def_id()) };
|
||||
let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
|
||||
self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args })
|
||||
}),
|
||||
)
|
||||
|
@ -2937,10 +2904,50 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
|||
|
||||
impl<C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {}
|
||||
|
||||
impl<'tcx> LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
|
||||
fn fn_abi_of_fn_ptr<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
let (param_env, (sig, extra_args)) = query.into_parts();
|
||||
|
||||
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
|
||||
sig,
|
||||
extra_args,
|
||||
None,
|
||||
CodegenFnAttrFlags::empty(),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
fn fn_abi_of_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
let (param_env, (instance, extra_args)) = query.into_parts();
|
||||
|
||||
let sig = instance.fn_sig_for_fn_abi(tcx);
|
||||
|
||||
let caller_location = if instance.def.requires_caller_location(tcx) {
|
||||
Some(tcx.caller_location_ty())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let attrs = tcx.codegen_fn_attrs(instance.def_id()).flags;
|
||||
|
||||
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
|
||||
sig,
|
||||
extra_args,
|
||||
caller_location,
|
||||
attrs,
|
||||
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
||||
)
|
||||
}
|
||||
|
||||
impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?)
|
||||
// arguments of this method, into a separate `struct`.
|
||||
fn fn_abi_new_internal(
|
||||
fn fn_abi_new_uncached(
|
||||
&self,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>],
|
||||
|
@ -2949,7 +2956,7 @@ impl<'tcx> LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
|
|||
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
||||
force_thin_self_ptr: bool,
|
||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
|
||||
debug!("fn_abi_new_uncached({:?}, {:?})", sig, extra_args);
|
||||
|
||||
let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig);
|
||||
|
||||
|
@ -3110,7 +3117,7 @@ impl<'tcx> LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
|
|||
can_unwind: fn_can_unwind(self.tcx(), codegen_fn_attr_flags, sig.abi),
|
||||
};
|
||||
self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?;
|
||||
debug!("FnAbi::new_internal = {:?}", fn_abi);
|
||||
debug!("fn_abi_new_uncached = {:?}", fn_abi);
|
||||
Ok(self.tcx.intern_fn_abi(fn_abi))
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
|
|||
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
||||
use rustc_session::utils::NativeLibKind;
|
||||
use rustc_session::Limits;
|
||||
use rustc_target::abi;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
|
||||
use rustc_ast as ast;
|
||||
|
|
|
@ -449,3 +449,25 @@ impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
|||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -601,6 +601,7 @@ pub struct FnAbi<'a, Ty> {
|
|||
}
|
||||
|
||||
/// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI.
|
||||
#[derive(Clone, Debug, HashStable_Generic)]
|
||||
pub enum AdjustForForeignAbiError {
|
||||
/// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs.
|
||||
Unsupported { arch: String, abi: spec::abi::Abi },
|
||||
|
|
Loading…
Add table
Reference in a new issue