test for record diff

This commit is contained in:
Folkert 2020-04-06 17:47:40 +02:00
parent fc8d9c2fd9
commit 2d6e47b8a6
5 changed files with 72 additions and 17 deletions

View file

@ -238,8 +238,9 @@ pub fn constrain_expr(
let fn_type = Variable(*fn_var);
let fn_region = loc_fn.region;
let fn_expected = NoExpectation(fn_type.clone());
// TODO look up the name and use NamedFnArg if possible.
let fn_reason = Reason::AnonymousFnCall {
let fn_reason = Reason::FnCall {
name: opt_symbol,
arity: loc_args.len() as u8,
};
@ -260,8 +261,9 @@ pub fn constrain_expr(
for (index, (arg_var, loc_arg)) in loc_args.iter().enumerate() {
let region = loc_arg.region;
let arg_type = Variable(*arg_var);
// TODO look up the name and use NamedFnArg if possible.
let reason = Reason::AnonymousFnArg {
let reason = Reason::FnArg {
name: opt_symbol,
arg_index: index as u8,
};
let expected_arg = ForReason(reason, arg_type.clone(), region);

View file

@ -741,8 +741,8 @@ pub fn constrain_expr(
fn_expected,
);
// TODO look up the name and use NamedFnArg if possible.
let fn_reason = Reason::AnonymousFnCall {
let fn_reason = Reason::FnCall {
name: opt_symbol,
arity: loc_args.len() as u8,
};
@ -753,7 +753,8 @@ pub fn constrain_expr(
let region = loc_arg.region;
let arg_type = Variable(*arg_var);
let reason = Reason::AnonymousFnArg {
let reason = Reason::FnArg {
name: opt_symbol,
arg_index: index as u8,
};

View file

@ -252,7 +252,6 @@ fn to_expr_report(
},
Reason::WhenBranch { index } => {
// NOTE: is 0-based
let ith = int_to_ordinal(index + 1);
report_mismatch(
@ -297,7 +296,7 @@ fn to_expr_report(
plain_text("I need all elements of a list to have the same type!"),
)
}
Reason::RecordUpdateValue(field) => report_mismatch(
Reason::RecordUpdateValue(field) => { report_mismatch(
filename,
&category,
found,
@ -316,9 +315,31 @@ fn to_expr_report(
]),
plain_text("But it should be:"),
plain_text("Record update syntax does not allow you to change the type of fields. You can achieve that with record literal syntax."),
),
)}
Reason::FnArg { name , arg_index } => {
let ith = int_to_ordinal(arg_index as usize + 1);
let this_function = match name {
None => plain_text("this function"),
Some(symbol) => ReportText::Value(symbol),
};
report_mismatch(
filename,
&category,
found,
expected_type,
region,
Some(expr_region),
Concat(vec![ plain_text(&format!("The {} argument to ", ith))
, this_function.clone(), plain_text(" is not what I expect:" )]),
plain_text("This argument is"),
Concat(vec![ plain_text("But "), this_function, plain_text(&format!(" needs the {} argument to be:", ith))]),
plain_text(""),
)
}
other => {
// AnonymousFnArg { arg_index: u8 },
// NamedFnArg(String /* function name */, u8 /* arg index */),
// AnonymousFnCall { arity: u8 },
// NamedFnCall(String /* function name */, u8 /* arity */),

View file

@ -1161,4 +1161,37 @@ mod test_reporting {
),
)
}
#[test]
fn record_field_mismatch() {
report_problem_as(
indoc!(
r#"
bar = { bar : 0x3 }
f : { foo : Int } -> Bool
f = \_ -> True
f bar
"#
),
indoc!(
r#"
The 1st argument to `f` is not what I expect:
6 f bar
^^^
This `bar` value is a:
{ bar : Int }
But `f` needs the 1st argument to be:
{ foo : Int }
"#
),
)
}
}

View file

@ -614,10 +614,8 @@ pub enum AnnotationSource {
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Reason {
AnonymousFnArg { arg_index: u8 },
NamedFnArg(String /* function name */, u8 /* arg index */),
AnonymousFnCall { arity: u8 },
NamedFnCall(String /* function name */, u8 /* arity */),
FnArg { name: Option<Symbol>, arg_index: u8 },
FnCall { name: Option<Symbol>, arity: u8 },
BinOpArg(BinOp, ArgSide),
BinOpRet(BinOp),
FloatLiteral,