Skip to content

Commit 46d6c3e

Browse files
committed
Implement #129347: inline attributes on async fn and async closures affect the poll impl
1 parent 122cbd0 commit 46d6c3e

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
66
use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, RtsanSetting, UsedBy};
77
use rustc_hir::def::DefKind;
88
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
9-
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
9+
use rustc_hir::{
10+
self as hir, Attribute, CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem,
11+
find_attr, lang_items,
12+
};
1013
use rustc_middle::middle::codegen_fn_attrs::{
1114
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
1215
};
@@ -386,6 +389,35 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
386389
}
387390
}
388391

392+
// #129347: desugared async coutines inherit inline attrs from the async fn/closure
393+
// Must not be reordered with the below override.
394+
if let Some(parent) = async_poll_inherit_inline(tcx, did.to_def_id()) {
395+
let parent_attrs = tcx.codegen_fn_attrs(parent);
396+
if matches!(parent_attrs.inline, InlineAttr::Never | InlineAttr::Hint | InlineAttr::Always)
397+
{
398+
codegen_fn_attrs.inline = parent_attrs.inline;
399+
}
400+
}
401+
402+
// #129347: the inline attributes should not be applied to the fn that creates the coroutine
403+
// Must not be reordered with the above override.
404+
{
405+
let def_kind = tcx.def_kind(did);
406+
let is_fn_with_possible_attribs =
407+
matches!(def_kind, DefKind::Fn | DefKind::AssocFn) && tcx.asyncness(did).is_async();
408+
409+
let is_async_closure = tcx.is_closure_like(did.into())
410+
&& matches!(
411+
tcx.hir_node_by_def_id(did).expect_closure().kind,
412+
rustc_hir::ClosureKind::CoroutineClosure(CoroutineDesugaring::Async)
413+
)
414+
&& tcx.asyncness(did).is_async();
415+
416+
if is_fn_with_possible_attribs || is_async_closure {
417+
codegen_fn_attrs.inline = InlineAttr::None;
418+
}
419+
}
420+
389421
// When `no_builtins` is applied at the crate level, we should add the
390422
// `no-builtins` attribute to each function to ensure it takes effect in LTO.
391423
let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID);
@@ -647,6 +679,23 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
647679
tcx.codegen_fn_attrs(tcx.trait_item_of(def_id)?).alignment
648680
}
649681

682+
// Checks if the given DefId is a desugared async couroutine that should inherit inline attrs.
683+
fn async_poll_inherit_inline(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
684+
let Some(kind) = tcx.coroutine_kind(def_id) else {
685+
return None;
686+
};
687+
688+
if matches!(
689+
kind,
690+
CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Fn)
691+
| CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)
692+
) {
693+
Some(tcx.parent(def_id))
694+
} else {
695+
None
696+
}
697+
}
698+
650699
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
651700
/// macros. There are two forms. The pure one without args to mark primal functions (the functions
652701
/// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the

0 commit comments

Comments
 (0)