Skip to content

Commit 663f1b8

Browse files
authored
Rollup merge of rust-lang#95149 - cjgillot:once-diag, r=estebank
Remove `Session::one_time_diagnostic` This is untracked mutable state, which modified the behaviour of queries. It was used for 2 things: some full-blown errors, but mostly for lint declaration notes ("the lint level is defined here" notes). It is replaced by the diagnostic deduplication infra which already exists in the diagnostic emitter. A new diagnostic level `OnceNote` is introduced specifically for lint notes, to deduplicate subdiagnostics. As a drive-by, diagnostic emission takes a `&mut` to allow dropping the `SubDiagnostic`s.
2 parents a2ebd5a + f7d5b7a commit 663f1b8

File tree

46 files changed

+227
-359
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+227
-359
lines changed

compiler/rustc_borrowck/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2361,8 +2361,8 @@ mod error {
23612361
if !self.errors.buffered.is_empty() {
23622362
self.errors.buffered.sort_by_key(|diag| diag.sort_span);
23632363

2364-
for diag in self.errors.buffered.drain(..) {
2365-
self.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag);
2364+
for mut diag in self.errors.buffered.drain(..) {
2365+
self.infcx.tcx.sess.diagnostic().emit_diagnostic(&mut diag);
23662366
}
23672367
}
23682368

compiler/rustc_codegen_ssa/src/back/write.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1748,7 +1748,7 @@ impl SharedEmitterMain {
17481748
if let Some(code) = diag.code {
17491749
d.code(code);
17501750
}
1751-
handler.emit_diagnostic(&d);
1751+
handler.emit_diagnostic(&mut d);
17521752
}
17531753
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
17541754
let msg = msg.strip_prefix("error: ").unwrap_or(&msg);

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
255255
// "secondary" errors if they occurred.
256256
let secondary_errors = mem::take(&mut self.secondary_errors);
257257
if self.error_emitted.is_none() {
258-
for error in secondary_errors {
259-
self.tcx.sess.diagnostic().emit_diagnostic(&error);
258+
for mut error in secondary_errors {
259+
self.tcx.sess.diagnostic().emit_diagnostic(&mut error);
260260
}
261261
} else {
262262
assert!(self.tcx.sess.has_errors().is_some());

compiler/rustc_driver/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1181,8 +1181,8 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
11811181
// a .span_bug or .bug call has already printed what
11821182
// it wants to print.
11831183
if !info.payload().is::<rustc_errors::ExplicitBug>() {
1184-
let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
1185-
handler.emit_diagnostic(&d);
1184+
let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
1185+
handler.emit_diagnostic(&mut d);
11861186
}
11871187

11881188
let mut xs: Vec<Cow<'static, str>> = vec![

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

+10-4
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
128128
DiagnosticBuilderState::Emittable(handler) => {
129129
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
130130

131-
let guar = handler.emit_diagnostic(&db.inner.diagnostic);
131+
let guar = handler.emit_diagnostic(&mut db.inner.diagnostic);
132132

133133
// Only allow a guarantee if the `level` wasn't switched to a
134134
// non-error - the field isn't `pub`, but the whole `Diagnostic`
@@ -190,7 +190,7 @@ impl EmissionGuarantee for () {
190190
DiagnosticBuilderState::Emittable(handler) => {
191191
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
192192

193-
handler.emit_diagnostic(&db.inner.diagnostic);
193+
handler.emit_diagnostic(&mut db.inner.diagnostic);
194194
}
195195
// `.emit()` was previously called, disallowed from repeating it.
196196
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@@ -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);
@@ -500,11 +506,11 @@ impl Drop for DiagnosticBuilderInner<'_> {
500506
// No `.emit()` or `.cancel()` calls.
501507
DiagnosticBuilderState::Emittable(handler) => {
502508
if !panicking() {
503-
handler.emit_diagnostic(&Diagnostic::new(
509+
handler.emit_diagnostic(&mut Diagnostic::new(
504510
Level::Bug,
505511
"the following error was constructed but not emitted",
506512
));
507-
handler.emit_diagnostic(&self.diagnostic);
513+
handler.emit_diagnostic(&mut self.diagnostic);
508514
panic!();
509515
}
510516
}

compiler/rustc_errors/src/emitter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ impl Emitter for SilentEmitter {
542542
if let Some(ref note) = self.fatal_note {
543543
d.note(note);
544544
}
545-
self.fatal_handler.emit_diagnostic(&d);
545+
self.fatal_handler.emit_diagnostic(&mut d);
546546
}
547547
}
548548
}

compiler/rustc_errors/src/lib.rs

+37-18
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)]
@@ -919,7 +920,7 @@ impl Handler {
919920
self.inner.borrow_mut().force_print_diagnostic(db)
920921
}
921922

922-
pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> {
923+
pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
923924
self.inner.borrow_mut().emit_diagnostic(diagnostic)
924925
}
925926

@@ -993,25 +994,25 @@ impl HandlerInner {
993994
self.taught_diagnostics.insert(code.clone())
994995
}
995996

996-
fn force_print_diagnostic(&mut self, db: Diagnostic) {
997-
self.emitter.emit_diagnostic(&db);
997+
fn force_print_diagnostic(&mut self, mut db: Diagnostic) {
998+
self.emitter.emit_diagnostic(&mut db);
998999
}
9991000

10001001
/// Emit all stashed diagnostics.
10011002
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
10021003
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
10031004
let mut reported = None;
1004-
diags.iter().for_each(|diag| {
1005+
for mut diag in diags {
10051006
if diag.is_error() {
10061007
reported = Some(ErrorGuaranteed(()));
10071008
}
1008-
self.emit_diagnostic(diag);
1009-
});
1009+
self.emit_diagnostic(&mut diag);
1010+
}
10101011
reported
10111012
}
10121013

10131014
// FIXME(eddyb) this should ideally take `diagnostic` by value.
1014-
fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> {
1015+
fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
10151016
if diagnostic.level == Level::DelayedBug {
10161017
// FIXME(eddyb) this should check for `has_errors` and stop pushing
10171018
// once *any* errors were emitted (and truncate `delayed_span_bugs`
@@ -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 {
@@ -1221,22 +1238,22 @@ impl HandlerInner {
12211238
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
12221239
diagnostic.set_span(sp.into());
12231240
diagnostic.note(&format!("delayed at {}", std::panic::Location::caller()));
1224-
self.emit_diagnostic(&diagnostic).unwrap()
1241+
self.emit_diagnostic(&mut diagnostic).unwrap()
12251242
}
12261243

12271244
// FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
12281245
// where the explanation of what "good path" is (also, it should be renamed).
12291246
fn delay_good_path_bug(&mut self, msg: &str) {
1230-
let diagnostic = Diagnostic::new(Level::DelayedBug, msg);
1247+
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
12311248
if self.flags.report_delayed_bugs {
1232-
self.emit_diagnostic(&diagnostic);
1249+
self.emit_diagnostic(&mut diagnostic);
12331250
}
12341251
let backtrace = std::backtrace::Backtrace::force_capture();
12351252
self.delayed_good_path_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
12361253
}
12371254

12381255
fn failure(&mut self, msg: &str) {
1239-
self.emit_diagnostic(&Diagnostic::new(FailureNote, msg));
1256+
self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg));
12401257
}
12411258

12421259
fn fatal(&mut self, msg: &str) -> FatalError {
@@ -1253,11 +1270,11 @@ impl HandlerInner {
12531270
if self.treat_err_as_bug() {
12541271
self.bug(msg);
12551272
}
1256-
self.emit_diagnostic(&Diagnostic::new(level, msg)).unwrap()
1273+
self.emit_diagnostic(&mut Diagnostic::new(level, msg)).unwrap()
12571274
}
12581275

12591276
fn bug(&mut self, msg: &str) -> ! {
1260-
self.emit_diagnostic(&Diagnostic::new(Bug, msg));
1277+
self.emit_diagnostic(&mut Diagnostic::new(Bug, msg));
12611278
panic::panic_any(ExplicitBug);
12621279
}
12631280

@@ -1267,7 +1284,7 @@ impl HandlerInner {
12671284
if no_bugs {
12681285
// Put the overall explanation before the `DelayedBug`s, to
12691286
// frame them better (e.g. separate warnings from them).
1270-
self.emit_diagnostic(&Diagnostic::new(Bug, explanation));
1287+
self.emit_diagnostic(&mut Diagnostic::new(Bug, explanation));
12711288
no_bugs = false;
12721289
}
12731290

@@ -1283,7 +1300,7 @@ impl HandlerInner {
12831300
}
12841301
bug.level = Level::Bug;
12851302

1286-
self.emit_diagnostic(&bug);
1303+
self.emit_diagnostic(&mut bug);
12871304
}
12881305

12891306
// Panic with `ExplicitBug` to avoid "unexpected panic" messages.
@@ -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_expand/src/proc_macro_server.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,8 @@ impl server::Diagnostic for Rustc<'_, '_> {
771771
) {
772772
diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
773773
}
774-
fn emit(&mut self, diag: Self::Diagnostic) {
775-
self.sess().span_diagnostic.emit_diagnostic(&diag);
774+
fn emit(&mut self, mut diag: Self::Diagnostic) {
775+
self.sess().span_diagnostic.emit_diagnostic(&mut diag);
776776
}
777777
}
778778

0 commit comments

Comments
 (0)