1use std::ops::Bound;
2use std::{cmp, fmt};
3
4use rustc_abi as abi;
5use rustc_abi::{
6 AddressSpace, Align, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData, PointeeInfo,
7 PointerKind, Primitive, ReprFlags, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout,
8 TyAbiInterface, VariantIdx, Variants,
9};
10use rustc_error_messages::DiagMessage;
11use rustc_errors::{
12 Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, msg,
13};
14use rustc_hir as hir;
15use rustc_hir::LangItem;
16use rustc_hir::def_id::DefId;
17use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension};
18use rustc_session::config::OptLevel;
19use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
20use rustc_target::callconv::FnAbi;
21use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
22use tracing::debug;
23
24use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
25use crate::query::TyCtxtAt;
26use crate::traits::ObligationCause;
27use crate::ty::normalize_erasing_regions::NormalizationError;
28use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};
29
30impl IntegerExt for abi::Integer {
#[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
use abi::Integer::{I8, I16, I32, I64, I128};
match (*self, signed) {
(I8, false) => tcx.types.u8,
(I16, false) => tcx.types.u16,
(I32, false) => tcx.types.u32,
(I64, false) => tcx.types.u64,
(I128, false) => tcx.types.u128,
(I8, true) => tcx.types.i8,
(I16, true) => tcx.types.i16,
(I32, true) => tcx.types.i32,
(I64, true) => tcx.types.i64,
(I128, true) => tcx.types.i128,
}
}
fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> abi::Integer {
use abi::Integer::{I8, I16, I32, I64, I128};
match ity {
ty::IntTy::I8 => I8,
ty::IntTy::I16 => I16,
ty::IntTy::I32 => I32,
ty::IntTy::I64 => I64,
ty::IntTy::I128 => I128,
ty::IntTy::Isize => cx.data_layout().ptr_sized_integer(),
}
}
fn from_uint_ty<C: HasDataLayout>(cx: &C, ity: ty::UintTy)
-> abi::Integer {
use abi::Integer::{I8, I16, I32, I64, I128};
match ity {
ty::UintTy::U8 => I8,
ty::UintTy::U16 => I16,
ty::UintTy::U32 => I32,
ty::UintTy::U64 => I64,
ty::UintTy::U128 => I128,
ty::UintTy::Usize => cx.data_layout().ptr_sized_integer(),
}
}
#[doc =
" Finds the appropriate Integer type and signedness for the given"]
#[doc = " signed discriminant range and `#[repr]` attribute."]
#[doc =
" N.B.: `u128` values above `i128::MAX` will be treated as signed, but"]
#[doc = " that shouldn\'t affect anything, other than maybe debuginfo."]
#[doc = ""]
#[doc =
" This is the basis for computing the type of the *tag* of an enum (which can be smaller than"]
#[doc =
" the type of the *discriminant*, which is determined by [`ReprOptions::discr_type`])."]
fn discr_range_of_repr<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>,
repr: &ReprOptions, min: i128, max: i128) -> (abi::Integer, bool) {
let unsigned_fit =
abi::Integer::fit_unsigned(cmp::max(min as u128, max as u128));
let signed_fit =
cmp::max(abi::Integer::fit_signed(min),
abi::Integer::fit_signed(max));
if let Some(ity) = repr.int {
let discr = abi::Integer::from_attr(&tcx, ity);
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
if discr < fit {
crate::util::bug::bug_fmt(format_args!("Integer::repr_discr: `#[repr]` hint too small for discriminant range of enum `{0}`",
ty))
}
return (discr, ity.is_signed());
}
let at_least =
if repr.c() {
tcx.data_layout().c_enum_min_size
} else { abi::Integer::I8 };
if unsigned_fit <= signed_fit {
(cmp::max(unsigned_fit, at_least), false)
} else { (cmp::max(signed_fit, at_least), true) }
}
}#[extension(pub trait IntegerExt)]
31impl abi::Integer {
32 #[inline]
33 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
34 use abi::Integer::{I8, I16, I32, I64, I128};
35 match (*self, signed) {
36 (I8, false) => tcx.types.u8,
37 (I16, false) => tcx.types.u16,
38 (I32, false) => tcx.types.u32,
39 (I64, false) => tcx.types.u64,
40 (I128, false) => tcx.types.u128,
41 (I8, true) => tcx.types.i8,
42 (I16, true) => tcx.types.i16,
43 (I32, true) => tcx.types.i32,
44 (I64, true) => tcx.types.i64,
45 (I128, true) => tcx.types.i128,
46 }
47 }
48
49 fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> abi::Integer {
50 use abi::Integer::{I8, I16, I32, I64, I128};
51 match ity {
52 ty::IntTy::I8 => I8,
53 ty::IntTy::I16 => I16,
54 ty::IntTy::I32 => I32,
55 ty::IntTy::I64 => I64,
56 ty::IntTy::I128 => I128,
57 ty::IntTy::Isize => cx.data_layout().ptr_sized_integer(),
58 }
59 }
60 fn from_uint_ty<C: HasDataLayout>(cx: &C, ity: ty::UintTy) -> abi::Integer {
61 use abi::Integer::{I8, I16, I32, I64, I128};
62 match ity {
63 ty::UintTy::U8 => I8,
64 ty::UintTy::U16 => I16,
65 ty::UintTy::U32 => I32,
66 ty::UintTy::U64 => I64,
67 ty::UintTy::U128 => I128,
68 ty::UintTy::Usize => cx.data_layout().ptr_sized_integer(),
69 }
70 }
71
72 fn discr_range_of_repr<'tcx>(
80 tcx: TyCtxt<'tcx>,
81 ty: Ty<'tcx>,
82 repr: &ReprOptions,
83 min: i128,
84 max: i128,
85 ) -> (abi::Integer, bool) {
86 let unsigned_fit = abi::Integer::fit_unsigned(cmp::max(min as u128, max as u128));
91 let signed_fit = cmp::max(abi::Integer::fit_signed(min), abi::Integer::fit_signed(max));
92
93 if let Some(ity) = repr.int {
94 let discr = abi::Integer::from_attr(&tcx, ity);
95 let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
96 if discr < fit {
97 bug!(
98 "Integer::repr_discr: `#[repr]` hint too small for \
99 discriminant range of enum `{}`",
100 ty
101 )
102 }
103 return (discr, ity.is_signed());
104 }
105
106 let at_least = if repr.c() {
107 tcx.data_layout().c_enum_min_size
110 } else {
111 abi::Integer::I8
113 };
114
115 if unsigned_fit <= signed_fit {
118 (cmp::max(unsigned_fit, at_least), false)
119 } else {
120 (cmp::max(signed_fit, at_least), true)
121 }
122 }
123}
124
125impl FloatExt for abi::Float {
#[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
use abi::Float::*;
match *self {
F16 => tcx.types.f16,
F32 => tcx.types.f32,
F64 => tcx.types.f64,
F128 => tcx.types.f128,
}
}
fn from_float_ty(fty: ty::FloatTy) -> Self {
use abi::Float::*;
match fty {
ty::FloatTy::F16 => F16,
ty::FloatTy::F32 => F32,
ty::FloatTy::F64 => F64,
ty::FloatTy::F128 => F128,
}
}
}#[extension(pub trait FloatExt)]
126impl abi::Float {
127 #[inline]
128 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
129 use abi::Float::*;
130 match *self {
131 F16 => tcx.types.f16,
132 F32 => tcx.types.f32,
133 F64 => tcx.types.f64,
134 F128 => tcx.types.f128,
135 }
136 }
137
138 fn from_float_ty(fty: ty::FloatTy) -> Self {
139 use abi::Float::*;
140 match fty {
141 ty::FloatTy::F16 => F16,
142 ty::FloatTy::F32 => F32,
143 ty::FloatTy::F64 => F64,
144 ty::FloatTy::F128 => F128,
145 }
146 }
147}
148
149impl PrimitiveExt for Primitive {
#[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
Primitive::Int(i, signed) => i.to_ty(tcx, signed),
Primitive::Float(f) => f.to_ty(tcx),
Primitive::Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit),
}
}
#[doc = " Return an *integer* type matching this primitive."]
#[doc = " Useful in particular when dealing with enum discriminants."]
#[inline]
fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
Primitive::Int(i, signed) => i.to_ty(tcx, signed),
Primitive::Pointer(_) => {
let signed = false;
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
}
Primitive::Float(_) =>
crate::util::bug::bug_fmt(format_args!("floats do not have an int type")),
}
}
}#[extension(pub trait PrimitiveExt)]
150impl Primitive {
151 #[inline]
152 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
153 match *self {
154 Primitive::Int(i, signed) => i.to_ty(tcx, signed),
155 Primitive::Float(f) => f.to_ty(tcx),
156 Primitive::Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit),
158 }
159 }
160
161 #[inline]
164 fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
165 match *self {
166 Primitive::Int(i, signed) => i.to_ty(tcx, signed),
167 Primitive::Pointer(_) => {
169 let signed = false;
170 tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
171 }
172 Primitive::Float(_) => bug!("floats do not have an int type"),
173 }
174 }
175}
176
177pub const WIDE_PTR_ADDR: usize = 0;
182
183pub const WIDE_PTR_EXTRA: usize = 1;
188
189pub const MAX_SIMD_LANES: u64 = rustc_abi::MAX_SIMD_LANES;
190
191#[derive(#[automatically_derived]
impl ::core::marker::Copy for ValidityRequirement { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ValidityRequirement {
#[inline]
fn clone(&self) -> ValidityRequirement { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ValidityRequirement {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ValidityRequirement::Inhabited => "Inhabited",
ValidityRequirement::Zero => "Zero",
ValidityRequirement::UninitMitigated0x01Fill =>
"UninitMitigated0x01Fill",
ValidityRequirement::Uninit => "Uninit",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ValidityRequirement {
#[inline]
fn eq(&self, other: &ValidityRequirement) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ValidityRequirement {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for ValidityRequirement {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for ValidityRequirement {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
ValidityRequirement::Inhabited => {}
ValidityRequirement::Zero => {}
ValidityRequirement::UninitMitigated0x01Fill => {}
ValidityRequirement::Uninit => {}
}
}
}
};HashStable)]
194pub enum ValidityRequirement {
195 Inhabited,
196 Zero,
197 UninitMitigated0x01Fill,
200 Uninit,
202}
203
204impl ValidityRequirement {
205 pub fn from_intrinsic(intrinsic: Symbol) -> Option<Self> {
206 match intrinsic {
207 sym::assert_inhabited => Some(Self::Inhabited),
208 sym::assert_zero_valid => Some(Self::Zero),
209 sym::assert_mem_uninitialized_valid => Some(Self::UninitMitigated0x01Fill),
210 _ => None,
211 }
212 }
213}
214
215impl fmt::Display for ValidityRequirement {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 match self {
218 Self::Inhabited => f.write_str("is inhabited"),
219 Self::Zero => f.write_str("allows being left zeroed"),
220 Self::UninitMitigated0x01Fill => f.write_str("allows being filled with 0x01"),
221 Self::Uninit => f.write_str("allows being left uninitialized"),
222 }
223 }
224}
225
226#[derive(#[automatically_derived]
impl ::core::marker::Copy for SimdLayoutError { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SimdLayoutError {
#[inline]
fn clone(&self) -> SimdLayoutError {
let _: ::core::clone::AssertParamIsClone<u64>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SimdLayoutError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SimdLayoutError::ZeroLength =>
::core::fmt::Formatter::write_str(f, "ZeroLength"),
SimdLayoutError::TooManyLanes(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"TooManyLanes", &__self_0),
}
}
}Debug, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for SimdLayoutError {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
SimdLayoutError::ZeroLength => {}
SimdLayoutError::TooManyLanes(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for SimdLayoutError {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
SimdLayoutError::ZeroLength => { 0usize }
SimdLayoutError::TooManyLanes(ref __binding_0) => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
SimdLayoutError::ZeroLength => {}
SimdLayoutError::TooManyLanes(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for SimdLayoutError {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { SimdLayoutError::ZeroLength }
1usize => {
SimdLayoutError::TooManyLanes(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SimdLayoutError`, expected 0..2, actual {0}",
n));
}
}
}
}
};TyDecodable)]
227pub enum SimdLayoutError {
228 ZeroLength,
230 TooManyLanes(u64),
233}
234
235#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for LayoutError<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for LayoutError<'tcx> {
#[inline]
fn clone(&self) -> LayoutError<'tcx> {
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<SimdLayoutError>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<NormalizationError<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ErrorGuaranteed>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for LayoutError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
LayoutError::Unknown(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Unknown", &__self_0),
LayoutError::SizeOverflow(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"SizeOverflow", &__self_0),
LayoutError::InvalidSimd { ty: __self_0, kind: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"InvalidSimd", "ty", __self_0, "kind", &__self_1),
LayoutError::TooGeneric(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"TooGeneric", &__self_0),
LayoutError::NormalizationFailure(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"NormalizationFailure", __self_0, &__self_1),
LayoutError::ReferencesError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ReferencesError", &__self_0),
LayoutError::Cycle(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Cycle",
&__self_0),
}
}
}Debug, const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for LayoutError<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
LayoutError::Unknown(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
LayoutError::SizeOverflow(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
LayoutError::InvalidSimd {
ty: ref __binding_0, kind: ref __binding_1 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
LayoutError::TooGeneric(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
LayoutError::NormalizationFailure(ref __binding_0,
ref __binding_1) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
LayoutError::ReferencesError(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
LayoutError::Cycle(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for LayoutError<'tcx> {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
LayoutError::Unknown(ref __binding_0) => { 0usize }
LayoutError::SizeOverflow(ref __binding_0) => { 1usize }
LayoutError::InvalidSimd {
ty: ref __binding_0, kind: ref __binding_1 } => {
2usize
}
LayoutError::TooGeneric(ref __binding_0) => { 3usize }
LayoutError::NormalizationFailure(ref __binding_0,
ref __binding_1) => {
4usize
}
LayoutError::ReferencesError(ref __binding_0) => { 5usize }
LayoutError::Cycle(ref __binding_0) => { 6usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
LayoutError::Unknown(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
LayoutError::SizeOverflow(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
LayoutError::InvalidSimd {
ty: ref __binding_0, kind: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
LayoutError::TooGeneric(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
LayoutError::NormalizationFailure(ref __binding_0,
ref __binding_1) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
LayoutError::ReferencesError(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
LayoutError::Cycle(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for LayoutError<'tcx> {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
LayoutError::Unknown(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
LayoutError::SizeOverflow(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => {
LayoutError::InvalidSimd {
ty: ::rustc_serialize::Decodable::decode(__decoder),
kind: ::rustc_serialize::Decodable::decode(__decoder),
}
}
3usize => {
LayoutError::TooGeneric(::rustc_serialize::Decodable::decode(__decoder))
}
4usize => {
LayoutError::NormalizationFailure(::rustc_serialize::Decodable::decode(__decoder),
::rustc_serialize::Decodable::decode(__decoder))
}
5usize => {
LayoutError::ReferencesError(::rustc_serialize::Decodable::decode(__decoder))
}
6usize => {
LayoutError::Cycle(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `LayoutError`, expected 0..7, actual {0}",
n));
}
}
}
}
};TyDecodable)]
236pub enum LayoutError<'tcx> {
237 Unknown(Ty<'tcx>),
245 SizeOverflow(Ty<'tcx>),
247 InvalidSimd { ty: Ty<'tcx>, kind: SimdLayoutError },
249 TooGeneric(Ty<'tcx>),
254 NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
262 ReferencesError(ErrorGuaranteed),
264 Cycle(ErrorGuaranteed),
266}
267
268impl<'tcx> LayoutError<'tcx> {
269 pub fn diagnostic_message(&self) -> DiagMessage {
270 use LayoutError::*;
271
272 match self {
273 Unknown(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the type `{$ty}` has an unknown layout"))msg!("the type `{$ty}` has an unknown layout"),
274 SizeOverflow(_) => {
275 rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("values of the type `{$ty}` are too big for the target architecture"))msg!("values of the type `{$ty}` are too big for the target architecture")
276 }
277 InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
278 rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the SIMD type `{$ty}` has more elements than the limit {$max_lanes}"))msg!("the SIMD type `{$ty}` has more elements than the limit {$max_lanes}")
279 }
280 InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => {
281 rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the SIMD type `{$ty}` has zero elements"))msg!("the SIMD type `{$ty}` has zero elements")
282 }
283 TooGeneric(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the type `{$ty}` does not have a fixed layout"))msg!("the type `{$ty}` does not have a fixed layout"),
284 NormalizationFailure(_, _) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized"))msg!(
285 "unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized"
286 ),
287 Cycle(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("a cycle occurred during layout computation"))msg!("a cycle occurred during layout computation"),
288 ReferencesError(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the type has an unknown layout"))msg!("the type has an unknown layout"),
289 }
290 }
291
292 pub fn into_diagnostic(self) -> crate::error::LayoutError<'tcx> {
293 use LayoutError::*;
294
295 use crate::error::LayoutError as E;
296 match self {
297 Unknown(ty) => E::Unknown { ty },
298 SizeOverflow(ty) => E::Overflow { ty },
299 InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
300 E::SimdTooManyLanes { ty, max_lanes }
301 }
302 InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => E::SimdZeroLength { ty },
303 TooGeneric(ty) => E::TooGeneric { ty },
304 NormalizationFailure(ty, e) => {
305 E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
306 }
307 Cycle(_) => E::Cycle,
308 ReferencesError(_) => E::ReferencesError,
309 }
310 }
311}
312
313impl<'tcx> fmt::Display for LayoutError<'tcx> {
316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317 match *self {
318 LayoutError::Unknown(ty) => f.write_fmt(format_args!("the type `{0}` has an unknown layout", ty))write!(f, "the type `{ty}` has an unknown layout"),
319 LayoutError::TooGeneric(ty) => {
320 f.write_fmt(format_args!("the type `{0}` does not have a fixed layout", ty))write!(f, "the type `{ty}` does not have a fixed layout")
321 }
322 LayoutError::SizeOverflow(ty) => {
323 f.write_fmt(format_args!("values of the type `{0}` are too big for the target architecture",
ty))write!(f, "values of the type `{ty}` are too big for the target architecture")
324 }
325 LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
326 f.write_fmt(format_args!("the SIMD type `{0}` has more elements than the limit {1}",
ty, max_lanes))write!(f, "the SIMD type `{ty}` has more elements than the limit {max_lanes}")
327 }
328 LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => {
329 f.write_fmt(format_args!("the SIMD type `{0}` has zero elements", ty))write!(f, "the SIMD type `{ty}` has zero elements")
330 }
331 LayoutError::NormalizationFailure(t, e) => f.write_fmt(format_args!("unable to determine layout for `{0}` because `{1}` cannot be normalized",
t, e.get_type_for_failure()))write!(
332 f,
333 "unable to determine layout for `{}` because `{}` cannot be normalized",
334 t,
335 e.get_type_for_failure()
336 ),
337 LayoutError::Cycle(_) => f.write_fmt(format_args!("a cycle occurred during layout computation"))write!(f, "a cycle occurred during layout computation"),
338 LayoutError::ReferencesError(_) => f.write_fmt(format_args!("the type has an unknown layout"))write!(f, "the type has an unknown layout"),
339 }
340 }
341}
342
343impl<'tcx> IntoDiagArg for LayoutError<'tcx> {
344 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
345 self.to_string().into_diag_arg(&mut None)
346 }
347}
348
349#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for LayoutCx<'tcx> {
#[inline]
fn clone(&self) -> LayoutCx<'tcx> {
let _:
::core::clone::AssertParamIsClone<abi::LayoutCalculator<TyCtxt<'tcx>>>;
let _: ::core::clone::AssertParamIsClone<ty::TypingEnv<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for LayoutCx<'tcx> { }Copy)]
350pub struct LayoutCx<'tcx> {
351 pub calc: abi::LayoutCalculator<TyCtxt<'tcx>>,
352 pub typing_env: ty::TypingEnv<'tcx>,
353}
354
355impl<'tcx> LayoutCx<'tcx> {
356 pub fn new(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Self {
357 Self { calc: abi::LayoutCalculator::new(tcx), typing_env }
358 }
359}
360
361#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for SizeSkeleton<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for SizeSkeleton<'tcx> {
#[inline]
fn clone(&self) -> SizeSkeleton<'tcx> {
let _: ::core::clone::AssertParamIsClone<Size>;
let _: ::core::clone::AssertParamIsClone<Option<Align>>;
let _: ::core::clone::AssertParamIsClone<ty::Const<'tcx>>;
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for SizeSkeleton<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SizeSkeleton::Known(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f, "Known",
__self_0, &__self_1),
SizeSkeleton::Generic(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Generic", &__self_0),
SizeSkeleton::Pointer { non_zero: __self_0, tail: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Pointer", "non_zero", __self_0, "tail", &__self_1),
}
}
}Debug)]
366pub enum SizeSkeleton<'tcx> {
367 Known(Size, Option<Align>),
370
371 Generic(ty::Const<'tcx>),
376
377 Pointer {
379 non_zero: bool,
381 tail: Ty<'tcx>,
385 },
386}
387
388impl<'tcx> SizeSkeleton<'tcx> {
389 pub fn compute(
390 ty: Ty<'tcx>,
391 tcx: TyCtxt<'tcx>,
392 typing_env: ty::TypingEnv<'tcx>,
393 ) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
394 if true {
if !!ty.has_non_region_infer() {
::core::panicking::panic("assertion failed: !ty.has_non_region_infer()")
};
};debug_assert!(!ty.has_non_region_infer());
395
396 let err = match tcx.layout_of(typing_env.as_query_input(ty)) {
398 Ok(layout) => {
399 if layout.is_sized() {
400 return Ok(SizeSkeleton::Known(layout.size, Some(layout.align.abi)));
401 } else {
402 return Err(tcx.arena.alloc(LayoutError::Unknown(ty)));
404 }
405 }
406 Err(err @ LayoutError::TooGeneric(_)) => err,
407 Err(
409 e @ LayoutError::Cycle(_)
410 | e @ LayoutError::Unknown(_)
411 | e @ LayoutError::SizeOverflow(_)
412 | e @ LayoutError::InvalidSimd { .. }
413 | e @ LayoutError::NormalizationFailure(..)
414 | e @ LayoutError::ReferencesError(_),
415 ) => return Err(e),
416 };
417
418 match *ty.kind() {
419 ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
420 let non_zero = !ty.is_raw_ptr();
421
422 let tail = tcx.struct_tail_raw(
423 pointee,
424 &ObligationCause::dummy(),
425 |ty| match tcx.try_normalize_erasing_regions(typing_env, ty) {
426 Ok(ty) => ty,
427 Err(e) => Ty::new_error_with_message(
428 tcx,
429 DUMMY_SP,
430 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("normalization failed for {0} but no errors reported",
e.get_type_for_failure()))
})format!(
431 "normalization failed for {} but no errors reported",
432 e.get_type_for_failure()
433 ),
434 ),
435 },
436 || {},
437 );
438
439 match tail.kind() {
440 ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => {
441 if true {
if !tail.has_non_region_param() {
::core::panicking::panic("assertion failed: tail.has_non_region_param()")
};
};debug_assert!(tail.has_non_region_param());
442 Ok(SizeSkeleton::Pointer {
443 non_zero,
444 tail: tcx.erase_and_anonymize_regions(tail),
445 })
446 }
447 ty::Error(guar) => {
448 return Err(tcx.arena.alloc(LayoutError::ReferencesError(*guar)));
450 }
451 _ => crate::util::bug::bug_fmt(format_args!("SizeSkeleton::compute({0}): layout errored ({1:?}), yet tail `{2}` is not a type parameter or a projection",
ty, err, tail))bug!(
452 "SizeSkeleton::compute({ty}): layout errored ({err:?}), yet \
453 tail `{tail}` is not a type parameter or a projection",
454 ),
455 }
456 }
457 ty::Array(inner, len) if tcx.features().transmute_generic_consts() => {
458 let len_eval = len.try_to_target_usize(tcx);
459 if len_eval == Some(0) {
460 return Ok(SizeSkeleton::Known(Size::from_bytes(0), None));
461 }
462
463 match SizeSkeleton::compute(inner, tcx, typing_env)? {
464 SizeSkeleton::Known(s, a) => {
467 if let Some(c) = len_eval {
468 let size = s
469 .bytes()
470 .checked_mul(c)
471 .ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
472 return Ok(SizeSkeleton::Known(Size::from_bytes(size), a));
474 }
475 Err(err)
476 }
477 SizeSkeleton::Pointer { .. } | SizeSkeleton::Generic(_) => Err(err),
478 }
479 }
480
481 ty::Adt(def, args) => {
482 if def.is_union() || def.variants().is_empty() || def.variants().len() > 2 {
484 return Err(err);
485 }
486
487 let zero_or_ptr_variant = |i| {
489 let i = VariantIdx::from_usize(i);
490 let fields =
491 def.variant(i).fields.iter().map(|field| {
492 SizeSkeleton::compute(field.ty(tcx, args), tcx, typing_env)
493 });
494 let mut ptr = None;
495 for field in fields {
496 let field = field?;
497 match field {
498 SizeSkeleton::Known(size, align) => {
499 let is_1zst = size.bytes() == 0
500 && align.is_some_and(|align| align.bytes() == 1);
501 if !is_1zst {
502 return Err(err);
503 }
504 }
505 SizeSkeleton::Pointer { .. } => {
506 if ptr.is_some() {
507 return Err(err);
508 }
509 ptr = Some(field);
510 }
511 SizeSkeleton::Generic(_) => {
512 return Err(err);
513 }
514 }
515 }
516 Ok(ptr)
517 };
518
519 let v0 = zero_or_ptr_variant(0)?;
520 if def.variants().len() == 1 {
522 if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
523 return Ok(SizeSkeleton::Pointer {
524 non_zero: non_zero
525 || match tcx.layout_scalar_valid_range(def.did()) {
526 (Bound::Included(start), Bound::Unbounded) => start > 0,
527 (Bound::Included(start), Bound::Included(end)) => {
528 0 < start && start < end
529 }
530 _ => false,
531 },
532 tail,
533 });
534 } else {
535 return Err(err);
536 }
537 }
538
539 let v1 = zero_or_ptr_variant(1)?;
540 match (v0, v1) {
542 (Some(SizeSkeleton::Pointer { non_zero: true, tail }), None)
543 | (None, Some(SizeSkeleton::Pointer { non_zero: true, tail })) => {
544 Ok(SizeSkeleton::Pointer { non_zero: false, tail })
545 }
546 _ => Err(err),
547 }
548 }
549
550 ty::Alias(..) => {
551 let normalized = tcx.normalize_erasing_regions(typing_env, ty);
552 if ty == normalized {
553 Err(err)
554 } else {
555 SizeSkeleton::compute(normalized, tcx, typing_env)
556 }
557 }
558
559 ty::Pat(base, _) => SizeSkeleton::compute(base, tcx, typing_env),
561
562 _ => Err(err),
563 }
564 }
565
566 pub fn same_size(self, other: SizeSkeleton<'tcx>) -> bool {
567 match (self, other) {
568 (SizeSkeleton::Known(a, _), SizeSkeleton::Known(b, _)) => a == b,
569 (SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => {
570 a == b
571 }
572 (SizeSkeleton::Generic(a), SizeSkeleton::Generic(b)) => a == b,
575 _ => false,
576 }
577 }
578}
579
580pub trait HasTyCtxt<'tcx>: HasDataLayout {
581 fn tcx(&self) -> TyCtxt<'tcx>;
582}
583
584pub trait HasTypingEnv<'tcx> {
585 fn typing_env(&self) -> ty::TypingEnv<'tcx>;
586
587 fn param_env(&self) -> ty::ParamEnv<'tcx> {
590 self.typing_env().param_env
591 }
592}
593
594impl<'tcx> HasDataLayout for TyCtxt<'tcx> {
595 #[inline]
596 fn data_layout(&self) -> &TargetDataLayout {
597 &self.data_layout
598 }
599}
600
601impl<'tcx> HasTargetSpec for TyCtxt<'tcx> {
602 fn target_spec(&self) -> &Target {
603 &self.sess.target
604 }
605}
606
607impl<'tcx> HasX86AbiOpt for TyCtxt<'tcx> {
608 fn x86_abi_opt(&self) -> X86Abi {
609 X86Abi {
610 regparm: self.sess.opts.unstable_opts.regparm,
611 reg_struct_return: self.sess.opts.unstable_opts.reg_struct_return,
612 }
613 }
614}
615
616impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
617 #[inline]
618 fn tcx(&self) -> TyCtxt<'tcx> {
619 *self
620 }
621}
622
623impl<'tcx> HasDataLayout for TyCtxtAt<'tcx> {
624 #[inline]
625 fn data_layout(&self) -> &TargetDataLayout {
626 &self.data_layout
627 }
628}
629
630impl<'tcx> HasTargetSpec for TyCtxtAt<'tcx> {
631 fn target_spec(&self) -> &Target {
632 &self.sess.target
633 }
634}
635
636impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> {
637 #[inline]
638 fn tcx(&self) -> TyCtxt<'tcx> {
639 **self
640 }
641}
642
643impl<'tcx> HasTypingEnv<'tcx> for LayoutCx<'tcx> {
644 fn typing_env(&self) -> ty::TypingEnv<'tcx> {
645 self.typing_env
646 }
647}
648
649impl<'tcx> HasDataLayout for LayoutCx<'tcx> {
650 fn data_layout(&self) -> &TargetDataLayout {
651 self.calc.cx.data_layout()
652 }
653}
654
655impl<'tcx> HasTargetSpec for LayoutCx<'tcx> {
656 fn target_spec(&self) -> &Target {
657 self.calc.cx.target_spec()
658 }
659}
660
661impl<'tcx> HasX86AbiOpt for LayoutCx<'tcx> {
662 fn x86_abi_opt(&self) -> X86Abi {
663 self.calc.cx.x86_abi_opt()
664 }
665}
666
667impl<'tcx> HasTyCtxt<'tcx> for LayoutCx<'tcx> {
668 fn tcx(&self) -> TyCtxt<'tcx> {
669 self.calc.cx
670 }
671}
672
673pub trait MaybeResult<T> {
674 type Error;
675
676 fn from(x: Result<T, Self::Error>) -> Self;
677 fn to_result(self) -> Result<T, Self::Error>;
678}
679
680impl<T> MaybeResult<T> for T {
681 type Error = !;
682
683 fn from(Ok(x): Result<T, Self::Error>) -> Self {
684 x
685 }
686 fn to_result(self) -> Result<T, Self::Error> {
687 Ok(self)
688 }
689}
690
691impl<T, E> MaybeResult<T> for Result<T, E> {
692 type Error = E;
693
694 fn from(x: Result<T, Self::Error>) -> Self {
695 x
696 }
697 fn to_result(self) -> Result<T, Self::Error> {
698 self
699 }
700}
701
702pub type TyAndLayout<'tcx> = rustc_abi::TyAndLayout<'tcx, Ty<'tcx>>;
703
704pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> {
707 type LayoutOfResult: MaybeResult<TyAndLayout<'tcx>> = TyAndLayout<'tcx>;
710
711 #[inline]
714 fn layout_tcx_at_span(&self) -> Span {
715 DUMMY_SP
716 }
717
718 fn handle_layout_err(
726 &self,
727 err: LayoutError<'tcx>,
728 span: Span,
729 ty: Ty<'tcx>,
730 ) -> <Self::LayoutOfResult as MaybeResult<TyAndLayout<'tcx>>>::Error;
731}
732
733pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
735 #[inline]
738 fn layout_of(&self, ty: Ty<'tcx>) -> Self::LayoutOfResult {
739 self.spanned_layout_of(ty, DUMMY_SP)
740 }
741
742 #[inline]
747 fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::LayoutOfResult {
748 let span = if !span.is_dummy() { span } else { self.layout_tcx_at_span() };
749 let tcx = self.tcx().at(span);
750
751 MaybeResult::from(
752 tcx.layout_of(self.typing_env().as_query_input(ty))
753 .map_err(|err| self.handle_layout_err(*err, span, ty)),
754 )
755 }
756}
757
758impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {}
759
760impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx> {
761 type LayoutOfResult = Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>;
762
763 #[inline]
764 fn handle_layout_err(
765 &self,
766 err: LayoutError<'tcx>,
767 _: Span,
768 _: Ty<'tcx>,
769 ) -> &'tcx LayoutError<'tcx> {
770 self.tcx().arena.alloc(err)
771 }
772}
773
774impl<'tcx, C> TyAbiInterface<'tcx, C> for Ty<'tcx>
775where
776 C: HasTyCtxt<'tcx> + HasTypingEnv<'tcx>,
777{
778 fn ty_and_layout_for_variant(
779 this: TyAndLayout<'tcx>,
780 cx: &C,
781 variant_index: VariantIdx,
782 ) -> TyAndLayout<'tcx> {
783 let layout = match this.variants {
784 Variants::Single { index } if index == variant_index => {
786 return this;
787 }
788
789 Variants::Single { .. } | Variants::Empty => {
790 let tcx = cx.tcx();
795 let typing_env = cx.typing_env();
796
797 if let Ok(original_layout) = tcx.layout_of(typing_env.as_query_input(this.ty)) {
799 match (&original_layout.variants, &this.variants) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(original_layout.variants, this.variants);
800 }
801
802 let fields = match this.ty.kind() {
803 ty::Adt(def, _) if def.variants().is_empty() => {
804 crate::util::bug::bug_fmt(format_args!("for_variant called on zero-variant enum {0}",
this.ty))bug!("for_variant called on zero-variant enum {}", this.ty)
805 }
806 ty::Adt(def, _) => def.variant(variant_index).fields.len(),
807 _ => crate::util::bug::bug_fmt(format_args!("`ty_and_layout_for_variant` on unexpected type {0}",
this.ty))bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty),
808 };
809 tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields))
810 }
811
812 Variants::Multiple { ref variants, .. } => {
813 cx.tcx().mk_layout(variants[variant_index].clone())
814 }
815 };
816
817 match (&*layout.variants(), &Variants::Single { index: variant_index }) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
818
819 TyAndLayout { ty: this.ty, layout }
820 }
821
822 fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> {
823 enum TyMaybeWithLayout<'tcx> {
824 Ty(Ty<'tcx>),
825 TyAndLayout(TyAndLayout<'tcx>),
826 }
827
828 fn field_ty_or_layout<'tcx>(
829 this: TyAndLayout<'tcx>,
830 cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>),
831 i: usize,
832 ) -> TyMaybeWithLayout<'tcx> {
833 let tcx = cx.tcx();
834 let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
835 TyAndLayout {
836 layout: tcx.mk_layout(LayoutData::scalar(cx, tag)),
837 ty: tag.primitive().to_ty(tcx),
838 }
839 };
840
841 match *this.ty.kind() {
842 ty::Bool
843 | ty::Char
844 | ty::Int(_)
845 | ty::Uint(_)
846 | ty::Float(_)
847 | ty::FnPtr(..)
848 | ty::Never
849 | ty::FnDef(..)
850 | ty::CoroutineWitness(..)
851 | ty::Foreign(..)
852 | ty::Dynamic(_, _) => {
853 crate::util::bug::bug_fmt(format_args!("TyAndLayout::field({0:?}): not applicable",
this))bug!("TyAndLayout::field({:?}): not applicable", this)
854 }
855
856 ty::Pat(base, _) => {
857 match (&i, &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(i, 0);
858 TyMaybeWithLayout::Ty(base)
859 }
860
861 ty::UnsafeBinder(bound_ty) => {
862 let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
863 field_ty_or_layout(TyAndLayout { ty, ..this }, cx, i)
864 }
865
866 ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
868 if !(i < this.fields.count()) {
::core::panicking::panic("assertion failed: i < this.fields.count()")
};assert!(i < this.fields.count());
869
870 if i == 0 {
875 let nil = tcx.types.unit;
876 let unit_ptr_ty = if this.ty.is_raw_ptr() {
877 Ty::new_mut_ptr(tcx, nil)
878 } else {
879 Ty::new_mut_ref(tcx, tcx.lifetimes.re_static, nil)
880 };
881
882 let typing_env = ty::TypingEnv::fully_monomorphized();
886 return TyMaybeWithLayout::TyAndLayout(TyAndLayout {
887 ty: this.ty,
888 ..tcx.layout_of(typing_env.as_query_input(unit_ptr_ty)).unwrap()
889 });
890 }
891
892 let mk_dyn_vtable = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
893 let min_count = ty::vtable_min_entries(
894 tcx,
895 principal.map(|principal| {
896 tcx.instantiate_bound_regions_with_erased(principal)
897 }),
898 );
899 Ty::new_imm_ref(
900 tcx,
901 tcx.lifetimes.re_static,
902 Ty::new_array(tcx, tcx.types.usize, min_count.try_into().unwrap()),
904 )
905 };
906
907 let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type()
908 && !pointee.references_error()
911 {
912 let metadata = tcx.normalize_erasing_regions(
913 cx.typing_env(),
914 Ty::new_projection(tcx, metadata_def_id, [pointee]),
915 );
916
917 if let ty::Adt(def, args) = metadata.kind()
922 && tcx.is_lang_item(def.did(), LangItem::DynMetadata)
923 && let ty::Dynamic(data, _) = args.type_at(0).kind()
924 {
925 mk_dyn_vtable(data.principal())
926 } else {
927 metadata
928 }
929 } else {
930 match tcx.struct_tail_for_codegen(pointee, cx.typing_env()).kind() {
931 ty::Slice(_) | ty::Str => tcx.types.usize,
932 ty::Dynamic(data, _) => mk_dyn_vtable(data.principal()),
933 _ => crate::util::bug::bug_fmt(format_args!("TyAndLayout::field({0:?}): not applicable",
this))bug!("TyAndLayout::field({:?}): not applicable", this),
934 }
935 };
936
937 TyMaybeWithLayout::Ty(metadata)
938 }
939
940 ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element),
942 ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
943
944 ty::Closure(_, args) => field_ty_or_layout(
946 TyAndLayout { ty: args.as_closure().tupled_upvars_ty(), ..this },
947 cx,
948 i,
949 ),
950
951 ty::CoroutineClosure(_, args) => field_ty_or_layout(
952 TyAndLayout { ty: args.as_coroutine_closure().tupled_upvars_ty(), ..this },
953 cx,
954 i,
955 ),
956
957 ty::Coroutine(def_id, args) => match this.variants {
958 Variants::Empty => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
959 Variants::Single { index } => TyMaybeWithLayout::Ty(
960 args.as_coroutine()
961 .state_tys(def_id, tcx)
962 .nth(index.as_usize())
963 .unwrap()
964 .nth(i)
965 .unwrap(),
966 ),
967 Variants::Multiple { tag, tag_field, .. } => {
968 if FieldIdx::from_usize(i) == tag_field {
969 return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
970 }
971 TyMaybeWithLayout::Ty(args.as_coroutine().prefix_tys()[i])
972 }
973 },
974
975 ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i]),
976
977 ty::Adt(def, args) => {
979 match this.variants {
980 Variants::Single { index } => {
981 let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
982 TyMaybeWithLayout::Ty(field.ty(tcx, args))
983 }
984 Variants::Empty => {
::core::panicking::panic_fmt(format_args!("there is no field in Variants::Empty types"));
}panic!("there is no field in Variants::Empty types"),
985
986 Variants::Multiple { tag, .. } => {
988 match (&i, &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(i, 0);
989 return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
990 }
991 }
992 }
993
994 ty::Alias(..)
995 | ty::Bound(..)
996 | ty::Placeholder(..)
997 | ty::Param(_)
998 | ty::Infer(_)
999 | ty::Error(_) => crate::util::bug::bug_fmt(format_args!("TyAndLayout::field: unexpected type `{0}`",
this.ty))bug!("TyAndLayout::field: unexpected type `{}`", this.ty),
1000 }
1001 }
1002
1003 match field_ty_or_layout(this, cx, i) {
1004 TyMaybeWithLayout::Ty(field_ty) => {
1005 cx.tcx().layout_of(cx.typing_env().as_query_input(field_ty)).unwrap_or_else(|e| {
1006 crate::util::bug::bug_fmt(format_args!("failed to get layout for `{0}`: {1:?},\ndespite it being a field (#{2}) of an existing layout: {3:#?}",
field_ty, e, i, this))bug!(
1007 "failed to get layout for `{field_ty}`: {e:?},\n\
1008 despite it being a field (#{i}) of an existing layout: {this:#?}",
1009 )
1010 })
1011 }
1012 TyMaybeWithLayout::TyAndLayout(field_layout) => field_layout,
1013 }
1014 }
1015
1016 fn ty_and_layout_pointee_info_at(
1019 this: TyAndLayout<'tcx>,
1020 cx: &C,
1021 offset: Size,
1022 ) -> Option<PointeeInfo> {
1023 let tcx = cx.tcx();
1024 let typing_env = cx.typing_env();
1025
1026 let optimize = tcx.sess.opts.optimize != OptLevel::No;
1030
1031 let pointee_info = match *this.ty.kind() {
1032 ty::RawPtr(_, _) | ty::FnPtr(..) if offset.bytes() == 0 => {
1033 Some(PointeeInfo { safe: None, size: Size::ZERO, align: Align::ONE })
1034 }
1035 ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
1036 tcx.layout_of(typing_env.as_query_input(ty)).ok().map(|layout| {
1037 let (size, kind);
1038 match mt {
1039 hir::Mutability::Not => {
1040 let frozen = optimize && ty.is_freeze(tcx, typing_env);
1041
1042 size = if frozen { layout.size } else { Size::ZERO };
1046
1047 kind = PointerKind::SharedRef { frozen };
1048 }
1049 hir::Mutability::Mut => {
1050 let unpin = optimize
1051 && ty.is_unpin(tcx, typing_env)
1052 && ty.is_unsafe_unpin(tcx, typing_env);
1053
1054 size = if unpin { layout.size } else { Size::ZERO };
1059
1060 kind = PointerKind::MutableRef { unpin };
1061 }
1062 };
1063 PointeeInfo { safe: Some(kind), size, align: layout.align.abi }
1064 })
1065 }
1066
1067 ty::Adt(..)
1068 if offset.bytes() == 0
1069 && let Some(pointee) = this.ty.boxed_ty() =>
1070 {
1071 tcx.layout_of(typing_env.as_query_input(pointee)).ok().map(|layout| PointeeInfo {
1072 safe: Some(PointerKind::Box {
1073 unpin: optimize
1075 && pointee.is_unpin(tcx, typing_env)
1076 && pointee.is_unsafe_unpin(tcx, typing_env),
1077 global: this.ty.is_box_global(tcx),
1078 }),
1079
1080 size: Size::ZERO,
1084
1085 align: layout.align.abi,
1086 })
1087 }
1088
1089 ty::Adt(adt_def, ..) if adt_def.is_maybe_dangling() => {
1090 Self::ty_and_layout_pointee_info_at(this.field(cx, 0), cx, offset).map(|info| {
1091 PointeeInfo {
1092 safe: None,
1095 size: Size::ZERO,
1097 align: info.align,
1099 }
1100 })
1101 }
1102
1103 _ => {
1104 let mut data_variant = match &this.variants {
1105 Variants::Multiple {
1115 tag_encoding:
1116 TagEncoding::Niche { untagged_variant, niche_variants, niche_start },
1117 tag_field,
1118 variants,
1119 ..
1120 } if variants.len() == 2
1121 && this.fields.offset(tag_field.as_usize()) == offset =>
1122 {
1123 let tagged_variant = if *untagged_variant == VariantIdx::ZERO {
1124 VariantIdx::from_u32(1)
1125 } else {
1126 VariantIdx::from_u32(0)
1127 };
1128 match (&tagged_variant, &*niche_variants.start()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(tagged_variant, *niche_variants.start());
1129 if *niche_start == 0 {
1130 Some(this.for_variant(cx, *untagged_variant))
1136 } else {
1137 None
1138 }
1139 }
1140 Variants::Multiple { .. } => None,
1141 Variants::Empty | Variants::Single { .. } => Some(this),
1142 };
1143
1144 if let Some(variant) = data_variant
1145 && let FieldsShape::Union(_) = variant.fields
1147 {
1148 data_variant = None;
1149 }
1150
1151 let mut result = None;
1152
1153 if let Some(variant) = data_variant {
1154 let ptr_end = offset + Primitive::Pointer(AddressSpace::ZERO).size(cx);
1157 for i in 0..variant.fields.count() {
1158 let field_start = variant.fields.offset(i);
1159 if field_start <= offset {
1160 let field = variant.field(cx, i);
1161 result = field.to_result().ok().and_then(|field| {
1162 if ptr_end <= field_start + field.size {
1163 let field_info =
1165 field.pointee_info_at(cx, offset - field_start);
1166 field_info
1167 } else {
1168 None
1169 }
1170 });
1171 if result.is_some() {
1172 break;
1173 }
1174 }
1175 }
1176 }
1177
1178 result
1179 }
1180 };
1181
1182 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/layout.rs:1182",
"rustc_middle::ty::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/layout.rs"),
::tracing_core::__macro_support::Option::Some(1182u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::layout"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("pointee_info_at (offset={0:?}, type kind: {1:?}) => {2:?}",
offset, this.ty.kind(), pointee_info) as &dyn Value))])
});
} else { ; }
};debug!(
1183 "pointee_info_at (offset={:?}, type kind: {:?}) => {:?}",
1184 offset,
1185 this.ty.kind(),
1186 pointee_info
1187 );
1188
1189 pointee_info
1190 }
1191
1192 fn is_adt(this: TyAndLayout<'tcx>) -> bool {
1193 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Adt(..) => true,
_ => false,
}matches!(this.ty.kind(), ty::Adt(..))
1194 }
1195
1196 fn is_never(this: TyAndLayout<'tcx>) -> bool {
1197 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Never => true,
_ => false,
}matches!(this.ty.kind(), ty::Never)
1198 }
1199
1200 fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
1201 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Tuple(..) => true,
_ => false,
}matches!(this.ty.kind(), ty::Tuple(..))
1202 }
1203
1204 fn is_unit(this: TyAndLayout<'tcx>) -> bool {
1205 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Tuple(list) if list.len() == 0 => true,
_ => false,
}matches!(this.ty.kind(), ty::Tuple(list) if list.len() == 0)
1206 }
1207
1208 fn is_transparent(this: TyAndLayout<'tcx>) -> bool {
1209 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Adt(def, _) if def.repr().transparent() => true,
_ => false,
}matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent())
1210 }
1211
1212 fn is_scalable_vector(this: TyAndLayout<'tcx>) -> bool {
1213 this.ty.is_scalable_vector()
1214 }
1215
1216 fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'tcx>) -> bool {
1218 #[allow(non_exhaustive_omitted_patterns)] match this.ty.kind() {
ty::Adt(def, _) if
def.repr().flags.contains(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS)
=> true,
_ => false,
}matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().flags.contains(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS))
1219 }
1220}
1221
1222#[inline]
1263#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("fn_can_unwind",
"rustc_middle::ty::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/layout.rs"),
::tracing_core::__macro_support::Option::Some(1263u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::layout"),
::tracing_core::field::FieldSet::new(&["fn_def_id", "abi"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&abi)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: bool = loop {};
return __tracing_attr_fake_return;
}
{
if let Some(did) = fn_def_id {
if tcx.codegen_fn_attrs(did).flags.contains(CodegenFnAttrFlags::NEVER_UNWIND)
{
return false;
}
if !tcx.sess.panic_strategy().unwinds() &&
!tcx.is_foreign_item(did) {
return false;
}
if !tcx.sess.opts.unstable_opts.panic_in_drop.unwinds() &&
tcx.is_lang_item(did, LangItem::DropInPlace) {
return false;
}
}
use ExternAbi::*;
match abi {
C { unwind } | System { unwind } | Cdecl { unwind } |
Stdcall { unwind } | Fastcall { unwind } | Vectorcall {
unwind } | Thiscall { unwind } | Aapcs { unwind } | Win64 {
unwind } | SysV64 { unwind } => unwind,
PtxKernel | Msp430Interrupt | X86Interrupt | GpuKernel |
EfiApi | AvrInterrupt | AvrNonBlockingInterrupt |
CmseNonSecureCall | CmseNonSecureEntry | Custom |
RiscvInterruptM | RiscvInterruptS | RustInvalid | Unadjusted
=> false,
Rust | RustCall | RustCold | RustPreserveNone =>
tcx.sess.panic_strategy().unwinds(),
}
}
}
}#[tracing::instrument(level = "debug", skip(tcx))]
1264pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi) -> bool {
1265 if let Some(did) = fn_def_id {
1266 if tcx.codegen_fn_attrs(did).flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) {
1268 return false;
1269 }
1270
1271 if !tcx.sess.panic_strategy().unwinds() && !tcx.is_foreign_item(did) {
1276 return false;
1277 }
1278
1279 if !tcx.sess.opts.unstable_opts.panic_in_drop.unwinds()
1284 && tcx.is_lang_item(did, LangItem::DropInPlace)
1285 {
1286 return false;
1287 }
1288 }
1289
1290 use ExternAbi::*;
1297 match abi {
1298 C { unwind }
1299 | System { unwind }
1300 | Cdecl { unwind }
1301 | Stdcall { unwind }
1302 | Fastcall { unwind }
1303 | Vectorcall { unwind }
1304 | Thiscall { unwind }
1305 | Aapcs { unwind }
1306 | Win64 { unwind }
1307 | SysV64 { unwind } => unwind,
1308 PtxKernel
1309 | Msp430Interrupt
1310 | X86Interrupt
1311 | GpuKernel
1312 | EfiApi
1313 | AvrInterrupt
1314 | AvrNonBlockingInterrupt
1315 | CmseNonSecureCall
1316 | CmseNonSecureEntry
1317 | Custom
1318 | RiscvInterruptM
1319 | RiscvInterruptS
1320 | RustInvalid
1321 | Unadjusted => false,
1322 Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(),
1323 }
1324}
1325
1326#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for FnAbiError<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for FnAbiError<'tcx> {
#[inline]
fn clone(&self) -> FnAbiError<'tcx> {
let _: ::core::clone::AssertParamIsClone<LayoutError<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for FnAbiError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
FnAbiError::Layout(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Layout",
&__self_0),
}
}
}Debug, const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for FnAbiError<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
FnAbiError::Layout(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
1328pub enum FnAbiError<'tcx> {
1329 Layout(LayoutError<'tcx>),
1331}
1332
1333impl<'a, 'b, G: EmissionGuarantee> Diagnostic<'a, G> for FnAbiError<'b> {
1334 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
1335 match self {
1336 Self::Layout(e) => e.into_diagnostic().into_diag(dcx, level),
1337 }
1338 }
1339}
1340
1341#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for FnAbiRequest<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
FnAbiRequest::OfFnPtr { sig: __self_0, extra_args: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"OfFnPtr", "sig", __self_0, "extra_args", &__self_1),
FnAbiRequest::OfInstance {
instance: __self_0, extra_args: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"OfInstance", "instance", __self_0, "extra_args",
&__self_1),
}
}
}Debug)]
1344pub enum FnAbiRequest<'tcx> {
1345 OfFnPtr { sig: ty::PolyFnSig<'tcx>, extra_args: &'tcx ty::List<Ty<'tcx>> },
1346 OfInstance { instance: ty::Instance<'tcx>, extra_args: &'tcx ty::List<Ty<'tcx>> },
1347}
1348
1349pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> {
1352 type FnAbiOfResult: MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>> = &'tcx FnAbi<'tcx, Ty<'tcx>>;
1355
1356 fn handle_fn_abi_err(
1364 &self,
1365 err: FnAbiError<'tcx>,
1366 span: Span,
1367 fn_abi_request: FnAbiRequest<'tcx>,
1368 ) -> <Self::FnAbiOfResult as MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>>::Error;
1369}
1370
1371pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
1373 #[inline]
1378 fn fn_abi_of_fn_ptr(
1379 &self,
1380 sig: ty::PolyFnSig<'tcx>,
1381 extra_args: &'tcx ty::List<Ty<'tcx>>,
1382 ) -> Self::FnAbiOfResult {
1383 let span = self.layout_tcx_at_span();
1385 let tcx = self.tcx().at(span);
1386
1387 MaybeResult::from(
1388 tcx.fn_abi_of_fn_ptr(self.typing_env().as_query_input((sig, extra_args))).map_err(
1389 |err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
1390 ),
1391 )
1392 }
1393
1394 #[inline]
1406 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("fn_abi_of_instance_no_deduced_attrs",
"rustc_middle::ty::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/layout.rs"),
::tracing_core::__macro_support::Option::Some(1406u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::layout"),
::tracing_core::field::FieldSet::new(&["instance",
"extra_args"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&instance)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&extra_args)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Self::FnAbiOfResult = loop {};
return __tracing_attr_fake_return;
}
{
let span = self.layout_tcx_at_span();
let tcx = self.tcx().at(span);
MaybeResult::from(tcx.fn_abi_of_instance_no_deduced_attrs(self.typing_env().as_query_input((instance,
extra_args))).map_err(|err|
{
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 })
}))
}
}
}#[tracing::instrument(level = "debug", skip(self))]
1407 fn fn_abi_of_instance_no_deduced_attrs(
1408 &self,
1409 instance: ty::Instance<'tcx>,
1410 extra_args: &'tcx ty::List<Ty<'tcx>>,
1411 ) -> Self::FnAbiOfResult {
1412 let span = self.layout_tcx_at_span();
1414 let tcx = self.tcx().at(span);
1415
1416 MaybeResult::from(
1417 tcx.fn_abi_of_instance_no_deduced_attrs(
1418 self.typing_env().as_query_input((instance, extra_args)),
1419 )
1420 .map_err(|err| {
1421 let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
1426 self.handle_fn_abi_err(
1427 *err,
1428 span,
1429 FnAbiRequest::OfInstance { instance, extra_args },
1430 )
1431 }),
1432 )
1433 }
1434
1435 #[inline]
1445 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("fn_abi_of_instance",
"rustc_middle::ty::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/layout.rs"),
::tracing_core::__macro_support::Option::Some(1445u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::layout"),
::tracing_core::field::FieldSet::new(&["instance",
"extra_args"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&instance)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&extra_args)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Self::FnAbiOfResult = loop {};
return __tracing_attr_fake_return;
}
{
let span = self.layout_tcx_at_span();
let tcx = self.tcx().at(span);
MaybeResult::from(tcx.fn_abi_of_instance(self.typing_env().as_query_input((instance,
extra_args))).map_err(|err|
{
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 })
}))
}
}
}#[tracing::instrument(level = "debug", skip(self))]
1446 fn fn_abi_of_instance(
1447 &self,
1448 instance: ty::Instance<'tcx>,
1449 extra_args: &'tcx ty::List<Ty<'tcx>>,
1450 ) -> Self::FnAbiOfResult {
1451 let span = self.layout_tcx_at_span();
1453 let tcx = self.tcx().at(span);
1454
1455 MaybeResult::from(
1456 tcx.fn_abi_of_instance(self.typing_env().as_query_input((instance, extra_args)))
1457 .map_err(|err| {
1458 let span =
1463 if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
1464 self.handle_fn_abi_err(
1465 *err,
1466 span,
1467 FnAbiRequest::OfInstance { instance, extra_args },
1468 )
1469 }),
1470 )
1471 }
1472}
1473
1474impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {}