Make fatal DiagnosticBuilder yield never
This commit is contained in:
parent
93313d108f
commit
928388bad2
11 changed files with 82 additions and 46 deletions
|
@ -198,6 +198,45 @@ impl EmissionGuarantee for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticBuilder<'a, !> {
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// `struct_*` methods on [`Handler`].
|
||||
crate fn new_fatal(handler: &'a Handler, message: &str) -> Self {
|
||||
let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message);
|
||||
Self::new_diagnostic_fatal(handler, diagnostic)
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed
|
||||
/// diagnostic.
|
||||
crate fn new_diagnostic_fatal(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 ! {
|
||||
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 => {}
|
||||
}
|
||||
// Then fatally error, returning `!`
|
||||
crate::FatalError.raise()
|
||||
}
|
||||
}
|
||||
|
||||
/// In general, the `DiagnosticBuilder` uses deref to allow access to
|
||||
/// the fields and methods of the embedded `diagnostic` in a
|
||||
/// transparent way. *However,* many of the methods are intended to
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(backtrace)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_else)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(adt_const_params)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -758,7 +759,7 @@ impl Handler {
|
|||
&self,
|
||||
span: impl Into<MultiSpan>,
|
||||
msg: &str,
|
||||
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
let mut result = self.struct_fatal(msg);
|
||||
result.set_span(span);
|
||||
result
|
||||
|
@ -770,15 +771,15 @@ impl Handler {
|
|||
span: impl Into<MultiSpan>,
|
||||
msg: &str,
|
||||
code: DiagnosticId,
|
||||
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
let mut result = self.struct_span_fatal(span, msg);
|
||||
result.code(code);
|
||||
result
|
||||
}
|
||||
|
||||
/// Construct a builder at the `Error` level with the `msg`.
|
||||
pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
DiagnosticBuilder::new_guaranteeing_error::<{ Level::Fatal }>(self, msg)
|
||||
pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, !> {
|
||||
DiagnosticBuilder::new_fatal(self, msg)
|
||||
}
|
||||
|
||||
/// Construct a builder at the `Help` level with the `msg`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue