Skip to content

Commit

Permalink
Split Handler::emit_diagnostic in two.
Browse files Browse the repository at this point in the history
Currently, `emit_diagnostic` takes `&mut self`.

This commit changes it so `emit_diagnostic` takes `self` and the new
`emit_diagnostic_without_consuming` function takes `&mut self`.

I find the distinction useful. The former case is much more common, and
avoids a bunch of `mut` and `&mut` occurrences. We can also restrict the
latter with `pub(crate)` which is nice.
  • Loading branch information
nnethercote committed Dec 14, 2023
1 parent bfb54c6 commit 792a2e3
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 45 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2502,8 +2502,8 @@ mod error {
if !self.errors.buffered.is_empty() {
self.errors.buffered.sort_by_key(|diag| diag.sort_span);

for mut diag in self.errors.buffered.drain(..) {
self.infcx.tcx.sess.diagnostic().emit_diagnostic(&mut diag);
for diag in self.errors.buffered.drain(..) {
self.infcx.tcx.sess.diagnostic().emit_diagnostic(diag);
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1848,7 +1848,7 @@ impl SharedEmitterMain {
d.code(code);
}
d.replace_args(diag.args);
handler.emit_diagnostic(&mut d);
handler.emit_diagnostic(d);
}
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
// "secondary" errors if they occurred.
let secondary_errors = mem::take(&mut self.secondary_errors);
if self.error_emitted.is_none() {
for mut error in secondary_errors {
self.tcx.sess.diagnostic().emit_diagnostic(&mut error);
for error in secondary_errors {
self.tcx.sess.diagnostic().emit_diagnostic(error);
}
} else {
assert!(self.tcx.sess.has_errors().is_some());
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;

let guar = handler.emit_diagnostic(&mut db.inner.diagnostic);
let guar = handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);

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

handler.emit_diagnostic(&mut db.inner.diagnostic);
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
Expand All @@ -207,7 +207,7 @@ impl EmissionGuarantee for Noted {
// First `.emit()` call, the `&Handler` is still available.
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
handler.emit_diagnostic(&mut db.inner.diagnostic);
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
Expand Down Expand Up @@ -236,7 +236,7 @@ impl EmissionGuarantee for Bug {
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;

handler.emit_diagnostic(&mut db.inner.diagnostic);
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
Expand All @@ -260,7 +260,7 @@ impl EmissionGuarantee for ! {
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;

handler.emit_diagnostic(&mut db.inner.diagnostic);
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
Expand All @@ -284,7 +284,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;

handler.emit_diagnostic(&mut db.inner.diagnostic);
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
}
// `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
Expand Down Expand Up @@ -365,7 +365,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
}
}

/// Emit the diagnostic.
/// Emit the diagnostic. Does not consume `self`, which may be surprising,
/// but there are various places that rely on continuing to use `self`
/// after calling `emit`.
#[track_caller]
pub fn emit(&mut self) -> G {
G::diagnostic_builder_emit_producing_guarantee(self)
Expand Down Expand Up @@ -640,13 +642,13 @@ impl Drop for DiagnosticBuilderInner<'_> {
// No `.emit()` or `.cancel()` calls.
DiagnosticBuilderState::Emittable(handler) => {
if !panicking() {
handler.emit_diagnostic(&mut Diagnostic::new(
handler.emit_diagnostic(Diagnostic::new(
Level::Bug,
DiagnosticMessage::from(
"the following error was constructed but not emitted",
),
));
handler.emit_diagnostic(&mut self.diagnostic);
handler.emit_diagnostic_without_consuming(&mut self.diagnostic);
panic!("error was constructed but not emitted");
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ impl Emitter for SilentEmitter {
if let Some(ref note) = self.fatal_note {
d.note(note.clone());
}
self.fatal_handler.emit_diagnostic(&mut d);
self.fatal_handler.emit_diagnostic(d);
}
}
}
Expand Down
47 changes: 32 additions & 15 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ impl Handler {
}
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
diagnostic.set_span(sp);
inner.emit_diagnostic(&mut diagnostic).unwrap()
inner.emit_diagnostic(diagnostic).unwrap()
}

// FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
Expand All @@ -1071,7 +1071,7 @@ impl Handler {

let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
if inner.flags.report_delayed_bugs {
inner.emit_diagnostic(&mut diagnostic);
inner.emit_diagnostic_without_consuming(&mut diagnostic);
}
let backtrace = std::backtrace::Backtrace::capture();
inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
Expand Down Expand Up @@ -1186,10 +1186,10 @@ impl Handler {
DiagnosticMessage::Str(warnings),
)),
(_, 0) => {
inner.emit_diagnostic(&mut Diagnostic::new(Fatal, errors));
inner.emit_diagnostic(Diagnostic::new(Fatal, errors));
}
(_, _) => {
inner.emit_diagnostic(&mut Diagnostic::new(Fatal, format!("{errors}; {warnings}")));
inner.emit_diagnostic(Diagnostic::new(Fatal, format!("{errors}; {warnings}")));
}
}

Expand Down Expand Up @@ -1256,8 +1256,17 @@ impl Handler {
self.inner.borrow_mut().emitter.emit_diagnostic(&db);
}

pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
self.inner.borrow_mut().emit_diagnostic(diagnostic)
pub fn emit_diagnostic(&self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
self.emit_diagnostic_without_consuming(&mut diagnostic)
}

// It's unfortunate this exists. `emit_diagnostic` is preferred, because it
// consumes the diagnostic, thus ensuring it is emitted just once.
pub(crate) fn emit_diagnostic_without_consuming(
&self,
diagnostic: &mut Diagnostic,
) -> Option<ErrorGuaranteed> {
self.inner.borrow_mut().emit_diagnostic_without_consuming(diagnostic)
}

pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed {
Expand Down Expand Up @@ -1371,7 +1380,7 @@ impl Handler {
// Here the diagnostic is given back to `emit_diagnostic` where it was first
// intercepted. Now it should be processed as usual, since the unstable expectation
// id is now stable.
inner.emit_diagnostic(&mut diag);
inner.emit_diagnostic(diag);
}
}

Expand Down Expand Up @@ -1413,7 +1422,7 @@ impl HandlerInner {
let has_errors = self.has_errors();
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
let mut reported = None;
for mut diag in diags {
for diag in diags {
// Decrement the count tracking the stash; emitting will increment it.
if diag.is_error() {
if matches!(diag.level, Level::Error { lint: true }) {
Expand All @@ -1433,14 +1442,20 @@ impl HandlerInner {
}
}
}
let reported_this = self.emit_diagnostic(&mut diag);
let reported_this = self.emit_diagnostic(diag);
reported = reported.or(reported_this);
}
reported
}

// FIXME(eddyb) this should ideally take `diagnostic` by value.
fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> {
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
self.emit_diagnostic_without_consuming(&mut diagnostic)
}

fn emit_diagnostic_without_consuming(
&mut self,
diagnostic: &mut Diagnostic,
) -> Option<ErrorGuaranteed> {
if matches!(diagnostic.level, Level::Error { .. } | Level::Fatal) && self.treat_err_as_bug()
{
diagnostic.level = Level::Bug;
Expand Down Expand Up @@ -1577,12 +1592,14 @@ impl HandlerInner {

#[track_caller]
fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
let mut diag = Diagnostic::new(Bug, msg);
diag.set_span(sp);
self.emit_diagnostic(diag);
panic::panic_any(ExplicitBug);
}

fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) {
self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg));
self.emit_diagnostic(Diagnostic::new(FailureNote, msg));
}

fn flush_delayed(
Expand Down Expand Up @@ -1614,7 +1631,7 @@ impl HandlerInner {
if no_bugs {
// Put the overall explanation before the `DelayedBug`s, to
// frame them better (e.g. separate warnings from them).
self.emit_diagnostic(&mut Diagnostic::new(Bug, explanation));
self.emit_diagnostic(Diagnostic::new(Bug, explanation));
no_bugs = false;
}

Expand All @@ -1629,7 +1646,7 @@ impl HandlerInner {
}
bug.level = Level::Bug;

self.emit_diagnostic(&mut bug);
self.emit_diagnostic(bug);
}

// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
None,
);
}
self.sess().span_diagnostic.emit_diagnostic(&mut diag);
self.sess().span_diagnostic.emit_diagnostic(diag);
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) {
let handler = tcx.sess.diagnostic();
// We normally use `handler.bug()` for bugs, but this is an exceptional case, so we do this
// instead to avoid an abort.
handler.emit_diagnostic(&mut Diagnostic::new(
handler.emit_diagnostic(Diagnostic::new(
Level::Bug,
"It looks like you're trying to break rust; would you like some ICE?",
));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {

if !errors_buffer.is_empty() {
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
for mut diag in errors_buffer {
self.tcx().sess.diagnostic().emit_diagnostic(&mut diag);
for diag in errors_buffer {
self.tcx().sess.diagnostic().emit_diagnostic(diag);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ macro_rules! panictry_buffer {
match $e {
Ok(e) => e,
Err(errs) => {
for mut e in errs {
$handler.emit_diagnostic(&mut e);
for e in errs {
$handler.emit_diagnostic(e);
}
FatalError.raise()
}
Expand Down Expand Up @@ -165,8 +165,8 @@ fn try_file_to_source_file(
fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> {
match try_file_to_source_file(sess, path, spanopt) {
Ok(source_file) => source_file,
Err(mut d) => {
sess.span_diagnostic.emit_diagnostic(&mut d);
Err(d) => {
sess.span_diagnostic.emit_diagnostic(d);
FatalError.raise();
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_query_system/src/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,8 @@ impl<D: Deps> DepGraphData<D> {

let handle = qcx.dep_context().sess().diagnostic();

for mut diagnostic in side_effects.diagnostics {
handle.emit_diagnostic(&mut diagnostic);
for diagnostic in side_effects.diagnostics {
handle.emit_diagnostic(diagnostic);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ pub fn report_msg<'tcx>(
}
}

handler.emit_diagnostic(&mut err);
handler.emit_diagnostic(err);
}

impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
Expand Down
6 changes: 2 additions & 4 deletions src/tools/rustfmt/src/parse/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,8 @@ impl ParseSess {
// Methods that should be restricted within the parse module.
impl ParseSess {
pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) {
for mut diagnostic in diagnostics {
self.parse_sess
.span_diagnostic
.emit_diagnostic(&mut diagnostic);
for diagnostic in diagnostics {
self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic);
}
}

Expand Down

0 comments on commit 792a2e3

Please sign in to comment.