Handle errors in generated type annotations

This commit is contained in:
snobee 2025-01-27 13:50:13 -08:00
parent 0ddf12e323
commit 46736ccaea
No known key found for this signature in database
GPG key ID: ABF756C92D69FDF1
5 changed files with 182 additions and 57 deletions

View file

@ -2184,6 +2184,98 @@ impl Subs {
_ => false,
}
}
pub fn var_contains_error(&self, var: Variable) -> bool {
match &self.get_content_without_compacting(var).clone() {
Content::Error => true,
Content::FlexVar(Some(index)) => {
// Generated names for errors start with `#`
self[*index].as_str().starts_with('#')
}
Content::FlexVar(..)
| Content::RigidVar(..)
| Content::FlexAbleVar(..)
| Content::RigidAbleVar(..)
| Content::ErasedLambda
| Content::RangedNumber(..)
| Content::Pure
| Content::Effectful
| Content::Structure(FlatType::EmptyRecord)
| Content::Structure(FlatType::EmptyTagUnion)
| Content::Structure(FlatType::EffectfulFunc) => false,
Content::RecursionVar { structure, .. } => self.var_contains_error(*structure),
Content::LambdaSet(LambdaSet {
solved,
recursion_var,
unspecialized,
..
}) => {
if let Some(rec_var) = recursion_var.into_variable() {
if self.var_contains_error(rec_var) {
return true;
}
}
unspecialized
.into_iter()
.any(|uls_index| self.var_contains_error(self[uls_index].0))
|| solved.variables().into_iter().any(|slice_index| {
self[slice_index]
.into_iter()
.any(|var_index| self.var_contains_error(self[var_index]))
})
}
Content::Alias(_symbol, args, actual, _kind) => {
self.var_contains_error(*actual)
|| args
.into_iter()
.take(args.len())
.any(|index| self.var_contains_error(self[index]))
}
Content::Structure(FlatType::Apply(_, args)) => args
.into_iter()
.any(|index| self.var_contains_error(self[index])),
Content::Structure(FlatType::Func(arg_vars, closure_var, ret_var, fx_var)) => {
self.var_contains_error(*closure_var)
|| self.var_contains_error(*ret_var)
|| self.var_contains_error(*fx_var)
|| arg_vars
.into_iter()
.any(|index| self.var_contains_error(self[index]))
}
Content::Structure(FlatType::Record(sorted_fields, ext_var)) => {
self.var_contains_error(*ext_var)
|| sorted_fields
.iter_variables()
.any(|index| self.var_contains_error(self[index]))
}
Content::Structure(FlatType::Tuple(elems, ext_var)) => {
self.var_contains_error(*ext_var)
|| elems
.iter_variables()
.any(|index| self.var_contains_error(self[index]))
}
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
self.var_contains_error(ext_var.var())
|| tags.variables().into_iter().any(|slice_index| {
self[slice_index]
.into_iter()
.any(|var_index| self.var_contains_error(self[var_index]))
})
}
Content::Structure(FlatType::FunctionOrTagUnion(_, _, ext_var)) => {
self.var_contains_error(ext_var.var())
}
Content::Structure(FlatType::RecursiveTagUnion(rec_var, tags, ext_var)) => {
self.var_contains_error(ext_var.var())
|| self.var_contains_error(*rec_var)
|| tags.variables().into_iter().any(|slice_index| {
self[slice_index]
.into_iter()
.any(|var_index| self.var_contains_error(self[var_index]))
})
}
}
}
}
#[inline(always)]