Skip to content

Commit c5b9cb4

Browse files
committed
errors: add emit_note/create_note
Add `Noted` marker struct that implements `EmissionGuarantee` so that `emit_note` and `create_note` can be implemented for struct diagnostics. Signed-off-by: David Wood <[email protected]>
1 parent c97922d commit c5b9cb4

File tree

4 files changed

+73
-2
lines changed

4 files changed

+73
-2
lines changed

compiler/rustc_errors/src/diagnostic_builder.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,56 @@ impl EmissionGuarantee for () {
232232
}
233233
}
234234

235+
/// Marker type which enables implementation of `create_note` and `emit_note` functions for
236+
/// note-without-error struct diagnostics.
237+
#[derive(Copy, Clone)]
238+
pub struct Noted;
239+
240+
impl<'a> DiagnosticBuilder<'a, Noted> {
241+
/// Convenience function for internal use, clients should use one of the
242+
/// `struct_*` methods on [`Handler`].
243+
pub(crate) fn new_note(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
244+
let diagnostic = Diagnostic::new_with_code(Level::Note, None, message);
245+
Self::new_diagnostic_note(handler, diagnostic)
246+
}
247+
248+
/// Creates a new `DiagnosticBuilder` with an already constructed
249+
/// diagnostic.
250+
pub(crate) fn new_diagnostic_note(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
251+
debug!("Created new diagnostic");
252+
Self {
253+
inner: DiagnosticBuilderInner {
254+
state: DiagnosticBuilderState::Emittable(handler),
255+
diagnostic: Box::new(diagnostic),
256+
},
257+
_marker: PhantomData,
258+
}
259+
}
260+
}
261+
262+
impl EmissionGuarantee for Noted {
263+
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
264+
match db.inner.state {
265+
// First `.emit()` call, the `&Handler` is still available.
266+
DiagnosticBuilderState::Emittable(handler) => {
267+
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
268+
handler.emit_diagnostic(&mut db.inner.diagnostic);
269+
}
270+
// `.emit()` was previously called, disallowed from repeating it.
271+
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
272+
}
273+
274+
Noted
275+
}
276+
277+
fn make_diagnostic_builder(
278+
handler: &Handler,
279+
msg: impl Into<DiagnosticMessage>,
280+
) -> DiagnosticBuilder<'_, Self> {
281+
DiagnosticBuilder::new_note(handler, msg)
282+
}
283+
}
284+
235285
impl<'a> DiagnosticBuilder<'a, !> {
236286
/// Convenience function for internal use, clients should use one of the
237287
/// `struct_*` methods on [`Handler`].

compiler/rustc_errors/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ pub use diagnostic::{
373373
AddSubdiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay,
374374
DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
375375
};
376-
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder};
376+
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder, Noted};
377377
use std::backtrace::Backtrace;
378378

379379
/// A handler deals with errors and other compiler output.

compiler/rustc_session/src/parse.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_data_structures::sync::{Lock, Lrc};
1313
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
1414
use rustc_errors::{
1515
fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
16-
DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, StashKey,
16+
DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, Noted, StashKey,
1717
};
1818
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
1919
use rustc_span::edition::Edition;
@@ -361,6 +361,17 @@ impl ParseSess {
361361
self.create_warning(warning).emit()
362362
}
363363

364+
pub fn create_note<'a>(
365+
&'a self,
366+
note: impl SessionDiagnostic<'a, Noted>,
367+
) -> DiagnosticBuilder<'a, Noted> {
368+
note.into_diagnostic(&self.span_diagnostic)
369+
}
370+
371+
pub fn emit_note<'a>(&'a self, note: impl SessionDiagnostic<'a, Noted>) -> Noted {
372+
self.create_note(note).emit()
373+
}
374+
364375
pub fn create_fatal<'a>(
365376
&'a self,
366377
fatal: impl SessionDiagnostic<'a, !>,

compiler/rustc_session/src/session.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_errors::registry::Registry;
2929
use rustc_errors::{
3030
error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
3131
EmissionGuarantee, ErrorGuaranteed, FluentBundle, Handler, LazyFallbackBundle, MultiSpan,
32+
Noted,
3233
};
3334
use rustc_macros::HashStable_Generic;
3435
pub use rustc_span::def_id::StableCrateId;
@@ -542,6 +543,15 @@ impl Session {
542543
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
543544
self.parse_sess.emit_warning(warning)
544545
}
546+
pub fn create_note<'a>(
547+
&'a self,
548+
note: impl SessionDiagnostic<'a, Noted>,
549+
) -> DiagnosticBuilder<'a, Noted> {
550+
self.parse_sess.create_note(note)
551+
}
552+
pub fn emit_note<'a>(&'a self, note: impl SessionDiagnostic<'a, Noted>) -> Noted {
553+
self.parse_sess.emit_note(note)
554+
}
545555
pub fn create_fatal<'a>(
546556
&'a self,
547557
fatal: impl SessionDiagnostic<'a, !>,

0 commit comments

Comments
 (0)