@@ -428,7 +428,7 @@ defmodule Module.Types.Descr do
428
428
## Funs
429
429
430
430
@ doc """
431
- Checks there is precisely one function with said arity.
431
+ Checks there is a function type (and only functions) with said arity.
432
432
"""
433
433
def fun_fetch ( :term , _arity ) , do: :error
434
434
@@ -752,8 +752,14 @@ defmodule Module.Types.Descr do
752
752
753
753
defp map_fetch_static ( descr , key ) when is_atom ( key ) do
754
754
case descr do
755
- % { map: [ { :open , fields , [ ] } ] } when fields == % { } ->
756
- { true , term ( ) }
755
+ # Optimization: if the key does not exist in the map,
756
+ # avoid building if_set/not_set pairs and return the
757
+ # popped value directly.
758
+ % { map: [ { tag , fields , [ ] } ] } when not is_map_key ( fields , key ) ->
759
+ case tag do
760
+ :open -> { true , term ( ) }
761
+ :closed -> { true , none ( ) }
762
+ end
757
763
758
764
% { map: map } ->
759
765
map_split_on_key ( map , key )
@@ -930,19 +936,24 @@ defmodule Module.Types.Descr do
930
936
# Takes a map dnf and a key and returns a list of unions of types
931
937
# for that key. It has to traverse both fields and negative entries.
932
938
defp map_split_on_key ( dnf , key ) do
933
- Enum . flat_map ( dnf , fn { tag , fields , negs } ->
934
- # %{...} the open map in a positive intersection can be ignored
935
- { fst , snd } =
936
- if tag == :open and fields == % { } do
937
- { term_or_optional ( ) , term_or_optional ( ) }
938
- else
939
- map_pop_key ( tag , fields , key )
939
+ Enum . flat_map ( dnf , fn
940
+ # Optimization: if there are no negatives,
941
+ # we can return the value directly.
942
+ { _tag , % { ^ key => value } , [ ] } ->
943
+ [ value ]
944
+
945
+ # Optimization: if there are no negatives
946
+ # and the key does not exist, return the default one.
947
+ { tag , % { } , [ ] } ->
948
+ [ map_tag_to_type ( tag ) ]
949
+
950
+ { tag , fields , negs } ->
951
+ { fst , snd } = map_pop_key ( tag , fields , key )
952
+
953
+ case map_split_negative ( negs , key , [ ] ) do
954
+ :empty -> [ ]
955
+ negative -> negative |> pair_make_disjoint ( ) |> pair_eliminate_negations ( fst , snd )
940
956
end
941
-
942
- case map_split_negative ( negs , key , [ ] ) do
943
- :empty -> [ ]
944
- negative -> negative |> pair_make_disjoint ( ) |> pair_eliminate_negations ( fst , snd )
945
- end
946
957
end )
947
958
end
948
959
0 commit comments