mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
elem_in_list
This commit is contained in:
parent
200adae507
commit
f8b3d5dce7
5 changed files with 63 additions and 8 deletions
|
@ -202,9 +202,12 @@ pub fn constrain_expr(
|
||||||
let list_elem_type = Type::Variable(*elem_var);
|
let list_elem_type = Type::Variable(*elem_var);
|
||||||
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
|
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
|
||||||
|
|
||||||
for loc_elem in loc_elems {
|
for (index, loc_elem) in loc_elems.iter().enumerate() {
|
||||||
let elem_expected =
|
let elem_expected = ForReason(
|
||||||
ForReason(Reason::ElemInList, list_elem_type.clone(), region);
|
Reason::ElemInList { index },
|
||||||
|
list_elem_type.clone(),
|
||||||
|
loc_elem.region,
|
||||||
|
);
|
||||||
let constraint =
|
let constraint =
|
||||||
constrain_expr(env, loc_elem.region, &loc_elem.value, elem_expected);
|
constrain_expr(env, loc_elem.region, &loc_elem.value, elem_expected);
|
||||||
|
|
||||||
|
|
|
@ -596,9 +596,12 @@ pub fn constrain_expr(
|
||||||
let entry_type = Type::Variable(*elem_var);
|
let entry_type = Type::Variable(*elem_var);
|
||||||
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
|
let mut constraints = Vec::with_capacity(1 + loc_elems.len());
|
||||||
|
|
||||||
for loc_elem in loc_elems.iter() {
|
for (index, loc_elem) in loc_elems.iter().enumerate() {
|
||||||
let elem_expected =
|
let elem_expected = Expected::ForReason(
|
||||||
Expected::ForReason(Reason::ElemInList, entry_type.clone(), region);
|
Reason::ElemInList { index },
|
||||||
|
entry_type.clone(),
|
||||||
|
region,
|
||||||
|
);
|
||||||
let constraint = constrain_expr(
|
let constraint = constrain_expr(
|
||||||
env,
|
env,
|
||||||
var_store,
|
var_store,
|
||||||
|
|
|
@ -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 => {
|
other => {
|
||||||
// AnonymousFnArg { arg_index: u8 },
|
// AnonymousFnArg { arg_index: u8 },
|
||||||
// NamedFnArg(String /* function name */, u8 /* arg index */),
|
// NamedFnArg(String /* function name */, u8 /* arg index */),
|
||||||
|
@ -288,7 +309,6 @@ fn to_expr_report(
|
||||||
// IntLiteral,
|
// IntLiteral,
|
||||||
// NumLiteral,
|
// NumLiteral,
|
||||||
// InterpolatedStringVar,
|
// InterpolatedStringVar,
|
||||||
// ElemInList,
|
|
||||||
// RecordUpdateValue(Lowercase),
|
// RecordUpdateValue(Lowercase),
|
||||||
// RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
|
// RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
|
||||||
todo!("I don't have a message yet for reason {:?}", other)
|
todo!("I don't have a message yet for reason {:?}", other)
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
fn circular_type() {
|
fn circular_type() {
|
||||||
report_problem_as(
|
report_problem_as(
|
||||||
|
|
|
@ -628,7 +628,7 @@ pub enum Reason {
|
||||||
WhenGuard,
|
WhenGuard,
|
||||||
IfCondition,
|
IfCondition,
|
||||||
IfBranch { index: usize, total_branches: usize },
|
IfBranch { index: usize, total_branches: usize },
|
||||||
ElemInList,
|
ElemInList { index: usize },
|
||||||
RecordUpdateValue(Lowercase),
|
RecordUpdateValue(Lowercase),
|
||||||
RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
|
RecordUpdateKeys(Symbol, SendMap<Lowercase, Type>),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue