@@ -29,6 +29,7 @@ use rustc_ast::unwrap_or;
2929use rustc_ast:: visit:: { self , Visitor } ;
3030use rustc_ast:: { self as ast, NodeId } ;
3131use rustc_ast:: { Crate , CRATE_NODE_ID } ;
32+ use rustc_ast:: { Expr , ExprKind , LitKind } ;
3233use rustc_ast:: { ItemKind , ModKind , Path } ;
3334use rustc_ast_lowering:: ResolverAstLowering ;
3435use rustc_ast_pretty:: pprust;
@@ -1076,8 +1077,8 @@ impl ResolverAstLowering for Resolver<'_> {
10761077 self . cstore ( ) . item_generics_num_lifetimes ( def_id, sess)
10771078 }
10781079
1079- fn item_attrs ( & self , def_id : DefId , sess : & Session ) -> Vec < ast :: Attribute > {
1080- self . cstore ( ) . item_attrs ( def_id , sess )
1080+ fn legacy_const_generic_args ( & self , expr : & Expr ) -> Option < Vec < usize > > {
1081+ self . legacy_const_generic_args ( expr )
10811082 }
10821083
10831084 fn get_partial_res ( & mut self , id : NodeId ) -> Option < PartialRes > {
@@ -3312,6 +3313,49 @@ impl<'a> Resolver<'a> {
33123313 pub fn opt_span ( & self , def_id : DefId ) -> Option < Span > {
33133314 if let Some ( def_id) = def_id. as_local ( ) { Some ( self . def_id_to_span [ def_id] ) } else { None }
33143315 }
3316+
3317+ /// Checks if an expression refers to a function marked with
3318+ /// `#[rustc_legacy_const_generics]` and returns the argument index list
3319+ /// from the attribute.
3320+ pub fn legacy_const_generic_args ( & self , expr : & Expr ) -> Option < Vec < usize > > {
3321+ if let ExprKind :: Path ( None , path) = & expr. kind {
3322+ // Don't perform legacy const generics rewriting if the path already
3323+ // has generic arguments.
3324+ if path. segments . last ( ) . unwrap ( ) . args . is_some ( ) {
3325+ return None ;
3326+ }
3327+
3328+ let partial_res = self . partial_res_map . get ( & expr. id ) ?;
3329+ if partial_res. unresolved_segments ( ) != 0 {
3330+ return None ;
3331+ }
3332+
3333+ if let Res :: Def ( def:: DefKind :: Fn , def_id) = partial_res. base_res ( ) {
3334+ // We only support cross-crate argument rewriting. Uses
3335+ // within the same crate should be updated to use the new
3336+ // const generics style.
3337+ if def_id. is_local ( ) {
3338+ return None ;
3339+ }
3340+
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 ) ;
3350+ }
3351+ _ => panic ! ( "invalid arg index" ) ,
3352+ }
3353+ }
3354+ return Some ( ret) ;
3355+ }
3356+ }
3357+ None
3358+ }
33153359}
33163360
33173361fn names_to_string ( names : & [ Symbol ] ) -> String {
0 commit comments