diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index d2d41a08..4c309c94 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -186,7 +186,7 @@ fn exhaustiveness_simple() { fn exhaustiveness_missing_empty_list() { let source_code = r#" fn foo() { - let thing = [1, 2] + let thing = [1, 2] when thing is { [a, ..] -> True } @@ -209,7 +209,7 @@ fn exhaustiveness_missing_empty_list() { fn exhaustiveness_missing_list_wildcards() { let source_code = r#" fn foo() { - let thing = [1, 2] + let thing = [1, 2] when thing is { [] -> True } @@ -232,7 +232,7 @@ fn exhaustiveness_missing_list_wildcards() { fn exhaustiveness_missing_list_wildcards_2() { let source_code = r#" fn foo() { - let thing = [1, 2] + let thing = [1, 2] when thing is { [] -> True [a] -> True @@ -256,7 +256,7 @@ fn exhaustiveness_missing_list_wildcards_2() { fn exhaustiveness_int() { let source_code = r#" fn foo() { - let thing = 1 + let thing = 1 when thing is { 1 -> True } @@ -279,7 +279,7 @@ fn exhaustiveness_int() { fn exhaustiveness_int_redundant() { let source_code = r#" fn foo() { - let thing = 1 + let thing = 1 when thing is { 1 -> True 1 -> True @@ -304,7 +304,7 @@ fn exhaustiveness_int_redundant() { fn exhaustiveness_let_binding() { let source_code = r#" fn foo() { - let Some(x) = None + let Some(x) = None True } "#; @@ -326,7 +326,7 @@ fn exhaustiveness_let_binding() { fn exhaustiveness_expect() { let source_code = r#" fn foo() { - expect Some(x) = None + expect Some(x) = None True } "#; @@ -476,7 +476,7 @@ fn exhaustiveness_complex() { } fn foo() { - let thing = ((Yes, 1), (Yes, [1, 2])) + let thing = ((Yes, 1), (Yes, [1, 2])) when thing is { ((Yes, _), (Yes, [])) -> True ((Yes, _), (No { .. }, _)) -> True diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index f15b9ecb..520901a2 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ ast::{ - Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, Pattern, + Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedPattern, UnqualifiedImport, UntypedArg, UntypedDefinition, Use, Validator, PIPE_VARIABLE, }, @@ -19,8 +19,8 @@ use super::{ error::{Error, Snippet, Warning}, exhaustive::{simplify, Matrix, PatternStack}, hydrator::Hydrator, - AccessorsMap, PatternConstructor, RecordAccessor, Type, TypeConstructor, TypeInfo, TypeVar, - ValueConstructor, ValueConstructorVariant, + AccessorsMap, RecordAccessor, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor, + ValueConstructorVariant, }; #[derive(Debug)] @@ -1484,75 +1484,6 @@ impl<'a> Environment<'a> { Ok(()) } - pub fn check_list_pattern_exhaustiveness( - &mut self, - patterns: Vec>>, - ) -> Result<(), Vec> { - let mut cover_empty = false; - let mut cover_tail = false; - - let patterns = patterns.iter().map(|p| match p { - Pattern::Assign { pattern, .. } => pattern, - _ => p, - }); - - // TODO: We could also warn on redundant patterns. As soon as we've matched the entire - // list, any new pattern is redundant. For example: - // - // when xs is { - // [] => ... - // [x, ..] => ... - // [y] => ... - // } - // - // That last pattern is actually redundant / unreachable. - for p in patterns { - match p { - Pattern::Var { .. } => { - cover_empty = true; - cover_tail = true; - } - Pattern::Discard { .. } => { - cover_empty = true; - cover_tail = true; - } - Pattern::List { elements, tail, .. } => { - if elements.is_empty() { - cover_empty = true; - } - match tail { - None => {} - Some(p) => match **p { - Pattern::Discard { .. } => { - cover_tail = true; - } - Pattern::Var { .. } => { - cover_tail = true; - } - _ => { - unreachable!() - } - }, - } - } - _ => {} - } - } - - if cover_empty && cover_tail { - Ok(()) - } else { - let mut missing = vec![]; - if !cover_empty { - missing.push("[]".to_owned()); - } - if !cover_tail { - missing.push("[_, ..]".to_owned()); - } - Err(missing) - } - } - /// Lookup constructors for type in the current scope. /// pub fn get_constructors_for_type( diff --git a/crates/aiken-lang/src/tipo/exhaustive.rs b/crates/aiken-lang/src/tipo/exhaustive.rs index c149c0fc..17101096 100644 --- a/crates/aiken-lang/src/tipo/exhaustive.rs +++ b/crates/aiken-lang/src/tipo/exhaustive.rs @@ -342,22 +342,9 @@ impl Matrix { } } - // (:) - // <$> Maybe.mapMaybe (isMissing alts ctors) altList - // <*> isExhaustive (Maybe.mapMaybe specializeRowByAnything matrix) (n - 1) return m; } - // let - // isAltExhaustive (Can.Ctor name _ arity _) = - // recoverCtor alts name arity <$> - // isExhaustive - // (Maybe.mapMaybe (specializeRowByCtor name arity) matrix) - // (arity + n - 1) - // in - // concatMap isAltExhaustive altList - // - alts.iter() .map(|ctor| { let tipo::ValueConstructor { variant, .. } = ctor;