Skip to content

Commit 77426cc

Browse files
authored
Handle Erlang/OTP 28 nominal types in Code.Typespec.fetch_types/1 (#15562)
1 parent ecf5517 commit 77426cc

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

lib/elixir/lib/code/typespec.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ defmodule Code.Typespec do
8080
Returns all types available from the module's BEAM code.
8181
8282
The result is returned as a list of tuples where the first
83-
element is the type (`:typep`, `:type` and `:opaque`).
83+
element is the type (`:typep`, `:type`, `:opaque` and, on Erlang/OTP 28+,
84+
`:nominal`).
8485
8586
The module must have a corresponding BEAM file which can be
8687
located by the runtime system. The types will be in the Erlang
@@ -95,9 +96,10 @@ defmodule Code.Typespec do
9596

9697
types =
9798
for {:attribute, _, kind, {name, _, args} = type} <- abstract_code,
98-
kind in [:opaque, :type] do
99+
kind in [:opaque, :type, :nominal] do
99100
cond do
100101
kind == :opaque -> {:opaque, type}
102+
kind == :nominal -> {:nominal, type}
101103
{name, length(args)} in exported_types -> {:type, type}
102104
true -> {:typep, type}
103105
end

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,23 @@ defmodule TypespecTest do
14381438
assert Code.Typespec.fetch_specs(Unknown) == :error
14391439
end
14401440

1441+
if System.otp_release() >= "28" do
1442+
test "retrieval of Erlang nominal types" do
1443+
forms = [
1444+
{:attribute, 1, :module, :typespec_nominal_sample},
1445+
{:attribute, 2, :export_type, [meters: 0]},
1446+
{:attribute, 3, :nominal, {:meters, {:type, 3, :integer, []}, []}},
1447+
{:attribute, 4, :type, {:plain, {:type, 4, :atom, []}, []}}
1448+
]
1449+
1450+
{:ok, :typespec_nominal_sample, beam} = :compile.forms(forms, [:debug_info])
1451+
1452+
assert {:ok, types} = Code.Typespec.fetch_types(beam)
1453+
assert {:nominal, {:meters, {:type, 3, :integer, []}, []}} in types
1454+
assert {:typep, {:plain, {:type, 4, :atom, []}, []}} in types
1455+
end
1456+
end
1457+
14411458
# This is a test that implements all types specified in lib/elixir/pages/typespecs.md
14421459
test "documented types and their AST" do
14431460
defmodule SomeStruct do

0 commit comments

Comments
 (0)