1
1
mirror of https://github.com/tweag/nickel.git synced 2024-09-20 16:08:14 +03:00

Adapt error reporting to type paths with lists

This commit is contained in:
Yann Hamdaoui 2021-01-21 19:53:36 +01:00
parent 3a87a88e90
commit 555877da8f
2 changed files with 14 additions and 10 deletions

View File

@ -488,8 +488,12 @@ fn report_ty_path(l: &label::Label, files: &mut Files<String>) -> (Label<FileId>
let (msg, notes) = if l.path.is_empty() {
(String::from("expected type"), Vec::new())
} else if ty_path::is_only_field(&l.path) {
(String::from("expected field type"), Vec::new())
} else if ty_path::has_no_arrow(&l.path) {
match l.path.last() {
Some(ty_path::Elem::List) => (String::from("expected list element type"), Vec::new()),
Some(ty_path::Elem::Field(_)) => (String::from("expected field type"), Vec::new()),
_ => unreachable!(),
}
}
// If the path is only composed of codomains, polarity is necessarily true and the cause of the
// blame is the return value of the function
@ -508,13 +512,13 @@ fn report_ty_path(l: &label::Label, files: &mut Files<String>) -> (Label<FileId>
],
)
} else {
// We ignore the `Field` elements of the path, since they do not impact polarity, and only
// consider "higher-order" elements to customize error messages.
// We ignore the `Field` and `List` elements of the path, since they do not impact
// polarity, and only consider "higher-order" elements to customize error messages.
let last = l
.path
.iter()
.filter(|elt| match *elt {
ty_path::Elem::Field(_) => false,
ty_path::Elem::Field(_) | ty_path::Elem::List => false,
_ => true,
})
.last()
@ -750,7 +754,7 @@ impl ToDiagnostic<FileId> for EvalError {
let mut msg = String::from("Blame error: ");
// Writing in a string should not raise an error, whence the fearless `unwrap()`
if l.path.is_empty() || ty_path::is_only_field(&l.path) {
if ty_path::has_no_arrow(&l.path) {
// An empty path or a path that contains only fields necessarily corresponds to
// a positive blame
assert!(l.polarity);

View File

@ -58,10 +58,10 @@ pub mod ty_path {
p.iter().all(|elt| *elt == Elem::Codomain)
}
/// Determine if the path has only `Field` components.
pub fn is_only_field(p: &Path) -> bool {
p.iter().all(|elt| match *elt {
Elem::Field(_) => true,
/// Determine if the path is not higher order, that is, if it doesn't contain any arrow.
pub fn has_no_arrow(p: &Path) -> bool {
!p.iter().any(|elt| match *elt {
Elem::Domain | Elem::Codomain => true,
_ => false,
})
}