@@ -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)
@@ -306,9 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
306310 [ sym:: rustc_never_returns_null_ptr, ..] => {
307311 self . check_applied_to_fn_or_method ( hir_id, attr. span ( ) , span, target)
308312 }
309- [ sym:: rustc_legacy_const_generics, ..] => {
310- self . check_rustc_legacy_const_generics ( hir_id, attr, span, target, item)
311- }
312313 [ sym:: rustc_lint_query_instability, ..] => {
313314 self . check_applied_to_fn_or_method ( hir_id, attr. span ( ) , span, target)
314315 }
@@ -1218,76 +1219,49 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
12181219 /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
12191220 fn check_rustc_legacy_const_generics (
12201221 & self ,
1221- hir_id : HirId ,
1222- attr : & Attribute ,
1223- span : Span ,
1224- target : Target ,
12251222 item : Option < ItemLike < ' _ > > ,
1223+ attr_span : Span ,
1224+ index_list : & ThinVec < ( usize , Span ) > ,
12261225 ) {
1227- let is_function = matches ! ( target, Target :: Fn ) ;
1228- if !is_function {
1229- self . dcx ( ) . emit_err ( errors:: AttrShouldBeAppliedToFn {
1230- attr_span : attr. span ( ) ,
1231- defn_span : span,
1232- on_crate : hir_id == CRATE_HIR_ID ,
1233- } ) ;
1234- return ;
1235- }
1236-
1237- let Some ( list) = attr. meta_item_list ( ) else {
1238- // The attribute form is validated on AST.
1239- return ;
1240- } ;
1241-
12421226 let Some ( ItemLike :: Item ( Item {
12431227 kind : ItemKind :: Fn { sig : FnSig { decl, .. } , generics, .. } ,
12441228 ..
12451229 } ) ) = item
12461230 else {
1247- bug ! ( "should be a function item" ) ;
1231+ // No error here, since it's already given by the parser
1232+ return ;
12481233 } ;
12491234
12501235 for param in generics. params {
12511236 match param. kind {
12521237 hir:: GenericParamKind :: Const { .. } => { }
12531238 _ => {
12541239 self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsOnly {
1255- attr_span : attr . span ( ) ,
1240+ attr_span,
12561241 param_span : param. span ,
12571242 } ) ;
12581243 return ;
12591244 }
12601245 }
12611246 }
12621247
1263- if list . len ( ) != generics. params . len ( ) {
1248+ if index_list . len ( ) != generics. params . len ( ) {
12641249 self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndex {
1265- attr_span : attr . span ( ) ,
1250+ attr_span,
12661251 generics_span : generics. span ,
12671252 } ) ;
12681253 return ;
12691254 }
12701255
1271- let arg_count = decl. inputs . len ( ) as u128 + generics. params . len ( ) as u128 ;
1272- let mut invalid_args = vec ! [ ] ;
1273- for meta in list {
1274- if let Some ( LitKind :: Int ( val, _) ) = meta. lit ( ) . map ( |lit| & lit. kind ) {
1275- if * val >= arg_count {
1276- let span = meta. span ( ) ;
1277- self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexExceed {
1278- span,
1279- arg_count : arg_count as usize ,
1280- } ) ;
1281- return ;
1282- }
1283- } else {
1284- invalid_args. push ( meta. span ( ) ) ;
1256+ let arg_count = decl. inputs . len ( ) + generics. params . len ( ) ;
1257+ for ( index, span) in index_list {
1258+ if * index >= arg_count {
1259+ self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexExceed {
1260+ span : * span,
1261+ arg_count,
1262+ } ) ;
12851263 }
12861264 }
1287-
1288- if !invalid_args. is_empty ( ) {
1289- self . dcx ( ) . emit_err ( errors:: RustcLegacyConstGenericsIndexNegative { invalid_args } ) ;
1290- }
12911265 }
12921266
12931267 /// Helper function for checking that the provided attribute is only applied to a function or
0 commit comments