diff --git a/lib/src/conflicts.rs b/lib/src/conflicts.rs index 941389a77..6d1257ed4 100644 --- a/lib/src/conflicts.rs +++ b/lib/src/conflicts.rs @@ -249,224 +249,3 @@ fn parse_conflict_hunk(input: &[u8]) -> Merge { Merge::new(removes, adds) } - -#[cfg(test)] -mod tests { - use super::*; - - fn c(removes: &[T], adds: &[T]) -> Merge { - Merge::new(removes.to_vec(), adds.to_vec()) - } - - #[test] - fn test_legacy_form_conversion() { - fn test_equivalent(legacy_form: (Vec, Vec), merge: Merge>) - where - T: Clone + PartialEq + std::fmt::Debug, - { - assert_eq!(merge.clone().into_legacy_form(), legacy_form); - assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge); - } - // Non-conflict - test_equivalent((vec![], vec![0]), Merge::new(vec![], vec![Some(0)])); - // Regular 3-way conflict - test_equivalent( - (vec![0], vec![1, 2]), - Merge::new(vec![Some(0)], vec![Some(1), Some(2)]), - ); - // Modify/delete conflict - test_equivalent( - (vec![0], vec![1]), - Merge::new(vec![Some(0)], vec![Some(1), None]), - ); - // Add/add conflict - test_equivalent( - (vec![], vec![0, 1]), - Merge::new(vec![None], vec![Some(0), Some(1)]), - ); - // 5-way conflict - test_equivalent( - (vec![0, 1], vec![2, 3, 4]), - Merge::new(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]), - ); - // 5-way delete/delete conflict - test_equivalent( - (vec![0, 1], vec![]), - Merge::new(vec![Some(0), Some(1)], vec![None, None, None]), - ); - } - - #[test] - fn test_as_resolved() { - assert_eq!(Merge::new(vec![], vec![0]).as_resolved(), Some(&0)); - // Even a trivially resolvable merge is not resolved - assert_eq!(Merge::new(vec![0], vec![0, 1]).as_resolved(), None); - } - - #[test] - fn test_simplify() { - // 1-way merge - assert_eq!(c(&[], &[0]).simplify(), c(&[], &[0])); - // 3-way merge - assert_eq!(c(&[0], &[0, 0]).simplify(), c(&[], &[0])); - assert_eq!(c(&[0], &[0, 1]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0], &[1, 0]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0], &[1, 1]).simplify(), c(&[0], &[1, 1])); - assert_eq!(c(&[0], &[1, 2]).simplify(), c(&[0], &[1, 2])); - // 5-way merge - assert_eq!(c(&[0, 0], &[0, 0, 0]).simplify(), c(&[], &[0])); - assert_eq!(c(&[0, 0], &[0, 0, 1]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 0], &[0, 1, 0]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 0], &[0, 1, 1]).simplify(), c(&[0], &[1, 1])); - assert_eq!(c(&[0, 0], &[0, 1, 2]).simplify(), c(&[0], &[1, 2])); - assert_eq!(c(&[0, 0], &[1, 0, 0]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 0], &[1, 0, 1]).simplify(), c(&[0], &[1, 1])); - assert_eq!(c(&[0, 0], &[1, 0, 2]).simplify(), c(&[0], &[1, 2])); - assert_eq!(c(&[0, 0], &[1, 1, 0]).simplify(), c(&[0], &[1, 1])); - assert_eq!(c(&[0, 0], &[1, 1, 1]).simplify(), c(&[0, 0], &[1, 1, 1])); - assert_eq!(c(&[0, 0], &[1, 1, 2]).simplify(), c(&[0, 0], &[1, 1, 2])); - assert_eq!(c(&[0, 0], &[1, 2, 0]).simplify(), c(&[0], &[1, 2])); - assert_eq!(c(&[0, 0], &[1, 2, 1]).simplify(), c(&[0, 0], &[1, 2, 1])); - assert_eq!(c(&[0, 0], &[1, 2, 2]).simplify(), c(&[0, 0], &[1, 2, 2])); - assert_eq!(c(&[0, 0], &[1, 2, 3]).simplify(), c(&[0, 0], &[1, 2, 3])); - assert_eq!(c(&[0, 1], &[0, 0, 0]).simplify(), c(&[1], &[0, 0])); - assert_eq!(c(&[0, 1], &[0, 0, 1]).simplify(), c(&[], &[0])); - assert_eq!(c(&[0, 1], &[0, 0, 2]).simplify(), c(&[1], &[0, 2])); - assert_eq!(c(&[0, 1], &[0, 1, 0]).simplify(), c(&[], &[0])); - assert_eq!(c(&[0, 1], &[0, 1, 1]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 1], &[0, 1, 2]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[0, 2, 0]).simplify(), c(&[1], &[2, 0])); - assert_eq!(c(&[0, 1], &[0, 2, 1]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[0, 2, 2]).simplify(), c(&[1], &[2, 2])); - assert_eq!(c(&[0, 1], &[0, 2, 3]).simplify(), c(&[1], &[2, 3])); - assert_eq!(c(&[0, 1], &[1, 0, 0]).simplify(), c(&[], &[0])); - assert_eq!(c(&[0, 1], &[1, 0, 1]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 1], &[1, 0, 2]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[1, 1, 0]).simplify(), c(&[], &[1])); - assert_eq!(c(&[0, 1], &[1, 1, 1]).simplify(), c(&[0], &[1, 1])); - assert_eq!(c(&[0, 1], &[1, 1, 2]).simplify(), c(&[0], &[2, 1])); - assert_eq!(c(&[0, 1], &[1, 2, 0]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[1, 2, 1]).simplify(), c(&[0], &[1, 2])); - assert_eq!(c(&[0, 1], &[1, 2, 2]).simplify(), c(&[0], &[2, 2])); - assert_eq!(c(&[0, 1], &[1, 2, 3]).simplify(), c(&[0], &[3, 2])); - assert_eq!(c(&[0, 1], &[2, 0, 0]).simplify(), c(&[1], &[2, 0])); - assert_eq!(c(&[0, 1], &[2, 0, 1]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[2, 0, 2]).simplify(), c(&[1], &[2, 2])); - assert_eq!(c(&[0, 1], &[2, 0, 3]).simplify(), c(&[1], &[2, 3])); - assert_eq!(c(&[0, 1], &[2, 1, 0]).simplify(), c(&[], &[2])); - assert_eq!(c(&[0, 1], &[2, 1, 1]).simplify(), c(&[0], &[2, 1])); - assert_eq!(c(&[0, 1], &[2, 1, 2]).simplify(), c(&[0], &[2, 2])); - assert_eq!(c(&[0, 1], &[2, 1, 3]).simplify(), c(&[0], &[2, 3])); - assert_eq!(c(&[0, 1], &[2, 2, 0]).simplify(), c(&[1], &[2, 2])); - assert_eq!(c(&[0, 1], &[2, 2, 1]).simplify(), c(&[0], &[2, 2])); - assert_eq!(c(&[0, 1], &[2, 2, 2]).simplify(), c(&[0, 1], &[2, 2, 2])); - assert_eq!(c(&[0, 1], &[2, 2, 3]).simplify(), c(&[0, 1], &[2, 2, 3])); - assert_eq!(c(&[0, 1], &[2, 3, 0]).simplify(), c(&[1], &[2, 3])); - assert_eq!(c(&[0, 1], &[2, 3, 1]).simplify(), c(&[0], &[2, 3])); - assert_eq!(c(&[0, 1], &[2, 3, 2]).simplify(), c(&[0, 1], &[2, 3, 2])); - assert_eq!(c(&[0, 1], &[2, 3, 3]).simplify(), c(&[0, 1], &[2, 3, 3])); - assert_eq!(c(&[0, 1], &[2, 3, 4]).simplify(), c(&[0, 1], &[2, 3, 4])); - assert_eq!( - c(&[0, 1, 2], &[3, 4, 5, 0]).simplify(), - c(&[1, 2], &[3, 5, 4]) - ); - } - - #[test] - fn test_merge_invariants() { - fn check_invariants(removes: &[u32], adds: &[u32]) { - let merge = Merge::new(removes.to_vec(), adds.to_vec()); - // `simplify()` is idempotent - assert_eq!( - merge.clone().simplify().simplify(), - merge.clone().simplify(), - "simplify() not idempotent for {merge:?}" - ); - // `resolve_trivial()` is unaffected by `simplify()` - assert_eq!( - merge.clone().simplify().resolve_trivial(), - merge.resolve_trivial(), - "simplify() changed result of resolve_trivial() for {merge:?}" - ); - } - // 1-way merge - check_invariants(&[], &[0]); - for i in 0..=1 { - for j in 0..=i + 1 { - // 3-way merge - check_invariants(&[0], &[i, j]); - for k in 0..=j + 1 { - for l in 0..=k + 1 { - // 5-way merge - check_invariants(&[0, i], &[j, k, l]); - } - } - } - } - } - - #[test] - fn test_map() { - fn increment(i: &i32) -> i32 { - i + 1 - } - // 1-way merge - assert_eq!(c(&[], &[1]).map(increment), c(&[], &[2])); - // 3-way merge - assert_eq!(c(&[1], &[3, 5]).map(increment), c(&[2], &[4, 6])); - } - - #[test] - fn test_maybe_map() { - fn sqrt(i: &i32) -> Option { - if *i >= 0 { - Some((*i as f64).sqrt() as i32) - } else { - None - } - } - // 1-way merge - assert_eq!(c(&[], &[1]).maybe_map(sqrt), Some(c(&[], &[1]))); - assert_eq!(c(&[], &[-1]).maybe_map(sqrt), None); - // 3-way merge - assert_eq!(c(&[1], &[4, 9]).maybe_map(sqrt), Some(c(&[1], &[2, 3]))); - assert_eq!(c(&[-1], &[4, 9]).maybe_map(sqrt), None); - assert_eq!(c(&[1], &[-4, 9]).maybe_map(sqrt), None); - } - - #[test] - fn test_try_map() { - fn sqrt(i: &i32) -> Result { - if *i >= 0 { - Ok((*i as f64).sqrt() as i32) - } else { - Err(()) - } - } - // 1-way merge - assert_eq!(c(&[], &[1]).try_map(sqrt), Ok(c(&[], &[1]))); - assert_eq!(c(&[], &[-1]).try_map(sqrt), Err(())); - // 3-way merge - assert_eq!(c(&[1], &[4, 9]).try_map(sqrt), Ok(c(&[1], &[2, 3]))); - assert_eq!(c(&[-1], &[4, 9]).try_map(sqrt), Err(())); - assert_eq!(c(&[1], &[-4, 9]).try_map(sqrt), Err(())); - } - - #[test] - fn test_flatten() { - // 1-way merge of 1-way merge - assert_eq!(c(&[], &[c(&[], &[0])]).flatten(), c(&[], &[0])); - // 1-way merge of 3-way merge - assert_eq!(c(&[], &[c(&[0], &[1, 2])]).flatten(), c(&[0], &[1, 2])); - // 3-way merge of 1-way merges - assert_eq!( - c(&[c(&[], &[0])], &[c(&[], &[1]), c(&[], &[2])]).flatten(), - c(&[0], &[1, 2]) - ); - // 3-way merge of 3-way merges - assert_eq!( - c(&[c(&[0], &[1, 2])], &[c(&[3], &[4, 5]), c(&[6], &[7, 8])]).flatten(), - c(&[3, 2, 1, 6], &[4, 5, 0, 7, 8]) - ); - } -} diff --git a/lib/src/merge.rs b/lib/src/merge.rs index 755cfe957..5d6db038e 100644 --- a/lib/src/merge.rs +++ b/lib/src/merge.rs @@ -550,6 +550,10 @@ fn get_file_contents(store: &Store, path: &RepoPath, term: &Option) -> C mod tests { use super::*; + fn c(removes: &[T], adds: &[T]) -> Merge { + Merge::new(removes.to_vec(), adds.to_vec()) + } + #[test] fn test_trivial_merge() { assert_eq!(trivial_merge(&[], &[0]), Some(&0)); @@ -611,4 +615,216 @@ mod tests { assert_eq!(trivial_merge(&[0, 1], &[2, 3, 3]), None); assert_eq!(trivial_merge(&[0, 1], &[2, 3, 4]), None); } + + #[test] + fn test_legacy_form_conversion() { + fn test_equivalent(legacy_form: (Vec, Vec), merge: Merge>) + where + T: Clone + PartialEq + std::fmt::Debug, + { + assert_eq!(merge.clone().into_legacy_form(), legacy_form); + assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge); + } + // Non-conflict + test_equivalent((vec![], vec![0]), Merge::new(vec![], vec![Some(0)])); + // Regular 3-way conflict + test_equivalent( + (vec![0], vec![1, 2]), + Merge::new(vec![Some(0)], vec![Some(1), Some(2)]), + ); + // Modify/delete conflict + test_equivalent( + (vec![0], vec![1]), + Merge::new(vec![Some(0)], vec![Some(1), None]), + ); + // Add/add conflict + test_equivalent( + (vec![], vec![0, 1]), + Merge::new(vec![None], vec![Some(0), Some(1)]), + ); + // 5-way conflict + test_equivalent( + (vec![0, 1], vec![2, 3, 4]), + Merge::new(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]), + ); + // 5-way delete/delete conflict + test_equivalent( + (vec![0, 1], vec![]), + Merge::new(vec![Some(0), Some(1)], vec![None, None, None]), + ); + } + + #[test] + fn test_as_resolved() { + assert_eq!(Merge::new(vec![], vec![0]).as_resolved(), Some(&0)); + // Even a trivially resolvable merge is not resolved + assert_eq!(Merge::new(vec![0], vec![0, 1]).as_resolved(), None); + } + + #[test] + fn test_simplify() { + // 1-way merge + assert_eq!(c(&[], &[0]).simplify(), c(&[], &[0])); + // 3-way merge + assert_eq!(c(&[0], &[0, 0]).simplify(), c(&[], &[0])); + assert_eq!(c(&[0], &[0, 1]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0], &[1, 0]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0], &[1, 1]).simplify(), c(&[0], &[1, 1])); + assert_eq!(c(&[0], &[1, 2]).simplify(), c(&[0], &[1, 2])); + // 5-way merge + assert_eq!(c(&[0, 0], &[0, 0, 0]).simplify(), c(&[], &[0])); + assert_eq!(c(&[0, 0], &[0, 0, 1]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 0], &[0, 1, 0]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 0], &[0, 1, 1]).simplify(), c(&[0], &[1, 1])); + assert_eq!(c(&[0, 0], &[0, 1, 2]).simplify(), c(&[0], &[1, 2])); + assert_eq!(c(&[0, 0], &[1, 0, 0]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 0], &[1, 0, 1]).simplify(), c(&[0], &[1, 1])); + assert_eq!(c(&[0, 0], &[1, 0, 2]).simplify(), c(&[0], &[1, 2])); + assert_eq!(c(&[0, 0], &[1, 1, 0]).simplify(), c(&[0], &[1, 1])); + assert_eq!(c(&[0, 0], &[1, 1, 1]).simplify(), c(&[0, 0], &[1, 1, 1])); + assert_eq!(c(&[0, 0], &[1, 1, 2]).simplify(), c(&[0, 0], &[1, 1, 2])); + assert_eq!(c(&[0, 0], &[1, 2, 0]).simplify(), c(&[0], &[1, 2])); + assert_eq!(c(&[0, 0], &[1, 2, 1]).simplify(), c(&[0, 0], &[1, 2, 1])); + assert_eq!(c(&[0, 0], &[1, 2, 2]).simplify(), c(&[0, 0], &[1, 2, 2])); + assert_eq!(c(&[0, 0], &[1, 2, 3]).simplify(), c(&[0, 0], &[1, 2, 3])); + assert_eq!(c(&[0, 1], &[0, 0, 0]).simplify(), c(&[1], &[0, 0])); + assert_eq!(c(&[0, 1], &[0, 0, 1]).simplify(), c(&[], &[0])); + assert_eq!(c(&[0, 1], &[0, 0, 2]).simplify(), c(&[1], &[0, 2])); + assert_eq!(c(&[0, 1], &[0, 1, 0]).simplify(), c(&[], &[0])); + assert_eq!(c(&[0, 1], &[0, 1, 1]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 1], &[0, 1, 2]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[0, 2, 0]).simplify(), c(&[1], &[2, 0])); + assert_eq!(c(&[0, 1], &[0, 2, 1]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[0, 2, 2]).simplify(), c(&[1], &[2, 2])); + assert_eq!(c(&[0, 1], &[0, 2, 3]).simplify(), c(&[1], &[2, 3])); + assert_eq!(c(&[0, 1], &[1, 0, 0]).simplify(), c(&[], &[0])); + assert_eq!(c(&[0, 1], &[1, 0, 1]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 1], &[1, 0, 2]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[1, 1, 0]).simplify(), c(&[], &[1])); + assert_eq!(c(&[0, 1], &[1, 1, 1]).simplify(), c(&[0], &[1, 1])); + assert_eq!(c(&[0, 1], &[1, 1, 2]).simplify(), c(&[0], &[2, 1])); + assert_eq!(c(&[0, 1], &[1, 2, 0]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[1, 2, 1]).simplify(), c(&[0], &[1, 2])); + assert_eq!(c(&[0, 1], &[1, 2, 2]).simplify(), c(&[0], &[2, 2])); + assert_eq!(c(&[0, 1], &[1, 2, 3]).simplify(), c(&[0], &[3, 2])); + assert_eq!(c(&[0, 1], &[2, 0, 0]).simplify(), c(&[1], &[2, 0])); + assert_eq!(c(&[0, 1], &[2, 0, 1]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[2, 0, 2]).simplify(), c(&[1], &[2, 2])); + assert_eq!(c(&[0, 1], &[2, 0, 3]).simplify(), c(&[1], &[2, 3])); + assert_eq!(c(&[0, 1], &[2, 1, 0]).simplify(), c(&[], &[2])); + assert_eq!(c(&[0, 1], &[2, 1, 1]).simplify(), c(&[0], &[2, 1])); + assert_eq!(c(&[0, 1], &[2, 1, 2]).simplify(), c(&[0], &[2, 2])); + assert_eq!(c(&[0, 1], &[2, 1, 3]).simplify(), c(&[0], &[2, 3])); + assert_eq!(c(&[0, 1], &[2, 2, 0]).simplify(), c(&[1], &[2, 2])); + assert_eq!(c(&[0, 1], &[2, 2, 1]).simplify(), c(&[0], &[2, 2])); + assert_eq!(c(&[0, 1], &[2, 2, 2]).simplify(), c(&[0, 1], &[2, 2, 2])); + assert_eq!(c(&[0, 1], &[2, 2, 3]).simplify(), c(&[0, 1], &[2, 2, 3])); + assert_eq!(c(&[0, 1], &[2, 3, 0]).simplify(), c(&[1], &[2, 3])); + assert_eq!(c(&[0, 1], &[2, 3, 1]).simplify(), c(&[0], &[2, 3])); + assert_eq!(c(&[0, 1], &[2, 3, 2]).simplify(), c(&[0, 1], &[2, 3, 2])); + assert_eq!(c(&[0, 1], &[2, 3, 3]).simplify(), c(&[0, 1], &[2, 3, 3])); + assert_eq!(c(&[0, 1], &[2, 3, 4]).simplify(), c(&[0, 1], &[2, 3, 4])); + assert_eq!( + c(&[0, 1, 2], &[3, 4, 5, 0]).simplify(), + c(&[1, 2], &[3, 5, 4]) + ); + } + + #[test] + fn test_merge_invariants() { + fn check_invariants(removes: &[u32], adds: &[u32]) { + let merge = Merge::new(removes.to_vec(), adds.to_vec()); + // `simplify()` is idempotent + assert_eq!( + merge.clone().simplify().simplify(), + merge.clone().simplify(), + "simplify() not idempotent for {merge:?}" + ); + // `resolve_trivial()` is unaffected by `simplify()` + assert_eq!( + merge.clone().simplify().resolve_trivial(), + merge.resolve_trivial(), + "simplify() changed result of resolve_trivial() for {merge:?}" + ); + } + // 1-way merge + check_invariants(&[], &[0]); + for i in 0..=1 { + for j in 0..=i + 1 { + // 3-way merge + check_invariants(&[0], &[i, j]); + for k in 0..=j + 1 { + for l in 0..=k + 1 { + // 5-way merge + check_invariants(&[0, i], &[j, k, l]); + } + } + } + } + } + + #[test] + fn test_map() { + fn increment(i: &i32) -> i32 { + i + 1 + } + // 1-way merge + assert_eq!(c(&[], &[1]).map(increment), c(&[], &[2])); + // 3-way merge + assert_eq!(c(&[1], &[3, 5]).map(increment), c(&[2], &[4, 6])); + } + + #[test] + fn test_maybe_map() { + fn sqrt(i: &i32) -> Option { + if *i >= 0 { + Some((*i as f64).sqrt() as i32) + } else { + None + } + } + // 1-way merge + assert_eq!(c(&[], &[1]).maybe_map(sqrt), Some(c(&[], &[1]))); + assert_eq!(c(&[], &[-1]).maybe_map(sqrt), None); + // 3-way merge + assert_eq!(c(&[1], &[4, 9]).maybe_map(sqrt), Some(c(&[1], &[2, 3]))); + assert_eq!(c(&[-1], &[4, 9]).maybe_map(sqrt), None); + assert_eq!(c(&[1], &[-4, 9]).maybe_map(sqrt), None); + } + + #[test] + fn test_try_map() { + fn sqrt(i: &i32) -> Result { + if *i >= 0 { + Ok((*i as f64).sqrt() as i32) + } else { + Err(()) + } + } + // 1-way merge + assert_eq!(c(&[], &[1]).try_map(sqrt), Ok(c(&[], &[1]))); + assert_eq!(c(&[], &[-1]).try_map(sqrt), Err(())); + // 3-way merge + assert_eq!(c(&[1], &[4, 9]).try_map(sqrt), Ok(c(&[1], &[2, 3]))); + assert_eq!(c(&[-1], &[4, 9]).try_map(sqrt), Err(())); + assert_eq!(c(&[1], &[-4, 9]).try_map(sqrt), Err(())); + } + + #[test] + fn test_flatten() { + // 1-way merge of 1-way merge + assert_eq!(c(&[], &[c(&[], &[0])]).flatten(), c(&[], &[0])); + // 1-way merge of 3-way merge + assert_eq!(c(&[], &[c(&[0], &[1, 2])]).flatten(), c(&[0], &[1, 2])); + // 3-way merge of 1-way merges + assert_eq!( + c(&[c(&[], &[0])], &[c(&[], &[1]), c(&[], &[2])]).flatten(), + c(&[0], &[1, 2]) + ); + // 3-way merge of 3-way merges + assert_eq!( + c(&[c(&[0], &[1, 2])], &[c(&[3], &[4, 5]), c(&[6], &[7, 8])]).flatten(), + c(&[3, 2, 1, 6], &[4, 5, 0, 7, 8]) + ); + } }