mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Merge pull request #394 from rtfeldman/annotation-def-match
Report when annotation pattern does not match definition pattern
This commit is contained in:
commit
39b70232de
5 changed files with 54 additions and 7 deletions
|
@ -168,7 +168,15 @@ pub fn canonicalize_defs<'a>(
|
||||||
pattern_type,
|
pattern_type,
|
||||||
)
|
)
|
||||||
} else {
|
} 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),
|
_ => to_pending_def(env, var_store, &loc_def.value, &mut scope, pattern_type),
|
||||||
|
|
|
@ -46,6 +46,10 @@ pub enum Problem {
|
||||||
replaced_region: Region,
|
replaced_region: Region,
|
||||||
},
|
},
|
||||||
RuntimeError(RuntimeError),
|
RuntimeError(RuntimeError),
|
||||||
|
SignatureDefMismatch {
|
||||||
|
annotation_pattern: Region,
|
||||||
|
def_pattern: Region,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use roc_collections::all::MutSet;
|
use roc_collections::all::MutSet;
|
||||||
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
||||||
use roc_problem::can::{Problem, RuntimeError};
|
use roc_problem::can::{Problem, RuntimeError};
|
||||||
|
use roc_region::all::Region;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
|
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
|
||||||
|
@ -238,6 +239,14 @@ pub fn can_problem<'b>(
|
||||||
alloc.reflow(" definitions from this tag union type."),
|
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."),
|
||||||
|
]),
|
||||||
Problem::RuntimeError(runtime_error) => pretty_runtime_error(alloc, runtime_error),
|
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]
|
#[test]
|
||||||
fn invalid_num() {
|
fn invalid_num() {
|
||||||
report_problem_as(
|
report_problem_as(
|
||||||
|
|
|
@ -212,7 +212,7 @@ pub fn name_all_type_vars(variable: Variable, subs: &mut Subs) {
|
||||||
|
|
||||||
for root in roots {
|
for root in roots {
|
||||||
// show the type variable number instead of `*`. useful for debugging
|
// show the type variable number instead of `*`. useful for debugging
|
||||||
// set_root_name(root, &(format!("<{:?}>", root).into()), subs);
|
// set_root_name(root, (format!("<{:?}>", root).into()), subs);
|
||||||
if let Some(Appearances::Multiple) = appearances.get(&root) {
|
if let Some(Appearances::Multiple) = appearances.get(&root) {
|
||||||
letters_used = name_root(letters_used, root, subs, &mut taken);
|
letters_used = name_root(letters_used, root, subs, &mut taken);
|
||||||
}
|
}
|
||||||
|
@ -227,21 +227,19 @@ fn name_root(
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let (generated_name, new_letters_used) = name_type_var(letters_used, taken);
|
let (generated_name, new_letters_used) = name_type_var(letters_used, taken);
|
||||||
|
|
||||||
set_root_name(root, &generated_name, subs);
|
set_root_name(root, generated_name, subs);
|
||||||
|
|
||||||
new_letters_used
|
new_letters_used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_root_name(root: Variable, name: &Lowercase, subs: &mut Subs) {
|
fn set_root_name(root: Variable, name: Lowercase, subs: &mut Subs) {
|
||||||
use crate::subs::Content::*;
|
use crate::subs::Content::*;
|
||||||
|
|
||||||
let mut descriptor = subs.get_without_compacting(root);
|
let mut descriptor = subs.get_without_compacting(root);
|
||||||
|
|
||||||
match descriptor.content {
|
match descriptor.content {
|
||||||
FlexVar(None) => {
|
FlexVar(None) => {
|
||||||
descriptor.content = FlexVar(Some(name.clone()));
|
descriptor.content = FlexVar(Some(name));
|
||||||
|
|
||||||
// TODO is this necessary, or was mutating descriptor in place sufficient?
|
|
||||||
subs.set(root, descriptor);
|
subs.set(root, descriptor);
|
||||||
}
|
}
|
||||||
FlexVar(Some(_existing)) => {
|
FlexVar(Some(_existing)) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue