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>,
|
inst: Instance<'tcx>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
assert!(!inst.substs.needs_infer());
|
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
|
/// 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 = &args[fn_sig.inputs().len()..];
|
||||||
let extra_args = extra_args
|
let extra_args = fx
|
||||||
.iter()
|
.tcx
|
||||||
.map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))
|
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let fn_abi = if let Some(instance) = instance {
|
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 {
|
} 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
|
let is_cold = instance
|
||||||
|
@ -525,7 +528,8 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||||
substs: drop_instance.substs,
|
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 = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
|
||||||
let sig = fx.bcx.import_signature(sig);
|
let sig = fx.bcx.import_signature(sig);
|
||||||
|
@ -534,7 +538,8 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||||
_ => {
|
_ => {
|
||||||
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
|
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(
|
let arg_value = drop_place.place_ref(
|
||||||
fx,
|
fx,
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||||
instance,
|
instance,
|
||||||
symbol_name,
|
symbol_name,
|
||||||
mir,
|
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,
|
bcx,
|
||||||
block_map,
|
block_map,
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
|
RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||||
self.0.sess.span_fatal(span, &err.to_string())
|
self.0.sess.span_fatal(span, &err.to_string())
|
||||||
|
|
|
@ -80,7 +80,10 @@ impl CommentWriter {
|
||||||
vec![
|
vec![
|
||||||
format!("symbol {}", tcx.symbol_name(instance).name),
|
format!("symbol {}", tcx.symbol_name(instance).name),
|
||||||
format!("instance {:?}", instance),
|
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(),
|
String::new(),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
self.cx.handle_fn_abi_err(err, span, fn_abi_request)
|
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
|
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) {
|
let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
|
||||||
// Create a fn pointer with the new signature.
|
// Create a fn pointer with the new signature.
|
||||||
|
|
|
@ -867,7 +867,7 @@ impl FnAbiOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||||
self.sess().span_fatal(span, &err.to_string())
|
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,
|
hir::Unsafety::Unsafe,
|
||||||
Abi::Rust,
|
Abi::Rust,
|
||||||
)),
|
)),
|
||||||
&[],
|
ty::List::empty(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn make_mir_scope(
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
callee,
|
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)
|
cx.dbg_scope_fn(callee, &callee_fn_abi, None)
|
||||||
}
|
}
|
||||||
None => unsafe {
|
None => unsafe {
|
||||||
|
|
|
@ -737,7 +737,7 @@ fn gen_fn<'ll, 'tcx>(
|
||||||
rust_fn_sig: ty::PolyFnSig<'tcx>,
|
rust_fn_sig: ty::PolyFnSig<'tcx>,
|
||||||
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||||
) -> (&'ll Type, &'ll Value) {
|
) -> (&'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 llty = fn_abi.llvm_type(cx);
|
||||||
let llfn = cx.declare_fn(name, &fn_abi);
|
let llfn = cx.declare_fn(name, &fn_abi);
|
||||||
cx.set_frame_pointer_type(llfn);
|
cx.set_frame_pointer_type(llfn);
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
) {
|
) {
|
||||||
assert!(!instance.substs.needs_infer());
|
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);
|
let lldecl = self.declare_fn(symbol_name, &fn_abi);
|
||||||
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
|
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
|
||||||
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
|
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() => {
|
ty::Adt(def, _) if def.is_box() => {
|
||||||
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).llvm_type(cx))
|
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),
|
_ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO),
|
||||||
};
|
};
|
||||||
cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
|
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),
|
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||||
substs: drop_fn.substs,
|
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];
|
let vtable = args[1];
|
||||||
args = &args[..1];
|
args = &args[..1];
|
||||||
(
|
(
|
||||||
|
@ -346,7 +346,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
fn_abi,
|
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(
|
helper.do_call(
|
||||||
self,
|
self,
|
||||||
|
@ -433,7 +433,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// Obtain the panic entry point.
|
// Obtain the panic entry point.
|
||||||
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
|
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
|
||||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
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);
|
let llfn = bx.get_fn_addr(instance);
|
||||||
|
|
||||||
// Codegen the actual panic invoke/call.
|
// Codegen the actual panic invoke/call.
|
||||||
|
@ -494,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let def_id =
|
let def_id =
|
||||||
common::langcall(bx.tcx(), Some(source_info.span), "", LangItem::Panic);
|
common::langcall(bx.tcx(), Some(source_info.span), "", LangItem::Panic);
|
||||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
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);
|
let llfn = bx.get_fn_addr(instance);
|
||||||
|
|
||||||
// Codegen the actual panic invoke/call.
|
// 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 = &args[sig.inputs().skip_binder().len()..];
|
||||||
let extra_args = extra_args
|
let extra_args = bx.tcx().mk_type_list(extra_args.iter().map(|op_arg| {
|
||||||
.iter()
|
|
||||||
.map(|op_arg| {
|
|
||||||
let op_ty = op_arg.ty(self.mir, bx.tcx());
|
let op_ty = op_arg.ty(self.mir, bx.tcx());
|
||||||
self.monomorphize(op_ty)
|
self.monomorphize(op_ty)
|
||||||
})
|
}));
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let fn_abi = match instance {
|
let fn_abi = match instance {
|
||||||
Some(instance) => bx.fn_abi_of_instance(instance, &extra_args),
|
Some(instance) => bx.fn_abi_of_instance(instance, extra_args),
|
||||||
None => bx.fn_abi_of_fn_ptr(sig, &extra_args),
|
None => bx.fn_abi_of_fn_ptr(sig, extra_args),
|
||||||
};
|
};
|
||||||
|
|
||||||
if intrinsic == Some(sym::transmute) {
|
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 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);
|
debug!("fn_abi: {:?}", fn_abi);
|
||||||
|
|
||||||
let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
|
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 }
|
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)
|
query dylib_dependency_formats(_: CrateNum)
|
||||||
-> &'tcx [(CrateNum, LinkagePreference)] {
|
-> &'tcx [(CrateNum, LinkagePreference)] {
|
||||||
desc { "dylib dependency formats of crate" }
|
desc { "dylib dependency formats of crate" }
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::ich::StableHashingContext;
|
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
|
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
|
||||||
use crate::ty::subst::Subst;
|
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_ast as ast;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::bit_set::BitSet;
|
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::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::ops::Bound;
|
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 {
|
pub trait IntegerExt {
|
||||||
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
|
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
|
||||||
fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
|
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.
|
/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
|
||||||
pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
|
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> {
|
pub enum LayoutError<'tcx> {
|
||||||
Unknown(Ty<'tcx>),
|
Unknown(Ty<'tcx>),
|
||||||
SizeOverflow(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 struct LayoutCx<'tcx, C> {
|
||||||
pub tcx: C,
|
pub tcx: C,
|
||||||
pub param_env: ty::ParamEnv<'tcx>,
|
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> {
|
impl<'tcx> ty::Instance<'tcx> {
|
||||||
// NOTE(eddyb) this is private to avoid using it from outside of
|
// NOTE(eddyb) this is private to avoid using it from outside of
|
||||||
// `fn_abi_of_instance` - any other uses are either too high-level
|
// `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`.
|
/// Error produced by attempting to compute or adjust a `FnAbi`.
|
||||||
|
#[derive(Clone, Debug, HashStable)]
|
||||||
pub enum FnAbiError<'tcx> {
|
pub enum FnAbiError<'tcx> {
|
||||||
/// Error produced by a `layout_of` call, while computing `FnAbi` initially.
|
/// Error produced by a `layout_of` call, while computing `FnAbi` initially.
|
||||||
Layout(LayoutError<'tcx>),
|
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
|
// FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not
|
||||||
// just for error handling.
|
// just for error handling.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FnAbiRequest<'a, 'tcx> {
|
pub enum FnAbiRequest<'tcx> {
|
||||||
OfFnPtr { sig: ty::PolyFnSig<'tcx>, extra_args: &'a [Ty<'tcx>] },
|
OfFnPtr { sig: ty::PolyFnSig<'tcx>, extra_args: &'tcx ty::List<Ty<'tcx>> },
|
||||||
OfInstance { instance: ty::Instance<'tcx>, extra_args: &'a [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.
|
/// 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<...>`).
|
/// `Self::FnAbiOfResult` (which does not need to be a `Result<...>`).
|
||||||
///
|
///
|
||||||
/// Most `impl`s, which propagate `FnAbiError`s, should simply return `err`,
|
/// 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
|
/// `cx.fn_abi_of_*(...)`, without any `Result<...>` around it to deal with
|
||||||
/// (and any `FnAbiError`s are turned into fatal errors or ICEs).
|
/// (and any `FnAbiError`s are turned into fatal errors or ICEs).
|
||||||
fn handle_fn_abi_err(
|
fn handle_fn_abi_err(
|
||||||
&self,
|
&self,
|
||||||
err: FnAbiError<'tcx>,
|
err: FnAbiError<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
fn_abi_request: FnAbiRequest<'tcx>,
|
||||||
) -> <Self::FnAbiOfResult as MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>>::Error;
|
) -> <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(
|
fn fn_abi_of_fn_ptr(
|
||||||
&self,
|
&self,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
extra_args: &[Ty<'tcx>],
|
extra_args: &'tcx ty::List<Ty<'tcx>>,
|
||||||
) -> Self::FnAbiOfResult {
|
) -> Self::FnAbiOfResult {
|
||||||
// FIXME(eddyb) get a better `span` here.
|
// FIXME(eddyb) get a better `span` here.
|
||||||
let span = self.layout_tcx_at_span();
|
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(
|
MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err(
|
||||||
cx.fn_abi_new_internal(sig, extra_args, None, CodegenFnAttrFlags::empty(), false)
|
|err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { 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
|
/// 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(
|
fn fn_abi_of_instance(
|
||||||
&self,
|
&self,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
extra_args: &[Ty<'tcx>],
|
extra_args: &'tcx ty::List<Ty<'tcx>>,
|
||||||
) -> Self::FnAbiOfResult {
|
) -> Self::FnAbiOfResult {
|
||||||
// FIXME(eddyb) get a better `span` here.
|
// FIXME(eddyb) get a better `span` here.
|
||||||
let span = self.layout_tcx_at_span();
|
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);
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
MaybeResult::from(
|
MaybeResult::from(
|
||||||
cx.fn_abi_new_internal(
|
tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| {
|
||||||
sig,
|
|
||||||
extra_args,
|
|
||||||
caller_location,
|
|
||||||
attrs,
|
|
||||||
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
|
||||||
)
|
|
||||||
.map_err(|err| {
|
|
||||||
// HACK(eddyb) at least for definitions of/calls to `Instance`s,
|
// HACK(eddyb) at least for definitions of/calls to `Instance`s,
|
||||||
// we can get some kind of span even if one wasn't provided.
|
// 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
|
// However, we don't do this early in order to avoid calling
|
||||||
// `def_span` unconditionally (which may have a perf penalty).
|
// `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 })
|
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<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?)
|
// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?)
|
||||||
// arguments of this method, into a separate `struct`.
|
// arguments of this method, into a separate `struct`.
|
||||||
fn fn_abi_new_internal(
|
fn fn_abi_new_uncached(
|
||||||
&self,
|
&self,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
extra_args: &[Ty<'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`.
|
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
||||||
force_thin_self_ptr: bool,
|
force_thin_self_ptr: bool,
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
) -> 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);
|
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),
|
can_unwind: fn_can_unwind(self.tcx(), codegen_fn_attr_flags, sig.abi),
|
||||||
};
|
};
|
||||||
self.fn_abi_adjust_for_abi(&mut fn_abi, 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))
|
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::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
||||||
use rustc_session::utils::NativeLibKind;
|
use rustc_session::utils::NativeLibKind;
|
||||||
use rustc_session::Limits;
|
use rustc_session::Limits;
|
||||||
|
use rustc_target::abi;
|
||||||
use rustc_target::spec::PanicStrategy;
|
use rustc_target::spec::PanicStrategy;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
|
|
@ -449,3 +449,25 @@ impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
||||||
DUMMY_SP
|
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.
|
/// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI.
|
||||||
|
#[derive(Clone, Debug, HashStable_Generic)]
|
||||||
pub enum AdjustForForeignAbiError {
|
pub enum AdjustForForeignAbiError {
|
||||||
/// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs.
|
/// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs.
|
||||||
Unsupported { arch: String, abi: spec::abi::Abi },
|
Unsupported { arch: String, abi: spec::abi::Abi },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue