Skip to content

Commit 055522f

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 <david.wood@huawei.com>
1 parent 7a8636c commit 055522f

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

compiler/rustc_errors/src/diagnostic_builder.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,56 @@ impl EmissionGuarantee for () {
242242
}
243243
}
244244

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

compiler/rustc_errors/src/lib.rs

Lines changed: 1 addition & 1 deletion
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, LintDiagnosticBuilder};
377+
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder, Noted};
378378
use std::backtrace::Backtrace;
379379

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

compiler/rustc_session/src/parse.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use rustc_data_structures::sync::{Lock, Lrc};
1212
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
1313
use rustc_errors::{
1414
fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
15-
DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
15+
DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted,
16+
StashKey,
1617
};
1718
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
1819
use rustc_span::edition::Edition;
@@ -364,6 +365,17 @@ impl ParseSess {
364365
self.create_warning(warning).emit()
365366
}
366367

368+
pub fn create_note<'a>(
369+
&'a self,
370+
note: impl IntoDiagnostic<'a, Noted>,
371+
) -> DiagnosticBuilder<'a, Noted> {
372+
note.into_diagnostic(&self.span_diagnostic)
373+
}
374+
375+
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
376+
self.create_note(note).emit()
377+
}
378+
367379
pub fn create_fatal<'a>(
368380
&'a self,
369381
fatal: impl IntoDiagnostic<'a, !>,

compiler/rustc_session/src/session.rs

Lines changed: 10 additions & 1 deletion
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;
@@ -533,6 +533,15 @@ impl Session {
533533
pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) {
534534
self.parse_sess.emit_warning(warning)
535535
}
536+
pub fn create_note<'a>(
537+
&'a self,
538+
note: impl IntoDiagnostic<'a, Noted>,
539+
) -> DiagnosticBuilder<'a, Noted> {
540+
self.parse_sess.create_note(note)
541+
}
542+
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
543+
self.parse_sess.emit_note(note)
544+
}
536545
pub fn create_fatal<'a>(
537546
&'a self,
538547
fatal: impl IntoDiagnostic<'a, !>,

0 commit comments

Comments
 (0)