Credence.Pattern.NoDeadMapUpdate
(credence v0.7.1)
Copy Markdown
Detects a no-op Map.update(key, literal, & &1) |> Map.drop([key]) (and the
Map.delete/direct-call variants) where the updated value is immediately
thrown away by dropping the same key.
Safe core only
In general Map.update(map, key, default, fun) runs fun on the existing
value when key is present, and eagerly evaluates default. Removing the
update would therefore drop any exception or side effect that fun/default
produces — e.g. %{prev: "x"} |> Map.update(:prev, 0, &(&1 - 1)) raises
ArithmeticError, whereas Map.drop(map, [:prev]) returns %{}. That is a
behaviour change, so those forms are intentionally not flagged.
This rule fires only when removing the update is provably output-identical:
funis the identity capture& &1—fun.(value) == valuefor every value, so it can never raise or side-effect; anddefaultis a literal — a pure value whose eager evaluation has no observable effect.
Under those two conditions the update is a genuine no-op before the key is dropped, so it can be removed for any input.
Bad
map |> Map.update(prev, 0, & &1) |> Map.drop([prev])
Map.delete(Map.update(map, key, 0, & &1), key)Good
Map.drop(map, [prev])
Map.delete(map, key)Auto-fix
Removes the dead identity Map.update call, keeping only the drop/delete.