diff options
author | José Valim <jose.valim@plataformatec.com.br> | 2020-01-03 17:18:22 +0100 |
---|---|---|
committer | José Valim <jose.valim@plataformatec.com.br> | 2020-01-03 17:18:27 +0100 |
commit | 5dd271d361bab1a86ddc72ac9512388d99d65744 (patch) | |
tree | 88b6d89502cf570b8c3ac871991aaee252f9e9ba | |
parent | 3b168073743c2c7ae963e2a8cd1ccadad1a27eca (diff) | |
download | elixir-5dd271d361bab1a86ddc72ac9512388d99d65744.tar.gz |
Fix bounded funs in macrocallbacks, closes #9687
-rw-r--r-- | lib/elixir/src/elixir_erl.erl | 5 | ||||
-rw-r--r-- | lib/elixir/test/elixir/typespec_test.exs | 8 | ||||
-rw-r--r-- | lib/iex/lib/iex/introspection.ex | 14 | ||||
-rw-r--r-- | lib/iex/test/iex/helpers_test.exs | 7 |
4 files changed, 20 insertions, 14 deletions
diff --git a/lib/elixir/src/elixir_erl.erl b/lib/elixir/src/elixir_erl.erl index 628842a40..1764cce8b 100644 --- a/lib/elixir/src/elixir_erl.erl +++ b/lib/elixir/src/elixir_erl.erl @@ -415,9 +415,10 @@ callspecs_form(Kind, Entries, Optional, Macros, Forms, ModuleMap) -> end end, Forms, lists:sort(Signatures)). +spec_for_macro({type, Line, 'bounded_fun', [H | T]}) -> + {type, Line, 'bounded_fun', [spec_for_macro(H) | T]}; spec_for_macro({type, Line, 'fun', [{type, _, product, Args} | T]}) -> - NewArgs = [{type, Line, term, []} | Args], - {type, Line, 'fun', [{type, Line, product, NewArgs} | T]}; + {type, Line, 'fun', [{type, Line, product, [{type, Line, term, []} | Args]} | T]}; spec_for_macro(Else) -> Else. diff --git a/lib/elixir/test/elixir/typespec_test.exs b/lib/elixir/test/elixir/typespec_test.exs index 1a48f180c..e9f1257f4 100644 --- a/lib/elixir/test/elixir/typespec_test.exs +++ b/lib/elixir/test/elixir/typespec_test.exs @@ -999,8 +999,8 @@ defmodule TypespecTest do @spec spec1 :: boolean def spec1, do: @spec - @callback callback2 :: boolean - @macrocallback macrocallback2 :: boolean + @callback callback2 :: var when var: boolean + @macrocallback macrocallback2 :: var when var: boolean @spec spec2 :: atom def spec2, do: @spec @@ -1029,14 +1029,14 @@ defmodule TypespecTest do ] = SpecModuleAttributes.spec4() assert [ - {:callback, {:"::", _, [{:callback2, _, _}, {:boolean, _, _}]}, + {:callback, {:when, _, [{:"::", _, [{:callback2, _, _}, {:var, _, _}]}, [var: {:boolean, _, _}]]}, {SpecModuleAttributes, _}}, {:callback, {:"::", _, [{:callback1, _, _}, {:integer, _, _}]}, {SpecModuleAttributes, _}} ] = SpecModuleAttributes.callback() assert [ - {:macrocallback, {:"::", _, [{:macrocallback2, _, _}, {:boolean, _, _}]}, + {:macrocallback, {:when, _, [{:"::", _, [{:macrocallback2, _, _}, {:var, _, _}]}, [var: {:boolean, _, _}]]}, {SpecModuleAttributes, _}}, {:macrocallback, {:"::", _, [{:macrocallback1, _, _}, {:integer, _, _}]}, {SpecModuleAttributes, _}} diff --git a/lib/iex/lib/iex/introspection.ex b/lib/iex/lib/iex/introspection.ex index 2eaa85b95..05b52d70b 100644 --- a/lib/iex/lib/iex/introspection.ex +++ b/lib/iex/lib/iex/introspection.ex @@ -576,11 +576,7 @@ defmodule IEx.Introspection do # * The arguments contain an additional first argument: the caller # * The arity is increased by 1 # - specs = - Enum.map(specs, fn {:type, line1, :fun, [{:type, line2, :product, [_ | args]}, spec]} -> - {:type, line1, :fun, [{:type, line2, :product, args}, spec]} - end) - + specs = Enum.map(specs, &unpack_caller/1) {kind_name_arity, specs} kind_name_arity -> @@ -588,6 +584,14 @@ defmodule IEx.Introspection do end end + defp unpack_caller({:type, line1, :fun, [{:type, line2, :product, [_ | args]} | tail]}) do + {:type, line1, :fun, [{:type, line2, :product, args} | tail]} + end + + defp unpack_caller({:type, line, :bounded_fun, [head | tail]}) do + {:type, line, :bounded_fun, [unpack_caller(head) | tail]} + end + def translate_callback_name_arity({name, arity}) do case Atom.to_string(name) do "MACRO-" <> macro_name -> {:macrocallback, String.to_atom(macro_name), arity - 1} diff --git a/lib/iex/test/iex/helpers_test.exs b/lib/iex/test/iex/helpers_test.exs index 4fb923c5d..5d8dab003 100644 --- a/lib/iex/test/iex/helpers_test.exs +++ b/lib/iex/test/iex/helpers_test.exs @@ -644,14 +644,15 @@ defmodule IEx.HelpersTest do content = """ defmodule Macrocallbacks do @macrocallback test(:foo) :: integer + @macrocallback test(:bar) :: var when var: integer end """ with_file(filename, content, fn -> assert c(filename, ".") == [Macrocallbacks] - - assert capture_io(fn -> b(Macrocallbacks) end) =~ - "@macrocallback test(:foo) :: integer()\n\n" + callbacks = capture_io(fn -> b(Macrocallbacks) end) + assert callbacks =~ "@macrocallback test(:foo) :: integer()\n" + assert callbacks =~ "@macrocallback test(:bar) :: var when var: integer()\n" end) after cleanup_modules([Macrocallbacks]) |