@@ -9,7 +9,7 @@ use rustc_ast::{
99 self as ast, AttrArgs , Attribute , DelimArgs , MetaItem , MetaItemInner , MetaItemKind , Safety ,
1010} ;
1111use rustc_errors:: { Applicability , PResult } ;
12- use rustc_feature:: { AttributeTemplate , BUILTIN_ATTRIBUTE_MAP , BuiltinAttribute } ;
12+ use rustc_feature:: { AttributeTemplate , BUILTIN_ATTRIBUTE_MAP , BuiltinAttribute , template } ;
1313use rustc_hir:: AttrPath ;
1414use rustc_hir:: lints:: AttributeLintKind ;
1515use rustc_parse:: parse_in;
@@ -30,15 +30,22 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
3030
3131 // Check input tokens for built-in and key-value attributes.
3232 match builtin_attr_info {
33- // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
34- Some ( BuiltinAttribute { name, template, .. } ) => {
33+ Some ( BuiltinAttribute { name, .. } ) => {
3534 if AttributeParser :: < Late > :: is_parsed_attribute ( slice:: from_ref ( & name) ) {
3635 return ;
3736 }
3837 match parse_meta ( psess, attr) {
3938 // Don't check safety again, we just did that
4039 Ok ( meta) => {
41- check_builtin_meta_item ( psess, & meta, attr. style , * name, * template, false )
40+ // FIXME The only unparsed builtin attributes that are left are the lint attributes, so we can hardcode the template here
41+ let lint_attrs = [ sym:: forbid, sym:: allow, sym:: warn, sym:: deny, sym:: expect] ;
42+ assert ! ( lint_attrs. contains( name) ) ;
43+
44+ let template = template ! (
45+ List : & [ "lint1" , "lint1, lint2, ..." , r#"lint1, lint2, lint3, reason = "...""# ] ,
46+ "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
47+ ) ;
48+ check_builtin_meta_item ( psess, & meta, attr. style , * name, template, false )
4249 }
4350 Err ( err) => {
4451 err. emit ( ) ;
0 commit comments