@@ -203,10 +203,11 @@ mod private {
203203#[ allow( private_interfaces) ]
204204pub trait Stage : Sized + ' static + Sealed {
205205 type Id : Copy ;
206- const SHOULD_EMIT_LINTS : bool ;
207206
208207 fn parsers ( ) -> & ' static group_type ! ( Self ) ;
209208
209+ fn should_emit_errors_and_lints ( & self ) -> bool ;
210+
210211 fn emit_err < ' sess > (
211212 & self ,
212213 sess : & ' sess Session ,
@@ -218,11 +219,15 @@ pub trait Stage: Sized + 'static + Sealed {
218219#[ allow( private_interfaces) ]
219220impl Stage for Early {
220221 type Id = NodeId ;
221- const SHOULD_EMIT_LINTS : bool = false ;
222222
223223 fn parsers ( ) -> & ' static group_type ! ( Self ) {
224224 & early:: ATTRIBUTE_PARSERS
225225 }
226+
227+ fn should_emit_errors_and_lints ( & self ) -> bool {
228+ self . emit_errors . should_emit ( )
229+ }
230+
226231 fn emit_err < ' sess > (
227232 & self ,
228233 sess : & ' sess Session ,
@@ -240,11 +245,15 @@ impl Stage for Early {
240245#[ allow( private_interfaces) ]
241246impl Stage for Late {
242247 type Id = HirId ;
243- const SHOULD_EMIT_LINTS : bool = true ;
244248
245249 fn parsers ( ) -> & ' static group_type ! ( Self ) {
246250 & late:: ATTRIBUTE_PARSERS
247251 }
252+
253+ fn should_emit_errors_and_lints ( & self ) -> bool {
254+ true
255+ }
256+
248257 fn emit_err < ' sess > (
249258 & self ,
250259 tcx : & ' sess Session ,
@@ -290,7 +299,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
290299 /// must be delayed until after HIR is built. This method will take care of the details of
291300 /// that.
292301 pub ( crate ) fn emit_lint ( & mut self , lint : AttributeLintKind , span : Span ) {
293- if !S :: SHOULD_EMIT_LINTS {
302+ if !self . stage . should_emit_errors_and_lints ( ) {
294303 return ;
295304 }
296305 let id = self . target_id ;
@@ -696,6 +705,22 @@ impl<'sess> AttributeParser<'sess, Early> {
696705 } ;
697706 parse_fn ( & mut cx, args)
698707 }
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+ }
699724}
700725
701726impl < ' sess , S : Stage > AttributeParser < ' sess , S > {
@@ -712,6 +737,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
712737 & self . sess
713738 }
714739
740+ pub ( crate ) fn stage ( & self ) -> & S {
741+ & self . stage
742+ }
743+
715744 pub ( crate ) fn features ( & self ) -> & ' sess Features {
716745 self . features . expect ( "features not available at this point in the compiler" )
717746 }
@@ -785,12 +814,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
785814 ast:: AttrKind :: Normal ( n) => {
786815 attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
787816
817+ // Parse attribute using new infra
788818 let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
789819 let path = parser. path ( ) ;
790820 let args = parser. args ( ) ;
791821 let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
792822
793823 if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
824+ self . validate_attribute ( attr, target_id, & mut emit_lint, true ) ;
794825 for ( template, accept) in accepts {
795826 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
796827 shared : SharedContext {
@@ -821,7 +852,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
821852 // // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]),
822853 // "attribute {path} wasn't parsed and isn't a know tool attribute",
823854 // );
824-
855+ self . validate_attribute ( attr , target_id , & mut emit_lint , false ) ;
825856 attributes. push ( Attribute :: Unparsed ( Box :: new ( AttrItem {
826857 path : AttrPath :: from_ast ( & n. item . path ) ,
827858 args : self . lower_attr_args ( & n. item . args , lower_span) ,
0 commit comments