record update value

This commit is contained in:
Folkert 2020-04-04 23:53:25 +02:00
parent f8b3d5dce7
commit 5b0d9e693b
4 changed files with 72 additions and 19 deletions

View file

@ -181,9 +181,10 @@ pub fn constrain_expr(
region, region,
); );
cons.push(con); // ensure constraints are solved in this order, gives better errors
cons.push(fields_con); cons.insert(0, fields_con);
cons.push(record_con); cons.insert(1, con);
cons.insert(2, record_con);
exists(vars, And(cons)) exists(vars, And(cons))
} }

View file

@ -302,11 +302,11 @@ where
Url => { Url => {
self.write_str("<")?; self.write_str("<")?;
} }
GlobalTag | PrivateTag | RecordField | Keyword => { GlobalTag | PrivateTag | Keyword => {
self.write_str("`")?; self.write_str("`")?;
} }
CodeBlock | PlainText | LineNumber | Error | GutterBar | TypeVariable | Alias CodeBlock | PlainText | LineNumber | Error | GutterBar | TypeVariable | Alias
| Module | Structure | Symbol | BinOp => {} | RecordField | Module | Structure | Symbol | BinOp => {}
} }
self.style_stack.push(*annotation); self.style_stack.push(*annotation);
Ok(()) Ok(())
@ -324,11 +324,11 @@ where
Url => { Url => {
self.write_str(">")?; self.write_str(">")?;
} }
GlobalTag | PrivateTag | RecordField | Keyword => { GlobalTag | PrivateTag | Keyword => {
self.write_str("`")?; self.write_str("`")?;
} }
CodeBlock | PlainText | LineNumber | Error | GutterBar | TypeVariable | Alias CodeBlock | PlainText | LineNumber | Error | GutterBar | TypeVariable | Alias
| Module | Structure | Symbol | BinOp => {} | RecordField | Module | Structure | Symbol | BinOp => {}
}, },
} }
Ok(()) Ok(())

View file

@ -121,7 +121,7 @@ fn to_expr_report(
use ReportText::*; use ReportText::*;
match expected { match expected {
Expected::NoExpectation(_expected_type) => todo!(), Expected::NoExpectation(expected_type) => todo!("hit no expectation with type {:?}", expected_type),
Expected::FromAnnotation(_name, _arity, _sub_context, _expected_type) => todo!(), Expected::FromAnnotation(_name, _arity, _sub_context, _expected_type) => todo!(),
Expected::ForReason(reason, expected_type, region) => match reason { Expected::ForReason(reason, expected_type, region) => match reason {
Reason::IfCondition => { Reason::IfCondition => {
@ -141,7 +141,7 @@ fn to_expr_report(
region, region,
Some(expr_region), Some(expr_region),
problem, problem,
plain_text("Right now its "), plain_text("Right now its"),
Concat(vec![ Concat(vec![
plain_text("but I need every "), plain_text("but I need every "),
keyword_text("if"), keyword_text("if"),
@ -177,7 +177,7 @@ fn to_expr_report(
region, region,
Some(expr_region), Some(expr_region),
problem, problem,
plain_text("Right now its "), plain_text("Right now its"),
Concat(vec![ Concat(vec![
plain_text("but I need every "), plain_text("but I need every "),
keyword_text("if"), keyword_text("if"),
@ -214,7 +214,7 @@ fn to_expr_report(
Concat(vec![ Concat(vec![
plain_text("The "), plain_text("The "),
keyword_text("else"), keyword_text("else"),
plain_text(" branch is "), plain_text(" branch is"),
]), ]),
Concat(vec![ Concat(vec![
plain_text("but the "), plain_text("but the "),
@ -268,7 +268,7 @@ fn to_expr_report(
keyword_text("when"), keyword_text("when"),
plain_text(" does not match all the previous branches"), plain_text(" does not match all the previous branches"),
]), ]),
plain_text(&format!("The {} branch is ", ith)), plain_text(&format!("The {} branch is", ith)),
plain_text("but all the previous branches have type"), plain_text("but all the previous branches have type"),
Concat(vec![ Concat(vec![
plain_text("instead. I need all branches of a "), plain_text("instead. I need all branches of a "),
@ -293,11 +293,31 @@ fn to_expr_report(
"The {} element of this list does not match all the previous elements", "The {} element of this list does not match all the previous elements",
ith ith
)), )),
plain_text(&format!("The {} element is ", ith)), plain_text(&format!("The {} element is", ith)),
plain_text("but all the previous elements in the list have type"), 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!"), plain_text("instead. I need all elements of a list to have the same type!"),
) )
} }
Reason::RecordUpdateValue(field) => report_mismatch(
filename,
&category,
found,
expected_type,
region,
Some(expr_region),
Concat(vec![
plain_text("I cannot update the "),
record_field_text(field.as_str()),
plain_text(" field like this"),
]),
Concat(vec![
plain_text("You are trying to update "),
record_field_text(field.as_str()),
plain_text(" to be"),
]),
plain_text("But it should be"),
plain_text("instead. Record update syntax does not allow you to change the type of fields. You can achieve that with record literal syntax."),
),
other => { other => {
// AnonymousFnArg { arg_index: u8 }, // AnonymousFnArg { arg_index: u8 },
// NamedFnArg(String /* function name */, u8 /* arg index */), // NamedFnArg(String /* function name */, u8 /* arg index */),
@ -397,11 +417,11 @@ fn add_category(this_is: ReportText, category: &Category) -> ReportText {
plain_text("expression produces"), plain_text("expression produces"),
]), ]),
List => Concat(vec![this_is, plain_text("a list of type")]), List => Concat(vec![this_is, plain_text(" a list of type")]),
Num => Concat(vec![this_is, plain_text("a number of type")]), Num => Concat(vec![this_is, plain_text(" a number of type")]),
Int => Concat(vec![this_is, plain_text("an integer of type")]), Int => Concat(vec![this_is, plain_text(" an integer of type")]),
Float => Concat(vec![this_is, plain_text("a float of type")]), Float => Concat(vec![this_is, plain_text(" a float of type")]),
Str => Concat(vec![this_is, plain_text("a string of type")]), Str => Concat(vec![this_is, plain_text(" a string of type")]),
Lambda => Concat(vec![this_is, plain_text("an anonymous function of type")]), Lambda => Concat(vec![this_is, plain_text("an anonymous function of type")]),
@ -416,7 +436,7 @@ fn add_category(this_is: ReportText, category: &Category) -> ReportText {
plain_text(" private tag application produces"), plain_text(" private tag application produces"),
]), ]),
Record => Concat(vec![this_is, plain_text("a record of type")]), Record => Concat(vec![this_is, plain_text(" a record of type")]),
Accessor(field) => Concat(vec![ Accessor(field) => Concat(vec![
plain_text("This "), plain_text("This "),

View file

@ -928,6 +928,38 @@ mod test_reporting {
) )
} }
#[test]
fn record_update_value() {
report_problem_as(
indoc!(
r#"
x : { foo : {} }
x = { foo: {} }
{ x & foo: "bar" }
"#
),
indoc!(
r#"
I cannot update the .foo field like this
4 { x & foo: "bar" }
^^^^^^^^^^^^^^^^^^
You are trying to update .foo to be a string of type
Str
But it should be
{}
instead. Record update syntax does not allow you to change the type of fields. You can achieve that with record literal syntax.
"#
),
)
}
#[test] #[test]
fn circular_type() { fn circular_type() {
report_problem_as( report_problem_as(