@@ -17,7 +17,7 @@ use middle::dependency_format;
17
17
use session:: search_paths:: PathKind ;
18
18
use session:: config:: DebugInfoLevel ;
19
19
use ty:: tls;
20
- use util:: nodemap:: { NodeMap , FnvHashMap } ;
20
+ use util:: nodemap:: { NodeMap , FnvHashMap , FnvHashSet } ;
21
21
use util:: common:: duration_to_secs_str;
22
22
use mir:: transform as mir_pass;
23
23
@@ -75,6 +75,10 @@ pub struct Session {
75
75
pub working_dir : PathBuf ,
76
76
pub lint_store : RefCell < lint:: LintStore > ,
77
77
pub lints : RefCell < NodeMap < Vec < ( lint:: LintId , Span , String ) > > > ,
78
+ /// Set of (span, message) tuples tracking lint (sub)diagnostics that have
79
+ /// been set once, but should not be set again, in order to avoid
80
+ /// redundantly verbose output (Issue #24690).
81
+ pub one_time_diagnostics : RefCell < FnvHashSet < ( Span , String ) > > ,
78
82
pub plugin_llvm_passes : RefCell < Vec < String > > ,
79
83
pub mir_passes : RefCell < mir_pass:: Passes > ,
80
84
pub plugin_attributes : RefCell < Vec < ( String , AttributeType ) > > ,
@@ -288,6 +292,26 @@ impl Session {
288
292
pub fn diagnostic < ' a > ( & ' a self ) -> & ' a errors:: Handler {
289
293
& self . parse_sess . span_diagnostic
290
294
}
295
+
296
+ /// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
297
+ /// deduplicates on span and message for this `Session`.
298
+ //
299
+ // FIXME: if the need arises for one-time diagnostics other than
300
+ // `span_note`, we almost certainly want to generalize this "check the
301
+ // one-time diagnostics map, then set message if it's not already there"
302
+ // code to accomodate all of them
303
+ pub fn diag_span_note_once < ' a , ' b > ( & ' a self ,
304
+ diag_builder : & ' b mut DiagnosticBuilder < ' a > ,
305
+ span : Span , message : & str ) {
306
+ let span_message = ( span, message. to_owned ( ) ) ;
307
+ let already_noted: bool = self . one_time_diagnostics . borrow ( )
308
+ . contains ( & span_message) ;
309
+ if !already_noted {
310
+ diag_builder. span_note ( span, & message) ;
311
+ self . one_time_diagnostics . borrow_mut ( ) . insert ( span_message) ;
312
+ }
313
+ }
314
+
291
315
pub fn codemap < ' a > ( & ' a self ) -> & ' a codemap:: CodeMap {
292
316
self . parse_sess . codemap ( )
293
317
}
@@ -561,6 +585,7 @@ pub fn build_session_(sopts: config::Options,
561
585
working_dir : env:: current_dir ( ) . unwrap ( ) ,
562
586
lint_store : RefCell :: new ( lint:: LintStore :: new ( ) ) ,
563
587
lints : RefCell :: new ( NodeMap ( ) ) ,
588
+ one_time_diagnostics : RefCell :: new ( FnvHashSet ( ) ) ,
564
589
plugin_llvm_passes : RefCell :: new ( Vec :: new ( ) ) ,
565
590
mir_passes : RefCell :: new ( mir_pass:: Passes :: new ( ) ) ,
566
591
plugin_attributes : RefCell :: new ( Vec :: new ( ) ) ,
0 commit comments