1use std::{assert_matches, iter};
2
3use rustc_abi::Primitive::Pointer;
4use rustc_abi::{Align, BackendRepr, ExternAbi, PointerKind, Scalar, Size};
5use rustc_attr_ir::find_attr;
6use rustc_attr_ir::lang_items::LangItem;
7use rustc_hir as hir;
8use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs;
9use rustc_middle::query::Providers;
10use rustc_middle::ty::layout::{
11 FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind,
12};
13use rustc_middle::ty::{self, Instance, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized};
14use rustc_span::def_id::DefId;
15use rustc_span::{DUMMY_SP, bug};
16use rustc_target::callconv::{
17 AbiMap, ArgAbi, ArgAttribute, ArgAttributes, FnAbi, IndirectMode, PassMode,
18};
19use tracing::debug;
20
21pub(crate) fn provide(providers: &mut Providers) {
22 *providers = Providers {
23 fn_abi_of_fn_ptr,
24 fn_abi_of_instance_no_deduced_attrs,
25 fn_abi_of_instance_raw,
26 ..*providers
27 };
28}
29
30{}
#[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_sig_for_fn_abi",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(35u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("instance")
}> =
::tracing::__macro_support::FieldName::new("instance");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&instance)
as &dyn ::tracing::field::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: ty::FnSig<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) =
instance.def {
return tcx.mk_fn_sig_safe_rust_abi([],
tcx.thread_local_ptr_ty(instance.def_id()));
}
let ty = instance.ty(tcx, typing_env);
match *ty.kind() {
ty::FnDef(def_id, args) => {
let mut sig =
tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx,
args.no_bound_vars().unwrap()).skip_norm_wip());
if let ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) =
instance.def {
let mut inputs_and_output = sig.inputs_and_output.to_vec();
inputs_and_output[0] =
Ty::new_mut_ptr(tcx, inputs_and_output[0]);
sig.inputs_and_output =
tcx.mk_type_list(&inputs_and_output);
}
sig
}
ty::Closure(def_id, args) => {
let sig =
tcx.instantiate_bound_regions_with_erased(args.as_closure().sig());
let env_ty =
tcx.closure_env_ty(Ty::new_closure(tcx, def_id, args),
args.as_closure().kind(), tcx.lifetimes.re_erased);
tcx.mk_fn_sig(iter::once(env_ty).chain(sig.inputs().iter().cloned()),
sig.output(), sig.fn_sig_kind)
}
ty::CoroutineClosure(def_id, args) => {
let coroutine_ty =
Ty::new_coroutine_closure(tcx, def_id, args);
let sig =
args.as_coroutine_closure().coroutine_closure_sig();
let mut coroutine_kind = args.as_coroutine_closure().kind();
let env_ty =
if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure {
receiver_by_ref, .. }) = instance.def {
coroutine_kind = ty::ClosureKind::FnOnce;
if receiver_by_ref {
Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty)
} else { coroutine_ty }
} else {
tcx.closure_env_ty(coroutine_ty, coroutine_kind,
tcx.lifetimes.re_erased)
};
let sig = tcx.instantiate_bound_regions_with_erased(sig);
tcx.mk_fn_sig(iter::once(env_ty).chain([sig.tupled_inputs_ty]),
sig.to_coroutine_given_kind_and_upvars(tcx,
args.as_coroutine_closure().parent_args(),
tcx.coroutine_for_closure(def_id), coroutine_kind,
tcx.lifetimes.re_erased,
args.as_coroutine_closure().tupled_upvars_ty(),
args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
sig.fn_sig_kind)
}
ty::Coroutine(did, args) => {
let coroutine_kind = tcx.coroutine_kind(did).unwrap();
let sig = args.as_coroutine().sig();
let env_ty =
Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
let pin_did =
tcx.require_lang_item(LangItem::Pin, DUMMY_SP);
let pin_adt_ref = tcx.adt_def(pin_did);
let pin_args = tcx.mk_args(&[env_ty.into()]);
let env_ty =
match coroutine_kind {
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen,
_) => {
env_ty
}
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async,
_) |
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen,
_) | hir::CoroutineKind::Coroutine(_) =>
Ty::new_adt(tcx, pin_adt_ref, pin_args),
};
let (resume_ty, ret_ty) =
match coroutine_kind {
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async,
_) => {
{
match (&sig.yield_ty, &tcx.types.unit) {
(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);
}
}
}
};
let poll_did =
tcx.require_lang_item(LangItem::Poll, DUMMY_SP);
let poll_adt_ref = tcx.adt_def(poll_did);
let poll_args = tcx.mk_args(&[sig.return_ty.into()]);
let ret_ty = Ty::new_adt(tcx, poll_adt_ref, poll_args);
{
if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
let expected_adt =
tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy,
DUMMY_SP));
{
match (&*resume_ty_adt, &expected_adt) {
(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);
}
}
}
};
} else {
{
::core::panicking::panic_fmt(format_args!("expected `ResumeTy`, found `{0:?}`",
sig.resume_ty));
};
};
}
let context_mut_ref = Ty::new_task_context(tcx);
(Some(context_mut_ref), ret_ty)
}
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen,
_) => {
let option_did =
tcx.require_lang_item(LangItem::Option, DUMMY_SP);
let option_adt_ref = tcx.adt_def(option_did);
let option_args = tcx.mk_args(&[sig.yield_ty.into()]);
let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
{
match (&sig.return_ty, &tcx.types.unit) {
(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);
}
}
}
};
{
match (&sig.resume_ty, &tcx.types.unit) {
(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);
}
}
}
};
(None, ret_ty)
}
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen,
_) => {
{
match (&sig.return_ty, &tcx.types.unit) {
(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);
}
}
}
};
let ret_ty = sig.yield_ty;
{
if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
let expected_adt =
tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy,
DUMMY_SP));
{
match (&*resume_ty_adt, &expected_adt) {
(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);
}
}
}
};
} else {
{
::core::panicking::panic_fmt(format_args!("expected `ResumeTy`, found `{0:?}`",
sig.resume_ty));
};
};
}
let context_mut_ref = Ty::new_task_context(tcx);
(Some(context_mut_ref), ret_ty)
}
hir::CoroutineKind::Coroutine(_) => {
let state_did =
tcx.require_lang_item(LangItem::CoroutineState, DUMMY_SP);
let state_adt_ref = tcx.adt_def(state_did);
let state_args =
tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]);
let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args);
(Some(sig.resume_ty), ret_ty)
}
};
if let Some(resume_ty) = resume_ty {
tcx.mk_fn_sig_safe_rust_abi([env_ty, resume_ty], ret_ty)
} else { tcx.mk_fn_sig_safe_rust_abi([env_ty], ret_ty) }
}
_ =>
::rustc_span::macros::bug_impl(None,
format_args!("unexpected type {0:?} in Instance::fn_sig",
ty), Location::caller()),
}
}
}
}#[tracing::instrument(level = "debug", skip(tcx, typing_env))]
36fn fn_sig_for_fn_abi<'tcx>(
37 tcx: TyCtxt<'tcx>,
38 instance: ty::Instance<'tcx>,
39 typing_env: ty::TypingEnv<'tcx>,
40) -> ty::FnSig<'tcx> {
41 if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) = instance.def {
42 return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id()));
43 }
44
45 let ty = instance.ty(tcx, typing_env);
46 match *ty.kind() {
47 ty::FnDef(def_id, args) => {
48 let mut sig = tcx.instantiate_bound_regions_with_erased(
49 tcx.fn_sig(def_id).instantiate(tcx, args.no_bound_vars().unwrap()).skip_norm_wip(),
50 );
51
52 if let ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) = instance.def {
54 let mut inputs_and_output = sig.inputs_and_output.to_vec();
55 inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
56 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
57 }
58
59 sig
60 }
61 ty::Closure(def_id, args) => {
62 let sig = tcx.instantiate_bound_regions_with_erased(args.as_closure().sig());
63 let env_ty = tcx.closure_env_ty(
64 Ty::new_closure(tcx, def_id, args),
65 args.as_closure().kind(),
66 tcx.lifetimes.re_erased,
67 );
68
69 tcx.mk_fn_sig(
70 iter::once(env_ty).chain(sig.inputs().iter().cloned()),
71 sig.output(),
72 sig.fn_sig_kind,
73 )
74 }
75 ty::CoroutineClosure(def_id, args) => {
76 let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args);
77 let sig = args.as_coroutine_closure().coroutine_closure_sig();
78
79 let mut coroutine_kind = args.as_coroutine_closure().kind();
84
85 let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure {
86 receiver_by_ref,
87 ..
88 }) = instance.def
89 {
90 coroutine_kind = ty::ClosureKind::FnOnce;
91
92 if receiver_by_ref {
95 Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty)
96 } else {
97 coroutine_ty
98 }
99 } else {
100 tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased)
101 };
102
103 let sig = tcx.instantiate_bound_regions_with_erased(sig);
104
105 tcx.mk_fn_sig(
106 iter::once(env_ty).chain([sig.tupled_inputs_ty]),
107 sig.to_coroutine_given_kind_and_upvars(
108 tcx,
109 args.as_coroutine_closure().parent_args(),
110 tcx.coroutine_for_closure(def_id),
111 coroutine_kind,
112 tcx.lifetimes.re_erased,
113 args.as_coroutine_closure().tupled_upvars_ty(),
114 args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
115 ),
116 sig.fn_sig_kind,
117 )
118 }
119 ty::Coroutine(did, args) => {
120 let coroutine_kind = tcx.coroutine_kind(did).unwrap();
121 let sig = args.as_coroutine().sig();
122
123 let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
124
125 let pin_did = tcx.require_lang_item(LangItem::Pin, DUMMY_SP);
126 let pin_adt_ref = tcx.adt_def(pin_did);
127 let pin_args = tcx.mk_args(&[env_ty.into()]);
128 let env_ty = match coroutine_kind {
129 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
130 env_ty
133 }
134 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
135 | hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)
136 | hir::CoroutineKind::Coroutine(_) => Ty::new_adt(tcx, pin_adt_ref, pin_args),
137 };
138
139 let (resume_ty, ret_ty) = match coroutine_kind {
146 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _) => {
147 assert_eq!(sig.yield_ty, tcx.types.unit);
149
150 let poll_did = tcx.require_lang_item(LangItem::Poll, DUMMY_SP);
151 let poll_adt_ref = tcx.adt_def(poll_did);
152 let poll_args = tcx.mk_args(&[sig.return_ty.into()]);
153 let ret_ty = Ty::new_adt(tcx, poll_adt_ref, poll_args);
154
155 #[cfg(debug_assertions)]
158 {
159 if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
160 let expected_adt =
161 tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
162 assert_eq!(*resume_ty_adt, expected_adt);
163 } else {
164 panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty);
165 };
166 }
167 let context_mut_ref = Ty::new_task_context(tcx);
168
169 (Some(context_mut_ref), ret_ty)
170 }
171 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
172 let option_did = tcx.require_lang_item(LangItem::Option, DUMMY_SP);
174 let option_adt_ref = tcx.adt_def(option_did);
175 let option_args = tcx.mk_args(&[sig.yield_ty.into()]);
176 let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
177
178 assert_eq!(sig.return_ty, tcx.types.unit);
179 assert_eq!(sig.resume_ty, tcx.types.unit);
180
181 (None, ret_ty)
182 }
183 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => {
184 assert_eq!(sig.return_ty, tcx.types.unit);
187
188 let ret_ty = sig.yield_ty;
190
191 #[cfg(debug_assertions)]
194 {
195 if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
196 let expected_adt =
197 tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
198 assert_eq!(*resume_ty_adt, expected_adt);
199 } else {
200 panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty);
201 };
202 }
203 let context_mut_ref = Ty::new_task_context(tcx);
204
205 (Some(context_mut_ref), ret_ty)
206 }
207 hir::CoroutineKind::Coroutine(_) => {
208 let state_did = tcx.require_lang_item(LangItem::CoroutineState, DUMMY_SP);
210 let state_adt_ref = tcx.adt_def(state_did);
211 let state_args = tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]);
212 let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args);
213
214 (Some(sig.resume_ty), ret_ty)
215 }
216 };
217
218 if let Some(resume_ty) = resume_ty {
219 tcx.mk_fn_sig_safe_rust_abi([env_ty, resume_ty], ret_ty)
220 } else {
221 tcx.mk_fn_sig_safe_rust_abi([env_ty], ret_ty)
223 }
224 }
225 _ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
226 }
227}
228
229struct FnAbiDesc<'tcx> {
231 layout_cx: LayoutCx<'tcx>,
232 sig: ty::FnSig<'tcx>,
233
234 instance: Option<Instance<'tcx>>,
235 caller_location: Option<Ty<'tcx>>,
236 is_virtual_call: bool,
237 extra_args: &'tcx [Ty<'tcx>],
238}
239
240impl<'tcx> FnAbiDesc<'tcx> {
241 fn for_fn_ptr(
242 tcx: TyCtxt<'tcx>,
243 query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
244 ) -> Self {
245 let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query;
246 Self {
247 layout_cx: LayoutCx::new(tcx, typing_env),
248 sig: tcx.normalize_erasing_regions(
249 typing_env,
250 Unnormalized::new_wip(tcx.instantiate_bound_regions_with_erased(sig)),
251 ),
252 instance: None,
253 caller_location: None,
254 is_virtual_call: false,
255 extra_args,
256 }
257 }
258
259 fn for_instance(
260 tcx: TyCtxt<'tcx>,
261 query: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
262 ) -> Self {
263 let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query;
264 let is_virtual_call = #[allow(non_exhaustive_omitted_patterns)] match instance.def {
ty::InstanceKind::Virtual(..) => true,
_ => false,
}matches!(instance.def, ty::InstanceKind::Virtual(..));
265 Self {
266 layout_cx: LayoutCx::new(tcx, typing_env),
267 sig: tcx.normalize_erasing_regions(
268 typing_env,
269 Unnormalized::new_wip(fn_sig_for_fn_abi(tcx, instance, typing_env)),
270 ),
271 instance: Some(instance),
272 caller_location: instance
273 .def
274 .requires_caller_location(tcx)
275 .then(|| tcx.caller_location_ty()),
276 is_virtual_call,
277 extra_args,
278 }
279 }
280}
281
282fn fn_abi_of_fn_ptr<'tcx>(
283 tcx: TyCtxt<'tcx>,
284 query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
285) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
286 let desc = FnAbiDesc::for_fn_ptr(tcx, query);
287 fn_abi_new_uncached(desc)
288}
289
290fn fn_abi_of_instance_no_deduced_attrs<'tcx>(
291 tcx: TyCtxt<'tcx>,
292 query: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
293) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
294 let desc = FnAbiDesc::for_instance(tcx, query);
295 fn_abi_new_uncached(desc)
296}
297
298fn fn_abi_of_instance_raw<'tcx>(
299 tcx: TyCtxt<'tcx>,
300 query: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
301) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
302 tcx.fn_abi_of_instance_no_deduced_attrs(query).map(|fn_abi| {
305 let params = FnAbiDesc::for_instance(tcx, query);
306 if let Some(Instance { def: InstanceKind::Item(fn_def_id), .. }) = params.instance {
310 fn_abi_adjust_for_deduced_attrs(¶ms.layout_cx, fn_abi, params.sig.abi(), fn_def_id)
311 } else {
312 fn_abi
313 }
314 })
315}
316
317fn arg_attrs_for_rust_scalar<'tcx>(
319 cx: LayoutCx<'tcx>,
320 scalar: Scalar,
321 layout: TyAndLayout<'tcx>,
322 offset: Size,
323 is_return: bool,
324 instance: Option<Instance<'tcx>>,
325) -> ArgAttributes {
326 let mut attrs = ArgAttributes::new();
327
328 if !scalar.is_uninit_valid() {
329 attrs.set(ArgAttribute::NoUndef);
330 }
331
332 let Scalar::Initialized { value: Pointer(_), valid_range } = scalar else { return attrs };
334
335 if !valid_range.contains(0) {
337 attrs.set(ArgAttribute::NonNull);
338 }
339
340 let tcx = cx.tcx();
341
342 if let Some(pointee) = layout.pointee_info_at(&cx, offset) {
343 if pointee.align > Align::ONE {
344 attrs.pointee_align =
345 Some(pointee.align.min(cx.tcx().sess.target.max_reliable_alignment()));
346 }
347
348 attrs.pointee_size = pointee.size;
349
350 if let Some(kind) = pointee.safe {
351 let noalias_for_box = tcx.sess.opts.unstable_opts.box_noalias;
355
356 let no_alias = match kind {
363 PointerKind::SharedRef { frozen } => frozen,
364 PointerKind::MutableRef { unpin } => unpin,
365 PointerKind::Box { unpin, global } => unpin && global && noalias_for_box,
366 };
367 if no_alias && !is_return {
370 attrs.set(ArgAttribute::NoAlias);
371 }
372
373 if tcx.sess.opts.unstable_opts.llvm_writable
375 && #[allow(non_exhaustive_omitted_patterns)] match kind {
PointerKind::MutableRef { unpin: true } => true,
_ => false,
}matches!(kind, PointerKind::MutableRef { unpin: true })
376 && !is_return
377 {
378 if let Some(Instance { def: InstanceKind::Item(def_id), .. }) = instance {
379 let rustc_no_writable = {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcNoWritable) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(tcx, def_id, RustcNoWritable);
380 if !rustc_no_writable {
381 attrs.set(ArgAttribute::Writable);
382 }
383 }
384 }
385
386 let no_free = !is_return
390 && match kind {
391 PointerKind::SharedRef { frozen } => frozen,
395 PointerKind::MutableRef { unpin } => unpin,
399 PointerKind::Box { .. } => false,
401 };
402 if no_free {
403 attrs.set(ArgAttribute::NoFree);
404 }
405
406 if #[allow(non_exhaustive_omitted_patterns)] match kind {
PointerKind::SharedRef { frozen: true } => true,
_ => false,
}matches!(kind, PointerKind::SharedRef { frozen: true }) && !is_return {
407 attrs.set(ArgAttribute::ReadOnly);
408 attrs.set(ArgAttribute::CapturesReadOnly);
409 }
410 }
411 }
412
413 attrs
414}
415
416fn fn_abi_sanity_check<'tcx>(
418 cx: &LayoutCx<'tcx>,
419 fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
420 spec_abi: ExternAbi,
421) {
422 fn fn_arg_attrs_sanity_check(attrs: &ArgAttributes, is_ret: bool) {
423 if attrs.regular.contains(ArgAttribute::NoFree) {
424 if !!is_ret {
{
::core::panicking::panic_fmt(format_args!("NoFree not valid on return values"));
}
};assert!(!is_ret, "NoFree not valid on return values");
425 }
426 }
427
428 fn fn_arg_sanity_check<'tcx>(
429 cx: &LayoutCx<'tcx>,
430 spec_abi: ExternAbi,
431 arg: &ArgAbi<'tcx, Ty<'tcx>>,
432 is_ret: bool,
433 ) {
434 let tcx = cx.tcx();
435
436 if spec_abi.is_rustic_abi() {
437 if arg.layout.is_zst() {
438 if !arg.is_ignore() {
::core::panicking::panic("assertion failed: arg.is_ignore()")
};assert!(arg.is_ignore());
441 }
442 if let PassMode::Indirect { mode, .. } = arg.mode
443 && spec_abi != ExternAbi::RustTail
444 {
445 if !(mode == IndirectMode::Pointer) {
{
::core::panicking::panic_fmt(format_args!("rust abi must use plain pointer mode"));
}
};assert!(mode == IndirectMode::Pointer, "rust abi must use plain pointer mode");
446 }
447 } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
448 {
match arg.mode {
PassMode::Indirect { mode: IndirectMode::Pointer, .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"PassMode::Indirect { mode: IndirectMode::Pointer, .. }",
::core::option::Option::Some(format_args!("the {0} ABI does not implement `#[rustc_pass_indirectly_in_non_rustic_abis]`",
spec_abi)));
}
}
};assert_matches!(
449 arg.mode,
450 PassMode::Indirect { mode: IndirectMode::Pointer, .. },
451 "the {spec_abi} ABI does not implement `#[rustc_pass_indirectly_in_non_rustic_abis]`"
452 );
453 }
454
455 match &arg.mode {
456 PassMode::Ignore => {
457 if !arg.layout.is_zst() {
::core::panicking::panic("assertion failed: arg.layout.is_zst()")
};assert!(arg.layout.is_zst());
458 }
459 PassMode::Direct(attrs) => {
460 match arg.layout.backend_repr {
464 BackendRepr::Scalar(_)
465 | BackendRepr::SimdVector { .. }
466 | BackendRepr::SimdScalableVector { .. } => {}
467 BackendRepr::ScalarPair { .. } => {
468 {
::core::panicking::panic_fmt(format_args!("`PassMode::Direct` used for ScalarPair type {0}",
arg.layout.ty));
}panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty)
469 }
470 BackendRepr::Memory { .. } => {
471 {
::core::panicking::panic_fmt(format_args!("`PassMode::Direct` for aggregates not allowed\nProblematic type: {0:#?}",
arg.layout));
};panic!(
472 "`PassMode::Direct` for aggregates not allowed\n\
473 Problematic type: {:#?}",
474 arg.layout,
475 );
476 }
477 }
478 fn_arg_attrs_sanity_check(attrs, is_ret);
479 }
480 PassMode::Pair(attrs1, attrs2) => {
481 if !#[allow(non_exhaustive_omitted_patterns)] match arg.layout.backend_repr {
BackendRepr::ScalarPair { .. } => true,
_ => false,
} {
{
::core::panicking::panic_fmt(format_args!("PassMode::Pair for type {0}",
arg.layout.ty));
}
};assert!(
484 matches!(arg.layout.backend_repr, BackendRepr::ScalarPair { .. }),
485 "PassMode::Pair for type {}",
486 arg.layout.ty
487 );
488 fn_arg_attrs_sanity_check(attrs1, is_ret);
489 fn_arg_attrs_sanity_check(attrs2, is_ret);
490 }
491 PassMode::Cast { .. } => {
492 if !arg.layout.is_sized() {
::core::panicking::panic("assertion failed: arg.layout.is_sized()")
};assert!(arg.layout.is_sized());
494 }
495 PassMode::Indirect { attrs, .. } => {
496 if !arg.layout.is_sized() {
::core::panicking::panic("assertion failed: arg.layout.is_sized()")
};assert!(arg.layout.is_sized());
501 fn_arg_attrs_sanity_check(attrs, false);
503 }
504 PassMode::IndirectUnsized { attrs, meta_attrs } => {
505 if !arg.layout.is_unsized() {
::core::panicking::panic("assertion failed: arg.layout.is_unsized()")
};assert!(arg.layout.is_unsized());
507 if !!is_ret { ::core::panicking::panic("assertion failed: !is_ret") };assert!(!is_ret);
509 let tail = tcx.struct_tail_for_codegen(arg.layout.ty, cx.typing_env);
511 if #[allow(non_exhaustive_omitted_patterns)] match tail.kind() {
ty::Foreign(..) => true,
_ => false,
}matches!(tail.kind(), ty::Foreign(..)) {
512 {
::core::panicking::panic_fmt(format_args!("unsized arguments must not be `extern` types"));
};panic!("unsized arguments must not be `extern` types");
517 }
518 fn_arg_attrs_sanity_check(attrs, false);
520 fn_arg_attrs_sanity_check(meta_attrs, false);
521 }
522 }
523 }
524
525 for arg in fn_abi.args.iter() {
526 fn_arg_sanity_check(cx, spec_abi, arg, false);
527 }
528 fn_arg_sanity_check(cx, spec_abi, &fn_abi.ret, true);
529}
530
531{}
#[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_new_uncached",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(531u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("sig")
}> =
::tracing::__macro_support::FieldName::new("sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("extra_args")
}> =
::tracing::__macro_support::FieldName::new("extra_args");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&extra_args)
as &dyn ::tracing::field::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:
Result<&'tcx FnAbi<'tcx, Ty<'tcx>>,
&'tcx FnAbiError<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = cx.tcx();
let abi_map = AbiMap::from_target(&tcx.sess.target);
let conv =
abi_map.canonize_abi(sig.abi(), sig.c_variadic()).unwrap();
let mut inputs = sig.inputs();
let extra_args =
if sig.abi() == ExternAbi::RustCall {
if !(!sig.c_variadic() && extra_args.is_empty()) {
::core::panicking::panic("assertion failed: !sig.c_variadic() && extra_args.is_empty()")
};
if let Some(input) = sig.inputs().last() &&
let ty::Tuple(tupled_arguments) = input.kind() {
inputs = &sig.inputs()[0..sig.inputs().len() - 1];
tupled_arguments
} else {
::rustc_span::macros::bug_impl(None,
format_args!("argument to function with \"rust-call\" ABI is not a tuple"),
Location::caller());
}
} else {
if !(sig.c_variadic() || extra_args.is_empty()) {
::core::panicking::panic("assertion failed: sig.c_variadic() || extra_args.is_empty()")
};
extra_args
};
let arg_of =
|ty: Ty<'tcx>, arg_idx: Option<usize>|
-> Result<_, &'tcx FnAbiError<'tcx>>
{
let span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("arg_of",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(568u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[],
::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,
&{ meta.fields().value_set_all(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
let _entered = span.enter();
let is_return = arg_idx.is_none();
let layout =
cx.layout_of(ty).map_err(|err|
&*tcx.arena.alloc(FnAbiError::Layout(*err)))?;
let layout =
if is_virtual_call && arg_idx == Some(0) {
make_thin_self_ptr(cx, layout)
} else { layout };
Ok(ArgAbi::new(layout,
|scalar, offset|
{
arg_attrs_for_rust_scalar(*cx, scalar, layout, offset,
is_return, instance)
}))
};
let mut fn_abi =
FnAbi {
ret: arg_of(sig.output(), None)?,
args: inputs.iter().copied().chain(extra_args.iter().copied()).chain(caller_location).enumerate().map(|(i,
ty)| arg_of(ty, Some(i))).collect::<Result<_, _>>()?,
c_variadic: sig.c_variadic(),
fixed_count: inputs.len() as u32,
conv,
can_unwind: fn_can_unwind(tcx,
instance.and_then(|instance|
match instance.def {
InstanceKind::Item(item) => Some(item),
InstanceKind::Intrinsic(item) => Some(item),
InstanceKind::Shim(ShimKind::DropGlue(def_id, _ty)) =>
Some(def_id),
InstanceKind::Shim(_) => None,
InstanceKind::Virtual(..) => None,
InstanceKind::LlvmIntrinsic(_) => None,
}), sig.abi()),
};
fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi());
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs:618",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(618u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("fn_abi_new_uncached = {0:?}",
fn_abi) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
fn_abi_sanity_check(cx, &fn_abi, sig.abi());
Ok(tcx.arena.alloc(fn_abi))
}
}
}#[tracing::instrument(level = "debug", skip(cx, caller_location, instance, is_virtual_call))]
532fn fn_abi_new_uncached<'tcx>(
533 FnAbiDesc {
534 layout_cx: ref cx,
535 sig,
536 instance,
537 caller_location,
538 is_virtual_call,
539 extra_args,
540 }: FnAbiDesc<'tcx>,
541) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
542 let tcx = cx.tcx();
543
544 let abi_map = AbiMap::from_target(&tcx.sess.target);
545 let conv = abi_map.canonize_abi(sig.abi(), sig.c_variadic()).unwrap();
546
547 let mut inputs = sig.inputs();
548 let extra_args = if sig.abi() == ExternAbi::RustCall {
549 assert!(!sig.c_variadic() && extra_args.is_empty());
550
551 if let Some(input) = sig.inputs().last()
552 && let ty::Tuple(tupled_arguments) = input.kind()
553 {
554 inputs = &sig.inputs()[0..sig.inputs().len() - 1];
555 tupled_arguments
556 } else {
557 bug!(
558 "argument to function with \"rust-call\" ABI \
559 is not a tuple"
560 );
561 }
562 } else {
563 assert!(sig.c_variadic() || extra_args.is_empty());
564 extra_args
565 };
566
567 let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
568 let span = tracing::debug_span!("arg_of");
569 let _entered = span.enter();
570 let is_return = arg_idx.is_none();
571
572 let layout = cx.layout_of(ty).map_err(|err| &*tcx.arena.alloc(FnAbiError::Layout(*err)))?;
573 let layout = if is_virtual_call && arg_idx == Some(0) {
574 make_thin_self_ptr(cx, layout)
578 } else {
579 layout
580 };
581
582 Ok(ArgAbi::new(layout, |scalar, offset| {
583 arg_attrs_for_rust_scalar(*cx, scalar, layout, offset, is_return, instance)
584 }))
585 };
586
587 let mut fn_abi = FnAbi {
588 ret: arg_of(sig.output(), None)?,
589 args: inputs
590 .iter()
591 .copied()
592 .chain(extra_args.iter().copied())
593 .chain(caller_location)
594 .enumerate()
595 .map(|(i, ty)| arg_of(ty, Some(i)))
596 .collect::<Result<_, _>>()?,
597 c_variadic: sig.c_variadic(),
598 fixed_count: inputs.len() as u32,
599 conv,
600 can_unwind: fn_can_unwind(
602 tcx,
603 instance.and_then(|instance| match instance.def {
604 InstanceKind::Item(item) => Some(item),
605 InstanceKind::Intrinsic(item) => Some(item),
606 InstanceKind::Shim(ShimKind::DropGlue(def_id, _ty)) => Some(def_id),
608 InstanceKind::Shim(_) => None,
609 InstanceKind::Virtual(..) => None,
611 InstanceKind::LlvmIntrinsic(_) => None,
613 }),
614 sig.abi(),
615 ),
616 };
617 fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi());
618 debug!("fn_abi_new_uncached = {:?}", fn_abi);
619 fn_abi_sanity_check(cx, &fn_abi, sig.abi());
620 Ok(tcx.arena.alloc(fn_abi))
621}
622
623{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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_adjust_for_abi",
"rustc_ty_utils::abi", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(623u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("fn_abi")
}> =
::tracing::__macro_support::FieldName::new("fn_abi");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("abi")
}> =
::tracing::__macro_support::FieldName::new("abi");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_abi)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&abi)
as &dyn ::tracing::field::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: () = loop {};
return __tracing_attr_fake_return;
}
{
{
match (&(abi), &(ExternAbi::LlvmIntrinsic)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val,
::core::option::Option::Some(format_args!("fn_abi_of_instance should not be called on LLVM intrinsics")));
}
}
}
};
if abi.is_rustic_abi() {
fn_abi.adjust_for_rust_abi(cx);
} else { fn_abi.adjust_for_foreign_abi(cx, abi); }
}
}
}#[tracing::instrument(level = "trace", skip(cx))]
624fn fn_abi_adjust_for_abi<'tcx>(
625 cx: &LayoutCx<'tcx>,
626 fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
627 abi: ExternAbi,
628) {
629 assert_ne!(
630 abi,
631 ExternAbi::LlvmIntrinsic,
632 "fn_abi_of_instance should not be called on LLVM intrinsics"
633 );
634
635 if abi.is_rustic_abi() {
636 fn_abi.adjust_for_rust_abi(cx);
637 } else {
638 fn_abi.adjust_for_foreign_abi(cx, abi);
639 }
640}
641
642{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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_adjust_for_deduced_attrs",
"rustc_ty_utils::abi", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(642u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("fn_abi")
}> =
::tracing::__macro_support::FieldName::new("fn_abi");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("abi")
}> =
::tracing::__macro_support::FieldName::new("abi");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("fn_def_id")
}> =
::tracing::__macro_support::FieldName::new("fn_def_id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_abi)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&abi)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_def_id)
as &dyn ::tracing::field::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: &'tcx FnAbi<'tcx, Ty<'tcx>> =
loop {};
return __tracing_attr_fake_return;
}
{
let tcx = cx.tcx();
let deduced =
if abi.is_rustic_abi() {
tcx.deduced_param_attrs(fn_def_id)
} else { &[] };
if deduced.is_empty() {
fn_abi
} else {
let mut fn_abi = fn_abi.clone();
apply_deduced_attributes(cx, deduced, 0, &mut fn_abi.ret);
for (arg_idx, arg) in fn_abi.args.iter_mut().enumerate() {
apply_deduced_attributes(cx, deduced, arg_idx + 1, arg);
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs:661",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(661u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("fn_abi_adjust_for_deduced_attrs = {0:?}",
fn_abi) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
fn_abi_sanity_check(cx, &fn_abi, abi);
tcx.arena.alloc(fn_abi)
}
}
}
}#[tracing::instrument(level = "trace", skip(cx))]
643fn fn_abi_adjust_for_deduced_attrs<'tcx>(
644 cx: &LayoutCx<'tcx>,
645 fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
646 abi: ExternAbi,
647 fn_def_id: DefId,
648) -> &'tcx FnAbi<'tcx, Ty<'tcx>> {
649 let tcx = cx.tcx();
650 let deduced = if abi.is_rustic_abi() { tcx.deduced_param_attrs(fn_def_id) } else { &[] };
653 if deduced.is_empty() {
654 fn_abi
655 } else {
656 let mut fn_abi = fn_abi.clone();
657 apply_deduced_attributes(cx, deduced, 0, &mut fn_abi.ret);
658 for (arg_idx, arg) in fn_abi.args.iter_mut().enumerate() {
659 apply_deduced_attributes(cx, deduced, arg_idx + 1, arg);
660 }
661 debug!("fn_abi_adjust_for_deduced_attrs = {:?}", fn_abi);
662 fn_abi_sanity_check(cx, &fn_abi, abi);
663 tcx.arena.alloc(fn_abi)
664 }
665}
666
667fn apply_deduced_attributes<'tcx>(
672 cx: &LayoutCx<'tcx>,
673 deduced: &[DeducedParamAttrs],
674 idx: usize,
675 arg: &mut ArgAbi<'tcx, Ty<'tcx>>,
676) {
677 let PassMode::Indirect { ref mut attrs, .. } = arg.mode else {
679 return;
680 };
681 let Some(deduced) = deduced.get(idx) else {
683 return;
684 };
685 if deduced.read_only(cx.tcx(), cx.typing_env, arg.layout.ty) {
686 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs:686",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(686u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("added deduced ReadOnly attribute")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("added deduced ReadOnly attribute");
687 attrs.regular.insert(ArgAttribute::ReadOnly);
688 }
689 if deduced.captures_none(cx.tcx(), cx.typing_env, arg.layout.ty) {
690 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs:690",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(690u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("added deduced CapturesNone attribute")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("added deduced CapturesNone attribute");
691 attrs.regular.insert(ArgAttribute::CapturesNone);
692 }
693}
694
695{}
#[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("make_thin_self_ptr",
"rustc_ty_utils::abi", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/abi.rs"),
::tracing_core::__macro_support::Option::Some(695u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::abi"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("layout")
}> =
::tracing::__macro_support::FieldName::new("layout");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&layout)
as &dyn ::tracing::field::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: TyAndLayout<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = cx.tcx();
let wide_pointer_ty =
if layout.is_unsized() {
Ty::new_mut_ptr(tcx, layout.ty)
} else {
match layout.backend_repr {
BackendRepr::ScalarPair { .. } | BackendRepr::Scalar(..) =>
(),
_ =>
::rustc_span::macros::bug_impl(None,
format_args!("receiver type has unsupported layout: {0:?}",
layout), Location::caller()),
}
let mut wide_pointer_layout = layout;
while !wide_pointer_layout.ty.is_raw_ptr() &&
!wide_pointer_layout.ty.is_ref() {
wide_pointer_layout =
wide_pointer_layout.non_1zst_field(cx).expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type").1
}
wide_pointer_layout.ty
};
let unit_ptr_ty = Ty::new_mut_ptr(tcx, tcx.types.unit);
TyAndLayout {
ty: wide_pointer_ty,
..tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(unit_ptr_ty)).unwrap()
}
}
}
}#[tracing::instrument(level = "debug", skip(cx))]
696fn make_thin_self_ptr<'tcx>(
697 cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>),
698 layout: TyAndLayout<'tcx>,
699) -> TyAndLayout<'tcx> {
700 let tcx = cx.tcx();
701 let wide_pointer_ty = if layout.is_unsized() {
702 Ty::new_mut_ptr(tcx, layout.ty)
705 } else {
706 match layout.backend_repr {
707 BackendRepr::ScalarPair { .. } | BackendRepr::Scalar(..) => (),
708 _ => bug!("receiver type has unsupported layout: {:?}", layout),
709 }
710
711 let mut wide_pointer_layout = layout;
717 while !wide_pointer_layout.ty.is_raw_ptr() && !wide_pointer_layout.ty.is_ref() {
718 wide_pointer_layout = wide_pointer_layout
719 .non_1zst_field(cx)
720 .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type")
721 .1
722 }
723
724 wide_pointer_layout.ty
725 };
726
727 let unit_ptr_ty = Ty::new_mut_ptr(tcx, tcx.types.unit);
731
732 TyAndLayout {
733 ty: wide_pointer_ty,
734
735 ..tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(unit_ptr_ty)).unwrap()
738 }
739}