Skip to content

Commit c654159

Browse files
author
José Valim
committed
Do not support inline types with defrecord
1 parent 6715c52 commit c654159

File tree

4 files changed

+16
-46
lines changed

4 files changed

+16
-46
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,11 +1476,11 @@ defmodule Kernel do
14761476
## Types
14771477
14781478
Every record defines a type named `t` that can be accessed in typespecs.
1479-
Those types can be specified when the record is defined:
1479+
Those types can be specified inside the record definition:
14801480
1481-
defrecord User,
1482-
name: "" :: string,
1483-
age: 0 :: integer
1481+
defrecord User do
1482+
record_type name: string, age: integer
1483+
end
14841484
14851485
All fields without a specified type are assumed to have type `term`.
14861486
@@ -1489,22 +1489,6 @@ defmodule Kernel do
14891489
14901490
@spec handle_user(User.t) :: boolean()
14911491
1492-
If the developer wants to define their own types to be used with the
1493-
record, Elixir allows a more lengthy definition with the help of the
1494-
`record_type` macro:
1495-
1496-
defrecord Config, counter: 0, failures: [] do
1497-
@type kind :: term
1498-
record_type counter: integer, failures: [kind]
1499-
end
1500-
1501-
1502-
This macro defines a module that generates accessors to manipulate the record
1503-
at both compilation and runtime.
1504-
1505-
See the `Record` module's documentation for a detailed description of records
1506-
in Elixir.
1507-
15081492
## Runtime introspection
15091493
15101494
At runtime, developers can use `__record__` to get information

lib/elixir/lib/record.ex

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ defmodule Record do
221221
end
222222

223223
@doc false
224-
def defrecord(name, values, opts) do
224+
def defrecord(name, fields, opts) do
225225
block = Keyword.get(opts, :do, nil)
226-
{ fields, types } = record_split(values)
226+
record_check!(fields)
227227

228228
quote do
229229
unquoted_fields = unquote(fields)
@@ -232,7 +232,7 @@ defmodule Record do
232232
import Elixir.Record.DSL
233233

234234
@record_fields []
235-
@record_types unquote(types)
235+
@record_types []
236236

237237
Elixir.Record.deffunctions(unquoted_fields, __ENV__)
238238
value = unquote(block)
@@ -242,25 +242,13 @@ defmodule Record do
242242
end
243243
end
244244

245-
defp record_split(fields) when is_list(fields) do
246-
record_split(fields, [], [])
245+
defp record_check!([{ field, { :::, _, [_, _] }}|_]) when is_atom(field) do
246+
raise ArgumentError, message: "typespecs are not supported inlined with defrecord, " <>
247+
"please use record_type instead"
247248
end
248249

249-
defp record_split(other) do
250-
{ other, [] }
251-
end
252-
253-
defp record_split([{ field, { :::, _, [default, type] }}|t], defaults, types) do
254-
record_split t, [{ field, default }|defaults], [{ field, Macro.escape(type) }|types]
255-
end
256-
257-
defp record_split([other|t], defaults, types) do
258-
record_split t, [other|defaults], types
259-
end
260-
261-
defp record_split([], defaults, types) do
262-
{ :lists.reverse(defaults), types }
263-
end
250+
defp record_check!([_|t]), do: record_check!(t)
251+
defp record_check!(_), do: :ok
264252

265253
@doc false
266254
def defrecordp(name, tag, fields) when is_atom(name) and is_atom(tag) and is_list(fields) do

lib/elixir/test/elixir/record_test.exs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ defrecord RecordTest.WithRecordType, a: 0, b: 1 do
4747
record_type a: integer
4848
end
4949

50-
defrecord RecordTest.WithInlineType, a: nil :: atom, b: 1 :: integer
51-
5250
defmodule RecordTest.Macros do
5351
defmacro gen do
5452
quote do

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,25 @@ defmodule Typespec.TypeTest do
1818
end
1919

2020
test "invalid type specification" do
21-
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
21+
assert_raise CompileError, %r"invalid type specification mytype = 1", fn ->
2222
test_module do
2323
@type mytype = 1
2424
end
2525
end
26-
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
26+
assert_raise CompileError, %r"invalid type specification mytype = 1", fn ->
2727
test_module do
2828
@typep mytype = 1
2929
end
3030
end
31-
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
31+
assert_raise CompileError, %r"invalid type specification mytype = 1", fn ->
3232
test_module do
3333
@opaque mytype = 1
3434
end
3535
end
3636
end
3737

3838
test "invalid function specification" do
39-
assert_raise ArgumentError, "invalid function type specification myfun = 1", fn ->
39+
assert_raise CompileError, %r"invalid function type specification myfun = 1", fn ->
4040
test_module do
4141
@spec myfun = 1
4242
end

0 commit comments

Comments
 (0)