Skip to content

Commit 5e715aa

Browse files
sneakoJosé Valim
authored andcommitted
User defined types with the name record fail to compile in 1.8.0-rc.0 (#8569)
Closes #8564 This is my first attempt to contribute code to elixir, so please forgive me if this PR is completely naive. Besides adding the `is_list/1` guards, I have updated the error message to specify that record specifications must use an atom `literal` as the name, to make it clear that the type `atom` is also not valid. Signed-off-by: José Valim <[email protected]>
1 parent 9b54efb commit 5e715aa

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

lib/elixir/lib/kernel/typespec.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,12 @@ defmodule Kernel.Typespec do
578578
end
579579

580580
# Handle records
581-
defp typespec({:record, meta, [atom]}, vars, caller, state) when is_atom(atom) do
581+
defp typespec({:record, meta, [atom]}, vars, caller, state) do
582582
typespec({:record, meta, [atom, []]}, vars, caller, state)
583583
end
584584

585-
defp typespec({:record, meta, [tag, field_specs]}, vars, caller, state) when is_atom(tag) do
585+
defp typespec({:record, meta, [tag, field_specs]}, vars, caller, state)
586+
when is_atom(tag) and is_list(field_specs) do
586587
# We cannot set a function name to avoid tracking
587588
# as a compile time dependency because for records it actually is one.
588589
case Macro.expand({tag, [], [{:{}, [], []}]}, caller) do
@@ -607,8 +608,9 @@ defmodule Kernel.Typespec do
607608
end
608609
end
609610

610-
defp typespec({:record, _meta, _args}, _vars, caller, _state) do
611-
compile_error(caller, "invalid record specification, expected the record name to be an atom")
611+
defp typespec({:record, _meta, [_tag, _field_specs]}, _vars, caller, _state) do
612+
message = "invalid record specification, expected the record name to be an atom literal"
613+
compile_error(caller, message)
612614
end
613615

614616
# Handle ranges

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,14 +571,25 @@ defmodule TypespecTest do
571571
end
572572
end
573573

574-
test "@type with invalid record" do
575-
assert_raise CompileError, ~r"invalid record specification", fn ->
574+
test "@type with a record which declares the name as the type `atom` rather than an atom literal" do
575+
assert_raise CompileError, ~r"expected the record name to be an atom literal", fn ->
576576
test_module do
577-
@type my_type :: record(atom)
577+
@type my_type :: record(atom, field: :foo)
578578
end
579579
end
580580
end
581581

582+
test "@type can be named record" do
583+
bytecode =
584+
test_module do
585+
@type record :: binary
586+
@spec foo?(record) :: boolean
587+
def foo?(_), do: true
588+
end
589+
590+
assert [type: {:record, {:type, _, :binary, []}, []}] = types(bytecode)
591+
end
592+
582593
test "@type with an invalid map notation" do
583594
assert_raise CompileError, ~r"invalid map specification", fn ->
584595
test_module do

0 commit comments

Comments
 (0)