Skip to content

Commit f8ebc72

Browse files
davidtwcoCleanCut
authored andcommitted
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 1e86226 commit f8ebc72

File tree

4 files changed

+78
-4
lines changed

4 files changed

+78
-4
lines changed

compiler/rustc_errors/src/diagnostic_builder.rs

+50
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,56 @@ impl EmissionGuarantee for () {
255255
}
256256
}
257257

258+
/// Marker type which enables implementation of `create_note` and `emit_note` functions for
259+
/// note-without-error struct diagnostics.
260+
#[derive(Copy, Clone)]
261+
pub struct Noted;
262+
263+
impl<'a> DiagnosticBuilder<'a, Noted> {
264+
/// Convenience function for internal use, clients should use one of the
265+
/// `struct_*` methods on [`Handler`].
266+
pub(crate) fn new_note(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
267+
let diagnostic = Diagnostic::new_with_code(Level::Note, None, message);
268+
Self::new_diagnostic_note(handler, diagnostic)
269+
}
270+
271+
/// Creates a new `DiagnosticBuilder` with an already constructed
272+
/// diagnostic.
273+
pub(crate) fn new_diagnostic_note(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
274+
debug!("Created new diagnostic");
275+
Self {
276+
inner: DiagnosticBuilderInner {
277+
state: DiagnosticBuilderState::Emittable(handler),
278+
diagnostic: Box::new(diagnostic),
279+
},
280+
_marker: PhantomData,
281+
}
282+
}
283+
}
284+
285+
impl EmissionGuarantee for Noted {
286+
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
287+
match db.inner.state {
288+
// First `.emit()` call, the `&Handler` is still available.
289+
DiagnosticBuilderState::Emittable(handler) => {
290+
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
291+
handler.emit_diagnostic(&mut db.inner.diagnostic);
292+
}
293+
// `.emit()` was previously called, disallowed from repeating it.
294+
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
295+
}
296+
297+
Noted
298+
}
299+
300+
fn make_diagnostic_builder(
301+
handler: &Handler,
302+
msg: impl Into<DiagnosticMessage>,
303+
) -> DiagnosticBuilder<'_, Self> {
304+
DiagnosticBuilder::new_note(handler, msg)
305+
}
306+
}
307+
258308
impl<'a> DiagnosticBuilder<'a, !> {
259309
/// Convenience function for internal use, clients should use one of the
260310
/// `struct_*` methods on [`Handler`].

compiler/rustc_errors/src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ pub use diagnostic::{
374374
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay,
375375
DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
376376
};
377-
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
377+
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
378378
use std::backtrace::Backtrace;
379379

380380
/// A handler deals with errors and other compiler output.
@@ -988,7 +988,11 @@ impl Handler {
988988
}
989989

990990
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
991-
if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None }
991+
if self.inner.borrow().has_errors() {
992+
Some(ErrorGuaranteed(()))
993+
} else {
994+
None
995+
}
992996
}
993997
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
994998
if self.inner.borrow().has_errors_or_lint_errors() {

compiler/rustc_session/src/parse.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lock, Lrc};
1212
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
1313
use rustc_errors::{
1414
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
15-
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
15+
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
1616
};
1717
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
1818
use rustc_span::edition::Edition;
@@ -354,6 +354,17 @@ impl ParseSess {
354354
self.create_warning(warning).emit()
355355
}
356356

357+
pub fn create_note<'a>(
358+
&'a self,
359+
note: impl IntoDiagnostic<'a, Noted>,
360+
) -> DiagnosticBuilder<'a, Noted> {
361+
note.into_diagnostic(&self.span_diagnostic)
362+
}
363+
364+
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
365+
self.create_note(note).emit()
366+
}
367+
357368
pub fn create_fatal<'a>(
358369
&'a self,
359370
fatal: impl IntoDiagnostic<'a, !>,

compiler/rustc_session/src/session.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_errors::json::JsonEmitter;
2828
use rustc_errors::registry::Registry;
2929
use rustc_errors::{
3030
error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
31-
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan,
31+
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
3232
};
3333
use rustc_macros::HashStable_Generic;
3434
pub use rustc_span::def_id::StableCrateId;
@@ -489,6 +489,15 @@ impl Session {
489489
pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) {
490490
self.parse_sess.emit_warning(warning)
491491
}
492+
pub fn create_note<'a>(
493+
&'a self,
494+
note: impl IntoDiagnostic<'a, Noted>,
495+
) -> DiagnosticBuilder<'a, Noted> {
496+
self.parse_sess.create_note(note)
497+
}
498+
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
499+
self.parse_sess.emit_note(note)
500+
}
492501
pub fn create_fatal<'a>(
493502
&'a self,
494503
fatal: impl IntoDiagnostic<'a, !>,

0 commit comments

Comments
 (0)