Skip to content

Commit fb6dd0f

Browse files
committed
Remove map_update as we can implement as a has_key?+put
1 parent 66d44be commit fb6dd0f

File tree

4 files changed

+9
-86
lines changed

4 files changed

+9
-86
lines changed

lib/elixir/lib/module/types/descr.ex

+7-53
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ defmodule Module.Types.Descr do
377377
right_dynamic = Map.get(right, :dynamic, right)
378378

379379
if empty?(left_static) do
380-
not empty?(intersection(left_dynamic, right_dynamic))
380+
not disjoint?(left_dynamic, right_dynamic)
381381
else
382382
subtype_static(left_static, right_dynamic)
383383
end
@@ -787,52 +787,6 @@ defmodule Module.Types.Descr do
787787
end
788788
end
789789

790-
@doc """
791-
Updates the `key` with a given type, assuming that the key is present
792-
in the descr, and that it is exclusively a map (or dynamic).
793-
"""
794-
def map_update(:term, _key, _type), do: :badmap
795-
def map_update(descr, key, :term), do: map_update_static_value(descr, key, :term)
796-
797-
def map_update(descr, key, type) do
798-
case :maps.take(:dynamic, type) do
799-
:error -> map_update_static_value(descr, key, type)
800-
{dynamic, _static} -> dynamic(map_update_static_value(descr, key, dynamic))
801-
end
802-
end
803-
804-
def map_update_static_value(descr, key, type) do
805-
case :maps.take(:dynamic, descr) do
806-
:error ->
807-
cond do
808-
subtype?(descr, open_map([{key, term()}])) -> map_put_static(descr, key, type)
809-
map_only?(descr) -> :badkey
810-
true -> :badmap
811-
end
812-
813-
{dynamic, static} when static == @none ->
814-
if not disjoint?(dynamic, open_map([{key, term()}])) do
815-
dynamic(map_put_static(dynamic, key, type))
816-
else
817-
:badkey
818-
end
819-
820-
{dynamic, static} ->
821-
if not disjoint?(dynamic, open_map([{key, term()}])) and
822-
subtype?(static, open_map([{key, type}])) do
823-
dynamic = map_put_static(dynamic, key, type)
824-
static = map_put_static(static, key, type)
825-
Map.put(static, :dynamic, dynamic)
826-
else
827-
if map_only?(static) do
828-
:badkey
829-
else
830-
:badmap
831-
end
832-
end
833-
end
834-
end
835-
836790
@doc """
837791
Adds a `key` of a given type, assuming that the descr is exclusively
838792
a map (or dynamic).
@@ -847,26 +801,26 @@ defmodule Module.Types.Descr do
847801
end
848802
end
849803

850-
def map_put_static_value(descr, key, type) do
804+
defp map_put_static_value(descr, key, type) do
851805
case :maps.take(:dynamic, descr) do
852806
:error ->
853807
if map_only?(descr) do
854-
map_put_static(descr, key, type)
808+
map_put_static_descr(descr, key, type)
855809
else
856810
:badmap
857811
end
858812

859813
{dynamic, static} when static == @none ->
860814
if descr_key?(dynamic, :map) do
861-
dynamic(map_put_static(dynamic, key, type))
815+
dynamic(map_put_static_descr(dynamic, key, type))
862816
else
863817
:badmap
864818
end
865819

866820
{dynamic, static} ->
867821
if descr_key?(dynamic, :map) and map_only?(static) do
868-
dynamic = map_put_static(dynamic, key, type)
869-
static = map_put_static(static, key, type)
822+
dynamic = map_put_static_descr(dynamic, key, type)
823+
static = map_put_static_descr(static, key, type)
870824
union(dynamic(dynamic), static)
871825
else
872826
:badmap
@@ -875,7 +829,7 @@ defmodule Module.Types.Descr do
875829
end
876830

877831
# Directly inserts a key of a given type into every positive and negative map
878-
def map_put_static(descr, key, type) do
832+
defp map_put_static_descr(descr, key, type) do
879833
map_delete_static(descr, key)
880834
|> Map.update!(:map, fn dnf ->
881835
Enum.map(dnf, fn {tag, fields, negs} ->

lib/elixir/lib/module/types/expr.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ defmodule Module.Types.Expr do
152152
{:ok, struct_type, context} <-
153153
Of.struct(module, args_types, :only_defaults, struct_meta, stack, context),
154154
{:ok, map_type, context} <- of_expr(map, stack, context) do
155-
if empty?(intersection(struct_type, map_type)) do
155+
if disjoint?(struct_type, map_type) do
156156
warning = {:badupdate, :struct, expr, struct_type, map_type, context}
157157
{:ok, dynamic(), warn(__MODULE__, warning, update_meta, stack, context)}
158158
else

lib/elixir/lib/module/types/of.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ defmodule Module.Types.Of do
279279
number_type?(left) and number_type?(right) ->
280280
{:ok, result, context}
281281

282-
empty?(intersection(left, right)) ->
282+
disjoint?(left, right) ->
283283
warning = {:mismatched_comparison, expr, context}
284284
{:ok, result, warn(warning, elem(expr, 1), stack, context)}
285285

lib/elixir/test/elixir/module/types/descr_test.exs

-31
Original file line numberDiff line numberDiff line change
@@ -663,37 +663,6 @@ defmodule Module.Types.DescrTest do
663663
assert equal?(type, atom())
664664
end
665665

666-
test "map_update" do
667-
assert map_update(empty_map(), :a, term()) == :badkey
668-
assert map_update(open_map(), :a, term()) == :badkey
669-
assert map_update(term(), :a, term()) == :badmap
670-
assert map_update(closed_map(a: integer()), :b, atom()) == :badkey
671-
assert map_update(open_map(a: integer()), :b, float()) == :badkey
672-
assert map_update(closed_map(a: if_set(integer())), :b, atom()) == :badkey
673-
assert map_update(union(dynamic(), empty_map()), :a, atom()) == :badkey
674-
assert map_update(closed_map(a: integer()), :a, atom()) == closed_map(a: atom())
675-
assert map_update(open_map(a: integer()), :a, atom()) |> equal?(open_map(a: atom()))
676-
assert map_update(dynamic(open_map()), :a, integer()) == dynamic(open_map(a: integer()))
677-
678-
assert closed_map(a: if_set(atom()), b: float())
679-
|> union(open_map(a: atom()))
680-
|> map_update(:a, integer()) ==
681-
:badkey
682-
683-
assert closed_map(a: if_set(atom()), b: float())
684-
|> union(open_map(a: atom()))
685-
|> difference(open_map(a: if_set(float())))
686-
|> map_update(:a, integer())
687-
|> map_fetch(:a) == {false, integer()}
688-
689-
assert map_update(difference(open_map(), open_map(a: not_set())), :a, fun()) ==
690-
open_map(a: fun())
691-
692-
# Update a key-value pair with dynamic type
693-
# Note: setting a field to a dynamic type makes the whole map become dynamic.
694-
assert map_update(open_map(a: atom()), :a, dynamic()) |> equal?(dynamic(open_map(a: term())))
695-
end
696-
697666
describe "disjoint" do
698667
test "map" do
699668
refute disjoint?(open_map(), open_map(a: integer()))

0 commit comments

Comments
 (0)