@@ -705,6 +705,22 @@ impl<'sess> AttributeParser<'sess, Early> {
705705 } ;
706706 parse_fn ( & mut cx, args)
707707 }
708+
709+ /// Returns whether the attribute is valid
710+ pub fn validate_attribute_early (
711+ sess : & ' sess Session ,
712+ attr : & ast:: Attribute ,
713+ target_node_id : NodeId ,
714+ ) -> bool {
715+ let parser = Self {
716+ features : None ,
717+ tools : Vec :: new ( ) ,
718+ parse_only : None ,
719+ sess,
720+ stage : Early { emit_errors : ShouldEmit :: ErrorsAndLints } ,
721+ } ;
722+ parser. validate_attribute ( attr, target_node_id, & mut |_| { } , true )
723+ }
708724}
709725
710726impl < ' sess , S : Stage > AttributeParser < ' sess , S > {
@@ -798,12 +814,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
798814 ast:: AttrKind :: Normal ( n) => {
799815 attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
800816
817+ // Parse attribute using new infra
801818 let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
802819 let path = parser. path ( ) ;
803820 let args = parser. args ( ) ;
804821 let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
805822
806823 if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
824+ self . validate_attribute ( attr, target_id, & mut emit_lint, true ) ;
807825 for ( template, accept) in accepts {
808826 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
809827 shared : SharedContext {
@@ -834,7 +852,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
834852 // // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]),
835853 // "attribute {path} wasn't parsed and isn't a know tool attribute",
836854 // );
837-
855+ self . validate_attribute ( attr , target_id , & mut emit_lint , false ) ;
838856 attributes. push ( Attribute :: Unparsed ( Box :: new ( AttrItem {
839857 path : AttrPath :: from_ast ( & n. item . path ) ,
840858 args : self . lower_attr_args ( & n. item . args , lower_span) ,
0 commit comments