@@ -6,7 +6,7 @@ use std::sync::Arc;
66
77use rustc_ast:: tokenstream:: { self , TokenTree } ;
88use rustc_ast:: { DelimArgs , LitKind , MetaItemLit , token} ;
9- use rustc_errors:: { Diag , ErrorGuaranteed } ;
9+ use rustc_errors:: ErrorGuaranteed ;
1010use rustc_hir:: { AttrArgs , AttrItem , Attribute , HirId } ;
1111use rustc_middle:: ty:: TyCtxt ;
1212use rustc_span:: symbol:: Ident ;
@@ -43,6 +43,37 @@ pub enum KlintAttribute {
4343 DiagnosticItem ( Symbol ) ,
4444}
4545
46+ #[ derive( Diagnostic ) ]
47+ #[ diag( "incorrect usage of `#[kint::preempt_count]`" ) ]
48+ #[ help( "{$help}" ) ]
49+ struct InvalidPreemptCountAttribute {
50+ #[ primary_span]
51+ pub span : Span ,
52+ pub help : & ' static str ,
53+ }
54+
55+ #[ derive( Diagnostic ) ]
56+ #[ diag( "unrecognized klint attribute" ) ]
57+ struct UnknownAttribute {
58+ #[ primary_span]
59+ pub span : Span ,
60+ }
61+
62+ #[ derive( Diagnostic ) ]
63+ #[ diag( "invalid klint attribute" ) ]
64+ struct InvalidAttribute {
65+ #[ primary_span]
66+ pub span : Span ,
67+ }
68+
69+ #[ derive( Diagnostic ) ]
70+ #[ diag( "incorrect usage of `#[kint::diagnostic_item]`" ) ]
71+ #[ help( r#"correct usage looks like `#[kint::diagnostic_item = "name"]`"# ) ]
72+ struct InvalidDiagnosticItem {
73+ #[ primary_span]
74+ pub span : Span ,
75+ }
76+
4677struct Cursor < ' a > {
4778 eof : TokenTree ,
4879 cursor : tokenstream:: TokenStreamIter < ' a > ,
@@ -75,26 +106,9 @@ impl<'a> Cursor<'a> {
75106
76107struct AttrParser < ' tcx > {
77108 tcx : TyCtxt < ' tcx > ,
78- hir_id : HirId ,
79109}
80110
81111impl < ' tcx > AttrParser < ' tcx > {
82- fn error (
83- & self ,
84- span : Span ,
85- decorate : impl for <' a , ' b > FnOnce ( & ' b mut Diag < ' a , ( ) > ) ,
86- ) -> Result < !, ErrorGuaranteed > {
87- self . tcx
88- . node_span_lint ( crate :: INCORRECT_ATTRIBUTE , self . hir_id , span, |lint| {
89- lint. primary_message ( "incorrect usage of `#[kint::preempt_count]`" ) ;
90- decorate ( lint) ;
91- } ) ;
92- Err ( self
93- . tcx
94- . dcx ( )
95- . span_delayed_bug ( span, "incorrect usage of `#[kint::preempt_count]`" ) )
96- }
97-
98112 fn parse_comma_delimited (
99113 & self ,
100114 mut cursor : Cursor < ' _ > ,
@@ -123,9 +137,10 @@ impl<'tcx> AttrParser<'tcx> {
123137 _
124138 )
125139 ) {
126- self . error ( comma. span ( ) , |diag| {
127- diag. help ( "`,` expected between property values" ) ;
128- } ) ?;
140+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
141+ span : comma. span ( ) ,
142+ help : "`,` expected between property values" ,
143+ } ) ) ?
129144 }
130145 }
131146 }
@@ -137,17 +152,18 @@ impl<'tcx> AttrParser<'tcx> {
137152 f : impl FnOnce ( Ident , Cursor < ' a > ) -> Result < Cursor < ' a > , ErrorGuaranteed > ,
138153 ) -> Result < Cursor < ' a > , ErrorGuaranteed > {
139154 let prop = cursor. next ( ) ;
140- let invalid_prop = |span| {
141- self . error ( span, |diag| {
142- diag. help ( "identifier expected" ) ;
143- } ) ?;
144- } ;
145155
146156 let TokenTree :: Token ( token, _) = prop else {
147- return invalid_prop ( prop. span ( ) ) ;
157+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
158+ span : prop. span ( ) ,
159+ help : "identifier expected" ,
160+ } ) ) ?
148161 } ;
149162 let Some ( ( name, _) ) = token. ident ( ) else {
150- return invalid_prop ( token. span ) ;
163+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
164+ span : token. span ,
165+ help : "identifier expected" ,
166+ } ) ) ?
151167 } ;
152168
153169 let need_eq = need_eq ( name) ?;
@@ -165,14 +181,16 @@ impl<'tcx> AttrParser<'tcx> {
165181 )
166182 ) ;
167183 if need_eq && !is_eq {
168- self . error ( eq. span ( ) , |diag| {
169- diag. help ( "`=` expected after property name" ) ;
170- } ) ?;
184+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
185+ span : eq. span ( ) ,
186+ help : "`=` expected after property name" ,
187+ } ) ) ?
171188 }
172189 if !need_eq && is_eq {
173- self . error ( eq. span ( ) , |diag| {
174- diag. help ( "unexpected `=` after property name" ) ;
175- } ) ?;
190+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
191+ span : eq. span ( ) ,
192+ help : "unexpected `=` after property name" ,
193+ } ) ) ?
176194 }
177195
178196 if is_eq {
@@ -186,9 +204,10 @@ impl<'tcx> AttrParser<'tcx> {
186204
187205 fn parse_i32 < ' a > ( & self , mut cursor : Cursor < ' a > ) -> Result < ( i32 , Cursor < ' a > ) , ErrorGuaranteed > {
188206 let expect_int = |span| {
189- self . error ( span, |diag| {
190- diag. help ( "an integer expected" ) ;
191- } )
207+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
208+ span,
209+ help : "an integer expected" ,
210+ } ) )
192211 } ;
193212
194213 let negative = if matches ! (
@@ -234,9 +253,10 @@ impl<'tcx> AttrParser<'tcx> {
234253 mut cursor : Cursor < ' a > ,
235254 ) -> Result < ( ( u32 , Option < u32 > ) , Cursor < ' a > ) , ErrorGuaranteed > {
236255 let expect_range = |span| {
237- self . error ( span, |diag| {
238- diag. help ( "a range expected" ) ;
239- } )
256+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
257+ span,
258+ help : "a range expected" ,
259+ } ) )
240260 } ;
241261
242262 let start_span = cursor. peek ( ) . span ( ) ;
@@ -332,9 +352,10 @@ impl<'tcx> AttrParser<'tcx> {
332352 if end. is_some ( ) && end. unwrap ( ) <= start {
333353 let end_span = cursor. next ( ) . span ( ) ;
334354
335- self . error ( start_span. until ( end_span) , |diag| {
336- diag. help ( "the preemption count expectation range must be non-empty" ) ;
337- } ) ?;
355+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
356+ span : start_span. until ( end_span) ,
357+ help : "the preemption count expectation range must be non-empty" ,
358+ } ) ) ?
338359 }
339360
340361 Ok ( ( ( start, end) , cursor) )
@@ -355,9 +376,10 @@ impl<'tcx> AttrParser<'tcx> {
355376 ..
356377 } ) = & item. args
357378 else {
358- self . error ( attr. span ( ) , |diag| {
359- diag. help ( "correct usage looks like `#[kint::preempt_count(...)]`" ) ;
360- } ) ?;
379+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
380+ span : attr. span ( ) ,
381+ help : "correct usage looks like `#[kint::preempt_count(...)]`" ,
382+ } ) ) ?
361383 } ;
362384
363385 self . parse_comma_delimited ( Cursor :: new ( tts. iter ( ) , delim_span. close ) , |cursor| {
@@ -367,13 +389,10 @@ impl<'tcx> AttrParser<'tcx> {
367389 Ok ( match name. name {
368390 crate :: symbol:: adjust | sym:: expect => true ,
369391 crate :: symbol:: unchecked => false ,
370- _ => {
371- self . error ( name. span , |diag| {
372- diag. help (
373- "unknown property, expected `adjust`, `expect` or `unchecked`" ,
374- ) ;
375- } ) ?;
376- }
392+ _ => Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
393+ span : name. span ,
394+ help : "unknown property, expected `adjust`, `expect` or `unchecked`" ,
395+ } ) ) ?,
377396 } )
378397 } ,
379398 |name, mut cursor| {
@@ -400,9 +419,10 @@ impl<'tcx> AttrParser<'tcx> {
400419 } ) ?;
401420
402421 if adjustment. is_none ( ) && expectation. is_none ( ) {
403- self . error ( delim_span. entire ( ) , |diag| {
404- diag. help ( "at least one of `adjust` or `expect` property must be specified" ) ;
405- } ) ?;
422+ Err ( self . tcx . dcx ( ) . emit_err ( InvalidPreemptCountAttribute {
423+ span : delim_span. entire ( ) ,
424+ help : "at least one of `adjust` or `expect` property must be specified" ,
425+ } ) ) ?
406426 }
407427
408428 Ok ( PreemptionCount {
@@ -421,9 +441,8 @@ impl<'tcx> AttrParser<'tcx> {
421441 } ;
422442 if item. path . segments . len ( ) != 2 {
423443 self . tcx
424- . node_span_lint ( crate :: INCORRECT_ATTRIBUTE , self . hir_id , item. span , |lint| {
425- lint. primary_message ( "invalid klint attribute" ) ;
426- } ) ;
444+ . dcx ( )
445+ . emit_err ( InvalidAttribute { span : item. span } ) ;
427446 return None ;
428447 }
429448 match item. path . segments [ 1 ] {
@@ -468,37 +487,26 @@ impl<'tcx> AttrParser<'tcx> {
468487 } ,
469488 } = item. args
470489 else {
471- self . error ( attr. span ( ) , |diag| {
472- diag. help (
473- r#"correct usage looks like `#[kint::diagnostic_item = "name"]`"# ,
474- ) ;
475- } )
476- . ok ( ) ?;
490+ self . tcx
491+ . dcx ( )
492+ . emit_err ( InvalidDiagnosticItem { span : attr. span ( ) } ) ;
493+ None ?
477494 } ;
478495
479496 Some ( KlintAttribute :: DiagnosticItem ( value) )
480497 }
481498 _ => {
482- self . tcx . node_span_lint (
483- crate :: INCORRECT_ATTRIBUTE ,
484- self . hir_id ,
485- item. path . span ,
486- |lint| {
487- lint. primary_message ( "unrecognized klint attribute" ) ;
488- } ,
489- ) ;
499+ self . tcx . dcx ( ) . emit_err ( UnknownAttribute {
500+ span : item. path . span ,
501+ } ) ;
490502 None
491503 }
492504 }
493505 }
494506}
495507
496- pub fn parse_klint_attribute (
497- tcx : TyCtxt < ' _ > ,
498- hir_id : HirId ,
499- attr : & Attribute ,
500- ) -> Option < KlintAttribute > {
501- AttrParser { tcx, hir_id } . parse ( attr)
508+ pub fn parse_klint_attribute ( tcx : TyCtxt < ' _ > , attr : & Attribute ) -> Option < KlintAttribute > {
509+ AttrParser { tcx } . parse ( attr)
502510}
503511
504512memoize ! (
@@ -508,7 +516,7 @@ memoize!(
508516 ) -> Arc <Vec <KlintAttribute >> {
509517 let mut v = Vec :: new( ) ;
510518 for attr in cx. hir_attrs( hir_id) {
511- let Some ( attr) = crate :: attribute:: parse_klint_attribute( cx. tcx, hir_id , attr) else {
519+ let Some ( attr) = crate :: attribute:: parse_klint_attribute( cx. tcx, attr) else {
512520 continue ;
513521 } ;
514522 v. push( attr) ;
0 commit comments