report error for invalid alias argument patterns

This commit is contained in:
Folkert 2020-07-03 16:54:28 +02:00
parent 474d164a8c
commit 667233a00d
4 changed files with 68 additions and 6 deletions

View File

@ -79,7 +79,10 @@ enum PendingDef<'a> {
ann: &'a Located<ast::TypeAnnotation<'a>>,
},
ShadowedAlias,
/// An invalid alias, that is ignored in the rest of the pipeline
/// e.g. a shadowed alias, or a definition like `MyAlias 1 : Int`
/// with an incorrect pattern
InvalidAlias,
}
#[derive(Clone, Debug, PartialEq)]
@ -899,9 +902,8 @@ fn canonicalize_pending_def<'a>(
.union(&can_ann.introduced_variables);
}
ShadowedAlias => {
// Since this alias was shadowed, it gets ignored and has no
// effect on the output.
InvalidAlias => {
// invalid aliases (shadowed, incorrect patterns) get ignored
}
TypedBody(loc_pattern, loc_can_pattern, loc_ann, loc_expr) => {
let ann =
@ -1365,7 +1367,13 @@ fn to_pending_def<'a>(
});
}
_ => {
panic!("TODO gracefully handle an invalid pattern appearing where a type alias rigid var should be.");
// any other pattern in this position is a syntax error.
env.problems.push(Problem::InvalidAliasRigid {
alias_name: symbol,
region: loc_var.region,
});
return PendingDef::InvalidAlias;
}
}
}
@ -1386,7 +1394,7 @@ fn to_pending_def<'a>(
shadow: loc_shadowed_symbol,
});
PendingDef::ShadowedAlias
PendingDef::InvalidAlias
}
}
}

View File

@ -50,6 +50,10 @@ pub enum Problem {
annotation_pattern: Region,
def_pattern: Region,
},
InvalidAliasRigid {
alias_name: Symbol,
region: Region,
},
}
#[derive(Clone, Debug, PartialEq)]

View File

@ -247,6 +247,21 @@ pub fn can_problem<'b>(
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::InvalidAliasRigid { alias_name, region } => alloc.stack(vec![
alloc.concat(vec![
alloc.reflow("This pattern in the definition of "),
alloc.symbol_unqualified(alias_name),
alloc.reflow(" is not what I expect:"),
]),
alloc.region(region),
alloc.concat(vec![
alloc.reflow("Only type variables like "),
alloc.type_variable("a".into()),
alloc.reflow(" or "),
alloc.type_variable("value".into()),
alloc.reflow(" can occur in this position."),
]),
]),
Problem::RuntimeError(runtime_error) => pretty_runtime_error(alloc, runtime_error),
};

View File

@ -2714,6 +2714,41 @@ mod test_reporting {
)
}
#[test]
fn invalid_alias_rigid_var_pattern() {
report_problem_as(
indoc!(
r#"
MyAlias 1 : Int
4
"#
),
indoc!(
r#"
-- SYNTAX PROBLEM --------------------------------------------------------------
This pattern in the definition of `MyAlias` is not what I expect:
1 MyAlias 1 : Int
^
Only type variables like `a` or `value` can occur in this position.
-- SYNTAX PROBLEM --------------------------------------------------------------
`MyAlias` is not used anywhere in your code.
1 MyAlias 1 : Int
^^^^^^^^^^^^^^^
If you didn't intend on using `MyAlias` then remove it so future readers
of your code don't wonder why it is there.
"#
),
)
}
#[test]
fn invalid_num() {
report_problem_as(