From a7a8cff3800ab6b6d616623ebbef84ea3af31f76 Mon Sep 17 00:00:00 2001 From: Henrik Tudborg Date: Mon, 15 Jun 2026 20:25:45 +0200 Subject: [PATCH] avoid using Keyword.pop/2 in ExUnit.Diff.struct_module/2 `struct_module` is being called for both structs and maps. `diff_quoted_struct` uses the return of `struct_module` to determine when to call `diff_quoted_struct` or `diff_map` --- lib/ex_unit/lib/ex_unit/diff.ex | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/ex_unit/lib/ex_unit/diff.ex b/lib/ex_unit/lib/ex_unit/diff.ex index 5ef4f6b0295..bf71f054a31 100644 --- a/lib/ex_unit/lib/ex_unit/diff.ex +++ b/lib/ex_unit/lib/ex_unit/diff.ex @@ -765,16 +765,20 @@ defmodule ExUnit.Diff do end end + # if kw represents a struct, this returns the result of `struct.__info__(:struct)`, otherwise nil defp struct_module(kw) do - {struct, struct_kw} = Keyword.pop(kw, :__struct__) - - info = - is_atom(struct) and struct != nil and - Code.ensure_loaded?(struct) and function_exported?(struct, :__info__, 1) and - struct.__info__(:struct) + case Enum.split_with(kw, fn {k, _} -> k == :__struct__ end) do + {[{_, struct} | _], struct_kw} when is_atom(struct) and struct != nil -> + info = + Code.ensure_loaded?(struct) and function_exported?(struct, :__info__, 1) and + struct.__info__(:struct) + + if info && Enum.all?(struct_kw, fn {k, _} -> Enum.any?(info, &(&1.field == k)) end) do + struct + end - if info && Enum.all?(struct_kw, fn {k, _} -> Enum.any?(info, &(&1.field == k)) end) do - struct + _ -> + nil end end