@@ -705,6 +705,22 @@ impl<'sess> AttributeParser<'sess, Early> {
705
705
} ;
706
706
parse_fn ( & mut cx, args)
707
707
}
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
+ }
708
724
}
709
725
710
726
impl < ' sess , S : Stage > AttributeParser < ' sess , S > {
@@ -798,12 +814,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
798
814
ast:: AttrKind :: Normal ( n) => {
799
815
attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
800
816
817
+ // Parse attribute using new infra
801
818
let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
802
819
let path = parser. path ( ) ;
803
820
let args = parser. args ( ) ;
804
821
let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
805
822
806
823
if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
824
+ self . validate_attribute ( attr, target_id, & mut emit_lint, true ) ;
807
825
for ( template, accept) in accepts {
808
826
let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
809
827
shared : SharedContext {
@@ -834,7 +852,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
834
852
// // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]),
835
853
// "attribute {path} wasn't parsed and isn't a know tool attribute",
836
854
// );
837
-
855
+ self . validate_attribute ( attr , target_id , & mut emit_lint , false ) ;
838
856
attributes. push ( Attribute :: Unparsed ( Box :: new ( AttrItem {
839
857
path : AttrPath :: from_ast ( & n. item . path ) ,
840
858
args : self . lower_attr_args ( & n. item . args , lower_span) ,
0 commit comments