Skip to content

Commit

Permalink
add source to diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
vemoo committed Aug 5, 2022
1 parent 18f166b commit aba8ec9
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 47 deletions.
16 changes: 12 additions & 4 deletions components/dada-execute/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,11 @@ impl<'me> Stepper<'me> {
}
TerminatorData::Error => {
let span = self.span_from_bir(terminator);
Err(error!(span, "compilation error encountered 😢").eyre(self.db))
Err(error!(Execute, span, "compilation error encountered 😢").eyre(self.db))
}
TerminatorData::Panic => {
let span = self.span_from_bir(terminator);
Err(error!(span, "panic! omg! 😱").eyre(self.db))
Err(error!(Execute, span, "panic! omg! 😱").eyre(self.db))
}
}
}
Expand Down Expand Up @@ -473,7 +473,7 @@ impl<'me> Stepper<'me> {
}
bir::ExprData::Error => {
let span = self.span_from_bir(expr);
Err(error!(span, "compilation error").eyre(self.db))
Err(error!(Execute, span, "compilation error").eyre(self.db))
}
}
}
Expand All @@ -484,13 +484,21 @@ impl<'me> Stepper<'me> {
object: &ObjectData,
what: &str,
) -> eyre::Report {
error!(span, "expected {}, found {}", what, object.kind_str(db)).eyre(db)
error!(
Execute,
span,
"expected {}, found {}",
what,
object.kind_str(db)
)
.eyre(db)
}

fn no_such_field(db: &dyn crate::Db, span: FileSpan, class: Class, name: Word) -> eyre::Report {
let class_name = class.name(db).as_str(db);
let class_span = class.name(db).span(db);
error!(
Execute,
span,
"the class `{}` has no field named `{}`",
class_name,
Expand Down
6 changes: 4 additions & 2 deletions components/dada-execute/src/step/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ impl Stepper<'_> {
// since we need to distinguish between an atomic location in a
// shared object vs a shared object in an (exclusive) atomic location.
let span = self.machine.pc().span(self.db);
return Err(error!(span, "atomic writes not implemented yet").eyre(self.db));
return Err(
error!(Execute, span, "atomic writes not implemented yet").eyre(self.db)
);
}

(Joint::Yes, Atomic::No) => {
let span = self.machine.pc().span(self.db);
return Err(error!(span, "cannot write to shared fields").eyre(self.db));
return Err(error!(Execute, span, "cannot write to shared fields").eyre(self.db));
}

(Joint::No, Atomic::Yes) | (Joint::No, Atomic::No) => {
Expand Down
1 change: 1 addition & 0 deletions components/dada-execute/src/step/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl Stepper<'_> {
Address::Local(lv) => self.machine[lv] = value,
Address::Constant(_) => {
return Err(error!(
Execute,
self.machine.pc().span(self.db),
"cannot store into a constant"
)
Expand Down
11 changes: 6 additions & 5 deletions components/dada-execute/src/step/apply_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl Stepper<'_> {
let op_error = || {
let span = self.span_from_bir(expr);
Err(error!(
Execute,
span,
"cannot apply operator {} to {} and {}",
op,
Expand All @@ -32,11 +33,11 @@ impl Stepper<'_> {
};
let div_zero_error = || {
let span = self.span_from_bir(expr);
Err(error!(span, "divide by zero").eyre(self.db))
Err(error!(Execute, span, "divide by zero").eyre(self.db))
};
let overflow_error = || {
let span = self.span_from_bir(expr);
Err(error!(span, "overflow").eyre(self.db))
Err(error!(Execute, span, "overflow").eyre(self.db))
};
match (&self.machine[lhs], &self.machine[rhs]) {
(&ObjectData::Bool(lhs), &ObjectData::Bool(rhs)) => match op {
Expand Down Expand Up @@ -149,11 +150,11 @@ impl Stepper<'_> {
) -> eyre::Result<Value> {
let div_zero_error = || {
let span = self.span_from_bir(expr);
Err(error!(span, "divide by zero").eyre(self.db))
Err(error!(Execute, span, "divide by zero").eyre(self.db))
};
let overflow_error = || {
let span = self.span_from_bir(expr);
Err(error!(span, "overflow").eyre(self.db))
Err(error!(Execute, span, "overflow").eyre(self.db))
};
match op {
Op::EqualEqual => Ok(self.machine.our_value(lhs == rhs)),
Expand All @@ -178,7 +179,7 @@ impl Stepper<'_> {
div_zero_error()
} else {
let span = self.span_from_bir(expr);
Err(error!(span, "signed division overflow").eyre(self.db))
Err(error!(Execute, span, "signed division overflow").eyre(self.db))
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion components/dada-execute/src/step/apply_unary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl Stepper<'_> {
let op_error = || {
let span = self.span_from_bir(expr);
Err(error!(
Execute,
span,
"cannot apply operator {} to {}",
op,
Expand All @@ -34,7 +35,7 @@ impl Stepper<'_> {
Ok(rhs) => Ok(self.machine.our_value(-rhs)),
Err(_) => {
let span = self.span_from_bir(expr);
Err(error!(span, "overflow").eyre(self.db))
Err(error!(Execute, span, "overflow").eyre(self.db))
}
},
_ => op_error(),
Expand Down
8 changes: 5 additions & 3 deletions components/dada-execute/src/step/await_thunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ impl Stepper<'_> {
(Joint::No, Leased::No) => return Ok(()),
};
let span = self.span_from_bir(thunk_place);
Err(error!(span, "awaiting something requires full ownership")
.primary_label(primary_label)
.eyre(self.db))
Err(
error!(Execute, span, "awaiting something requires full ownership")
.primary_label(primary_label)
.eyre(self.db),
)
}
}
3 changes: 3 additions & 0 deletions components/dada-execute/src/step/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl Stepper<'_> {
data => {
let span = self.span_from_bir(callee);
Err(error!(
Execute,
span,
"expected something callable, found {}",
data.kind_str(self.db)
Expand Down Expand Up @@ -114,6 +115,7 @@ impl Stepper<'_> {
if let Some(actual_word) = actual_label.word(db) {
if expected_name != actual_word {
return Err(error!(
Execute,
actual_label.span(db),
"expected to find an argument named `{}`, but found the name `{}`",
expected_name.as_str(db),
Expand All @@ -126,6 +128,7 @@ impl Stepper<'_> {

if actual_labels.len() != expected_names.len() {
return Err(error!(
Execute,
self.span_from_bir(call_terminator),
"expected to find {} arguments, but found {}",
expected_names.len(),
Expand Down
2 changes: 1 addition & 1 deletion components/dada-execute/src/step/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Stepper<'_> {
.await
.with_context(|| {
let span_now = self.machine.pc().span(self.db);
error!(span_now, "error printing `{:?}`", message_str).eyre(self.db)
error!(Execute, span_now, "error printing `{:?}`", message_str).eyre(self.db)
})?;

Ok(self.machine.our_value(()))
Expand Down
13 changes: 8 additions & 5 deletions components/dada-execute/src/step/traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ impl Stepper<'_> {
expired_at: Option<ProgramCounter>,
) -> eyre::Report {
match expired_at {
None => error!(place_span, "accessing uninitialized memory").eyre(self.db),
None => error!(Execute, place_span, "accessing uninitialized memory").eyre(self.db),
Some(expired_at) => {
let expired_at_span = expired_at.span(self.db);

Expand All @@ -336,10 +336,13 @@ impl Stepper<'_> {
"lease was cancelled here"
};

error!(place_span, "your lease to this object was cancelled")
.primary_label("cancelled lease used here")
.secondary_label(expired_at_span, secondary_label)
.eyre(self.db)
error!(
Execute,
place_span, "your lease to this object was cancelled"
)
.primary_label("cancelled lease used here")
.secondary_label(expired_at_span, secondary_label)
.eyre(self.db)
}
}
}
Expand Down
63 changes: 50 additions & 13 deletions components/dada-ir/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ pub struct ErrorReported;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[non_exhaustive]
pub struct Diagnostic {
pub source: Source,
pub severity: Severity,
pub span: FileSpan,
pub message: String,
pub labels: Vec<Label>,
pub children: Vec<Diagnostic>,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Source {
Lex,
Parse,
Validate,
Execute,
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Severity {
Help,
Expand All @@ -41,48 +50,73 @@ pub struct Diagnostics(Diagnostic);
/// Convenience macro for avoiding `format!`
#[macro_export]
macro_rules! diag {
($severity:expr, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder($severity, $span, format!($($message)*))
($source:ident, $severity:ident, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder(
$crate::diagnostic::Source::$source,
$crate::diagnostic::Severity::$severity,
$span, format!($($message)*)
)
}
}

/// Convenience macro for avoiding `format!`
#[macro_export]
macro_rules! error {
($span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder($crate::diagnostic::Severity::Error, $span, format!($($message)*))
($source:ident, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder(
$crate::diagnostic::Source::$source,
$crate::diagnostic::Severity::Error,
$span, format!($($message)*)
)
}
}

/// Convenience macro for avoiding `format!`
#[macro_export]
macro_rules! warning {
($span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder($crate::diagnostic::Severity::Warning, $span, format!($($message)*))
($source:ident, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder(
$crate::diagnostic::Source::$source,
$crate::diagnostic::Severity::Warning,
$span, format!($($message)*)
)
}
}

/// Convenience macro for avoiding `format!`
#[macro_export]
macro_rules! note {
($span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder($crate::diagnostic::Severity::Note, $span, format!($($message)*))
($source:ident, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder(
$crate::diagnostic::Source::$source,
$crate::diagnostic::Severity::Note,
$span, format!($($message)*)
)
}
}

/// Convenience macro for avoiding `format!`
#[macro_export]
macro_rules! help {
($span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder($crate::diagnostic::Severity::Help, $span, format!($($message)*))
($source:ident, $span:expr, $($message:tt)*) => {
$crate::diagnostic::Diagnostic::builder(
$crate::diagnostic::Source::$source,
$crate::diagnostic::Severity::Help,
$span, format!($($message)*)
)
}
}

impl Diagnostic {
/// Create a new diagnostic builder with the given "main message" at the
/// given span.
pub fn builder(severity: Severity, span: FileSpan, message: String) -> DiagnosticBuilder {
DiagnosticBuilder::new(severity, span, message)
pub fn builder(
source: Source,
severity: Severity,
span: FileSpan,
message: String,
) -> DiagnosticBuilder {
DiagnosticBuilder::new(source, severity, span, message)
}

/// Emit the diagnostic to the [`Diagnostics`] accumulator.
Expand All @@ -107,6 +141,7 @@ impl Label {

#[must_use]
pub struct DiagnosticBuilder {
source: Source,
severity: Severity,
span: FileSpan,
message: String,
Expand All @@ -122,8 +157,9 @@ pub struct DiagnosticBuilder {
}

impl DiagnosticBuilder {
fn new(severity: Severity, span: FileSpan, message: impl ToString) -> Self {
fn new(source: Source, severity: Severity, span: FileSpan, message: impl ToString) -> Self {
Self {
source,
severity,
span,
message: message.to_string(),
Expand Down Expand Up @@ -186,6 +222,7 @@ impl DiagnosticBuilder {
}

Diagnostic {
source: self.source,
severity: self.severity,
span: self.span,
message: self.message,
Expand Down
1 change: 1 addition & 0 deletions components/dada-lex/src/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ where
.unwrap_or(self.file_len),
);
dada_ir::error!(
Lex,
Span {
start: ch_offset,
end,
Expand Down
7 changes: 6 additions & 1 deletion components/dada-parse/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,12 @@ impl<'me> Parser<'me> {
}

fn error(&self, span: Span, message: impl ToString) -> DiagnosticBuilder {
dada_ir::error!(span.in_file(self.input_file), "{}", message.to_string())
dada_ir::error!(
Parse,
span.in_file(self.input_file),
"{}",
message.to_string()
)
}
}

Expand Down
3 changes: 2 additions & 1 deletion components/dada-parse/src/parser/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ impl<'db> Parser<'db> {
} else {
let span = self.tokens.last_span();
self.tokens.consume();
dada_ir::error!(span.in_file(self.input_file), "unexpected token").emit(self.db);
dada_ir::error!(Parse, span.in_file(self.input_file), "unexpected token")
.emit(self.db);
}
}

Expand Down
1 change: 1 addition & 0 deletions components/dada-validate/src/validate/name_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl RootDefinitions {
if let Some(&other_definition) = names.get(&name) {
let other_item: Item = other_definition.try_into().unwrap();
dada_ir::error!(
Validate,
item.name_span(db),
"already have a {} named `{}`",
other_item.kind_str(),
Expand Down
Loading

0 comments on commit aba8ec9

Please sign in to comment.