Skip to content

Commit 5dd271d

Browse files
author
José Valim
committed
Fix bounded funs in macrocallbacks, closes #9687
1 parent 3b16807 commit 5dd271d

File tree

4 files changed

+20
-14
lines changed

4 files changed

+20
-14
lines changed

lib/elixir/src/elixir_erl.erl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,10 @@ callspecs_form(Kind, Entries, Optional, Macros, Forms, ModuleMap) ->
415415
end
416416
end, Forms, lists:sort(Signatures)).
417417

418+
spec_for_macro({type, Line, 'bounded_fun', [H | T]}) ->
419+
{type, Line, 'bounded_fun', [spec_for_macro(H) | T]};
418420
spec_for_macro({type, Line, 'fun', [{type, _, product, Args} | T]}) ->
419-
NewArgs = [{type, Line, term, []} | Args],
420-
{type, Line, 'fun', [{type, Line, product, NewArgs} | T]};
421+
{type, Line, 'fun', [{type, Line, product, [{type, Line, term, []} | Args]} | T]};
421422
spec_for_macro(Else) ->
422423
Else.
423424

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -999,8 +999,8 @@ defmodule TypespecTest do
999999
@spec spec1 :: boolean
10001000
def spec1, do: @spec
10011001

1002-
@callback callback2 :: boolean
1003-
@macrocallback macrocallback2 :: boolean
1002+
@callback callback2 :: var when var: boolean
1003+
@macrocallback macrocallback2 :: var when var: boolean
10041004

10051005
@spec spec2 :: atom
10061006
def spec2, do: @spec
@@ -1029,14 +1029,14 @@ defmodule TypespecTest do
10291029
] = SpecModuleAttributes.spec4()
10301030

10311031
assert [
1032-
{:callback, {:"::", _, [{:callback2, _, _}, {:boolean, _, _}]},
1032+
{:callback, {:when, _, [{:"::", _, [{:callback2, _, _}, {:var, _, _}]}, [var: {:boolean, _, _}]]},
10331033
{SpecModuleAttributes, _}},
10341034
{:callback, {:"::", _, [{:callback1, _, _}, {:integer, _, _}]},
10351035
{SpecModuleAttributes, _}}
10361036
] = SpecModuleAttributes.callback()
10371037

10381038
assert [
1039-
{:macrocallback, {:"::", _, [{:macrocallback2, _, _}, {:boolean, _, _}]},
1039+
{:macrocallback, {:when, _, [{:"::", _, [{:macrocallback2, _, _}, {:var, _, _}]}, [var: {:boolean, _, _}]]},
10401040
{SpecModuleAttributes, _}},
10411041
{:macrocallback, {:"::", _, [{:macrocallback1, _, _}, {:integer, _, _}]},
10421042
{SpecModuleAttributes, _}}

lib/iex/lib/iex/introspection.ex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -576,18 +576,22 @@ defmodule IEx.Introspection do
576576
# * The arguments contain an additional first argument: the caller
577577
# * The arity is increased by 1
578578
#
579-
specs =
580-
Enum.map(specs, fn {:type, line1, :fun, [{:type, line2, :product, [_ | args]}, spec]} ->
581-
{:type, line1, :fun, [{:type, line2, :product, args}, spec]}
582-
end)
583-
579+
specs = Enum.map(specs, &unpack_caller/1)
584580
{kind_name_arity, specs}
585581

586582
kind_name_arity ->
587583
{kind_name_arity, specs}
588584
end
589585
end
590586

587+
defp unpack_caller({:type, line1, :fun, [{:type, line2, :product, [_ | args]} | tail]}) do
588+
{:type, line1, :fun, [{:type, line2, :product, args} | tail]}
589+
end
590+
591+
defp unpack_caller({:type, line, :bounded_fun, [head | tail]}) do
592+
{:type, line, :bounded_fun, [unpack_caller(head) | tail]}
593+
end
594+
591595
def translate_callback_name_arity({name, arity}) do
592596
case Atom.to_string(name) do
593597
"MACRO-" <> macro_name -> {:macrocallback, String.to_atom(macro_name), arity - 1}

lib/iex/test/iex/helpers_test.exs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,14 +644,15 @@ defmodule IEx.HelpersTest do
644644
content = """
645645
defmodule Macrocallbacks do
646646
@macrocallback test(:foo) :: integer
647+
@macrocallback test(:bar) :: var when var: integer
647648
end
648649
"""
649650

650651
with_file(filename, content, fn ->
651652
assert c(filename, ".") == [Macrocallbacks]
652-
653-
assert capture_io(fn -> b(Macrocallbacks) end) =~
654-
"@macrocallback test(:foo) :: integer()\n\n"
653+
callbacks = capture_io(fn -> b(Macrocallbacks) end)
654+
assert callbacks =~ "@macrocallback test(:foo) :: integer()\n"
655+
assert callbacks =~ "@macrocallback test(:bar) :: var when var: integer()\n"
655656
end)
656657
after
657658
cleanup_modules([Macrocallbacks])

0 commit comments

Comments
 (0)