diff options
author | Eric Meadows-Jönsson <eric.meadows.jonsson@gmail.com> | 2020-07-06 15:42:22 +0200 |
---|---|---|
committer | Eric Meadows-Jönsson <eric.meadows.jonsson@gmail.com> | 2020-07-06 15:43:23 +0200 |
commit | 1bc87cd117ee8762bfa267985aec2b3dcd7a673b (patch) | |
tree | ef4c7e83570f4b011c5a21961720002177fd70ba | |
parent | 9ff09855990c6336f030138939a95be6d3a1bb07 (diff) | |
download | elixir-emj/is-map-key-optional.tar.gz |
is_map_key/2 should add optional keysemj/is-map-key-optional
Closes #10148.
-rw-r--r-- | lib/elixir/lib/module/types/pattern.ex | 2 | ||||
-rw-r--r-- | lib/elixir/test/elixir/module/types_test.exs | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/lib/elixir/lib/module/types/pattern.ex b/lib/elixir/lib/module/types/pattern.ex index aeaea3e2d..907875fb0 100644 --- a/lib/elixir/lib/module/types/pattern.ex +++ b/lib/elixir/lib/module/types/pattern.ex @@ -267,7 +267,7 @@ defmodule Module.Types.Pattern do {:is_integer, 1} => {[:integer], :boolean}, {:is_list, 1} => {[{:list, :dynamic}], :boolean}, {:is_map, 1} => {[{:map, [{:optional, :dynamic, :dynamic}]}], :boolean}, - {:is_map_key, 2} => {[:dynamic, {:map, []}], :dynamic}, + {:is_map_key, 2} => {[:dynamic, {:map, [{:optional, :dynamic, :dynamic}]}], :dynamic}, {:is_number, 1} => {[:number], :boolean}, {:is_pid, 1} => {[:pid], :boolean}, {:is_port, 1} => {[:port], :boolean}, diff --git a/lib/elixir/test/elixir/module/types_test.exs b/lib/elixir/test/elixir/module/types_test.exs index a4b7f04d4..b3bee2304 100644 --- a/lib/elixir/test/elixir/module/types_test.exs +++ b/lib/elixir/test/elixir/module/types_test.exs @@ -19,6 +19,20 @@ defmodule Module.TypesTest do end end + defmacrop quoted_fun(patterns, guards \\ [true], body) do + quote do + {patterns, guards, body} = unquote(Macro.escape(expand_expr(patterns, guards, body))) + + with {:ok, _types, context} <- Types.of_head(patterns, guards, def_expr(), new_context()), + {:ok, type, context} <- Types.of_body(body, context) do + {:ok, Types.lift_type(type, context)} + else + {:error, {Types, reason, location}} -> + {:error, {reason, location}} + end + end + end + defp expand_head(patterns, guards) do {_, vars} = Macro.prewalk(patterns, [], fn @@ -42,6 +56,17 @@ defmodule Module.TypesTest do {patterns, guards} end + defp expand_expr(patterns, guards, body) do + fun = + quote do + fn unquote(patterns) when unquote(guards) -> unquote(body) end + end + + {ast, _env} = :elixir_expand.expand(fun, __ENV__) + {:fn, _, [{:->, _, [[{:when, _, [patterns, guards]}], body]}]} = ast + {patterns, guards, body} + end + defp new_context() do Types.context("types_test.ex", TypesTest, {:test, 0}) end @@ -249,6 +274,12 @@ defmodule Module.TypesTest do end end + describe "of_body/2" do + test "not is_struct/2" do + assert quoted_fun([var], [not is_struct(var, URI)], var.name) == {:ok, {:var, 0}} + end + end + test "format_type/1" do assert Types.format_type(:binary) == "binary()" assert Types.format_type({:atom, true}) == "true" |