@@ -79,10 +79,10 @@ pub struct Session {
79
79
pub working_dir : ( String , bool ) ,
80
80
pub lint_store : RefCell < lint:: LintStore > ,
81
81
pub lints : RefCell < lint:: LintTable > ,
82
- /// Set of (LintId, span , message) tuples tracking lint (sub)diagnostics
83
- /// that have been set once, but should not be set again, in order to avoid
84
- /// redundantly verbose output (Issue #24690).
85
- pub one_time_diagnostics : RefCell < FxHashSet < ( lint:: LintId , Span , String ) > > ,
82
+ /// Set of (LintId, Option<Span> , message) tuples tracking lint
83
+ /// (sub)diagnostics that have been set once, but should not be set again,
84
+ /// in order to avoid redundantly verbose output (Issue #24690).
85
+ pub one_time_diagnostics : RefCell < FxHashSet < ( lint:: LintId , Option < Span > , String ) > > ,
86
86
pub plugin_llvm_passes : RefCell < Vec < String > > ,
87
87
pub plugin_attributes : RefCell < Vec < ( String , AttributeType ) > > ,
88
88
pub crate_types : RefCell < Vec < config:: CrateType > > ,
@@ -157,6 +157,13 @@ pub struct PerfStats {
157
157
pub decode_def_path_tables_time : Cell < Duration > ,
158
158
}
159
159
160
+ /// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
161
+ enum DiagnosticBuilderMethod {
162
+ Note ,
163
+ SpanNote ,
164
+ // add more variants as needed to support one-time diagnostics
165
+ }
166
+
160
167
impl Session {
161
168
pub fn local_crate_disambiguator ( & self ) -> Symbol {
162
169
* self . crate_disambiguator . borrow ( )
@@ -329,34 +336,53 @@ impl Session {
329
336
& self . parse_sess . span_diagnostic
330
337
}
331
338
332
- /// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
333
- /// deduplicates on lint ID, span, and message for this `Session` if we're
334
- /// not outputting in JSON mode.
335
- //
336
- // FIXME: if the need arises for one-time diagnostics other than
337
- // `span_note`, we almost certainly want to generalize this
338
- // "check/insert-into the one-time diagnostics map, then set message if
339
- // it's not already there" code to accomodate all of them
340
- pub fn diag_span_note_once < ' a , ' b > ( & ' a self ,
341
- diag_builder : & ' b mut DiagnosticBuilder < ' a > ,
342
- lint : & ' static lint:: Lint , span : Span , message : & str ) {
339
+ /// Analogous to calling methods on the given `DiagnosticBuilder`, but
340
+ /// deduplicates on lint ID, span (if any), and message for this `Session`
341
+ /// if we're not outputting in JSON mode.
342
+ fn diag_once < ' a , ' b > ( & ' a self ,
343
+ diag_builder : & ' b mut DiagnosticBuilder < ' a > ,
344
+ method : DiagnosticBuilderMethod ,
345
+ lint : & ' static lint:: Lint , message : & str , span : Option < Span > ) {
346
+ let mut do_method = || {
347
+ match method {
348
+ DiagnosticBuilderMethod :: Note => {
349
+ diag_builder. note ( message) ;
350
+ } ,
351
+ DiagnosticBuilderMethod :: SpanNote => {
352
+ diag_builder. span_note ( span. expect ( "span_note expects a span" ) , message) ;
353
+ }
354
+ }
355
+ } ;
356
+
343
357
match self . opts . error_format {
344
358
// when outputting JSON for tool consumption, the tool might want
345
359
// the duplicates
346
360
config:: ErrorOutputType :: Json => {
347
- diag_builder . span_note ( span , & message ) ;
361
+ do_method ( )
348
362
} ,
349
363
_ => {
350
364
let lint_id = lint:: LintId :: of ( lint) ;
351
365
let id_span_message = ( lint_id, span, message. to_owned ( ) ) ;
352
366
let fresh = self . one_time_diagnostics . borrow_mut ( ) . insert ( id_span_message) ;
353
367
if fresh {
354
- diag_builder . span_note ( span , & message ) ;
368
+ do_method ( )
355
369
}
356
370
}
357
371
}
358
372
}
359
373
374
+ pub fn diag_span_note_once < ' a , ' b > ( & ' a self ,
375
+ diag_builder : & ' b mut DiagnosticBuilder < ' a > ,
376
+ lint : & ' static lint:: Lint , span : Span , message : & str ) {
377
+ self . diag_once ( diag_builder, DiagnosticBuilderMethod :: SpanNote , lint, message, Some ( span) ) ;
378
+ }
379
+
380
+ pub fn diag_note_once < ' a , ' b > ( & ' a self ,
381
+ diag_builder : & ' b mut DiagnosticBuilder < ' a > ,
382
+ lint : & ' static lint:: Lint , message : & str ) {
383
+ self . diag_once ( diag_builder, DiagnosticBuilderMethod :: Note , lint, message, None ) ;
384
+ }
385
+
360
386
pub fn codemap < ' a > ( & ' a self ) -> & ' a codemap:: CodeMap {
361
387
self . parse_sess . codemap ( )
362
388
}
0 commit comments