Skip to content

Commit

Permalink
Improve error reporting, add a test.
Browse files Browse the repository at this point in the history
  • Loading branch information
vakaras committed Jan 14, 2020
1 parent 25fc3e8 commit 75f5bbd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
11 changes: 11 additions & 0 deletions datapond-derive/tests/fail/arg_mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32, z: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(y, x).
};
}
11 changes: 11 additions & 0 deletions datapond-derive/tests/fail/arg_mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: Wrong number of arguments for inp: expected 2, found 3.
--> $DIR/arg_mismatch.rs:9:22
|
9 | out(x, y) :- inp(y, x).
| ^^^

error: The predicate inp was declared here.
--> $DIR/arg_mismatch.rs:7:15
|
7 | input inp(x: u32, y: u32, z: u32)
| ^^^
1 change: 1 addition & 0 deletions datapond-derive/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
fn tests() {
let runner = trybuild::TestCases::new();
runner.pass("tests/pass/*.rs");
runner.compile_fail("tests/fail/*.rs");
}
35 changes: 25 additions & 10 deletions src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,42 @@ use std::fmt;
pub struct Error {
pub msg: String,
pub span: Span,
pub hint_span: Option<Span>,
pub hint: Option<(String, Span)>,
}

impl Error {
fn new(msg: String, span: Span) -> Self {
Self {
msg: msg,
span: span,
hint_span: None,
hint: None,
}
}
fn with_hint_span(msg: String, span: Span, hint_span: Span) -> Self {
fn with_hint_span(msg: String, span: Span, hint_msg: String, hint_span: Span) -> Self {
Self {
msg: msg,
span: span,
hint_span: Some(hint_span),
hint: Some((hint_msg, hint_span)),
}
}
pub fn to_syn_error(&self) -> syn::Error {
let mut error = syn::Error::new(self.span, &self.msg);
if let Some((hint_msg, hint_span)) = &self.hint {
error.combine(syn::Error::new(hint_span.clone(), hint_msg));
}
error
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(hint_span) = self.hint_span {
if let Some((hint_msg, hint_span)) = &self.hint {
write!(
f,
"{} at {:?} (hint: {:?})",
"{} at {:?} ({} at {:?})",
self.msg,
self.span.start(),
hint_msg,
hint_span.start()
)
} else {
Expand All @@ -57,13 +65,15 @@ fn check_head(
})?;
if head.args.len() != decl.parameters.len() {
let msg = format!(
"Wrong number of arguments: expected {}, found {}.",
"Wrong number of arguments for {}: expected {}, found {}.",
head.predicate,
decl.parameters.len(),
head.args.len(),
decl.parameters.len()
);
return Err(Error::with_hint_span(
msg,
head.predicate.span(),
format!("The predicate {} was declared here.", head.predicate),
decl.name.span(),
));
}
Expand All @@ -86,13 +96,15 @@ fn check_body(
past::ArgList::Positional(positional_args) => {
if positional_args.len() != decl.parameters.len() {
let msg = format!(
"Wrong number of arguments: expected {}, found {}.",
"Wrong number of arguments for {}: expected {}, found {}.",
literal.predicate,
positional_args.len(),
decl.parameters.len()
);
return Err(Error::with_hint_span(
msg,
literal.predicate.span(),
format!("The predicate {} was declared here.", decl.name),
decl.name.span(),
));
}
Expand Down Expand Up @@ -131,8 +143,11 @@ fn check_body(
}
for key in kwargs.keys() {
if !used_parameters.contains(key) {
let available_parameters: Vec<_> = used_parameters.iter().map(|parameter| parameter.to_string()).collect();
return Err(Error::new(
format!("Unknown parameter {} in predicate.", key),
format!("Unknown parameter {} in predicate {}. Available parameters are: {}.",
key, literal.predicate, available_parameters.join(","),
),
literal.predicate.span(),
));
}
Expand Down

0 comments on commit 75f5bbd

Please sign in to comment.