mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
ty::layout: replicate layout_of
setup for fn_abi_of_{fn_ptr,instance}
.
This commit is contained in:
parent
319dec89e7
commit
e9b68304ef
@ -5,7 +5,7 @@ mod pass_mode;
|
|||||||
mod returning;
|
mod returning;
|
||||||
|
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_target::abi::call::{Conv, FnAbi};
|
use rustc_target::abi::call::{Conv, FnAbi};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ 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, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]))
|
clif_sig_from_fn_abi(tcx, triple, &RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, &[]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instance must be monomorphized
|
/// Instance must be monomorphized
|
||||||
@ -355,9 +355,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
.map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))
|
.map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let fn_abi = if let Some(instance) = instance {
|
let fn_abi = if let Some(instance) = instance {
|
||||||
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, &extra_args)
|
||||||
} else {
|
} else {
|
||||||
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), 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 +525,7 @@ 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 = FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), virtual_drop, &[]);
|
let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, &[]);
|
||||||
|
|
||||||
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 +534,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
|||||||
_ => {
|
_ => {
|
||||||
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
|
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
|
||||||
|
|
||||||
let fn_abi = FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), drop_instance, &[]);
|
let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, &[]);
|
||||||
|
|
||||||
let arg_value = drop_place.place_ref(
|
let arg_value = drop_place.place_ref(
|
||||||
fx,
|
fx,
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::ty::adjustment::PointerCast;
|
use rustc_middle::ty::adjustment::PointerCast;
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_target::abi::call::FnAbi;
|
|
||||||
|
|
||||||
use crate::constant::ConstantCx;
|
use crate::constant::ConstantCx;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -62,7 +61,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
instance,
|
instance,
|
||||||
symbol_name,
|
symbol_name,
|
||||||
mir,
|
mir,
|
||||||
fn_abi: Some(FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
|
fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, &[])),
|
||||||
|
|
||||||
bcx,
|
bcx,
|
||||||
block_map,
|
block_map,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers};
|
use rustc_middle::ty::layout::{
|
||||||
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
|
||||||
|
};
|
||||||
use rustc_middle::ty::SymbolName;
|
use rustc_middle::ty::SymbolName;
|
||||||
use rustc_target::abi::call::FnAbi;
|
use rustc_target::abi::call::FnAbi;
|
||||||
use rustc_target::abi::{Integer, Primitive};
|
use rustc_target::abi::{Integer, Primitive};
|
||||||
@ -266,6 +268,20 @@ impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||||
|
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn handle_fn_abi_err(
|
||||||
|
&self,
|
||||||
|
err: FnAbiError<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||||
|
) -> ! {
|
||||||
|
RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
@ -378,6 +394,43 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||||
|
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn handle_fn_abi_err(
|
||||||
|
&self,
|
||||||
|
err: FnAbiError<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||||
|
) -> ! {
|
||||||
|
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||||
|
self.0.sess.span_fatal(span, &err.to_string())
|
||||||
|
} else {
|
||||||
|
match fn_abi_request {
|
||||||
|
FnAbiRequest::OfFnPtr { sig, extra_args } => {
|
||||||
|
span_bug!(
|
||||||
|
span,
|
||||||
|
"`fn_abi_of_fn_ptr({}, {:?})` failed: {}",
|
||||||
|
sig,
|
||||||
|
extra_args,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FnAbiRequest::OfInstance { instance, extra_args } => {
|
||||||
|
span_bug!(
|
||||||
|
span,
|
||||||
|
"`fn_abi_of_instance({}, {:?})` failed: {}",
|
||||||
|
instance,
|
||||||
|
extra_args,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> {
|
impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.0
|
self.0
|
||||||
|
@ -129,9 +129,7 @@ pub(crate) fn codegen_constant<'tcx>(
|
|||||||
};
|
};
|
||||||
let const_val = match const_.val {
|
let const_val = match const_.val {
|
||||||
ConstKind::Value(const_val) => const_val,
|
ConstKind::Value(const_val) => const_val,
|
||||||
ConstKind::Unevaluated(uv)
|
ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => {
|
||||||
if fx.tcx.is_static(uv.def.did) =>
|
|
||||||
{
|
|
||||||
assert!(uv.substs(fx.tcx).is_empty());
|
assert!(uv.substs(fx.tcx).is_empty());
|
||||||
assert!(uv.promoted.is_none());
|
assert!(uv.promoted.is_none());
|
||||||
|
|
||||||
|
@ -61,9 +61,8 @@ use cranelift_codegen::{
|
|||||||
write::{FuncWriter, PlainWriter},
|
write::{FuncWriter, PlainWriter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_session::config::OutputType;
|
use rustc_session::config::OutputType;
|
||||||
use rustc_target::abi::call::FnAbi;
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -81,7 +80,7 @@ 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 {:?}", FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
|
format!("abi {:?}", RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, &[])),
|
||||||
String::new(),
|
String::new(),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,10 +15,12 @@ use rustc_codegen_ssa::traits::*;
|
|||||||
use rustc_codegen_ssa::MemFlags;
|
use rustc_codegen_ssa::MemFlags;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
use rustc_middle::ty::layout::{
|
||||||
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
|
||||||
|
};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{self, Align, Size, WrappingRange};
|
use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
|
||||||
use rustc_target::spec::{HasTargetSpec, Target};
|
use rustc_target::spec::{HasTargetSpec, Target};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
@ -97,6 +99,20 @@ impl LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
|
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn handle_fn_abi_err(
|
||||||
|
&self,
|
||||||
|
err: FnAbiError<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||||
|
) -> ! {
|
||||||
|
self.cx.handle_fn_abi_err(err, span, fn_abi_request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for Builder<'_, 'll, 'tcx> {
|
impl Deref for Builder<'_, 'll, 'tcx> {
|
||||||
type Target = CodegenCx<'ll, 'tcx>;
|
type Target = CodegenCx<'ll, 'tcx>;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
//! and methods are represented as just a fn ptr and not a full
|
//! and methods are represented as just a fn ptr and not a full
|
||||||
//! closure.
|
//! closure.
|
||||||
|
|
||||||
use crate::abi::{FnAbi, FnAbiLlvmExt};
|
use crate::abi::FnAbiLlvmExt;
|
||||||
use crate::attributes;
|
use crate::attributes;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
@ -12,7 +12,7 @@ use crate::value::Value;
|
|||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||||
use rustc_middle::ty::{self, Instance, TypeFoldable};
|
use rustc_middle::ty::{self, Instance, TypeFoldable};
|
||||||
|
|
||||||
/// Codegens a reference to a fn/method item, monomorphizing and
|
/// Codegens a reference to a fn/method item, monomorphizing and
|
||||||
@ -42,7 +42,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
|
|||||||
sym
|
sym
|
||||||
);
|
);
|
||||||
|
|
||||||
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
|
let fn_abi = cx.fn_abi_of_instance(instance, &[]);
|
||||||
|
|
||||||
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.
|
||||||
|
@ -15,14 +15,19 @@ use rustc_data_structures::base_n;
|
|||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_middle::mir::mono::CodegenUnit;
|
use rustc_middle::mir::mono::CodegenUnit;
|
||||||
use rustc_middle::ty::layout::{HasParamEnv, LayoutError, LayoutOfHelpers, TyAndLayout};
|
use rustc_middle::ty::layout::{
|
||||||
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||||
|
TyAndLayout,
|
||||||
|
};
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::config::{CFGuard, CrateType, DebugInfo};
|
use rustc_session::config::{CFGuard, CrateType, DebugInfo};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
|
use rustc_target::abi::{
|
||||||
|
call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx,
|
||||||
|
};
|
||||||
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
|
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
@ -853,3 +858,40 @@ impl LayoutOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FnAbiOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
|
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn handle_fn_abi_err(
|
||||||
|
&self,
|
||||||
|
err: FnAbiError<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
fn_abi_request: FnAbiRequest<'_, 'tcx>,
|
||||||
|
) -> ! {
|
||||||
|
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||||
|
self.sess().span_fatal(span, &err.to_string())
|
||||||
|
} else {
|
||||||
|
match fn_abi_request {
|
||||||
|
FnAbiRequest::OfFnPtr { sig, extra_args } => {
|
||||||
|
span_bug!(
|
||||||
|
span,
|
||||||
|
"`fn_abi_of_fn_ptr({}, {:?})` failed: {}",
|
||||||
|
sig,
|
||||||
|
extra_args,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FnAbiRequest::OfInstance { instance, extra_args } => {
|
||||||
|
span_bug!(
|
||||||
|
span,
|
||||||
|
"`fn_abi_of_instance({}, {:?})` failed: {}",
|
||||||
|
instance,
|
||||||
|
extra_args,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
|
|
||||||
use crate::abi::{Abi, FnAbi};
|
use crate::abi::Abi;
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ use rustc_middle::mir::coverage::{
|
|||||||
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
|
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::subst::InternalSubsts;
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
|
|
||||||
@ -200,8 +200,7 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
|
|||||||
|
|
||||||
let llfn = cx.declare_fn(
|
let llfn = cx.declare_fn(
|
||||||
&tcx.symbol_name(instance).name,
|
&tcx.symbol_name(instance).name,
|
||||||
&FnAbi::of_fn_ptr(
|
&cx.fn_abi_of_fn_ptr(
|
||||||
cx,
|
|
||||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
iter::once(tcx.mk_unit()),
|
iter::once(tcx.mk_unit()),
|
||||||
tcx.mk_unit(),
|
tcx.mk_unit(),
|
||||||
|
@ -3,12 +3,11 @@ use super::utils::DIB;
|
|||||||
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
|
|
||||||
use crate::abi::FnAbi;
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{DILocation, DIScope};
|
use crate::llvm::debuginfo::{DILocation, DIScope};
|
||||||
use rustc_middle::mir::{Body, SourceScope};
|
use rustc_middle::mir::{Body, SourceScope};
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_middle::ty::{self, Instance};
|
use rustc_middle::ty::{self, Instance};
|
||||||
use rustc_session::config::DebugInfo;
|
use rustc_session::config::DebugInfo;
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ fn make_mir_scope(
|
|||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
callee,
|
callee,
|
||||||
);
|
);
|
||||||
let callee_fn_abi = FnAbi::of_instance(cx, callee, &[]);
|
let callee_fn_abi = cx.fn_abi_of_instance(callee, &[]);
|
||||||
cx.dbg_scope_fn(callee, &callee_fn_abi, None)
|
cx.dbg_scope_fn(callee, &callee_fn_abi, None)
|
||||||
}
|
}
|
||||||
None => unsafe {
|
None => unsafe {
|
||||||
|
@ -15,7 +15,7 @@ use rustc_codegen_ssa::mir::operand::OperandRef;
|
|||||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, LayoutOf};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::{sym, symbol::kw, Span, Symbol};
|
use rustc_span::{sym, symbol::kw, Span, Symbol};
|
||||||
@ -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 = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]);
|
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, &[]);
|
||||||
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);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::abi::FnAbi;
|
|
||||||
use crate::attributes;
|
use crate::attributes;
|
||||||
use crate::base;
|
use crate::base;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
@ -8,7 +7,7 @@ use rustc_codegen_ssa::traits::*;
|
|||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
pub use rustc_middle::mir::mono::MonoItem;
|
pub use rustc_middle::mir::mono::MonoItem;
|
||||||
use rustc_middle::mir::mono::{Linkage, Visibility};
|
use rustc_middle::mir::mono::{Linkage, Visibility};
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, LayoutOf};
|
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||||
use rustc_middle::ty::{self, Instance, TypeFoldable};
|
use rustc_middle::ty::{self, Instance, TypeFoldable};
|
||||||
use rustc_session::config::CrateType;
|
use rustc_session::config::CrateType;
|
||||||
use rustc_target::spec::RelocModel;
|
use rustc_target::spec::RelocModel;
|
||||||
@ -53,7 +52,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||||||
) {
|
) {
|
||||||
assert!(!instance.substs.needs_infer());
|
assert!(!instance.substs.needs_infer());
|
||||||
|
|
||||||
let fn_abi = FnAbi::of_instance(self, instance, &[]);
|
let fn_abi = self.fn_abi_of_instance(instance, &[]);
|
||||||
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());
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use crate::abi::FnAbi;
|
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::context::TypeLowering;
|
use crate::context::TypeLowering;
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, Ty, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TypeFoldable};
|
||||||
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
|
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
|
||||||
@ -231,7 +230,7 @@ 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(&FnAbi::of_fn_ptr(cx, sig, &[])),
|
ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, &[])),
|
||||||
_ => 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);
|
||||||
|
@ -14,7 +14,7 @@ use rustc_hir::lang_items::LangItem;
|
|||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
use rustc_middle::mir::{self, SwitchTargets};
|
use rustc_middle::mir::{self, SwitchTargets};
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, LayoutOf};
|
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
|
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
@ -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 = FnAbi::of_instance(&bx, virtual_drop, &[]);
|
let fn_abi = bx.fn_abi_of_instance(virtual_drop, &[]);
|
||||||
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), FnAbi::of_instance(&bx, drop_fn, &[])),
|
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, &[])),
|
||||||
};
|
};
|
||||||
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 = FnAbi::of_instance(&bx, instance, &[]);
|
let fn_abi = bx.fn_abi_of_instance(instance, &[]);
|
||||||
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 = FnAbi::of_instance(bx, instance, &[]);
|
let fn_abi = bx.fn_abi_of_instance(instance, &[]);
|
||||||
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.
|
||||||
@ -579,8 +579,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let fn_abi = match instance {
|
let fn_abi = match instance {
|
||||||
Some(instance) => FnAbi::of_instance(&bx, instance, &extra_args),
|
Some(instance) => bx.fn_abi_of_instance(instance, &extra_args),
|
||||||
None => FnAbi::of_fn_ptr(&bx, sig, &extra_args),
|
None => bx.fn_abi_of_fn_ptr(sig, &extra_args),
|
||||||
};
|
};
|
||||||
|
|
||||||
if intrinsic == Some(sym::transmute) {
|
if intrinsic == Some(sym::transmute) {
|
||||||
|
@ -2,7 +2,7 @@ use crate::traits::*;
|
|||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
|
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
|
||||||
use rustc_target::abi::call::{FnAbi, PassMode};
|
use rustc_target::abi::call::{FnAbi, PassMode};
|
||||||
|
|
||||||
@ -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 = FnAbi::of_instance(cx, instance, &[]);
|
let fn_abi = cx.fn_abi_of_instance(instance, &[]);
|
||||||
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);
|
||||||
|
@ -8,14 +8,15 @@ use rustc_data_structures::fx::FxHashMap;
|
|||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||||
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
||||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::{Ty, TyCtxt};
|
||||||
use rustc_session::{
|
use rustc_session::{
|
||||||
config::{self, OutputFilenames, PrintRequest},
|
config::{self, OutputFilenames, PrintRequest},
|
||||||
Session,
|
Session,
|
||||||
};
|
};
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
|
use rustc_target::abi::call::FnAbi;
|
||||||
use rustc_target::spec::Target;
|
use rustc_target::spec::Target;
|
||||||
|
|
||||||
pub use rustc_data_structures::sync::MetadataRef;
|
pub use rustc_data_structures::sync::MetadataRef;
|
||||||
@ -38,12 +39,19 @@ pub trait BackendTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Backend<'tcx>:
|
pub trait Backend<'tcx>:
|
||||||
Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
|
Sized
|
||||||
|
+ BackendTypes
|
||||||
|
+ HasTyCtxt<'tcx>
|
||||||
|
+ LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
|
||||||
|
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T> Backend<'tcx> for T where
|
impl<'tcx, T> Backend<'tcx> for T where
|
||||||
Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
|
Self: BackendTypes
|
||||||
|
+ HasTyCtxt<'tcx>
|
||||||
|
+ LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
|
||||||
|
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2035,6 +2035,12 @@ impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> HasTargetSpec for ty::query::TyCtxtAt<'tcx> {
|
||||||
|
fn target_spec(&self) -> &Target {
|
||||||
|
&self.sess.target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> {
|
impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
@ -2142,10 +2148,10 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::LayoutOfResult {
|
fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::LayoutOfResult {
|
||||||
let span = if !span.is_dummy() { span } else { self.layout_tcx_at_span() };
|
let span = if !span.is_dummy() { span } else { self.layout_tcx_at_span() };
|
||||||
|
let tcx = self.tcx().at(span);
|
||||||
|
|
||||||
MaybeResult::from(
|
MaybeResult::from(
|
||||||
self.tcx()
|
tcx.layout_of(self.param_env().and(ty))
|
||||||
.at(span)
|
|
||||||
.layout_of(self.param_env().and(ty))
|
|
||||||
.map_err(|err| self.handle_layout_err(err, span, ty)),
|
.map_err(|err| self.handle_layout_err(err, span, ty)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -2545,10 +2551,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
|
|||||||
|
|
||||||
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
|
||||||
// `FnAbi::of_instance` - any other uses are either too high-level
|
// `fn_abi_of_instance` - any other uses are either too high-level
|
||||||
// for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
|
// for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
|
||||||
// or should go through `FnAbi` instead, to avoid losing any
|
// or should go through `FnAbi` instead, to avoid losing any
|
||||||
// adjustments `FnAbi::of_instance` might be performing.
|
// adjustments `fn_abi_of_instance` might be performing.
|
||||||
fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
||||||
// FIXME(davidtwco,eddyb): A `ParamEnv` should be passed through to this function.
|
// FIXME(davidtwco,eddyb): A `ParamEnv` should be passed through to this function.
|
||||||
let ty = self.ty(tcx, ty::ParamEnv::reveal_all());
|
let ty = self.ty(tcx, ty::ParamEnv::reveal_all());
|
||||||
@ -2801,7 +2807,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`.
|
||||||
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>),
|
||||||
|
|
||||||
@ -2830,125 +2836,124 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FnAbiExt<'tcx, C>
|
// FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not
|
||||||
where
|
// just for error handling.
|
||||||
C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
|
#[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>] },
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait for contexts that want to be able to compute `FnAbi`s.
|
||||||
|
/// This automatically gives access to `FnAbiOf`, through a blanket `impl`.
|
||||||
|
pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> {
|
||||||
|
/// The `&FnAbi`-wrapping type (or `&FnAbi` itself), which will be
|
||||||
|
/// returned from `fn_abi_of_*` (see also `handle_fn_abi_err`).
|
||||||
|
type FnAbiOfResult: MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>;
|
||||||
|
|
||||||
|
/// Helper used for `fn_abi_of_*`, to adapt `tcx.fn_abi_of_*(...)` into a
|
||||||
|
/// `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
|
||||||
|
/// `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>,
|
||||||
|
) -> <Self::FnAbiOfResult as MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>>::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blanket extension trait for contexts that can compute `FnAbi`s.
|
||||||
|
pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
||||||
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
|
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
|
||||||
///
|
///
|
||||||
/// NB: this doesn't handle virtual calls - those should use `FnAbi::of_instance`
|
/// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
|
||||||
/// instead, where the instance is an `InstanceDef::Virtual`.
|
/// instead, where the instance is an `InstanceDef::Virtual`.
|
||||||
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self;
|
#[inline]
|
||||||
|
fn fn_abi_of_fn_ptr(
|
||||||
|
&self,
|
||||||
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
|
extra_args: &[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() };
|
||||||
|
|
||||||
|
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 })
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
|
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
|
||||||
/// direct calls to an `fn`.
|
/// direct calls to an `fn`.
|
||||||
///
|
///
|
||||||
/// NB: that includes virtual calls, which are represented by "direct calls"
|
/// NB: that includes virtual calls, which are represented by "direct calls"
|
||||||
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
/// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
||||||
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self;
|
#[inline]
|
||||||
}
|
fn fn_abi_of_instance(
|
||||||
|
&self,
|
||||||
|
instance: ty::Instance<'tcx>,
|
||||||
|
extra_args: &[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() };
|
||||||
|
|
||||||
impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
|
|
||||||
where
|
|
||||||
C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
|
|
||||||
{
|
|
||||||
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self {
|
|
||||||
call::FnAbi::new_internal(
|
|
||||||
&LayoutCx { tcx: cx.tcx(), param_env: cx.param_env() },
|
|
||||||
sig,
|
|
||||||
extra_args,
|
|
||||||
None,
|
|
||||||
CodegenFnAttrFlags::empty(),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
// FIXME(eddyb) get a better `span` here.
|
|
||||||
let span = DUMMY_SP;
|
|
||||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
|
||||||
cx.tcx().sess.span_fatal(span, &err.to_string())
|
|
||||||
} else {
|
|
||||||
span_bug!(span, "`FnAbi::of_fn_ptr({}, {:?})` failed: {}", sig, extra_args, err);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> &'tcx Self {
|
|
||||||
let sig = instance.fn_sig_for_fn_abi(cx.tcx());
|
let sig = instance.fn_sig_for_fn_abi(cx.tcx());
|
||||||
|
|
||||||
let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
|
let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
|
||||||
Some(cx.tcx().caller_location_ty())
|
Some(cx.tcx.caller_location_ty())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags;
|
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id()).flags;
|
||||||
|
|
||||||
call::FnAbi::new_internal(
|
MaybeResult::from(
|
||||||
&LayoutCx { tcx: cx.tcx(), param_env: cx.param_env() },
|
cx.fn_abi_new_internal(
|
||||||
sig,
|
sig,
|
||||||
extra_args,
|
extra_args,
|
||||||
caller_location,
|
caller_location,
|
||||||
attrs,
|
attrs,
|
||||||
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
||||||
|
)
|
||||||
|
.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()) };
|
||||||
|
self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args })
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
// FIXME(eddyb) get a better `span` here.
|
|
||||||
let span = cx.tcx().def_span(instance.def_id());
|
|
||||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
|
||||||
cx.tcx().sess.span_fatal(span, &err.to_string())
|
|
||||||
} else {
|
|
||||||
span_bug!(
|
|
||||||
span,
|
|
||||||
"`FnAbi::of_instance({}, {:?})` failed: {}",
|
|
||||||
instance,
|
|
||||||
extra_args,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation detail of computing `FnAbi`s, shouldn't be exported.
|
impl<C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {}
|
||||||
// FIXME(eddyb) move this off of being generic on `C: LayoutOf`, and
|
|
||||||
// explicitly take `LayoutCx` *or* `TyCtxt` and `ParamEnvAnd<...>`.
|
impl<'tcx> LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
|
||||||
trait FnAbiInternalExt<'tcx, C>
|
|
||||||
where
|
|
||||||
C: LayoutOf<'tcx, LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>>
|
|
||||||
+ HasTargetSpec,
|
|
||||||
{
|
|
||||||
// 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 new_internal(
|
fn fn_abi_new_internal(
|
||||||
cx: &C,
|
&self,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
extra_args: &[Ty<'tcx>],
|
extra_args: &[Ty<'tcx>],
|
||||||
caller_location: Option<Ty<'tcx>>,
|
caller_location: Option<Ty<'tcx>>,
|
||||||
codegen_fn_attr_flags: CodegenFnAttrFlags,
|
codegen_fn_attr_flags: CodegenFnAttrFlags,
|
||||||
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
||||||
make_self_ptr_thin: bool,
|
|
||||||
) -> Result<&'tcx Self, FnAbiError<'tcx>>;
|
|
||||||
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, C> FnAbiInternalExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
|
|
||||||
where
|
|
||||||
C: LayoutOf<'tcx, LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>>
|
|
||||||
+ HasTargetSpec,
|
|
||||||
{
|
|
||||||
fn new_internal(
|
|
||||||
cx: &C,
|
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
|
||||||
extra_args: &[Ty<'tcx>],
|
|
||||||
caller_location: Option<Ty<'tcx>>,
|
|
||||||
codegen_fn_attr_flags: CodegenFnAttrFlags,
|
|
||||||
force_thin_self_ptr: bool,
|
force_thin_self_ptr: bool,
|
||||||
) -> Result<&'tcx Self, FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||||
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
|
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
|
||||||
|
|
||||||
let sig = cx.tcx().normalize_erasing_late_bound_regions(cx.param_env(), sig);
|
let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig);
|
||||||
|
|
||||||
let conv = conv_from_spec_abi(cx.tcx(), sig.abi);
|
let conv = conv_from_spec_abi(self.tcx(), sig.abi);
|
||||||
|
|
||||||
let mut inputs = sig.inputs();
|
let mut inputs = sig.inputs();
|
||||||
let extra_args = if sig.abi == RustCall {
|
let extra_args = if sig.abi == RustCall {
|
||||||
@ -2975,7 +2980,7 @@ where
|
|||||||
extra_args.to_vec()
|
extra_args.to_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = &cx.tcx().sess.target;
|
let target = &self.tcx.sess.target;
|
||||||
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
|
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
|
||||||
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
|
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
|
||||||
let linux_s390x_gnu_like =
|
let linux_s390x_gnu_like =
|
||||||
@ -3008,7 +3013,7 @@ where
|
|||||||
attrs.set(ArgAttribute::NonNull);
|
attrs.set(ArgAttribute::NonNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pointee) = layout.pointee_info_at(cx, offset) {
|
if let Some(pointee) = layout.pointee_info_at(self, offset) {
|
||||||
if let Some(kind) = pointee.safe {
|
if let Some(kind) = pointee.safe {
|
||||||
attrs.pointee_align = Some(pointee.align);
|
attrs.pointee_align = Some(pointee.align);
|
||||||
|
|
||||||
@ -3055,17 +3060,17 @@ where
|
|||||||
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
|
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
|
||||||
let is_return = arg_idx.is_none();
|
let is_return = arg_idx.is_none();
|
||||||
|
|
||||||
let layout = cx.layout_of(ty)?;
|
let layout = self.layout_of(ty)?;
|
||||||
let layout = if force_thin_self_ptr && arg_idx == Some(0) {
|
let layout = if force_thin_self_ptr && arg_idx == Some(0) {
|
||||||
// Don't pass the vtable, it's not an argument of the virtual fn.
|
// Don't pass the vtable, it's not an argument of the virtual fn.
|
||||||
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
|
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
|
||||||
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
|
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
|
||||||
make_thin_self_ptr(cx, layout)
|
make_thin_self_ptr(self, layout)
|
||||||
} else {
|
} else {
|
||||||
layout
|
layout
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| {
|
let mut arg = ArgAbi::new(self, layout, |layout, scalar, offset| {
|
||||||
let mut attrs = ArgAttributes::new();
|
let mut attrs = ArgAttributes::new();
|
||||||
adjust_for_rust_scalar(&mut attrs, scalar, *layout, offset, is_return);
|
adjust_for_rust_scalar(&mut attrs, scalar, *layout, offset, is_return);
|
||||||
attrs
|
attrs
|
||||||
@ -3102,14 +3107,18 @@ where
|
|||||||
c_variadic: sig.c_variadic,
|
c_variadic: sig.c_variadic,
|
||||||
fixed_count: inputs.len(),
|
fixed_count: inputs.len(),
|
||||||
conv,
|
conv,
|
||||||
can_unwind: fn_can_unwind(cx.tcx(), codegen_fn_attr_flags, sig.abi),
|
can_unwind: fn_can_unwind(self.tcx(), codegen_fn_attr_flags, sig.abi),
|
||||||
};
|
};
|
||||||
fn_abi.adjust_for_abi(cx, sig.abi)?;
|
self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?;
|
||||||
debug!("FnAbi::new_internal = {:?}", fn_abi);
|
debug!("FnAbi::new_internal = {:?}", fn_abi);
|
||||||
Ok(cx.tcx().intern_fn_abi(fn_abi))
|
Ok(self.tcx.intern_fn_abi(fn_abi))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) -> Result<(), FnAbiError<'tcx>> {
|
fn fn_abi_adjust_for_abi(
|
||||||
|
&self,
|
||||||
|
fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
|
||||||
|
abi: SpecAbi,
|
||||||
|
) -> Result<(), FnAbiError<'tcx>> {
|
||||||
if abi == SpecAbi::Unadjusted {
|
if abi == SpecAbi::Unadjusted {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -3148,7 +3157,7 @@ where
|
|||||||
// anyway, we control all calls to it in libstd.
|
// anyway, we control all calls to it in libstd.
|
||||||
Abi::Vector { .. }
|
Abi::Vector { .. }
|
||||||
if abi != SpecAbi::PlatformIntrinsic
|
if abi != SpecAbi::PlatformIntrinsic
|
||||||
&& cx.tcx().sess.target.simd_types_indirect =>
|
&& self.tcx.sess.target.simd_types_indirect =>
|
||||||
{
|
{
|
||||||
arg.make_indirect();
|
arg.make_indirect();
|
||||||
return;
|
return;
|
||||||
@ -3159,7 +3168,7 @@ where
|
|||||||
|
|
||||||
// Pass and return structures up to 2 pointers in size by value, matching `ScalarPair`.
|
// Pass and return structures up to 2 pointers in size by value, matching `ScalarPair`.
|
||||||
// LLVM will usually pass these in 2 registers, which is more efficient than by-ref.
|
// LLVM will usually pass these in 2 registers, which is more efficient than by-ref.
|
||||||
let max_by_val_size = Pointer.size(cx) * 2;
|
let max_by_val_size = Pointer.size(self) * 2;
|
||||||
let size = arg.layout.size;
|
let size = arg.layout.size;
|
||||||
|
|
||||||
if arg.layout.is_unsized() || size > max_by_val_size {
|
if arg.layout.is_unsized() || size > max_by_val_size {
|
||||||
@ -3171,12 +3180,12 @@ where
|
|||||||
arg.cast_to(Reg { kind: RegKind::Integer, size });
|
arg.cast_to(Reg { kind: RegKind::Integer, size });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fixup(&mut self.ret);
|
fixup(&mut fn_abi.ret);
|
||||||
for arg in &mut self.args {
|
for arg in &mut fn_abi.args {
|
||||||
fixup(arg);
|
fixup(arg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.adjust_for_foreign_abi(cx, abi)?;
|
fn_abi.adjust_for_foreign_abi(self, abi)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user