@@ -45,16 +45,15 @@ use hir::{BodyId, HirId};
4545use rustc_abi:: ExternAbi ;
4646use rustc_ast as ast;
4747use rustc_ast:: * ;
48- use rustc_attr_parsing:: { AttributeParser , ShouldEmit } ;
4948use rustc_data_structures:: fx:: FxHashSet ;
5049use rustc_errors:: ErrorGuaranteed ;
5150use rustc_hir as hir;
5251use rustc_hir:: attrs:: { AttributeKind , InlineAttr } ;
53- use rustc_hir:: def_id:: { DefId , LocalDefId } ;
52+ use rustc_hir:: def_id:: DefId ;
5453use rustc_middle:: span_bug;
55- use rustc_middle:: ty:: { Asyncness , DelegationAttrs , DelegationFnSigAttrs } ;
54+ use rustc_middle:: ty:: Asyncness ;
5655use rustc_span:: symbol:: kw;
57- use rustc_span:: { DUMMY_SP , Ident , Span , Symbol } ;
56+ use rustc_span:: { Ident , Span , Symbol } ;
5857use smallvec:: SmallVec ;
5958
6059use crate :: delegation:: generics:: { GenericsGenerationResult , GenericsGenerationResults } ;
@@ -80,7 +79,7 @@ struct AttrAdditionInfo {
8079
8180enum AttrAdditionKind {
8281 Default { factory : fn ( Span ) -> hir:: Attribute } ,
83- Inherit { flag : DelegationFnSigAttrs , factory : fn ( Span , & hir:: Attribute ) -> hir:: Attribute } ,
82+ Inherit { factory : fn ( Span , & hir:: Attribute ) -> hir:: Attribute } ,
8483}
8584
8685const PARENT_ID : hir:: ItemLocalId = hir:: ItemLocalId :: ZERO ;
@@ -97,7 +96,6 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
9796
9897 hir:: Attribute :: Parsed ( AttributeKind :: MustUse { span, reason } )
9998 } ,
100- flag : DelegationFnSigAttrs :: MUST_USE ,
10199 } ,
102100 } ,
103101 AttrAdditionInfo {
@@ -108,43 +106,11 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
108106 } ,
109107] ;
110108
111- type DelegationIdsVec = SmallVec < [ DefId ; 1 ] > ;
112-
113- // As delegations can now refer to another delegation, we have a delegation path
114- // of the following type: reuse (current delegation) <- reuse (delegee_id) <- ... <- reuse <- function (root_function_id).
115- // In its most basic and widely used form: reuse (current delegation) <- function (delegee_id, root_function_id)
116- struct DelegationIds {
117- path : DelegationIdsVec ,
118- }
119-
120- impl DelegationIds {
121- fn new ( path : DelegationIdsVec ) -> Self {
122- assert ! ( !path. is_empty( ) ) ;
123- Self { path }
124- }
125-
126- // Id of the first function in (non)local crate that is being reused
127- fn root_function_id ( & self ) -> DefId {
128- * self . path . last ( ) . expect ( "Ids vector can't be empty" )
129- }
130-
131- // Id of the first definition which is being reused,
132- // can be either function, in this case `root_id == delegee_id`, or other delegation
133- fn delegee_id ( & self ) -> DefId {
134- * self . path . first ( ) . expect ( "Ids vector can't be empty" )
135- }
136- }
137-
138109impl < ' hir , R : ResolverAstLoweringExt < ' hir > > LoweringContext < ' _ , ' hir , R > {
139110 fn is_method ( & self , def_id : DefId , span : Span ) -> bool {
140111 match self . tcx . def_kind ( def_id) {
141112 DefKind :: Fn => false ,
142- DefKind :: AssocFn => match def_id. as_local ( ) {
143- Some ( local_def_id) => {
144- self . resolver . delegation_fn_sig ( local_def_id) . is_some_and ( |sig| sig. has_self )
145- }
146- None => self . tcx . associated_item ( def_id) . is_method ( ) ,
147- } ,
113+ DefKind :: AssocFn => self . tcx . associated_item ( def_id) . is_method ( ) ,
148114 _ => span_bug ! ( span, "unexpected DefKind for delegation item" ) ,
149115 }
150116 }
@@ -157,10 +123,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
157123 let span = self . lower_span ( delegation. path . segments . last ( ) . unwrap ( ) . ident . span ) ;
158124
159125 // Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356)
160- let ids = if let Some ( delegation_info) =
126+ let sig_id = if let Some ( delegation_info) =
161127 self . resolver . delegation_info ( self . local_def_id ( item_id) )
162128 {
163- self . get_delegation_ids ( delegation_info. resolution_node , span)
129+ self . get_sig_id ( delegation_info. resolution_node , span)
164130 } else {
165131 return self . generate_delegation_error (
166132 self . dcx ( ) . span_delayed_bug (
@@ -172,28 +138,16 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
172138 ) ;
173139 } ;
174140
175- match ids {
176- Ok ( ids) => {
177- self . add_attrs_if_needed ( span, & ids) ;
178-
179- let delegee_id = ids. delegee_id ( ) ;
180- let root_function_id = ids. root_function_id ( ) ;
141+ match sig_id {
142+ Ok ( sig_id) => {
143+ self . add_attrs_if_needed ( span, sig_id) ;
181144
182- // `is_method` is used to choose the name of the first parameter (`self` or `arg0`),
183- // if the original function is not a method (without `self`), then it can not be added
184- // during chain of reuses, so we use `root_function_id` here
185- let is_method = self . is_method ( root_function_id, span) ;
145+ let is_method = self . is_method ( sig_id, span) ;
186146
187- // Here we use `root_function_id` as we can not get params information out of potential delegation reuse,
188- // we need a function to extract this information
189- let ( param_count, c_variadic) = self . param_count ( root_function_id) ;
147+ let ( param_count, c_variadic) = self . param_count ( sig_id) ;
190148
191- let mut generics = self . lower_delegation_generics (
192- delegation,
193- ids. root_function_id ( ) ,
194- item_id,
195- span,
196- ) ;
149+ let mut generics =
150+ self . lower_delegation_generics ( delegation, sig_id, item_id, span) ;
197151
198152 let body_id = self . lower_delegation_body (
199153 delegation,
@@ -204,20 +158,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
204158 span,
205159 ) ;
206160
207- // Here we use `delegee_id`, as this id will then be used to calculate parent for generics
208- // inheritance, and we want this id to point on a delegee, not on the original
209- // function (see https://github.com/rust-lang/rust/issues/150152#issuecomment-3674834654)
210- let decl = self . lower_delegation_decl (
211- delegee_id,
212- param_count,
213- c_variadic,
214- span,
215- & generics,
216- ) ;
161+ let decl =
162+ self . lower_delegation_decl ( sig_id, param_count, c_variadic, span, & generics) ;
217163
218- // Here we pass `root_function_id` as we want to inherit signature (including consts, async)
219- // from the root function that started delegation
220- let sig = self . lower_delegation_sig ( root_function_id, decl, span) ;
164+ let sig = self . lower_delegation_sig ( sig_id, decl, span) ;
221165 let ident = self . lower_ident ( delegation. ident ) ;
222166
223167 let generics = self . arena . alloc ( hir:: Generics {
@@ -236,9 +180,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
236180 }
237181 }
238182
239- fn add_attrs_if_needed ( & mut self , span : Span , ids : & DelegationIds ) {
183+ fn add_attrs_if_needed ( & mut self , span : Span , sig_id : DefId ) {
240184 let new_attrs =
241- self . create_new_attrs ( ATTRS_ADDITIONS , span, ids , self . attrs . get ( & PARENT_ID ) ) ;
185+ self . create_new_attrs ( ATTRS_ADDITIONS , span, sig_id , self . attrs . get ( & PARENT_ID ) ) ;
242186
243187 if new_attrs. is_empty ( ) {
244188 return ;
@@ -258,15 +202,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
258202 & self ,
259203 candidate_additions : & [ AttrAdditionInfo ] ,
260204 span : Span ,
261- ids : & DelegationIds ,
205+ sig_id : DefId ,
262206 existing_attrs : Option < & & [ hir:: Attribute ] > ,
263207 ) -> Vec < hir:: Attribute > {
264- let defs_orig_attrs = ids
265- . path
266- . iter ( )
267- . map ( |def_id| ( * def_id, self . parse_local_original_attrs ( * def_id) ) )
268- . collect :: < Vec < _ > > ( ) ;
269-
270208 candidate_additions
271209 . iter ( )
272210 . filter_map ( |addition_info| {
@@ -280,83 +218,22 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
280218
281219 match addition_info. kind {
282220 AttrAdditionKind :: Default { factory } => Some ( factory ( span) ) ,
283- AttrAdditionKind :: Inherit { flag, factory } => {
284- for ( def_id, orig_attrs) in & defs_orig_attrs {
285- let original_attr = match def_id. as_local ( ) {
286- Some ( local_id) => self
287- . get_attrs ( local_id)
288- . flags
289- . contains ( flag)
290- . then ( || {
291- orig_attrs
292- . as_ref ( )
293- . map ( |attrs| {
294- attrs. iter ( ) . find ( |base_attr| {
295- ( addition_info. equals ) ( base_attr)
296- } )
297- } )
298- . flatten ( )
299- } )
300- . flatten ( ) ,
301- None =>
302- {
303- #[ allow( deprecated) ]
304- self . tcx
305- . get_all_attrs ( * def_id)
306- . iter ( )
307- . find ( |base_attr| ( addition_info. equals ) ( base_attr) )
308- }
309- } ;
310-
311- if let Some ( original_attr) = original_attr {
312- return Some ( factory ( span, original_attr) ) ;
313- }
314- }
315-
316- None
221+ AttrAdditionKind :: Inherit { factory, .. } =>
222+ {
223+ #[ allow( deprecated) ]
224+ self . tcx
225+ . get_all_attrs ( sig_id)
226+ . iter ( )
227+ . find_map ( |a| ( addition_info. equals ) ( a) . then ( || factory ( span, a) ) )
317228 }
318229 }
319230 } )
320231 . collect :: < Vec < _ > > ( )
321232 }
322233
323- fn parse_local_original_attrs ( & self , def_id : DefId ) -> Option < Vec < hir:: Attribute > > {
324- if let Some ( local_id) = def_id. as_local ( ) {
325- let attrs = & self . get_attrs ( local_id) . to_inherit ;
326-
327- if !attrs. is_empty ( ) {
328- return Some ( AttributeParser :: parse_limited_all (
329- self . tcx . sess ,
330- attrs,
331- None ,
332- hir:: Target :: Fn ,
333- DUMMY_SP ,
334- DUMMY_NODE_ID ,
335- Some ( self . tcx . features ( ) ) ,
336- ShouldEmit :: Nothing ,
337- ) ) ;
338- }
339- }
340-
341- None
342- }
343-
344- fn get_attrs ( & self , local_id : LocalDefId ) -> & DelegationAttrs {
345- // local_id can correspond either to a function or other delegation
346- if let Some ( fn_sig) = self . resolver . delegation_fn_sig ( local_id) {
347- & fn_sig. attrs
348- } else {
349- & self . resolver . delegation_info ( local_id) . expect ( "processing delegation" ) . attrs
350- }
351- }
352-
353- fn get_delegation_ids (
354- & self ,
355- mut node_id : NodeId ,
356- span : Span ,
357- ) -> Result < DelegationIds , ErrorGuaranteed > {
234+ fn get_sig_id ( & self , mut node_id : NodeId , span : Span ) -> Result < DefId , ErrorGuaranteed > {
358235 let mut visited: FxHashSet < NodeId > = Default :: default ( ) ;
359- let mut path: DelegationIdsVec = Default :: default ( ) ;
236+ let mut path: SmallVec < [ DefId ; 1 ] > = Default :: default ( ) ;
360237
361238 loop {
362239 visited. insert ( node_id) ;
@@ -389,7 +266,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
389266 } ) ;
390267 }
391268 } else {
392- return Ok ( DelegationIds :: new ( path) ) ;
269+ return Ok ( path[ 0 ] ) ;
393270 }
394271 }
395272 }
@@ -400,15 +277,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
400277
401278 // Function parameter count, including C variadic `...` if present.
402279 fn param_count ( & self , def_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
403- if let Some ( local_sig_id) = def_id. as_local ( ) {
404- match self . resolver . delegation_fn_sig ( local_sig_id) {
405- Some ( sig) => ( sig. param_count , sig. c_variadic ) ,
406- None => ( 0 , false ) ,
407- }
408- } else {
409- let sig = self . tcx . fn_sig ( def_id) . skip_binder ( ) . skip_binder ( ) ;
410- ( sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ) , sig. c_variadic )
411- }
280+ let sig = self . tcx . fn_sig ( def_id) . skip_binder ( ) . skip_binder ( ) ;
281+ ( sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ) , sig. c_variadic )
412282 }
413283
414284 fn lower_delegation_decl (
@@ -455,41 +325,21 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
455325 decl : & ' hir hir:: FnDecl < ' hir > ,
456326 span : Span ,
457327 ) -> hir:: FnSig < ' hir > {
458- let header = if let Some ( local_sig_id) = sig_id. as_local ( ) {
459- match self . resolver . delegation_fn_sig ( local_sig_id) {
460- Some ( sig) => {
461- let parent = self . tcx . parent ( sig_id) ;
462- // HACK: we override the default safety instead of generating attributes from the ether.
463- // We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
464- // and here we need the hir attributes.
465- let default_safety =
466- if sig. attrs . flags . contains ( DelegationFnSigAttrs :: TARGET_FEATURE )
467- || self . tcx . def_kind ( parent) == DefKind :: ForeignMod
468- {
469- hir:: Safety :: Unsafe
470- } else {
471- hir:: Safety :: Safe
472- } ;
473- self . lower_fn_header ( sig. header , default_safety, & [ ] )
474- }
475- None => self . generate_header_error ( ) ,
476- }
477- } else {
478- let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
479- let asyncness = match self . tcx . asyncness ( sig_id) {
480- Asyncness :: Yes => hir:: IsAsync :: Async ( span) ,
481- Asyncness :: No => hir:: IsAsync :: NotAsync ,
482- } ;
483- hir:: FnHeader {
484- safety : if self . tcx . codegen_fn_attrs ( sig_id) . safe_target_features {
485- hir:: HeaderSafety :: SafeTargetFeatures
486- } else {
487- hir:: HeaderSafety :: Normal ( sig. safety )
488- } ,
489- constness : self . tcx . constness ( sig_id) ,
490- asyncness,
491- abi : sig. abi ,
492- }
328+ let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
329+ let asyncness = match self . tcx . asyncness ( sig_id) {
330+ Asyncness :: Yes => hir:: IsAsync :: Async ( span) ,
331+ Asyncness :: No => hir:: IsAsync :: NotAsync ,
332+ } ;
333+
334+ let header = hir:: FnHeader {
335+ safety : if self . tcx . codegen_fn_attrs ( sig_id) . safe_target_features {
336+ hir:: HeaderSafety :: SafeTargetFeatures
337+ } else {
338+ hir:: HeaderSafety :: Normal ( sig. safety )
339+ } ,
340+ constness : self . tcx . constness ( sig_id) ,
341+ asyncness,
342+ abi : sig. abi ,
493343 } ;
494344
495345 hir:: FnSig { decl, header, span }
0 commit comments