Skip to main content

W0080 - maps:merge/2 call can be simplified

Warning

main(K, V, Map) ->
maps:merge(Map, #{K => V}).
%% ^^^^^^^^^^^^^^^^^^^^^^^^^^ 💡 weak: Consider using map update syntax instead
main(Map) ->
maps:merge(Map, #{}).
%% ^^^^^^^^^^^^^^^^^^^^ 💡 weak: Merging with an empty map is a no-op
main(Map) ->
maps:merge(#{}, Map).
%% ^^^^^^^^^^^^^^^^^^^^ 💡 weak: Merging with an empty map is a no-op

Explanation

The diagnostic flags maps:merge/2 calls that can be replaced by simpler expressions. Three forms are detected:

  1. Update formmaps:merge(M, #{K1 => V1, ...}) becomes M#{K1 => V1, ...}. The map update syntax is more idiomatic, faster at runtime, and produces less garbage. Because the keys of the literal are statically known, the compiler can specialise the update — this is not possible when the second argument is a runtime map value.

  2. Empty second argumentmaps:merge(M, #{}) becomes M. Merging with an empty map is a no-op.

  3. Empty first argumentmaps:merge(#{}, M) becomes M. Same.

When the first argument is itself a non-empty map literal, the rewrite combines both literals' fields into a single map: maps:merge(#{a => 1}, #{a => 2, b => 3}) becomes #{a => 1, a => 2, b => 3}. Erlang's => operator inserts or overwrites, so the rightmost write wins on key overlap — the same semantics as maps:merge/2's "second argument wins" behaviour. Combining (rather than emitting Lit1#{Lit2_fields}) avoids triggering L1318 ("expression updates a literal").

When the first argument is a map update (M#{x => 1}), the rewrite appends the literal's fields to the existing update rather than nesting another #{...}: maps:merge(M#{x => 1}, #{K => V}) becomes M#{x => 1, K => V}. The same => last-write-wins rule preserves "second argument wins" semantics on overlapping keys.

Conditions

The diagnostic only fires when the rewrite is a syntactic substitution:

  • For the update form, the first argument must be a bound variable, a non-empty map literal, or a map update expression; the second argument must be a non-empty map literal.
  • For the empty-merge forms, the non-empty side must be a bound variable, a map literal, or a map update expression.