Improve cycle error message

Closes #2513
This commit is contained in:
Ayaz Hafiz 2022-05-10 12:11:17 -04:00
parent 1fb6718c00
commit 4339d50480
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
2 changed files with 21 additions and 9 deletions

View File

@ -62,6 +62,7 @@ struct ErrorTypeState {
letters_used: u32, letters_used: u32,
problems: Vec<crate::types::Problem>, problems: Vec<crate::types::Problem>,
context: ErrorTypeContext, context: ErrorTypeContext,
recursive_tag_unions_seen: Vec<Variable>,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@ -1869,6 +1870,7 @@ impl Subs {
letters_used: 0, letters_used: 0,
problems: Vec::new(), problems: Vec::new(),
context, context,
recursive_tag_unions_seen: Vec::new(),
}; };
(var_to_err_type(self, &mut state, var), state.problems) (var_to_err_type(self, &mut state, var), state.problems)
@ -3337,7 +3339,10 @@ fn content_to_err_type(
ErrorType::RigidAbleVar(name, ability) ErrorType::RigidAbleVar(name, ability)
} }
RecursionVar { opt_name, .. } => { RecursionVar {
opt_name,
structure,
} => {
let name = match opt_name { let name = match opt_name {
Some(name_index) => subs.field_names[name_index.index as usize].clone(), Some(name_index) => subs.field_names[name_index.index as usize].clone(),
None => { None => {
@ -3350,7 +3355,11 @@ fn content_to_err_type(
} }
}; };
ErrorType::FlexVar(name) if state.recursive_tag_unions_seen.contains(&var) {
ErrorType::FlexVar(name)
} else {
var_to_err_type(subs, state, structure)
}
} }
Alias(symbol, args, aliased_to, kind) => { Alias(symbol, args, aliased_to, kind) => {
@ -3531,6 +3540,8 @@ fn flat_type_to_err_type(
} }
RecursiveTagUnion(rec_var, tags, ext_var) => { RecursiveTagUnion(rec_var, tags, ext_var) => {
state.recursive_tag_unions_seen.push(rec_var);
let mut err_tags = SendMap::default(); let mut err_tags = SendMap::default();
for (name_index, slice_index) in tags.iter_all() { for (name_index, slice_index) in tags.iter_all() {

View File

@ -3509,8 +3509,9 @@ mod test_reporting {
This `ACons` tag application has the type: This `ACons` tag application has the type:
[ ACons (Num (Integer Signed64)) [ [ ACons (Num (Integer Signed64)) [
BCons (Num (Integer Signed64)) [ ACons Str [ BCons I64 a, BNil ], BCons (Num (Integer Signed64)) [ ACons Str [ BCons I64 [
ANil ], BNil ], ANil ] ACons I64 (BList I64 I64), ANil ] as , BNil ], ANil ], BNil ],
ANil ]
But the type annotation on `x` says it should be: But the type annotation on `x` says it should be:
@ -9792,12 +9793,12 @@ I need all branches in an `if` to have the same type!
"recursion_var_specialization_error", "recursion_var_specialization_error",
indoc!( indoc!(
r#" r#"
Job a : [ Job (List (Job a)) a ] Job a : [ Job (List (Job a)) ]
job : Job Str job : Job Str
when job is when job is
Job lst _ -> lst == "" Job lst -> lst == ""
"# "#
), ),
indoc!( indoc!(
@ -9806,8 +9807,8 @@ I need all branches in an `if` to have the same type!
The 2nd argument to `isEq` is not what I expect: The 2nd argument to `isEq` is not what I expect:
9 Job lst _ -> lst == "" 9 Job lst -> lst == ""
^^ ^^
This argument is a string of type: This argument is a string of type:
@ -9815,7 +9816,7 @@ I need all branches in an `if` to have the same type!
But `isEq` needs the 2nd argument to be: But `isEq` needs the 2nd argument to be:
List a List [ Job ] as
"# "#
), ),
) )