From c37f8d57606f61bfc3f5d2f05d0a3b4451c13211 Mon Sep 17 00:00:00 2001 From: Alex Waygood <alex.waygood@gmail.com> Date: Thu, 16 Jan 2025 12:25:57 +0000 Subject: [PATCH] Move length-checking logic into `order_sequences` function --- .../src/types/type_ordering.rs | 56 ++++++------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/type_ordering.rs b/crates/red_knot_python_semantic/src/types/type_ordering.rs index 24ac219259984b..5bfbdb61608948 100644 --- a/crates/red_knot_python_semantic/src/types/type_ordering.rs +++ b/crates/red_knot_python_semantic/src/types/type_ordering.rs @@ -88,12 +88,7 @@ pub(super) fn order_union_elements<'db>( (_, Type::FunctionLiteral(_)) => Ordering::Greater, (Type::Tuple(left), Type::Tuple(right)) => { - let left_elements = left.elements(db); - let right_elements = right.elements(db); - left_elements - .len() - .cmp(&right_elements.len()) - .then_with(|| order_sequences(db, left_elements, right_elements)) + order_sequences(db, left.elements(db), right.elements(db)) } (Type::Tuple(_), _) => Ordering::Less, (_, Type::Tuple(_)) => Ordering::Greater, @@ -168,33 +163,14 @@ pub(super) fn order_union_elements<'db>( (_, Type::Dynamic(_)) => Ordering::Greater, (Type::Union(left), Type::Union(right)) => { - let left_elements = left.elements(db); - let right_elements = right.elements(db); - left_elements - .len() - .cmp(&right_elements.len()) - .then_with(|| order_sequences(db, left_elements, right_elements)) + order_sequences(db, left.elements(db), right.elements(db)) } (Type::Union(_), _) => Ordering::Less, (_, Type::Union(_)) => Ordering::Greater, (Type::Intersection(left), Type::Intersection(right)) => { - let left_pos = left.positive(db); - let right_pos = right.positive(db); - let left_neg = left.negative(db); - let right_neg = right.negative(db); - - left_pos - .len() - .cmp(&right_pos.len()) - .then_with(|| left_neg.len().cmp(&right_neg.len())) - .then_with(|| { - order_sequences( - db, - left_pos.iter().chain(left_neg), - right_pos.iter().chain(right_neg), - ) - }) + order_sequences(db, left.positive(db), right.positive(db)) + .then_with(|| order_sequences(db, left.negative(db), right.negative(db))) } } } @@ -283,14 +259,18 @@ fn order_dynamic_elements(left: DynamicType, right: DynamicType) -> Ordering { /// Determine a canonical order for two types that wrap sequences of other types. /// /// This is useful for ordering tuples, unions and intersections. -fn order_sequences<'db>( - db: &'db dyn Db, - left: impl IntoIterator<Item = &'db Type<'db>>, - right: impl IntoIterator<Item = &'db Type<'db>>, -) -> Ordering { - left.into_iter() - .zip(right) - .map(|(left, right)| order_union_elements(db, left, right)) - .find(|ordering| !ordering.is_eq()) - .unwrap_or(Ordering::Equal) +fn order_sequences<'db, I, J>(db: &'db dyn Db, left: I, right: I) -> Ordering +where + I: IntoIterator<IntoIter = J>, + J: ExactSizeIterator<Item = &'db Type<'db>>, +{ + let left = left.into_iter(); + let right = right.into_iter(); + + left.len().cmp(&right.len()).then_with(|| { + left.zip(right) + .map(|(left, right)| order_union_elements(db, left, right)) + .find(|ordering| !ordering.is_eq()) + .unwrap_or(Ordering::Equal) + }) }