Credence.Pattern.NoFindValueDefaultCase
(credence v0.7.0)
Copy Markdown
Detects Enum.find_value/2 where the result is immediately checked
against nil to provide a default, instead of using the 3-arity
version that accepts a default argument.
Bad
case Enum.find_value(list, &process/1) do
nil -> :default
val -> val
end
Enum.find_value(list, &process/1) || :defaultGood
Enum.find_value(list, :default, &process/1)Auto-fix
Replaces the case/|| wrapper with the 3-arity call.
Safety
This rule is deliberately limited to Enum.find_value, and (for the
case form) only when the nil -> clause comes first. The reason
is that the rewrite must give the exact same answer for every input:
Enum.find/2is not covered.find/2returns the matching element, which can itself benil(orfalse). A genuinely foundnilelement would be treated as "not found" by both thecase nil ->clause and byEnum.find/3differently (find/3returns the foundnil, thecasereturns the default), so the answers diverge.find_valueonly ever returns a truthy value ornil, sonilunambiguously means "nothing found".The identity clause must come after the
nil ->clause. If it comes first (val -> val; nil -> d) it matchesniltoo, making thenil ->clause dead code — the expression then returnsnil(never the default), so rewriting to/3would change the answer.||is safe only forfind_value(its result is neverfalse).Enum.find/2 || defaultis not covered: a foundfalse/nilelement is falsy and would wrongly fall through to the default.