Skip to content

Commit e9d13d5

Browse files
author
José Valim
committed
Ensure proper @type is generated for dynamic struct
1 parent 25a5dbc commit e9d13d5

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3316,6 +3316,15 @@ defmodule Kernel do
33163316

33173317
types =
33183318
case bootstraped?(Kernel.Typespec) do
3319+
true when types == [] ->
3320+
quote unquote: false do
3321+
unless Kernel.Typespec.defines_type?(__MODULE__, :t, 0) do
3322+
types = Enum.map(fields, fn {key, _} ->
3323+
{key, quote(do: term)}
3324+
end)
3325+
@type t :: %{unquote_splicing(types), __struct__: __MODULE__}
3326+
end
3327+
end
33193328
true ->
33203329
quote do
33213330
unless Kernel.Typespec.defines_type?(__MODULE__, :t, 0) do
@@ -3326,7 +3335,10 @@ defmodule Kernel do
33263335
nil
33273336
end
33283337

3329-
[types, fields]
3338+
quote do
3339+
unquote(fields)
3340+
unquote(types)
3341+
end
33303342
end
33313343

33323344
@doc ~S"""

lib/elixir/test/elixir/kernel/typespec_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,20 @@ defmodule Kernel.TypespecTest do
282282
]}, []}] = types
283283
end
284284

285+
test "@type from dynamic structs" do
286+
types = test_module do
287+
fields = [name: nil, age: 0]
288+
defstruct fields
289+
@type
290+
end
291+
292+
assert [{:t, {:type, _, :map, [
293+
{:type, _, :map_field_assoc, {:atom, _, :name}, {:type, _, :term, []}},
294+
{:type, _, :map_field_assoc, {:atom, _, :age}, {:type, _, :term, []}},
295+
{:type, _, :map_field_assoc, {:atom, _, :__struct__}, {:atom, _, Kernel.TypespecTest.T}}
296+
]}, []}] = types
297+
end
298+
285299
test "@type unquote fragment" do
286300
spec = test_module do
287301
quoted = quote unquote: false do

0 commit comments

Comments
 (0)