@@ -10,9 +10,10 @@ use std::collections::hash_map::Entry;
1010use std:: slice;
1111
1212use rustc_abi:: { Align , ExternAbi , Size } ;
13- use rustc_ast:: { AttrStyle , LitKind , MetaItemKind , ast} ;
13+ use rustc_ast:: { AttrStyle , MetaItemKind , ast} ;
1414use rustc_attr_parsing:: { AttributeParser , Late } ;
1515use rustc_data_structures:: fx:: FxHashMap ;
16+ use rustc_data_structures:: thin_vec:: ThinVec ;
1617use rustc_errors:: { DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
1718use rustc_feature:: {
1819 ACCEPTED_LANG_FEATURES , AttributeDuplicates , AttributeType , BUILTIN_ATTRIBUTE_MAP ,
@@ -211,6 +212,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
211212 Attribute :: Parsed ( AttributeKind :: MacroExport { span, .. } ) => {
212213 self . check_macro_export ( hir_id, * span, target)
213214 } ,
215+ Attribute :: Parsed ( AttributeKind :: RustcLegacyConstGenerics { attr_span, fn_indexes} ) => {
216+ self . check_rustc_legacy_const_generics ( item, * attr_span, fn_indexes)
217+ } ,
214218 Attribute :: Parsed ( AttributeKind :: Doc ( attr) ) => self . check_doc_attrs ( attr, hir_id, target) ,
215219 Attribute :: Parsed ( AttributeKind :: EiiImpls ( impls) ) => {
216220 self . check_eii_impl ( impls, target)
@@ -305,9 +309,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
305309 [ sym:: rustc_never_returns_null_ptr, ..] => {
306310 self . check_applied_to_fn_or_method ( hir_id, attr. span ( ) , span, target)
307311 }
308- [ sym:: rustc_legacy_const_generics, ..] => {
309- self . check_rustc_legacy_const_generics ( hir_id, attr, span, target, item)
310- }
311312 [ sym:: rustc_lint_query_instability, ..] => {
312313 self . check_applied_to_fn_or_method ( hir_id, attr. span ( ) , span, target)
313314 }
@@ -1217,76 +1218,50 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
12171218 /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
12181219 fn check_rustc_legacy_const_generics (
12191220 & self ,
1220- hir_id : HirId ,
1221- attr : & Attribute ,
1222- span : Span ,
1223- target : Target ,
12241221 item : Option < ItemLike < ' _ > > ,
1222+ attr_span : Span ,
1223+ index_list : & ThinVec < ( usize , Span ) > ,
12251224 ) {
1226- let is_function = matches ! ( target, Target :: Fn ) ;
1227- if !is_function {
1228- self . dcx ( ) . emit_err ( errors:: AttrShouldBeAppliedToFn {
1229- attr_span : attr. span ( ) ,
1230- defn_span : span,
1231- on_crate : hir_id == CRATE_HIR_ID ,
1232- } ) ;
1233- return ;
1234- }
1235-
1236- let Some ( list) = attr. meta_item_list ( ) else {
1237- // The attribute form is validated on AST.
1238- return ;
1239- } ;
1240-
12411225 let Some ( ItemLike :: Item ( Item {
12421226 kind : ItemKind :: Fn { sig : FnSig { decl, .. } , generics, .. } ,
12431227 ..
12441228 } ) ) = item
12451229 else {
1246- bug ! ( "should be a function item" ) ;
1230+ // No error here, since it's already given by the parser
1231+ return ;
12471232 } ;
12481233
12491234 for param in generics. params {
12501235 match param. kind {
12511236 hir:: GenericParamKind :: Const { .. } => { }
12521237 _ => {
12531238 self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsOnly {
1254- attr_span : attr . span ( ) ,
1239+ attr_span,
12551240 param_span : param. span ,
12561241 } ) ;
12571242 return ;
12581243 }
12591244 }
12601245 }
12611246
1262- if list . len ( ) != generics. params . len ( ) {
1247+ if index_list . len ( ) != generics. params . len ( ) {
12631248 self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndex {
1264- attr_span : attr . span ( ) ,
1249+ attr_span,
12651250 generics_span : generics. span ,
12661251 } ) ;
12671252 return ;
12681253 }
12691254
1270- let arg_count = decl. inputs . len ( ) as u128 + generics. params . len ( ) as u128 ;
1271- let mut invalid_args = vec ! [ ] ;
1272- for meta in list {
1273- if let Some ( LitKind :: Int ( val, _) ) = meta. lit ( ) . map ( |lit| & lit. kind ) {
1274- if * val >= arg_count {
1275- let span = meta. span ( ) ;
1276- self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexExceed {
1277- span,
1278- arg_count : arg_count as usize ,
1279- } ) ;
1280- return ;
1281- }
1282- } else {
1283- invalid_args. push ( meta. span ( ) ) ;
1255+ let arg_count = decl. inputs . len ( ) + generics. params . len ( ) ;
1256+ for ( index, span) in index_list {
1257+ if * index >= arg_count {
1258+ self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexExceed {
1259+ span : * span,
1260+ arg_count,
1261+ } ) ;
1262+ return ;
12841263 }
12851264 }
1286-
1287- if !invalid_args. is_empty ( ) {
1288- self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexNegative { invalid_args } ) ;
1289- }
12901265 }
12911266
12921267 /// Helper function for checking that the provided attribute is only applied to a function or
0 commit comments