remove more clones

This commit is contained in:
Folkert 2020-07-25 17:06:13 +02:00
parent ef9aa7773b
commit b308ea0802

View file

@ -147,9 +147,8 @@ fn to_decision_tree(raw_branches: Vec<Branch>) -> DecisionTree {
match check_for_match(&branches) { match check_for_match(&branches) {
Some(goal) => DecisionTree::Match(goal), Some(goal) => DecisionTree::Match(goal),
None => { None => {
// TODO remove clone // must clone here to release the borrow on `branches`
let path = pick_path(&branches).clone(); let path = pick_path(&branches).clone();
let (edges, fallback) = gather_edges(branches, &path); let (edges, fallback) = gather_edges(branches, &path);
let mut decision_edges: Vec<_> = edges let mut decision_edges: Vec<_> = edges
@ -211,15 +210,16 @@ fn flatten<'a>(
path_pattern: (Path, Guard<'a>, Pattern<'a>), path_pattern: (Path, Guard<'a>, Pattern<'a>),
path_patterns: &mut Vec<(Path, Guard<'a>, Pattern<'a>)>, path_patterns: &mut Vec<(Path, Guard<'a>, Pattern<'a>)>,
) { ) {
match &path_pattern.2 { match path_pattern.2 {
Pattern::AppliedTag { Pattern::AppliedTag {
union, union,
arguments, arguments,
tag_id, tag_id,
.. tag_name,
} => { layout,
// TODO do we need to check that guard.is_none() here? } if union.alternatives.len() == 1 => {
if union.alternatives.len() == 1 { // TODO ^ do we need to check that guard.is_none() here?
let path = path_pattern.0; let path = path_pattern.0;
// Theory: unbox doesn't have any value for us, because one-element tag unions // Theory: unbox doesn't have any value for us, because one-element tag unions
// don't store the tag anyway. // don't store the tag anyway.
@ -227,7 +227,13 @@ fn flatten<'a>(
path_patterns.push(( path_patterns.push((
Path::Unbox(Box::new(path)), Path::Unbox(Box::new(path)),
path_pattern.1.clone(), path_pattern.1.clone(),
path_pattern.2.clone(), Pattern::AppliedTag {
union,
arguments,
tag_id,
tag_name,
layout,
},
)); ));
} else { } else {
for (index, (arg_pattern, _)) in arguments.iter().enumerate() { for (index, (arg_pattern, _)) in arguments.iter().enumerate() {
@ -235,7 +241,7 @@ fn flatten<'a>(
( (
Path::Index { Path::Index {
index: index as u64, index: index as u64,
tag_id: *tag_id, tag_id,
path: Box::new(path.clone()), path: Box::new(path.clone()),
}, },
// same guard here? // same guard here?
@ -246,9 +252,6 @@ fn flatten<'a>(
); );
} }
} }
} else {
path_patterns.push(path_pattern);
}
} }
_ => { _ => {
@ -282,8 +285,7 @@ fn gather_edges<'a>(
branches: Vec<Branch<'a>>, branches: Vec<Branch<'a>>,
path: &Path, path: &Path,
) -> (Vec<(Test<'a>, Vec<Branch<'a>>)>, Vec<Branch<'a>>) { ) -> (Vec<(Test<'a>, Vec<Branch<'a>>)>, Vec<Branch<'a>>) {
// TODO remove clone let relevant_tests = tests_at_path(path, &branches);
let relevant_tests = tests_at_path(path, branches.clone());
let check = is_complete(&relevant_tests); let check = is_complete(&relevant_tests);
@ -307,12 +309,12 @@ fn gather_edges<'a>(
/// FIND RELEVANT TESTS /// FIND RELEVANT TESTS
fn tests_at_path<'a>(selected_path: &Path, branches: Vec<Branch<'a>>) -> Vec<Test<'a>> { fn tests_at_path<'a>(selected_path: &Path, branches: &[Branch<'a>]) -> Vec<Test<'a>> {
// NOTE the ordering of the result is important! // NOTE the ordering of the result is important!
let mut all_tests = Vec::new(); let mut all_tests = Vec::new();
for branch in branches.into_iter() { for branch in branches {
test_at_path(selected_path, branch, &mut all_tests); test_at_path(selected_path, branch, &mut all_tests);
} }
@ -341,7 +343,7 @@ fn tests_at_path<'a>(selected_path: &Path, branches: Vec<Branch<'a>>) -> Vec<Tes
unique unique
} }
fn test_at_path<'a>(selected_path: &Path, branch: Branch<'a>, all_tests: &mut Vec<Test<'a>>) { fn test_at_path<'a>(selected_path: &Path, branch: &Branch<'a>, all_tests: &mut Vec<Test<'a>>) {
use Pattern::*; use Pattern::*;
use Test::*; use Test::*;
@ -457,7 +459,7 @@ fn edges_for<'a>(
) -> (Test<'a>, Vec<Branch<'a>>) { ) -> (Test<'a>, Vec<Branch<'a>>) {
let mut new_branches = Vec::new(); let mut new_branches = Vec::new();
for branch in branches.into_iter() { for branch in branches.iter() {
to_relevant_branch(&test, path, branch, &mut new_branches); to_relevant_branch(&test, path, branch, &mut new_branches);
} }
@ -467,13 +469,13 @@ fn edges_for<'a>(
fn to_relevant_branch<'a>( fn to_relevant_branch<'a>(
test: &Test<'a>, test: &Test<'a>,
path: &Path, path: &Path,
branch: Branch<'a>, branch: &Branch<'a>,
new_branches: &mut Vec<Branch<'a>>, new_branches: &mut Vec<Branch<'a>>,
) { ) {
// TODO remove clone // TODO remove clone
match extract(path, branch.patterns.clone()) { match extract(path, branch.patterns.clone()) {
Extract::NotFound => { Extract::NotFound => {
new_branches.push(branch); new_branches.push(branch.clone());
} }
Extract::Found { Extract::Found {
start, start,
@ -509,7 +511,7 @@ fn to_relevant_branch_help<'a>(
path: &Path, path: &Path,
mut start: Vec<(Path, Guard<'a>, Pattern<'a>)>, mut start: Vec<(Path, Guard<'a>, Pattern<'a>)>,
end: Vec<(Path, Guard<'a>, Pattern<'a>)>, end: Vec<(Path, Guard<'a>, Pattern<'a>)>,
branch: Branch<'a>, branch: &Branch<'a>,
guard: Guard<'a>, guard: Guard<'a>,
pattern: Pattern<'a>, pattern: Pattern<'a>,
) -> Option<Branch<'a>> { ) -> Option<Branch<'a>> {
@ -517,7 +519,7 @@ fn to_relevant_branch_help<'a>(
use Test::*; use Test::*;
match pattern { match pattern {
Identifier(_) | Underscore | Shadowed(_, _) | UnsupportedPattern(_) => Some(branch), Identifier(_) | Underscore | Shadowed(_, _) | UnsupportedPattern(_) => Some(branch.clone()),
RecordDestructure(destructs, _) => match test { RecordDestructure(destructs, _) => match test {
IsCtor { IsCtor {
@ -678,19 +680,14 @@ fn extract<'a>(
) -> Extract<'a> { ) -> Extract<'a> {
let mut start = Vec::new(); let mut start = Vec::new();
// TODO remove this clone
let mut copy = path_patterns.clone();
// TODO potential ordering problem // TODO potential ordering problem
for (index, current) in path_patterns.into_iter().enumerate() { let mut it = path_patterns.into_iter();
while let Some(current) = it.next() {
if &current.0 == selected_path { if &current.0 == selected_path {
return Extract::Found { return Extract::Found {
start, start,
found_pattern: (current.1, current.2), found_pattern: (current.1, current.2),
end: { end: it.collect::<Vec<_>>(),
copy.drain(0..=index);
copy
},
}; };
} else { } else {
start.push(current); start.push(current);