Skip to content

Commit 0b49d05

Browse files
committed
Filter OnceNote in diagnostic infra.
1 parent 056951d commit 0b49d05

29 files changed

+183
-282
lines changed

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType {
7070
AnnotationType::Error
7171
}
7272
Level::Warning => AnnotationType::Warning,
73-
Level::Note => AnnotationType::Note,
73+
Level::Note | Level::OnceNote => AnnotationType::Note,
7474
Level::Help => AnnotationType::Help,
7575
// FIXME(#59346): Not sure how to map this level
7676
Level::FailureNote => AnnotationType::Error,

compiler/rustc_errors/src/diagnostic.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,12 @@ impl Diagnostic {
135135
| Level::Error { .. }
136136
| Level::FailureNote => true,
137137

138-
Level::Warning | Level::Note | Level::Help | Level::Allow | Level::Expect(_) => false,
138+
Level::Warning
139+
| Level::Note
140+
| Level::OnceNote
141+
| Level::Help
142+
| Level::Allow
143+
| Level::Expect(_) => false,
139144
}
140145
}
141146

@@ -333,13 +338,27 @@ impl Diagnostic {
333338
self
334339
}
335340

341+
/// Prints the span with a note above it.
342+
/// This is like [`Diagnostic::note()`], but it gets its own span.
343+
pub fn note_once(&mut self, msg: &str) -> &mut Self {
344+
self.sub(Level::OnceNote, msg, MultiSpan::new(), None);
345+
self
346+
}
347+
336348
/// Prints the span with a note above it.
337349
/// This is like [`Diagnostic::note()`], but it gets its own span.
338350
pub fn span_note<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
339351
self.sub(Level::Note, msg, sp.into(), None);
340352
self
341353
}
342354

355+
/// Prints the span with a note above it.
356+
/// This is like [`Diagnostic::note()`], but it gets its own span.
357+
pub fn span_note_once<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
358+
self.sub(Level::OnceNote, msg, sp.into(), None);
359+
self
360+
}
361+
343362
/// Add a warning attached to this diagnostic.
344363
pub fn warn(&mut self, msg: &str) -> &mut Self {
345364
self.sub(Level::Warning, msg, MultiSpan::new(), None);

compiler/rustc_errors/src/diagnostic_builder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,17 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
396396
) -> &mut Self);
397397

398398
forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
399+
forward!(pub fn note_once(&mut self, msg: &str) -> &mut Self);
399400
forward!(pub fn span_note(
400401
&mut self,
401402
sp: impl Into<MultiSpan>,
402403
msg: &str,
403404
) -> &mut Self);
405+
forward!(pub fn span_note_once(
406+
&mut self,
407+
sp: impl Into<MultiSpan>,
408+
msg: &str,
409+
) -> &mut Self);
404410
forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
405411
forward!(pub fn span_warn(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> &mut Self);
406412
forward!(pub fn help(&mut self, msg: &str) -> &mut Self);

compiler/rustc_errors/src/lib.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
66
#![feature(crate_visibility_modifier)]
7+
#![feature(drain_filter)]
78
#![feature(backtrace)]
89
#![feature(if_let_guard)]
910
#![feature(let_else)]
@@ -1070,7 +1071,23 @@ impl HandlerInner {
10701071
// Only emit the diagnostic if we've been asked to deduplicate and
10711072
// haven't already emitted an equivalent diagnostic.
10721073
if !(self.flags.deduplicate_diagnostics && already_emitted(self)) {
1073-
self.emitter.emit_diagnostic(diagnostic);
1074+
debug!(?diagnostic);
1075+
debug!(?self.emitted_diagnostics);
1076+
let already_emitted_sub = |sub: &mut SubDiagnostic| {
1077+
debug!(?sub);
1078+
if sub.level != Level::OnceNote {
1079+
return false;
1080+
}
1081+
let mut hasher = StableHasher::new();
1082+
sub.hash(&mut hasher);
1083+
let diagnostic_hash = hasher.finish();
1084+
debug!(?diagnostic_hash);
1085+
!self.emitted_diagnostics.insert(diagnostic_hash)
1086+
};
1087+
1088+
diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {});
1089+
1090+
self.emitter.emit_diagnostic(&diagnostic);
10741091
if diagnostic.is_error() {
10751092
self.deduplicated_err_count += 1;
10761093
} else if diagnostic.level == Warning {
@@ -1350,6 +1367,8 @@ pub enum Level {
13501367
},
13511368
Warning,
13521369
Note,
1370+
/// A note that is only emitted once.
1371+
OnceNote,
13531372
Help,
13541373
FailureNote,
13551374
Allow,
@@ -1372,7 +1391,7 @@ impl Level {
13721391
Warning => {
13731392
spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows));
13741393
}
1375-
Note => {
1394+
Note | OnceNote => {
13761395
spec.set_fg(Some(Color::Green)).set_intense(true);
13771396
}
13781397
Help => {
@@ -1389,7 +1408,7 @@ impl Level {
13891408
Bug | DelayedBug => "error: internal compiler error",
13901409
Fatal | Error { .. } => "error",
13911410
Warning => "warning",
1392-
Note => "note",
1411+
Note | OnceNote => "note",
13931412
Help => "help",
13941413
FailureNote => "failure-note",
13951414
Allow => panic!("Shouldn't call on allowed error"),

compiler/rustc_middle/src/lint.rs

+16-38
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_session::lint::{
1212
builtin::{self, FORBIDDEN_LINT_GROUPS},
1313
FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId,
1414
};
15-
use rustc_session::{DiagnosticMessageId, Session};
15+
use rustc_session::Session;
1616
use rustc_span::hygiene::MacroKind;
1717
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
1818
use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
@@ -245,7 +245,6 @@ impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> {
245245
}
246246

247247
pub fn explain_lint_level_source(
248-
sess: &Session,
249248
lint: &'static Lint,
250249
level: Level,
251250
src: LintLevelSource,
@@ -254,11 +253,7 @@ pub fn explain_lint_level_source(
254253
let name = lint.name_lower();
255254
match src {
256255
LintLevelSource::Default => {
257-
sess.diag_note_once(
258-
err,
259-
DiagnosticMessageId::from(lint),
260-
&format!("`#[{}({})]` on by default", level.as_str(), name),
261-
);
256+
err.note_once(&format!("`#[{}({})]` on by default", level.as_str(), name));
262257
}
263258
LintLevelSource::CommandLine(lint_flag_val, orig_level) => {
264259
let flag = match orig_level {
@@ -273,46 +268,29 @@ pub fn explain_lint_level_source(
273268
};
274269
let hyphen_case_lint_name = name.replace('_', "-");
275270
if lint_flag_val.as_str() == name {
276-
sess.diag_note_once(
277-
err,
278-
DiagnosticMessageId::from(lint),
279-
&format!(
280-
"requested on the command line with `{} {}`",
281-
flag, hyphen_case_lint_name
282-
),
283-
);
271+
err.note_once(&format!(
272+
"requested on the command line with `{} {}`",
273+
flag, hyphen_case_lint_name
274+
));
284275
} else {
285276
let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-");
286-
sess.diag_note_once(
287-
err,
288-
DiagnosticMessageId::from(lint),
289-
&format!(
290-
"`{} {}` implied by `{} {}`",
291-
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
292-
),
293-
);
277+
err.note_once(&format!(
278+
"`{} {}` implied by `{} {}`",
279+
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
280+
));
294281
}
295282
}
296283
LintLevelSource::Node(lint_attr_name, src, reason) => {
297284
if let Some(rationale) = reason {
298285
err.note(rationale.as_str());
299286
}
300-
sess.diag_span_note_once(
301-
err,
302-
DiagnosticMessageId::from(lint),
303-
src,
304-
"the lint level is defined here",
305-
);
287+
err.span_note_once(src, "the lint level is defined here");
306288
if lint_attr_name.as_str() != name {
307289
let level_str = level.as_str();
308-
sess.diag_note_once(
309-
err,
310-
DiagnosticMessageId::from(lint),
311-
&format!(
312-
"`#[{}({})]` implied by `#[{}({})]`",
313-
level_str, name, level_str, lint_attr_name
314-
),
315-
);
290+
err.note_once(&format!(
291+
"`#[{}({})]` implied by `#[{}({})]`",
292+
level_str, name, level_str, lint_attr_name
293+
));
316294
}
317295
}
318296
}
@@ -412,7 +390,7 @@ pub fn struct_lint_level<'s, 'd>(
412390
return;
413391
}
414392

415-
explain_lint_level_source(sess, lint, level, src, &mut err);
393+
explain_lint_level_source(lint, level, src, &mut err);
416394

417395
let name = lint.name_lower();
418396
let is_force_warn = matches!(level, Level::ForceWarn);

compiler/rustc_middle/src/middle/stability.rs

+10-25
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
1717
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
1818
use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer};
1919
use rustc_session::parse::feature_err_issue;
20-
use rustc_session::{DiagnosticMessageId, Session};
20+
use rustc_session::Session;
2121
use rustc_span::symbol::{sym, Symbol};
22-
use rustc_span::{MultiSpan, Span};
22+
use rustc_span::Span;
2323
use std::num::NonZeroU32;
2424

2525
#[derive(PartialEq, Clone, Copy, Debug)]
@@ -94,30 +94,15 @@ pub fn report_unstable(
9494
None => format!("use of unstable library feature '{}'", &feature),
9595
};
9696

97-
let msp: MultiSpan = span.into();
98-
let sm = &sess.parse_sess.source_map();
99-
let span_key = msp.primary_span().and_then(|sp: Span| {
100-
if !sp.is_dummy() {
101-
let file = sm.lookup_char_pos(sp.lo()).file;
102-
if file.is_imported() { None } else { Some(span) }
103-
} else {
104-
None
105-
}
106-
});
107-
108-
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
109-
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
110-
if fresh {
111-
if is_soft {
112-
soft_handler(SOFT_UNSTABLE, span, &msg)
113-
} else {
114-
let mut err =
115-
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg);
116-
if let Some((inner_types, ref msg, sugg, applicability)) = suggestion {
117-
err.span_suggestion(inner_types, msg, sugg, applicability);
118-
}
119-
err.emit();
97+
if is_soft {
98+
soft_handler(SOFT_UNSTABLE, span, &msg)
99+
} else {
100+
let mut err =
101+
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg);
102+
if let Some((inner_types, ref msg, sugg, applicability)) = suggestion {
103+
err.span_suggestion(inner_types, msg, sugg, applicability);
120104
}
105+
err.emit();
121106
}
122107
}
123108

compiler/rustc_mir_transform/src/check_unsafety.rs

-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
554554
tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root);
555555
assert_eq!(level, Level::Allow);
556556
lint::explain_lint_level_source(
557-
tcx.sess,
558557
UNSAFE_OP_IN_UNSAFE_FN,
559558
Level::Allow,
560559
source,

0 commit comments

Comments
 (0)