Fix error reporting on cyclic definitions.

Fixes #292
This commit is contained in:
KtorZ 2023-01-20 20:07:37 +01:00
parent ce65236514
commit 4459fdb360
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
1 changed files with 31 additions and 16 deletions

View File

@ -18,7 +18,7 @@ use crate::{
}; };
use super::{ use super::{
error::{Error, Warning}, error::{Error, Snippet, Warning},
hydrator::Hydrator, hydrator::Hydrator,
AccessorsMap, PatternConstructor, RecordAccessor, Type, TypeConstructor, TypeInfo, TypeVar, AccessorsMap, PatternConstructor, RecordAccessor, Type, TypeConstructor, TypeInfo, TypeVar,
ValueConstructor, ValueConstructorVariant, ValueConstructor, ValueConstructorVariant,
@ -867,26 +867,41 @@ impl<'a> Environment<'a> {
Some(e) => { Some(e) => {
let known_types_after = names.keys().copied().collect::<Vec<_>>(); let known_types_after = names.keys().copied().collect::<Vec<_>>();
if known_types_before == known_types_after { if known_types_before == known_types_after {
let cycle = remaining_definitions let unknown_name = match e {
Error::UnknownType { ref name, .. } => name,
_ => "",
};
let mut is_cyclic = false;
let unknown_types = remaining_definitions
.into_iter() .into_iter()
.filter_map(|def| match def { .filter_map(|def| match def {
Definition::TypeAlias(TypeAlias { Definition::TypeAlias(TypeAlias {
alias, location, .. alias, location, ..
}) => Some((alias.to_owned(), location.to_owned())), }) => {
_ => None, is_cyclic = is_cyclic || alias == unknown_name;
}) Some(Snippet {
.collect::<Vec<(String, Span)>>(); location: location.to_owned(),
match cycle.first() {
None => Err(e),
Some((alias, location)) => {
let mut types =
cycle.iter().map(|def| def.0.clone()).collect::<Vec<_>>();
types.push(alias.clone());
Err(Error::CyclicTypeDefinitions {
location: *location,
types,
}) })
} }
Definition::DataType(DataType { name, location, .. }) => {
is_cyclic = is_cyclic || name == unknown_name;
Some(Snippet {
location: location.to_owned(),
})
}
Definition::Fn { .. }
| Definition::Use { .. }
| Definition::ModuleConstant { .. }
| Definition::Test { .. } => None,
})
.collect::<Vec<Snippet>>();
if is_cyclic {
Err(Error::CyclicTypeDefinitions {
errors: unknown_types,
})
} else {
Err(e)
} }
} else { } else {
self.register_types(remaining_definitions, module, hydrators, names) self.register_types(remaining_definitions, module, hydrators, names)