elem_in_list

This commit is contained in:
Folkert 2020-04-04 16:38:41 +02:00
parent 200adae507
commit f8b3d5dce7
5 changed files with 63 additions and 8 deletions

View file

@ -202,9 +202,12 @@ pub fn constrain_expr(
let list_elem_type = Type::Variable(*elem_var);
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
for loc_elem in loc_elems {
let elem_expected =
ForReason(Reason::ElemInList, list_elem_type.clone(), region);
for (index, loc_elem) in loc_elems.iter().enumerate() {
let elem_expected = ForReason(
Reason::ElemInList { index },
list_elem_type.clone(),
loc_elem.region,
);
let constraint =
constrain_expr(env, loc_elem.region, &loc_elem.value, elem_expected);

View file

@ -596,9 +596,12 @@ pub fn constrain_expr(
let entry_type = Type::Variable(*elem_var);
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
for loc_elem in loc_elems.iter() {
let elem_expected =
Expected::ForReason(Reason::ElemInList, entry_type.clone(), region);
for (index, loc_elem) in loc_elems.iter().enumerate() {
let elem_expected = Expected::ForReason(
Reason::ElemInList { index },
entry_type.clone(),
region,
);
let constraint = constrain_expr(
env,
var_store,

View file

@ -277,6 +277,27 @@ fn to_expr_report(
]),
)
}
Reason::ElemInList { index } => {
// NOTE: is 0-based
let ith = int_to_ordinal(index + 1);
report_mismatch(
filename,
&category,
found,
expected_type,
region,
Some(expr_region),
plain_text(&format!(
"The {} element of this list does not match all the previous elements",
ith
)),
plain_text(&format!("The {} element is ", ith)),
plain_text("but all the previous elements in the list have type"),
plain_text("instead. I need all elements of a list to have the same type!"),
)
}
other => {
// AnonymousFnArg { arg_index: u8 },
// NamedFnArg(String /* function name */, u8 /* arg index */),
@ -288,7 +309,6 @@ fn to_expr_report(
// IntLiteral,
// NumLiteral,
// InterpolatedStringVar,
// ElemInList,
// RecordUpdateValue(Lowercase),
// RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
todo!("I don't have a message yet for reason {:?}", other)

View file

@ -899,6 +899,35 @@ mod test_reporting {
)
}
#[test]
fn elem_in_list() {
report_problem_as(
indoc!(
r#"
[ 1, 3, "foo" ]
"#
),
indoc!(
r#"
The 3rd element of this list does not match all the previous elements
1 [ 1, 3, "foo" ]
^^^^^
The 3rd element is a string of type
Str
but all the previous elements in the list have type
Num a
instead. I need all elements of a list to have the same type!
"#
),
)
}
#[test]
fn circular_type() {
report_problem_as(

View file

@ -628,7 +628,7 @@ pub enum Reason {
WhenGuard,
IfCondition,
IfBranch { index: usize, total_branches: usize },
ElemInList,
ElemInList { index: usize },
RecordUpdateValue(Lowercase),
RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
}