@@ -43,13 +43,15 @@ use hir::def::{DefKind, PartialRes, Res};
4343use hir:: { BodyId , HirId } ;
4444use rustc_abi:: ExternAbi ;
4545use rustc_ast:: * ;
46+ use rustc_attr_parsing:: { AttributeParser , ShouldEmit } ;
4647use rustc_errors:: ErrorGuaranteed ;
48+ use rustc_hir:: Target ;
4749use rustc_hir:: attrs:: { AttributeKind , InlineAttr } ;
4850use rustc_hir:: def_id:: DefId ;
4951use rustc_middle:: span_bug;
5052use rustc_middle:: ty:: { Asyncness , DelegationFnSigAttrs , ResolverAstLowering } ;
5153use rustc_span:: symbol:: kw;
52- use rustc_span:: { Ident , Span , Symbol } ;
54+ use rustc_span:: { DUMMY_SP , Ident , Span , Symbol } ;
5355use { rustc_ast as ast, rustc_hir as hir} ;
5456
5557use super :: { GenericArgsMode , ImplTraitContext , LoweringContext , ParamMode } ;
@@ -69,7 +71,7 @@ struct AttributeAdditionInfo {
6971
7072enum AttributeAdditionKind {
7173 Default { factory : fn ( Span ) -> hir:: Attribute } ,
72- Inherit { flag : DelegationFnSigAttrs , factory : fn ( Span ) -> hir:: Attribute } ,
74+ Inherit { flag : DelegationFnSigAttrs , factory : fn ( Span , & hir :: Attribute ) -> hir:: Attribute } ,
7375}
7476
7577const PARENT_ID : hir:: ItemLocalId = hir:: ItemLocalId :: ZERO ;
@@ -78,7 +80,17 @@ static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[
7880 AttributeAdditionInfo {
7981 equals : |a| matches ! ( a, hir:: Attribute :: Parsed ( AttributeKind :: MustUse { .. } ) ) ,
8082 kind : AttributeAdditionKind :: Inherit {
81- factory : |span| hir:: Attribute :: Parsed ( AttributeKind :: MustUse { span, reason : None } ) ,
83+ factory : |span, original_attribute| {
84+ let reason = match original_attribute {
85+ hir:: Attribute :: Parsed ( AttributeKind :: MustUse {
86+ span : _,
87+ reason : Some ( reason) ,
88+ } ) => Some ( reason. clone ( ) ) ,
89+ _ => None ,
90+ } ;
91+
92+ hir:: Attribute :: Parsed ( AttributeKind :: MustUse { span, reason } )
93+ } ,
8294 flag : DelegationFnSigAttrs :: MUST_USE ,
8395 } ,
8496 } ,
@@ -160,6 +172,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
160172 sig_id : DefId ,
161173 existing_attrs : Option < & & [ hir:: Attribute ] > ,
162174 ) -> Vec < hir:: Attribute > {
175+ let local_original_attributes = self . parse_local_original_attributes ( sig_id) ;
176+
163177 candidate_additions
164178 . iter ( )
165179 . filter_map ( |addition_info| {
@@ -174,33 +188,57 @@ impl<'hir> LoweringContext<'_, 'hir> {
174188 match addition_info. kind {
175189 AttributeAdditionKind :: Default { factory } => Some ( factory ( span) ) ,
176190 AttributeAdditionKind :: Inherit { flag, factory } => {
177- // Check if an attribute present on the target of delegation,
178- // either in this crate or other
179- let should_inherit = match sig_id. as_local ( ) {
191+ let original_attribute = match sig_id. as_local ( ) {
180192 Some ( local_id) => self
181193 . resolver
182194 . delegation_fn_sigs
183195 . get ( & local_id)
184- . is_some_and ( |sig| sig. attrs_flags . contains ( flag) ) ,
185- // We can not use `tcx.has_attr` and symbol here as attributes
186- // from other crates have None in their identifiers
196+ . is_some_and ( |sig| sig. attrs_flags . contains ( flag) )
197+ . then ( || {
198+ local_original_attributes
199+ . as_ref ( )
200+ . map ( |attrs| {
201+ attrs
202+ . iter ( )
203+ . find ( |base_attr| ( addition_info. equals ) ( base_attr) )
204+ } )
205+ . flatten ( )
206+ } )
207+ . flatten ( ) ,
187208 None => self
188209 . tcx
189210 . get_all_attrs ( sig_id)
190211 . iter ( )
191- . any ( |base_attr| ( addition_info. equals ) ( base_attr) ) ,
212+ . find ( |base_attr| ( addition_info. equals ) ( base_attr) ) ,
192213 } ;
193214
194- match should_inherit {
195- true => Some ( factory ( span) ) ,
196- false => None ,
197- }
215+ original_attribute. map ( |a| factory ( span, a) )
198216 }
199217 }
200218 } )
201219 . collect :: < Vec < _ > > ( )
202220 }
203221
222+ fn parse_local_original_attributes ( & self , sig_id : DefId ) -> Option < Vec < hir:: Attribute > > {
223+ if let Some ( local_id) = sig_id. as_local ( )
224+ && let Some ( info) = self . resolver . delegation_fn_sigs . get ( & local_id)
225+ && !info. to_inherit_attrs . is_empty ( )
226+ {
227+ Some ( AttributeParser :: parse_limited_all (
228+ self . tcx . sess ,
229+ info. to_inherit_attrs . as_slice ( ) ,
230+ None ,
231+ Target :: Fn ,
232+ DUMMY_SP ,
233+ DUMMY_NODE_ID ,
234+ Some ( self . tcx . features ( ) ) ,
235+ ShouldEmit :: Nothing ,
236+ ) )
237+ } else {
238+ None
239+ }
240+ }
241+
204242 fn get_delegation_sig_id (
205243 & self ,
206244 item_id : NodeId ,
0 commit comments