implement canonicalization error when signature pattern does not match definition pattern.

This commit is contained in:
Folkert 2020-07-02 23:24:10 +02:00
parent 5c81b46d1c
commit 0cfb16c7d5
4 changed files with 55 additions and 1 deletions

View File

@ -168,7 +168,15 @@ pub fn canonicalize_defs<'a>(
pattern_type,
)
} else {
panic!("TODO gracefully handle the case where a type annotation appears immediately before a body def, but the patterns are different. This should be an error; put a newline or comment between them!");
// the pattern of the annotation does not match the pattern of the body directly below it
env.problems.push(Problem::SignatureDefMismatch {
annotation_pattern: pattern.region,
def_pattern: body_pattern.region,
});
// both the annotation and definition are skipped!
iter.next();
continue;
}
}
_ => to_pending_def(env, var_store, &loc_def.value, &mut scope, pattern_type),

View File

@ -46,6 +46,10 @@ pub enum Problem {
replaced_region: Region,
},
RuntimeError(RuntimeError),
SignatureDefMismatch {
annotation_pattern: Region,
def_pattern: Region,
},
}
#[derive(Clone, Debug, PartialEq)]

View File

@ -1,6 +1,7 @@
use roc_collections::all::MutSet;
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
use roc_problem::can::{Problem, RuntimeError};
use roc_region::all::Region;
use std::path::PathBuf;
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
@ -238,6 +239,19 @@ pub fn can_problem<'b>(
alloc.reflow(" definitions from this tag union type."),
]),
]),
Problem::SignatureDefMismatch {
ref annotation_pattern,
ref def_pattern,
} => alloc.stack(vec![
alloc.reflow("This annotation does not match the definition immediately following it:"),
alloc.region(Region::span_across(annotation_pattern, def_pattern)),
alloc.reflow("Is it a typo? If not, put either a newline or comment between them."),
// TODO add link to this guide section
// alloc.hint().append(alloc.reflow(
// "If you want an unused type parameter (a so-called \"phantom type\"), \
// read the guide section on phantom data.",
// )),
]),
Problem::RuntimeError(runtime_error) => pretty_runtime_error(alloc, runtime_error),
};

View File

@ -2684,6 +2684,34 @@ mod test_reporting {
)
}
#[test]
fn annotation_definition_mismatch() {
report_problem_as(
indoc!(
r#"
bar : Int
foo = \x -> x
# NOTE: neither bar or foo are defined at this point
4
"#
),
indoc!(
r#"
-- SYNTAX PROBLEM --------------------------------------------------------------
This annotation does not match the definition immediately following
it:
1 > bar : Int
2 > foo = \x -> x
Is it a typo? If not, put either a newline or comment between them.
"#
),
)
}
#[test]
fn invalid_num() {
report_problem_as(