@@ -2754,13 +2754,29 @@ defmodule Module.Types.Descr do
27542754 bdd_leaf ( tag , Map . replace! ( fields , diff_key , difference ( type1 , type2 ) ) )
27552755
27562756 _ ->
2757- bdd_difference ( map1 , map2 , & map_leaf_intersection / 2 , nil )
2757+ bdd_difference ( map1 , map2 , & map_leaf_intersection / 2 , & map_leaf_disjoint? / 2 )
27582758 end
27592759 end
27602760 end
27612761
27622762 defp map_difference ( bdd1 , bdd2 ) ,
2763- do: bdd_difference ( bdd1 , bdd2 , & map_leaf_intersection / 2 , nil )
2763+ do: bdd_difference ( bdd1 , bdd2 , & map_leaf_intersection / 2 , & map_leaf_disjoint? / 2 )
2764+
2765+ defp map_leaf_disjoint? ( bdd_leaf ( _tag1 , fields1 ) , bdd_leaf ( _tag2 , fields2 ) ) do
2766+ disjoint_structs? ( fields1 , fields2 )
2767+ end
2768+
2769+ defp disjoint_structs? ( % { __struct__: % { atom: atom } = d1 } , % { __struct__: d2 } )
2770+ when map_size ( d1 ) == 1 do
2771+ disjoint_atom_descr? ( atom , d2 )
2772+ end
2773+
2774+ defp disjoint_structs? ( % { __struct__: d1 } , % { __struct__: % { atom: atom } = d2 } )
2775+ when map_size ( d2 ) == 1 do
2776+ disjoint_atom_descr? ( atom , d1 )
2777+ end
2778+
2779+ defp disjoint_structs? ( _ , _ ) , do: false
27642780
27652781 # Intersects two map literals; throws if their intersection is empty.
27662782 # Both open: the result is open.
@@ -4301,16 +4317,16 @@ defmodule Module.Types.Descr do
43014317
43024318 # A very cheap check for tagged tuples
43034319 defp disjoint_tagged_tuples? ( [ % { atom: atom } = d1 | _ ] , [ d2 | _ ] ) when map_size ( d1 ) == 1 ,
4304- do: disjoint_tagged_atom ?( atom , d2 )
4320+ do: disjoint_atom_descr ?( atom , d2 )
43054321
43064322 defp disjoint_tagged_tuples? ( [ d1 | _ ] , [ % { atom: atom } = d2 | _ ] ) when map_size ( d2 ) == 1 ,
4307- do: disjoint_tagged_atom ?( atom , d1 )
4323+ do: disjoint_atom_descr ?( atom , d1 )
43084324
43094325 defp disjoint_tagged_tuples? ( _ , _ ) , do: false
43104326
4311- defp disjoint_tagged_atom ?( _atom , :term ) , do: false
4312- defp disjoint_tagged_atom ?( atom1 , % { atom: atom2 } ) , do: atom_intersection ( atom1 , atom2 ) === 0
4313- defp disjoint_tagged_atom ?( _atom , % { } ) , do: true
4327+ defp disjoint_atom_descr ?( _atom , :term ) , do: false
4328+ defp disjoint_atom_descr ?( atom1 , % { atom: atom2 } ) , do: atom_intersection ( atom1 , atom2 ) === 0
4329+ defp disjoint_atom_descr ?( _atom , % { } ) , do: true
43144330
43154331 defp non_empty_tuple_literals_intersection ( tuples ) do
43164332 try do
0 commit comments