@@ -4791,31 +4791,29 @@ defmodule Module.Types.Descr do
47914791 defp tuple_literal_intersection ( :open , [ ] , tag , elements ) , do: { tag , elements }
47924792
47934793 defp tuple_literal_intersection ( tag1 , elements1 , tag2 , elements2 ) do
4794- if mismatched_tuple_sizes? ( tag1 , elements1 , tag2 , elements2 ) do
4795- :empty
4796- else
4797- try do
4798- zip_non_empty_intersection! ( elements1 , elements2 , [ ] )
4799- catch
4800- :empty -> :empty
4801- else
4802- elements when tag1 == :open and tag2 == :open -> { :open , elements }
4803- elements -> { :closed , elements }
4804- end
4794+ case tuple_sizes_strategy ( tag1 , length ( elements1 ) , tag2 , length ( elements2 ) ) do
4795+ :disjoint ->
4796+ :empty
4797+
4798+ _ ->
4799+ try do
4800+ zip_non_empty_intersection! ( elements1 , elements2 , [ ] )
4801+ catch
4802+ :empty -> :empty
4803+ else
4804+ elements when tag1 == :open and tag2 == :open -> { :open , elements }
4805+ elements -> { :closed , elements }
4806+ end
48054807 end
48064808 end
48074809
4808- defp mismatched_tuple_sizes? ( :closed , elems1 , :closed , elems2 ) ,
4809- do: length ( elems1 ) != length ( elems2 )
4810-
4811- defp mismatched_tuple_sizes? ( :closed , elems1 , :open , elems2 ) ,
4812- do: length ( elems1 ) < length ( elems2 )
4813-
4814- defp mismatched_tuple_sizes? ( :open , elems1 , :closed , elems2 ) ,
4815- do: length ( elems2 ) < length ( elems1 )
4816-
4817- defp mismatched_tuple_sizes? ( :open , _ , :open , _ ) ,
4818- do: false
4810+ defp tuple_sizes_strategy ( :closed , n1 , :closed , n2 ) when n1 != n2 , do: :disjoint
4811+ defp tuple_sizes_strategy ( :closed , n1 , _ , n2 ) when n1 == n2 , do: :maybe_subtype
4812+ defp tuple_sizes_strategy ( :closed , n1 , :open , n2 ) when n1 < n2 , do: :disjoint
4813+ defp tuple_sizes_strategy ( _ , n1 , :open , n2 ) when n1 == n2 , do: :maybe_subtype
4814+ defp tuple_sizes_strategy ( _ , n1 , :open , n2 ) when n1 > n2 , do: :maybe_subtype
4815+ defp tuple_sizes_strategy ( :open , n1 , :closed , n2 ) when n1 > n2 , do: :disjoint
4816+ defp tuple_sizes_strategy ( _ , _ , _ , _ ) , do: :none
48194817
48204818 # Intersects two lists of types, and _appends_ the extra elements to the result.
48214819 defp zip_non_empty_intersection! ( [ ] , types2 , acc ) , do: Enum . reverse ( acc , types2 )
@@ -4845,27 +4843,22 @@ defmodule Module.Types.Descr do
48454843 do: bdd_difference ( bdd1 , bdd2 , & tuple_leaf_compare / 2 )
48464844
48474845 defp tuple_leaf_compare ( bdd_leaf ( tag1 , elements1 ) , bdd_leaf ( tag2 , elements2 ) ) do
4848- if mismatched_tuple_sizes? ( tag1 , elements1 , tag2 , elements2 ) do
4849- :disjoint
4850- else
4851- tuple_leaf_compare ( elements1 , elements2 , tag1 , tag2 )
4846+ case tuple_sizes_strategy ( tag1 , length ( elements1 ) , tag2 , length ( elements2 ) ) do
4847+ :disjoint -> :disjoint
4848+ other -> tuple_leaf_compare ( elements1 , elements2 , other == :maybe_subtype )
48524849 end
48534850 end
48544851
4855- defp tuple_leaf_compare ( [ head1 | tail1 ] , [ head2 | tail2 ] , tag1 , tag2 ) do
4852+ defp tuple_leaf_compare ( [ head1 | tail1 ] , [ head2 | tail2 ] , subtype? ) do
48564853 cond do
48574854 disjoint? ( head1 , head2 ) -> :disjoint
4858- subtype? ( head1 , head2 ) -> tuple_leaf_compare ( tail1 , tail2 , tag1 , tag2 )
4855+ subtype? and subtype? ( head1 , head2 ) -> tuple_leaf_compare ( tail1 , tail2 , subtype? )
48594856 true -> :none
48604857 end
48614858 end
48624859
4863- defp tuple_leaf_compare ( tail1 , tail2 , tag1 , tag2 ) do
4864- cond do
4865- tail1 == [ ] and tail2 == [ ] and ( tag1 == :closed or tag1 == tag2 ) -> :subtype
4866- tail1 != [ ] and tag2 == :open -> :subtype
4867- true -> :none
4868- end
4860+ defp tuple_leaf_compare ( _tail1 , _tail2 , subtype? ) do
4861+ if subtype? , do: :subtype , else: :none
48694862 end
48704863
48714864 defp non_empty_tuple_literals_intersection ( tuples ) do
0 commit comments