@@ -6,7 +6,10 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
66use rustc_hir:: attrs:: { AttributeKind , InlineAttr , InstructionSetAttr , RtsanSetting , UsedBy } ;
77use rustc_hir:: def:: DefKind ;
88use 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+ } ;
1013use 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