@@ -79,10 +79,10 @@ pub struct Session {
7979 pub working_dir : ( String , bool ) ,
8080 pub lint_store : RefCell < lint:: LintStore > ,
8181 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 ) > > ,
8686 pub plugin_llvm_passes : RefCell < Vec < String > > ,
8787 pub plugin_attributes : RefCell < Vec < ( String , AttributeType ) > > ,
8888 pub crate_types : RefCell < Vec < config:: CrateType > > ,
@@ -157,6 +157,13 @@ pub struct PerfStats {
157157 pub decode_def_path_tables_time : Cell < Duration > ,
158158}
159159
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+
160167impl Session {
161168 pub fn local_crate_disambiguator ( & self ) -> Symbol {
162169 * self . crate_disambiguator . borrow ( )
@@ -329,34 +336,53 @@ impl Session {
329336 & self . parse_sess . span_diagnostic
330337 }
331338
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+
343357 match self . opts . error_format {
344358 // when outputting JSON for tool consumption, the tool might want
345359 // the duplicates
346360 config:: ErrorOutputType :: Json => {
347- diag_builder . span_note ( span , & message ) ;
361+ do_method ( )
348362 } ,
349363 _ => {
350364 let lint_id = lint:: LintId :: of ( lint) ;
351365 let id_span_message = ( lint_id, span, message. to_owned ( ) ) ;
352366 let fresh = self . one_time_diagnostics . borrow_mut ( ) . insert ( id_span_message) ;
353367 if fresh {
354- diag_builder . span_note ( span , & message ) ;
368+ do_method ( )
355369 }
356370 }
357371 }
358372 }
359373
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+
360386 pub fn codemap < ' a > ( & ' a self ) -> & ' a codemap:: CodeMap {
361387 self . parse_sess . codemap ( )
362388 }
0 commit comments