Skip to content

Commit

Permalink
refactor: replace blanket() with get_emitted_error()
Browse files Browse the repository at this point in the history
This ensures that an error was previously emitted preventing a situation
where ErrorGuaranteed is returned without anything errors being reported
  • Loading branch information
junlarsen committed Feb 15, 2025
1 parent de88e20 commit 7f4b482
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 8 deletions.
2 changes: 1 addition & 1 deletion compiler/eight-driver/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl<'session> Pipeline<'session> {
) -> Result<O, PipelineError> {
match (self.dcx().is_empty(), cond) {
(true, true) => Ok(operation(self)?),
(false, _) => Err(self.dcx().blanket().into()),
(false, _) => Err(self.dcx().get_emitted_error().into()),
(_, false) => Err(self.get_terminator_error()),
}
}
Expand Down
29 changes: 25 additions & 4 deletions compiler/eight-support/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use thiserror::Error;
/// A token that indicates that an error occurred.
///
/// The diagnostic associated with this error has been collected.
#[derive(Error, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[derive(Error, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[error("error dispatched through diagnostic context")]
pub struct ErrorGuaranteed(pub(crate) ());

Expand Down Expand Up @@ -38,6 +38,7 @@ impl DiagnosticSource {
/// order to collect more diagnostics), or fatal (the compiler should exit immediately).
pub struct DiagnosticContext {
diagnostics: Mutex<Vec<Report>>,
errors: Mutex<Vec<ErrorGuaranteed>>,
src: Rc<DiagnosticSource>,
}

Expand All @@ -49,6 +50,7 @@ impl DiagnosticContext {
pub fn new(src: Rc<DiagnosticSource>, max_diagnostic_count: usize) -> Self {
Self {
src,
errors: Mutex::new(Vec::new()),
diagnostics: Mutex::new(Vec::with_capacity(min(max_diagnostic_count, 16))),
}
}
Expand All @@ -67,11 +69,30 @@ impl DiagnosticContext {
.unwrap_or_else(|_| ice!("failed to acquire diagnostics lock"));
diagnostics.push(Report::from(diagnostic));
// At the moment we don't have warnings, so we always return an error here.
ErrorGuaranteed(())
let err = ErrorGuaranteed(());
let mut errors = self
.errors
.lock()
.unwrap_or_else(|_| ice!("failed to acquire error set lock"));
errors.push(err);
// Give the lock to get_emitted_error()
drop(errors);
self.get_emitted_error()
}

pub fn blanket(&self) -> ErrorGuaranteed {
ErrorGuaranteed(())
/// Get the last emitted ErrorGuaranteed reference.
///
/// It being the last error holds no importance because ErrorGuaranteed is opaque, but it does
/// ensure that an error was emitted before returning a reference to an ErrorGuaranteed.
pub fn get_emitted_error(&self) -> ErrorGuaranteed {
let errors = self
.errors
.lock()
.unwrap_or_else(|_| ice!("failed to acquire error set locl"));
let err = errors.last().unwrap_or_else(|| {
ice!("attempted to get previously emitted error with zero recorded errors")
});
err.to_owned()
}

/// Report all the collected diagnostics to stderr.
Expand Down
2 changes: 1 addition & 1 deletion compiler/eight-syntax/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<'a> LexerInput<'a> {
span: Span::pos(start + 1),
});
}
Err(self.dcx.blanket())
Err(self.dcx.get_emitted_error())
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/eight-syntax/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl<'a> ParserInput<'a> {
span: Span::pos(self.lexer.pos()),
}));
}
return Err(self.dcx.blanket());
return Err(self.dcx.get_emitted_error());
}
}
}
Expand Down Expand Up @@ -125,7 +125,7 @@ impl<'a, 'ast> Parser<'a, 'ast> {
span: Span::pos(pos),
}));
}
Err(self.dcx.blanket())
Err(self.dcx.get_emitted_error())
}

/// Determine if the next token in the token stream matches the given type.
Expand Down

0 comments on commit 7f4b482

Please sign in to comment.