@@ -11,7 +11,8 @@ use super::{
1111/// in an [`crate::types::IntersectionType`] or a [`crate::types::UnionType`] in order for them
1212/// to be compared for equivalence.
1313///
14- /// Two unions / intersections are compared lexicographically.
14+ /// Two intersections are compared lexicographically.
15+ /// Two unions are never compared in this function because DNF does not permit nested unions.
1516///
1617/// Element types must already be sorted.
1718///
@@ -21,7 +22,7 @@ use super::{
2122/// create here is not user-facing. However, it doesn't really "make sense" for `Type` to implement
2223/// [`Ord`] in terms of the semantics. There are many different ways in which you could plausibly
2324/// sort a list of types; this is only one (somewhat arbitrary, at times) possible ordering.
24- pub ( super ) fn union_elements_ordering < ' db > (
25+ pub ( super ) fn union_or_intersection_elements_ordering < ' db > (
2526 left : & Type < ' db > ,
2627 right : & Type < ' db > ,
2728 db : & ' db dyn crate :: Db ,
@@ -269,38 +270,32 @@ pub(super) fn union_elements_ordering<'db>(
269270 ( Type :: Dynamic ( _) , _) => Ordering :: Less ,
270271 ( _, Type :: Dynamic ( _) ) => Ordering :: Greater ,
271272
272- ( Type :: Union ( left) , Type :: Union ( right) ) => {
273- if left. elements ( db) . len ( ) != right. elements ( db) . len ( ) {
274- return left. elements ( db) . len ( ) . cmp ( & right. elements ( db) . len ( ) ) ;
275- }
276- // Lexicographically compare the elements of the two unions.
277- for ( left, right) in left. elements ( db) . iter ( ) . zip ( right. elements ( db) ) {
278- let ordering = union_elements_ordering ( left, right, db) ;
279- if ordering != Ordering :: Equal {
280- return ordering;
281- }
282- }
283- Ordering :: Equal
273+ ( Type :: Union ( _) , Type :: Union ( _) ) => {
274+ unreachable ! ( "our type representation does not permit nested unions" ) ;
284275 }
285276 ( Type :: Union ( _) , _) => Ordering :: Less ,
286277 ( _, Type :: Union ( _) ) => Ordering :: Greater ,
287278
288279 ( Type :: Intersection ( left) , Type :: Intersection ( right) ) => {
289280 // Lexicographically compare the elements of the two intersections.
290- if left. positive ( db) . len ( ) != right. positive ( db) . len ( ) {
291- return left. positive ( db) . len ( ) . cmp ( & right. positive ( db) . len ( ) ) ;
281+ let left_positive = left. positive ( db) ;
282+ let right_positive = right. positive ( db) ;
283+ if left_positive. len ( ) != right_positive. len ( ) {
284+ return left_positive. len ( ) . cmp ( & right_positive. len ( ) ) ;
292285 }
293- if left. negative ( db) . len ( ) != right. negative ( db) . len ( ) {
294- return left. negative ( db) . len ( ) . cmp ( & right. negative ( db) . len ( ) ) ;
286+ let left_negative = left. negative ( db) ;
287+ let right_negative = right. negative ( db) ;
288+ if left_negative. len ( ) != right_negative. len ( ) {
289+ return left_negative. len ( ) . cmp ( & right_negative. len ( ) ) ;
295290 }
296- for ( left, right) in left . positive ( db ) . iter ( ) . zip ( right . positive ( db ) ) {
297- let ordering = union_elements_ordering ( left, right, db) ;
291+ for ( left, right) in left_positive . iter ( ) . zip ( right_positive ) {
292+ let ordering = union_or_intersection_elements_ordering ( left, right, db) ;
298293 if ordering != Ordering :: Equal {
299294 return ordering;
300295 }
301296 }
302- for ( left, right) in left . negative ( db ) . iter ( ) . zip ( right . negative ( db ) ) {
303- let ordering = union_elements_ordering ( left, right, db) ;
297+ for ( left, right) in left_negative . iter ( ) . zip ( right_negative ) {
298+ let ordering = union_or_intersection_elements_ordering ( left, right, db) ;
304299 if ordering != Ordering :: Equal {
305300 return ordering;
306301 }
0 commit comments