@@ -996,6 +996,8 @@ pub struct Resolver<'a> {
996996 /// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
997997 /// FIXME: Replace with a more general AST map (together with some other fields).
998998 trait_impl_items : FxHashSet < LocalDefId > ,
999+
1000+ legacy_const_generic_args : FxHashMap < DefId , Option < Vec < usize > > > ,
9991001}
10001002
10011003/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1077,7 +1079,7 @@ impl ResolverAstLowering for Resolver<'_> {
10771079 self . cstore ( ) . item_generics_num_lifetimes ( def_id, sess)
10781080 }
10791081
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 > > {
10811083 self . legacy_const_generic_args ( expr)
10821084 }
10831085
@@ -1321,6 +1323,7 @@ impl<'a> Resolver<'a> {
13211323 invocation_parents,
13221324 next_disambiguator : Default :: default ( ) ,
13231325 trait_impl_items : Default :: default ( ) ,
1326+ legacy_const_generic_args : Default :: default ( ) ,
13241327 } ;
13251328
13261329 let root_parent_scope = ParentScope :: module ( graph_root, & resolver) ;
@@ -3317,7 +3320,7 @@ impl<'a> Resolver<'a> {
33173320 /// Checks if an expression refers to a function marked with
33183321 /// `#[rustc_legacy_const_generics]` and returns the argument index list
33193322 /// 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 > > {
33213324 if let ExprKind :: Path ( None , path) = & expr. kind {
33223325 // Don't perform legacy const generics rewriting if the path already
33233326 // has generic arguments.
@@ -3338,20 +3341,32 @@ impl<'a> Resolver<'a> {
33383341 return None ;
33393342 }
33403343
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" ) ,
33503360 }
3351- _ => panic ! ( "invalid arg index" ) ,
33523361 }
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;
33553370 }
33563371 }
33573372 None
0 commit comments