mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
implement canonicalization error when signature pattern does not match definition pattern.
This commit is contained in:
parent
5c81b46d1c
commit
0cfb16c7d5
@ -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),
|
||||
|
@ -46,6 +46,10 @@ pub enum Problem {
|
||||
replaced_region: Region,
|
||||
},
|
||||
RuntimeError(RuntimeError),
|
||||
SignatureDefMismatch {
|
||||
annotation_pattern: Region,
|
||||
def_pattern: Region,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
@ -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),
|
||||
};
|
||||
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user