@@ -257,7 +257,7 @@ defmodule Module.Types.Descr do
257
257
case descr do
258
258
% { dynamic: % { optional: 1 } } -> % { dynamic: % { optional: 1 } }
259
259
% { optional: 1 } -> % { optional: 1 }
260
- _ -> % { }
260
+ _ -> @ none
261
261
end
262
262
end
263
263
@@ -464,13 +464,21 @@ defmodule Module.Types.Descr do
464
464
465
465
defp iterator_difference_static ( :none , map ) , do: map
466
466
467
- defp empty_difference_static? ( left , :term ) , do: not Map . has_key? ( left , :optional )
467
+ # This function is designed to compute the difference during subtyping efficiently.
468
+ # Do not use it for anything else.
469
+ defp empty_difference_subtype? ( % { dynamic: dyn_left } = left , % { dynamic: dyn_right } = right ) do
470
+ # Dynamic will either exist on both sides or on none
471
+ empty_difference_subtype? ( dyn_left , dyn_right ) and
472
+ empty_difference_subtype? ( Map . delete ( left , :dynamic ) , Map . delete ( right , :dynamic ) )
473
+ end
474
+
475
+ defp empty_difference_subtype? ( left , :term ) , do: keep_optional ( left ) == @ none
468
476
469
- defp empty_difference_static ?( left , right ) do
470
- iterator_empty_difference_static ?( :maps . next ( :maps . iterator ( unfold ( left ) ) ) , unfold ( right ) )
477
+ defp empty_difference_subtype ?( left , right ) do
478
+ iterator_empty_difference_subtype ?( :maps . next ( :maps . iterator ( unfold ( left ) ) ) , unfold ( right ) )
471
479
end
472
480
473
- defp iterator_empty_difference_static ?( { key , v1 , iterator } , map ) do
481
+ defp iterator_empty_difference_subtype ?( { key , v1 , iterator } , map ) do
474
482
case map do
475
483
% { ^ key => v2 } ->
476
484
value = difference ( key , v1 , v2 )
@@ -479,15 +487,14 @@ defmodule Module.Types.Descr do
479
487
% { } ->
480
488
empty_key? ( key , v1 )
481
489
end and
482
- iterator_empty_difference_static ?( :maps . next ( iterator ) , map )
490
+ iterator_empty_difference_subtype ?( :maps . next ( iterator ) , map )
483
491
end
484
492
485
- defp iterator_empty_difference_static ?( :none , _map ) , do: true
493
+ defp iterator_empty_difference_subtype ?( :none , _map ) , do: true
486
494
487
495
# Returning 0 from the callback is taken as none() for that subtype.
488
496
defp difference ( :atom , v1 , v2 ) , do: atom_difference ( v1 , v2 )
489
497
defp difference ( :bitmap , v1 , v2 ) , do: v1 - ( v1 &&& v2 )
490
- defp difference ( :dynamic , v1 , v2 ) , do: dynamic_difference ( v1 , v2 )
491
498
defp difference ( :list , v1 , v2 ) , do: list_difference ( v1 , v2 )
492
499
defp difference ( :map , v1 , v2 ) , do: map_difference ( v1 , v2 )
493
500
defp difference ( :optional , 1 , 1 ) , do: 0
@@ -535,7 +542,6 @@ defmodule Module.Types.Descr do
535
542
defp empty_key? ( :map , value ) , do: map_empty? ( value )
536
543
defp empty_key? ( :list , value ) , do: list_empty? ( value )
537
544
defp empty_key? ( :tuple , value ) , do: tuple_empty? ( value )
538
- defp empty_key? ( :dynamic , value ) , do: empty? ( value )
539
545
defp empty_key? ( _ , _value ) , do: false
540
546
541
547
@ doc """
@@ -662,7 +668,7 @@ defmodule Module.Types.Descr do
662
668
end
663
669
664
670
defp subtype_static? ( same , same ) , do: true
665
- defp subtype_static? ( left , right ) , do: empty_difference_static ?( left , right )
671
+ defp subtype_static? ( left , right ) , do: empty_difference_subtype ?( left , right )
666
672
667
673
@ doc """
668
674
Check if a type is equal to another.
@@ -2116,13 +2122,6 @@ defmodule Module.Types.Descr do
2116
2122
defp dynamic_intersection ( left , right ) ,
2117
2123
do: symmetrical_intersection ( unfold ( left ) , unfold ( right ) , & intersection / 3 )
2118
2124
2119
- defp dynamic_difference ( left , right ) do
2120
- case difference_static ( left , right ) do
2121
- value when value == @ none -> 0
2122
- value -> value
2123
- end
2124
- end
2125
-
2126
2125
defp dynamic_to_quoted ( descr , opts ) do
2127
2126
cond do
2128
2127
descr == % { } ->
0 commit comments