Skip to content

Commit 90f504e

Browse files
committed
Deprecate usage around __struct__/0
1 parent 5128922 commit 90f504e

File tree

3 files changed

+25
-37
lines changed

3 files changed

+25
-37
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5565,27 +5565,8 @@ defmodule Kernel do
55655565
# it is the bootstrapped version or not.
55665566
Elixir.Kernel.@(impl(true))
55675567

5568-
# TODO: Change the implementation on v2.0 to simply call Kernel.struct!/2
55695568
def exception(args) when Kernel.is_list(args) do
5570-
struct = __struct__()
5571-
{valid, invalid} = Enum.split_with(args, fn {k, _} -> Map.has_key?(struct, k) end)
5572-
5573-
case invalid do
5574-
[] ->
5575-
:ok
5576-
5577-
_ ->
5578-
IO.warn(
5579-
"the following fields are unknown when raising " <>
5580-
"#{Kernel.inspect(__MODULE__)}: #{Kernel.inspect(invalid)}. " <>
5581-
"Please make sure to only give known fields when raising " <>
5582-
"or redefine #{Kernel.inspect(__MODULE__)}.exception/1 to " <>
5583-
"discard unknown fields. Future Elixir versions will raise on " <>
5584-
"unknown fields given to raise/2"
5585-
)
5586-
end
5587-
5588-
Kernel.struct!(struct, valid)
5569+
struct!(__MODULE__, args)
55895570
end
55905571

55915572
defoverridable exception: 1

lib/elixir/lib/map.ex

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,25 +1011,22 @@ defmodule Map do
10111011
@doc """
10121012
Converts a `struct` to map.
10131013
1014-
It accepts the struct module or a struct itself and
1015-
simply removes the `__struct__` field from the given struct
1016-
or from a new struct generated from the given module.
1014+
It accepts a struct and simply removes the `__struct__` field
1015+
from the given struct.
10171016
10181017
## Example
10191018
10201019
defmodule User do
10211020
defstruct [:name]
10221021
end
10231022
1024-
Map.from_struct(User)
1025-
#=> %{name: nil}
1026-
10271023
Map.from_struct(%User{name: "john"})
10281024
#=> %{name: "john"}
10291025
10301026
"""
10311027
@spec from_struct(atom | struct) :: map
10321028
def from_struct(struct) when is_atom(struct) do
1029+
IO.warn("Map.from_struct/1 with a module is deprecated, please pass a struct instead")
10331030
delete(struct.__struct__(), :__struct__)
10341031
end
10351032

lib/ex_unit/lib/ex_unit/diff.ex

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -702,15 +702,13 @@ defmodule ExUnit.Diff do
702702
# Structs
703703

704704
defp diff_quoted_struct(kw, right, env) do
705-
struct1 = kw[:__struct__]
706-
left = load_struct(kw[:__struct__])
707-
708-
if left && Enum.all?(kw, fn {k, _} -> Map.has_key?(left, k) end) do
705+
if struct = struct_module(kw) do
709706
with true <- Macro.quoted_literal?(kw),
710-
{eval_kw, []} <- safe_eval(kw) do
711-
diff_quoted_struct(struct!(left, eval_kw), kw, right, struct1, env)
707+
{eval_kw, []} <- safe_eval(kw),
708+
{:ok, data} <- load_struct(struct, eval_kw) do
709+
diff_quoted_struct(data, kw, right, struct, env)
712710
else
713-
_ -> diff_map(kw, right, struct1, maybe_struct(right), env)
711+
_ -> diff_map(kw, right, struct, maybe_struct(right), env)
714712
end
715713
else
716714
diff_map(kw, right, nil, maybe_struct(right), env)
@@ -746,13 +744,25 @@ defmodule ExUnit.Diff do
746744
end
747745
end
748746

749-
defp load_struct(struct) do
750-
if is_atom(struct) and struct != nil and
751-
Code.ensure_loaded?(struct) and function_exported?(struct, :__struct__, 0) do
752-
struct.__struct__()
747+
defp struct_module(kw) do
748+
{struct, struct_kw} = Keyword.pop(kw, :__struct__)
749+
750+
info =
751+
is_atom(struct) and struct != nil and
752+
Code.ensure_loaded?(struct) and function_exported?(struct, :__info__, 1) and
753+
struct.__info__(:struct)
754+
755+
if info && Enum.all?(struct_kw, fn {k, _} -> Enum.any?(info, &(&1.field == k)) end) do
756+
struct
753757
end
754758
end
755759

760+
defp load_struct(struct, kw) do
761+
{:ok, struct!(struct, kw)}
762+
rescue
763+
_ -> :error
764+
end
765+
756766
defp maybe_struct(%name{}), do: name
757767
defp maybe_struct(_), do: nil
758768

0 commit comments

Comments
 (0)