@@ -464,6 +464,26 @@ defmodule Module.Types.Descr do
464464
465465 defp iterator_difference_static ( :none , map ) , do: map
466466
467+ defp empty_difference_static? ( left , :term ) , do: not Map . has_key? ( left , :optional )
468+
469+ defp empty_difference_static? ( left , right ) do
470+ iterator_empty_difference_static? ( :maps . next ( :maps . iterator ( unfold ( left ) ) ) , unfold ( right ) )
471+ end
472+
473+ defp iterator_empty_difference_static? ( { key , v1 , iterator } , map ) do
474+ case map do
475+ % { ^ key => v2 } ->
476+ value = difference ( key , v1 , v2 )
477+ value in @ empty_difference or empty_key? ( key , value )
478+
479+ % { } ->
480+ empty_key? ( key , v1 )
481+ end and
482+ iterator_empty_difference_static? ( :maps . next ( iterator ) , map )
483+ end
484+
485+ defp iterator_empty_difference_static? ( :none , _map ) , do: true
486+
467487 # Returning 0 from the callback is taken as none() for that subtype.
468488 defp difference ( :atom , v1 , v2 ) , do: atom_difference ( v1 , v2 )
469489 defp difference ( :bitmap , v1 , v2 ) , do: v1 - ( v1 &&& v2 )
@@ -491,7 +511,7 @@ defmodule Module.Types.Descr do
491511 def empty? ( :term ) , do: false
492512
493513 def empty? ( % { } = descr ) do
494- case :maps . get ( :dynamic , descr , _default = descr ) do
514+ case :maps . get ( :dynamic , descr , descr ) do
495515 :term ->
496516 false
497517
@@ -511,9 +531,11 @@ defmodule Module.Types.Descr do
511531
512532 # For atom, bitmap, and optional, if the key is present,
513533 # then they are not empty,
534+ defp empty_key? ( :fun , value ) , do: fun_empty? ( value )
514535 defp empty_key? ( :map , value ) , do: map_empty? ( value )
515536 defp empty_key? ( :list , value ) , do: list_empty? ( value )
516537 defp empty_key? ( :tuple , value ) , do: tuple_empty? ( value )
538+ defp empty_key? ( :dynamic , value ) , do: empty? ( value )
517539 defp empty_key? ( _ , _value ) , do: false
518540
519541 @ doc """
@@ -640,7 +662,7 @@ defmodule Module.Types.Descr do
640662 end
641663
642664 defp subtype_static? ( same , same ) , do: true
643- defp subtype_static? ( left , right ) , do: empty? ( difference_static ( left , right ) )
665+ defp subtype_static? ( left , right ) , do: empty_difference_static? ( left , right )
644666
645667 @ doc """
646668 Check if a type is equal to another.
0 commit comments