mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
correct list pattern match checking to add extra anythings for patterns with rest
This commit is contained in:
parent
ee10af2c68
commit
37a8bbd87c
1 changed files with 28 additions and 6 deletions
|
@ -389,7 +389,6 @@ pub fn is_useful(mut old_matrix: PatternMatrix, mut vector: Row) -> bool {
|
||||||
vector.extend(args);
|
vector.extend(args);
|
||||||
} else {
|
} else {
|
||||||
// TODO turn this into an iteration over the outer loop rather than bouncing
|
// TODO turn this into an iteration over the outer loop rather than bouncing
|
||||||
vector.extend(args);
|
|
||||||
for list_ctor in spec_list_ctors {
|
for list_ctor in spec_list_ctors {
|
||||||
let mut old_matrix = old_matrix.clone();
|
let mut old_matrix = old_matrix.clone();
|
||||||
let mut spec_matrix = Vec::with_capacity(old_matrix.len());
|
let mut spec_matrix = Vec::with_capacity(old_matrix.len());
|
||||||
|
@ -400,7 +399,31 @@ pub fn is_useful(mut old_matrix: PatternMatrix, mut vector: Row) -> bool {
|
||||||
&mut spec_matrix,
|
&mut spec_matrix,
|
||||||
);
|
);
|
||||||
|
|
||||||
if is_useful(spec_matrix, vector.clone()) {
|
// Add Anythings for the missing elements.
|
||||||
|
let full_args = if let ListArity::Slice(before, _) = arity {
|
||||||
|
if arity.min_len() < list_ctor.min_len() {
|
||||||
|
let (before, after) = args.split_at(before);
|
||||||
|
let num_extra_wildcards =
|
||||||
|
list_ctor.min_len() - arity.min_len();
|
||||||
|
let extra_wildcards =
|
||||||
|
std::iter::repeat(&Anything).take(num_extra_wildcards);
|
||||||
|
|
||||||
|
before
|
||||||
|
.iter()
|
||||||
|
.chain(extra_wildcards)
|
||||||
|
.chain(after)
|
||||||
|
.cloned()
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
args.clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.clone()
|
||||||
|
};
|
||||||
|
let mut nested_vector = vector.clone();
|
||||||
|
nested_vector.extend(full_args);
|
||||||
|
|
||||||
|
if is_useful(spec_matrix, nested_vector) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,9 +550,8 @@ fn specialize_row_by_list(spec_arity: ListArity, mut row: Row) -> Option<Row> {
|
||||||
debug_assert!(spec_arity.min_len() > this_arity.min_len());
|
debug_assert!(spec_arity.min_len() > this_arity.min_len());
|
||||||
match this_arity {
|
match this_arity {
|
||||||
ListArity::Exact(_) => internal_error!("exact-sized lists cannot cover lists of other minimum length"),
|
ListArity::Exact(_) => internal_error!("exact-sized lists cannot cover lists of other minimum length"),
|
||||||
ListArity::Slice(before, after) => {
|
ListArity::Slice(before, _) => {
|
||||||
let before = &args[..before];
|
let (before, after) = args.split_at(before);
|
||||||
let after = &args[this_arity.min_len() - after..];
|
|
||||||
let num_extra_wildcards = spec_arity.min_len() - this_arity.min_len();
|
let num_extra_wildcards = spec_arity.min_len() - this_arity.min_len();
|
||||||
let extra_wildcards = std::iter::repeat(&Anything).take(num_extra_wildcards);
|
let extra_wildcards = std::iter::repeat(&Anything).take(num_extra_wildcards);
|
||||||
|
|
||||||
|
@ -847,7 +869,7 @@ fn build_list_ctors_covering_patterns(
|
||||||
}
|
}
|
||||||
(max_prefix_len, max_suffix_len)
|
(max_prefix_len, max_suffix_len)
|
||||||
};
|
};
|
||||||
let l = inf_cover_prefix + inf_cover_suffix;
|
let l = inf_cover_prefix + inf_cover_suffix + 1;
|
||||||
|
|
||||||
let exact_size_lists = (min_len..l) // exclusive
|
let exact_size_lists = (min_len..l) // exclusive
|
||||||
.map(ListArity::Exact);
|
.map(ListArity::Exact);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue