1
+ use std:: borrow:: Cow ;
1
2
use std:: cell:: RefCell ;
2
3
use std:: collections:: BTreeMap ;
3
4
use std:: ops:: { Deref , DerefMut } ;
@@ -213,7 +214,6 @@ mod private {
213
214
#[ allow( private_interfaces) ]
214
215
pub trait Stage : Sized + ' static + Sealed {
215
216
type Id : Copy ;
216
- const SHOULD_EMIT_LINTS : bool ;
217
217
218
218
fn parsers ( ) -> & ' static group_type ! ( Self ) ;
219
219
@@ -222,13 +222,14 @@ pub trait Stage: Sized + 'static + Sealed {
222
222
sess : & ' sess Session ,
223
223
diag : impl for < ' x > Diagnostic < ' x > ,
224
224
) -> ErrorGuaranteed ;
225
+
226
+ fn should_emit ( & self ) -> ShouldEmit ;
225
227
}
226
228
227
229
// allow because it's a sealed trait
228
230
#[ allow( private_interfaces) ]
229
231
impl Stage for Early {
230
232
type Id = NodeId ;
231
- const SHOULD_EMIT_LINTS : bool = false ;
232
233
233
234
fn parsers ( ) -> & ' static group_type ! ( Self ) {
234
235
& early:: ATTRIBUTE_PARSERS
@@ -244,13 +245,16 @@ impl Stage for Early {
244
245
sess. dcx ( ) . create_err ( diag) . delay_as_bug ( )
245
246
}
246
247
}
248
+
249
+ fn should_emit ( & self ) -> ShouldEmit {
250
+ self . emit_errors
251
+ }
247
252
}
248
253
249
254
// allow because it's a sealed trait
250
255
#[ allow( private_interfaces) ]
251
256
impl Stage for Late {
252
257
type Id = HirId ;
253
- const SHOULD_EMIT_LINTS : bool = true ;
254
258
255
259
fn parsers ( ) -> & ' static group_type ! ( Self ) {
256
260
& late:: ATTRIBUTE_PARSERS
@@ -262,6 +266,10 @@ impl Stage for Late {
262
266
) -> ErrorGuaranteed {
263
267
tcx. dcx ( ) . emit_err ( diag)
264
268
}
269
+
270
+ fn should_emit ( & self ) -> ShouldEmit {
271
+ ShouldEmit :: ErrorsAndLints
272
+ }
265
273
}
266
274
267
275
/// used when parsing attributes for miscellaneous things *before* ast lowering
@@ -300,7 +308,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
300
308
/// must be delayed until after HIR is built. This method will take care of the details of
301
309
/// that.
302
310
pub ( crate ) fn emit_lint ( & mut self , lint : AttributeLintKind , span : Span ) {
303
- if !S :: SHOULD_EMIT_LINTS {
311
+ if !self . stage . should_emit ( ) . should_emit ( ) {
304
312
return ;
305
313
}
306
314
let id = self . target_id ;
@@ -686,9 +694,9 @@ impl<'sess> AttributeParser<'sess, Early> {
686
694
target_node_id : NodeId ,
687
695
features : Option < & ' sess Features > ,
688
696
emit_errors : ShouldEmit ,
689
- parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & ArgParser < ' _ > ) -> T ,
697
+ parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & ArgParser < ' _ > ) -> Option < T > ,
690
698
template : & AttributeTemplate ,
691
- ) -> T {
699
+ ) -> Option < T > {
692
700
let mut parser = Self {
693
701
features,
694
702
tools : Vec :: new ( ) ,
@@ -699,7 +707,7 @@ impl<'sess> AttributeParser<'sess, Early> {
699
707
let ast:: AttrKind :: Normal ( normal_attr) = & attr. kind else {
700
708
panic ! ( "parse_single called on a doc attr" )
701
709
} ;
702
- let meta_parser = MetaItemParser :: from_attr ( normal_attr, & sess. psess ) ;
710
+ let meta_parser = MetaItemParser :: from_attr ( normal_attr, & sess. psess , emit_errors ) ? ;
703
711
let path = meta_parser. path ( ) ;
704
712
let args = meta_parser. args ( ) ;
705
713
let mut cx: AcceptContext < ' _ , ' sess , Early > = AcceptContext {
@@ -804,14 +812,22 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
804
812
// }))
805
813
// }
806
814
ast:: AttrKind :: Normal ( n) => {
807
- attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
815
+ attr_paths. push ( PathParser ( Cow :: Borrowed ( & n. item . path ) ) ) ;
808
816
809
- let parser = MetaItemParser :: from_attr ( n, & self . sess . psess ) ;
810
- let path = parser. path ( ) ;
811
- let args = parser. args ( ) ;
812
- let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
817
+ let parts =
818
+ n. item . path . segments . iter ( ) . map ( |seg| seg. ident . name ) . collect :: < Vec < _ > > ( ) ;
813
819
814
820
if let Some ( accepts) = S :: parsers ( ) . 0 . get ( parts. as_slice ( ) ) {
821
+ let Some ( parser) = MetaItemParser :: from_attr (
822
+ n,
823
+ & self . sess . psess ,
824
+ self . stage . should_emit ( ) ,
825
+ ) else {
826
+ continue ;
827
+ } ;
828
+ let path = parser. path ( ) ;
829
+ let args = parser. args ( ) ;
830
+
815
831
for ( template, accept) in accepts {
816
832
let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
817
833
shared : SharedContext {
0 commit comments