diff --git a/lib/elixir/lib/inspect.ex b/lib/elixir/lib/inspect.ex index bc7cb170f0d..6407ac6adbf 100644 --- a/lib/elixir/lib/inspect.ex +++ b/lib/elixir/lib/inspect.ex @@ -455,6 +455,9 @@ defimpl Inspect, for: Any do only = Keyword.get(options, :only, fields) except = Keyword.get(options, :except, []) + :ok = validate_option(only, fields, module) + :ok = validate_option(except, fields, module) + filtered_fields = fields |> Enum.reject(&(&1 in except)) @@ -478,6 +481,17 @@ defimpl Inspect, for: Any do end end + defp validate_option(option_list, fields, module) do + case option_list -- fields do + [] -> + :ok + + unknown_fields -> + raise ArgumentError, + "unknown fields #{Kernel.inspect(unknown_fields)} given when deriving the Inspect protocol for #{Kernel.inspect(module)}. :only and :except values must match struct fields" + end + end + def inspect(%module{} = struct, opts) do try do module.__struct__() diff --git a/lib/elixir/test/elixir/inspect_test.exs b/lib/elixir/test/elixir/inspect_test.exs index c5088c045f9..860da0e76b7 100644 --- a/lib/elixir/test/elixir/inspect_test.exs +++ b/lib/elixir/test/elixir/inspect_test.exs @@ -694,6 +694,28 @@ defmodule Inspect.MapTest do "%Inspect.MapTest.StructWithAllFieldsInOnlyOption{\n a: 1,\n b: 2\n}" end + test "struct missing fields in the :only option" do + assert_raise ArgumentError, + "unknown fields [:c] given when deriving the Inspect protocol for Inspect.MapTest.StructMissingFieldsInOnlyOption. :only and :except values must match struct fields", + fn -> + defmodule StructMissingFieldsInOnlyOption do + @derive {Inspect, only: [:c]} + defstruct [:a, :b] + end + end + end + + test "struct missing fields in the :except option" do + assert_raise ArgumentError, + "unknown fields [:c, :d] given when deriving the Inspect protocol for Inspect.MapTest.StructMissingFieldsInExceptOption. :only and :except values must match struct fields", + fn -> + defmodule StructMissingFieldsInExceptOption do + @derive {Inspect, except: [:c, :d]} + defstruct [:a, :b] + end + end + end + defmodule StructWithExceptOption do @derive {Inspect, except: [:b, :c]} defstruct [:a, :b, :c, :d]