@@ -996,6 +996,8 @@ pub struct Resolver<'a> {
996
996
/// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
997
997
/// FIXME: Replace with a more general AST map (together with some other fields).
998
998
trait_impl_items : FxHashSet < LocalDefId > ,
999
+
1000
+ legacy_const_generic_args : FxHashMap < DefId , Option < Vec < usize > > > ,
999
1001
}
1000
1002
1001
1003
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1077,7 +1079,7 @@ impl ResolverAstLowering for Resolver<'_> {
1077
1079
self . cstore ( ) . item_generics_num_lifetimes ( def_id, sess)
1078
1080
}
1079
1081
1080
- fn legacy_const_generic_args ( & self , expr : & Expr ) -> Option < Vec < usize > > {
1082
+ fn legacy_const_generic_args ( & mut self , expr : & Expr ) -> Option < Vec < usize > > {
1081
1083
self . legacy_const_generic_args ( expr)
1082
1084
}
1083
1085
@@ -1321,6 +1323,7 @@ impl<'a> Resolver<'a> {
1321
1323
invocation_parents,
1322
1324
next_disambiguator : Default :: default ( ) ,
1323
1325
trait_impl_items : Default :: default ( ) ,
1326
+ legacy_const_generic_args : Default :: default ( ) ,
1324
1327
} ;
1325
1328
1326
1329
let root_parent_scope = ParentScope :: module ( graph_root, & resolver) ;
@@ -3317,7 +3320,7 @@ impl<'a> Resolver<'a> {
3317
3320
/// Checks if an expression refers to a function marked with
3318
3321
/// `#[rustc_legacy_const_generics]` and returns the argument index list
3319
3322
/// from the attribute.
3320
- pub fn legacy_const_generic_args ( & self , expr : & Expr ) -> Option < Vec < usize > > {
3323
+ pub fn legacy_const_generic_args ( & mut self , expr : & Expr ) -> Option < Vec < usize > > {
3321
3324
if let ExprKind :: Path ( None , path) = & expr. kind {
3322
3325
// Don't perform legacy const generics rewriting if the path already
3323
3326
// has generic arguments.
@@ -3338,20 +3341,32 @@ impl<'a> Resolver<'a> {
3338
3341
return None ;
3339
3342
}
3340
3343
3341
- let attrs = self . cstore ( ) . item_attrs ( def_id, self . session ) ;
3342
- let attr = attrs
3343
- . iter ( )
3344
- . find ( |a| self . session . check_name ( a, sym:: rustc_legacy_const_generics) ) ?;
3345
- let mut ret = vec ! [ ] ;
3346
- for meta in attr. meta_item_list ( ) ? {
3347
- match meta. literal ( ) ?. kind {
3348
- LitKind :: Int ( a, _) => {
3349
- ret. push ( a as usize ) ;
3344
+ if let Some ( v) = self . legacy_const_generic_args . get ( & def_id) {
3345
+ return v. clone ( ) ;
3346
+ }
3347
+
3348
+ let parse_attrs = || {
3349
+ let attrs = self . cstore ( ) . item_attrs ( def_id, self . session ) ;
3350
+ let attr = attrs
3351
+ . iter ( )
3352
+ . find ( |a| self . session . check_name ( a, sym:: rustc_legacy_const_generics) ) ?;
3353
+ let mut ret = vec ! [ ] ;
3354
+ for meta in attr. meta_item_list ( ) ? {
3355
+ match meta. literal ( ) ?. kind {
3356
+ LitKind :: Int ( a, _) => {
3357
+ ret. push ( a as usize ) ;
3358
+ }
3359
+ _ => panic ! ( "invalid arg index" ) ,
3350
3360
}
3351
- _ => panic ! ( "invalid arg index" ) ,
3352
3361
}
3353
- }
3354
- return Some ( ret) ;
3362
+ Some ( ret)
3363
+ } ;
3364
+
3365
+ // Cache the lookup to avoid parsing attributes for an iterm
3366
+ // multiple times.
3367
+ let ret = parse_attrs ( ) ;
3368
+ self . legacy_const_generic_args . insert ( def_id, ret. clone ( ) ) ;
3369
+ return ret;
3355
3370
}
3356
3371
}
3357
3372
None
0 commit comments