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>
This commit is contained in:
parent
1e86226e9d
commit
f8ebc72b4a
@ -255,6 +255,56 @@ impl EmissionGuarantee for () {
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker type which enables implementation of `create_note` and `emit_note` functions for
|
||||
/// note-without-error struct diagnostics.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Noted;
|
||||
|
||||
impl<'a> DiagnosticBuilder<'a, Noted> {
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// `struct_*` methods on [`Handler`].
|
||||
pub(crate) fn new_note(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
|
||||
let diagnostic = Diagnostic::new_with_code(Level::Note, None, message);
|
||||
Self::new_diagnostic_note(handler, diagnostic)
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed
|
||||
/// diagnostic.
|
||||
pub(crate) fn new_diagnostic_note(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
|
||||
debug!("Created new diagnostic");
|
||||
Self {
|
||||
inner: DiagnosticBuilderInner {
|
||||
state: DiagnosticBuilderState::Emittable(handler),
|
||||
diagnostic: Box::new(diagnostic),
|
||||
},
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmissionGuarantee for Noted {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
handler.emit_diagnostic(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
|
||||
Noted
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new_note(handler, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticBuilder<'a, !> {
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// `struct_*` methods on [`Handler`].
|
||||
|
@ -374,7 +374,7 @@ pub use diagnostic::{
|
||||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay,
|
||||
DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
|
||||
};
|
||||
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
|
||||
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
|
||||
use std::backtrace::Backtrace;
|
||||
|
||||
/// A handler deals with errors and other compiler output.
|
||||
@ -988,7 +988,11 @@ impl Handler {
|
||||
}
|
||||
|
||||
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None }
|
||||
if self.inner.borrow().has_errors() {
|
||||
Some(ErrorGuaranteed(()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
if self.inner.borrow().has_errors_or_lint_errors() {
|
||||
|
@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lock, Lrc};
|
||||
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
|
||||
use rustc_errors::{
|
||||
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
|
||||
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
|
||||
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
|
||||
};
|
||||
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
|
||||
use rustc_span::edition::Edition;
|
||||
@ -354,6 +354,17 @@ impl ParseSess {
|
||||
self.create_warning(warning).emit()
|
||||
}
|
||||
|
||||
pub fn create_note<'a>(
|
||||
&'a self,
|
||||
note: impl IntoDiagnostic<'a, Noted>,
|
||||
) -> DiagnosticBuilder<'a, Noted> {
|
||||
note.into_diagnostic(&self.span_diagnostic)
|
||||
}
|
||||
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
|
||||
self.create_note(note).emit()
|
||||
}
|
||||
|
||||
pub fn create_fatal<'a>(
|
||||
&'a self,
|
||||
fatal: impl IntoDiagnostic<'a, !>,
|
||||
|
@ -28,7 +28,7 @@ use rustc_errors::json::JsonEmitter;
|
||||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{
|
||||
error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
|
||||
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan,
|
||||
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
pub use rustc_span::def_id::StableCrateId;
|
||||
@ -489,6 +489,15 @@ impl Session {
|
||||
pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) {
|
||||
self.parse_sess.emit_warning(warning)
|
||||
}
|
||||
pub fn create_note<'a>(
|
||||
&'a self,
|
||||
note: impl IntoDiagnostic<'a, Noted>,
|
||||
) -> DiagnosticBuilder<'a, Noted> {
|
||||
self.parse_sess.create_note(note)
|
||||
}
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
|
||||
self.parse_sess.emit_note(note)
|
||||
}
|
||||
pub fn create_fatal<'a>(
|
||||
&'a self,
|
||||
fatal: impl IntoDiagnostic<'a, !>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user