@@ -48,10 +48,10 @@ defmodule Module.Types.Descr do
4848 # Remark: those are explicit BDD constructors. The functional constructors are `bdd_new/1` and `bdd_new/3`.
4949 @ fun_top { :negation , % { } }
5050 @ atom_top { :negation , :sets . new ( version: 2 ) }
51- @ map_top { :erlang . phash2 ( { :open , @ fields_new } ) , :open , @ fields_new }
52- @ non_empty_list_top { :erlang . phash2 ( { :term , :term } ) , :term , :term }
53- @ tuple_top { :erlang . phash2 ( { :open , [ ] } ) , :open , [ ] }
54- @ map_empty { :erlang . phash2 ( { :closed , @ fields_new } ) , :closed , @ fields_new }
51+ @ map_top { :erlang . phash2 ( [ :open | @ fields_new ] ) , :open , @ fields_new }
52+ @ non_empty_list_top { :erlang . phash2 ( [ :term | :term ] ) , :term , :term }
53+ @ tuple_top { :erlang . phash2 ( [ :open | [ ] ] ) , :open , [ ] }
54+ @ map_empty { - :erlang . phash2 ( @ fields_new ) , :closed , @ fields_new }
5555
5656 defmacrop bdd_leaf ( arg1 , arg2 ) do
5757 quote do
@@ -441,7 +441,7 @@ defmodule Module.Types.Descr do
441441 defp union ( :atom , v1 , v2 ) , do: atom_union ( v1 , v2 )
442442 defp union ( :bitmap , v1 , v2 ) , do: v1 ||| v2
443443 defp union ( :dynamic , v1 , v2 ) , do: dynamic_union ( v1 , v2 )
444- defp union ( :list , v1 , v2 ) , do: list_union ( v1 , v2 )
444+ defp union ( :list , v1 , v2 ) , do: bdd_union ( v1 , v2 )
445445 defp union ( :map , v1 , v2 ) , do: map_union ( v1 , v2 )
446446 defp union ( :optional , 1 , 1 ) , do: 1
447447 defp union ( :tuple , v1 , v2 ) , do: tuple_union ( v1 , v2 )
@@ -2243,9 +2243,6 @@ defmodule Module.Types.Descr do
22432243 defp list_tail_unfold ( :term ) , do: @ not_non_empty_list
22442244 defp list_tail_unfold ( other ) , do: Map . delete ( other , :list )
22452245
2246- @ compile { :inline , list_union: 2 }
2247- defp list_union ( bdd1 , bdd2 ) , do: bdd_union ( bdd1 , bdd2 )
2248-
22492246 defp list_top? ( bdd_leaf ( :term , :term ) ) , do: true
22502247 defp list_top? ( _ ) , do: false
22512248
@@ -3052,8 +3049,8 @@ defmodule Module.Types.Descr do
30523049 end
30533050 end
30543051
3055- defp map_intersection ( bdd_leaf ( :open , [ ] ) , bdd ) , do: bdd
3056- defp map_intersection ( bdd , bdd_leaf ( :open , [ ] ) ) , do: bdd
3052+ defp map_intersection ( bdd_leaf ( :open , fields ) , bdd ) when is_fields_empty ( fields ) , do: bdd
3053+ defp map_intersection ( bdd , bdd_leaf ( :open , fields ) ) when is_fields_empty ( fields ) , do: bdd
30573054 defp map_intersection ( bdd1 , bdd2 ) , do: bdd_intersection ( bdd1 , bdd2 , & map_leaf_intersection / 2 )
30583055
30593056 defp map_leaf_intersection ( bdd_leaf ( tag1 , fields1 ) , bdd_leaf ( tag2 , fields2 ) ) do
@@ -3065,11 +3062,12 @@ defmodule Module.Types.Descr do
30653062 end
30663063 end
30673064
3068- defp map_difference ( _ , bdd_leaf ( :open , [ ] ) ) ,
3065+ defp map_difference ( _ , bdd_leaf ( :open , fields ) ) when is_fields_empty ( fields ) ,
30693066 do: :bdd_bot
30703067
3071- defp map_difference ( bdd_leaf ( :open , [ ] ) , { _ , _ , _ , _ , _ } = bdd2 ) ,
3072- do: bdd_negation ( bdd2 )
3068+ defp map_difference ( bdd_leaf ( :open , fields ) , { _ , _ , _ , _ , _ } = bdd2 )
3069+ when is_fields_empty ( fields ) ,
3070+ do: bdd_negation ( bdd2 )
30733071
30743072 defp map_difference ( bdd1 , bdd2 ) ,
30753073 do: bdd_difference ( bdd1 , bdd2 , & map_leaf_difference / 3 )
@@ -5217,7 +5215,6 @@ defmodule Module.Types.Descr do
52175215 end
52185216 end
52195217
5220- @ compile { :inline , tuple_union: 2 }
52215218 defp tuple_union ( bdd1 , bdd2 ) , do: bdd_union ( bdd1 , bdd2 )
52225219
52235220 defp maybe_optimize_tuple_union ( { tag1 , pos1 } = tuple1 , { tag2 , pos2 } = tuple2 ) do
@@ -5782,7 +5779,10 @@ defmodule Module.Types.Descr do
57825779
57835780 ## BDD helpers
57845781
5785- defp bdd_leaf_new ( arg1 , arg2 ) , do: { :erlang . phash2 ( { arg1 , arg2 } ) , arg1 , arg2 }
5782+ # Some of our operations rely on eliminating closed tuples/maps,
5783+ # so we make sure they always come first.
5784+ defp bdd_leaf_new ( :closed , arg2 ) , do: { - :erlang . phash2 ( arg2 ) , :closed , arg2 }
5785+ defp bdd_leaf_new ( arg1 , arg2 ) , do: { :erlang . phash2 ( [ arg1 | arg2 ] ) , arg1 , arg2 }
57865786
57875787 defp bdd_node_new ( lit , c , u , d ) ,
57885788 do: { bdd_compute_hash ( lit , c , u , d ) , lit , c , u , d }
0 commit comments