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 exhaustiveness_nested_list_and_tuples() {
fn assert_step(step: &str, expected: &str) { fn assert_step(step: &str, expected: &str) {
let result = check(parse(step)); let result = check(parse(step));
println!("{result:#?}");
assert!(matches!( assert!(matches!(
result, result,
Err(( Err((

View File

@ -1488,36 +1488,52 @@ impl<'a> Environment<'a> {
/// ///
pub fn get_constructors_for_type( pub fn get_constructors_for_type(
&mut self, &mut self,
full_module_name: &Option<String>, full_module_name: &String,
name: &str, name: &str,
location: Span, location: Span,
) -> Result<&Vec<String>, Error> { ) -> Result<Vec<ValueConstructor>, Error> {
match full_module_name { if full_module_name.is_empty() || full_module_name == self.current_module {
None => self self.module_types_constructors
.module_types_constructors
.get(name) .get(name)
.ok_or_else(|| Error::UnknownType { .ok_or_else(|| Error::UnknownType {
name: name.to_string(), name: name.to_string(),
types: self.module_types.keys().map(|t| t.to_string()).collect(), types: self.module_types.keys().map(|t| t.to_string()).collect(),
location, location,
}), })?
.iter()
Some(m) => { .map(|constructor| {
let module = self.scope
self.importable_modules .get(constructor)
.get(m) .cloned()
.ok_or_else(|| Error::UnknownModule { .ok_or_else(|| Error::UnknownModuleValue {
location,
name: name.to_string(), name: name.to_string(),
imported_modules: self module_name: self.current_module.clone(),
.importable_modules value_constructors: self
.module_values
.keys() .keys()
.map(|t| t.to_string()) .map(|t| t.to_string())
.collect(), .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 module
.types_constructors .types_constructors
.get(name) .get(name)
@ -1526,8 +1542,25 @@ impl<'a> Environment<'a> {
name: name.to_string(), name: name.to_string(),
module_name: module.name.clone(), module_name: module.name.clone(),
type_constructors: module.types.keys().map(|t| t.to_string()).collect(), 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, location,
tipo, tipo,
with_spread, with_spread,
module,
.. ..
} => { } => {
let (type_module, type_name, arity) = match tipo.deref() { let (module, type_name, arity) = match tipo.deref() {
tipo::Type::App { tipo::Type::App {
name: type_name, name: type_name,
module, module,
@ -583,25 +582,7 @@ pub(super) fn simplify(
_ => unreachable!("tipo should be a Type::App"), _ => unreachable!("tipo should be a Type::App"),
}; };
let module_opt = if type_module.is_empty() || environment.current_module == type_module let alts = environment.get_constructors_for_type(module, type_name, *location)?;
{
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 mut args = Vec::new(); let mut args = Vec::new();