fix(exhaustiveness): adjust helper method to get contructors properly

This commit is contained in:
rvcas 2023-08-03 16:14:42 -04:00
parent 675b737898
commit 60ac8ab591
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
3 changed files with 53 additions and 40 deletions

View File

@ -523,7 +523,6 @@ fn exhaustiveness_tuple() {
fn exhaustiveness_nested_list_and_tuples() {
fn assert_step(step: &str, expected: &str) {
let result = check(parse(step));
println!("{result:#?}");
assert!(matches!(
result,
Err((

View File

@ -1488,36 +1488,52 @@ impl<'a> Environment<'a> {
///
pub fn get_constructors_for_type(
&mut self,
full_module_name: &Option<String>,
full_module_name: &String,
name: &str,
location: Span,
) -> Result<&Vec<String>, Error> {
match full_module_name {
None => self
.module_types_constructors
) -> Result<Vec<ValueConstructor>, Error> {
if full_module_name.is_empty() || full_module_name == self.current_module {
self.module_types_constructors
.get(name)
.ok_or_else(|| Error::UnknownType {
name: name.to_string(),
types: self.module_types.keys().map(|t| t.to_string()).collect(),
location,
}),
Some(m) => {
let module =
self.importable_modules
.get(m)
.ok_or_else(|| Error::UnknownModule {
location,
})?
.iter()
.map(|constructor| {
self.scope
.get(constructor)
.cloned()
.ok_or_else(|| Error::UnknownModuleValue {
name: name.to_string(),
imported_modules: self
.importable_modules
module_name: self.current_module.clone(),
value_constructors: self
.module_values
.keys()
.map(|t| t.to_string())
.collect(),
})?;
location,
})
})
.collect()
} else {
let module = self
.importable_modules
.get(full_module_name)
.ok_or_else(|| Error::UnknownModule {
location,
name: name.to_string(),
imported_modules: self
.importable_modules
.keys()
.map(|t| t.to_string())
.collect(),
})?;
self.unused_modules.remove(m);
self.unused_modules.remove(full_module_name);
let constructors =
module
.types_constructors
.get(name)
@ -1526,8 +1542,25 @@ impl<'a> Environment<'a> {
name: name.to_string(),
module_name: module.name.clone(),
type_constructors: module.types.keys().map(|t| t.to_string()).collect(),
})?;
constructors
.iter()
.map(|constructor| {
module.values.get(constructor).cloned().ok_or_else(|| {
Error::UnknownModuleValue {
name: name.to_string(),
module_name: module.name.clone(),
value_constructors: module
.values
.keys()
.map(|t| t.to_string())
.collect(),
location,
}
})
}
})
.collect()
}
}
}

View File

@ -561,10 +561,9 @@ pub(super) fn simplify(
location,
tipo,
with_spread,
module,
..
} => {
let (type_module, type_name, arity) = match tipo.deref() {
let (module, type_name, arity) = match tipo.deref() {
tipo::Type::App {
name: type_name,
module,
@ -583,25 +582,7 @@ pub(super) fn simplify(
_ => unreachable!("tipo should be a Type::App"),
};
let module_opt = if type_module.is_empty() || environment.current_module == type_module
{
None
} else {
Some(type_module.clone())
};
let constructors = environment
.get_constructors_for_type(&module_opt, type_name, *location)?
.clone();
let mut alts = Vec::new();
for constructor in constructors {
let value_constructor =
environment.get_value_constructor(module.as_ref(), &constructor, *location)?;
alts.push(value_constructor.clone());
}
let alts = environment.get_constructors_for_type(module, type_name, *location)?;
let mut args = Vec::new();