Existing issue
Elixir and Erlang/OTP versions
Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]
Interactive Elixir (1.21.0-dev)
Operating system
any
Current behavior
Map update incorrectly refines original map fields with replacement type constraints
Repro 1:
defmodule MapOverwrite do
def replace(m), do: %{m | a: 1}.a + 1
def run, do: replace(%{a: :old})
def original(m) do
%{a: 1} = %{m | a: 1}
case m.a do
:old -> :kept_original
_ -> :other
end
end
end
IO.inspect(MapOverwrite.run())
IO.inspect(MapOverwrite.original(%{a: :old}))
Result: code works fine and prints:
but raises 2 false positive warnings:
warning: incompatible types given to replace/1:
replace(%{a: :old})
given types:
%{a: :old}
but expected one of:
%{..., a: float() or integer()}
└─ iex:3: MapOverwrite.run/0
warning: the following clause will never match:
:old ->
because it attempts to match on the result of:
m.a
which has type:
integer()
└─ iex:9: MapOverwrite.original/1
Another repro:
defmodule MapOverwriteCase do
def original(m) do
case %{m | a: 1} do
%{a: 1} -> :ok
end
case m.a do
:old -> :kept_original
_ -> :other
end
end
def domain(m) do
case %{m | a: 1} do
%{a: 1} -> :ok
end
end
def run, do: domain(%{a: :old})
end
IO.inspect(MapOverwriteCase.original(%{a: :old}))
IO.inspect(MapOverwriteCase.run())
Result:
False positive warnings:
warning: the following clause will never match:
:old ->
because it attempts to match on the result of:
m.a
which has type:
integer()
└─ iex:11: MapOverwriteCase.original/1
warning: incompatible types given to domain/1:
domain(%{a: :old})
given types:
%{a: :old}
but expected one of:
%{..., a: integer()}
└─ iex:22: MapOverwriteCase.run/0
Note list and tuple does not seem to be affected by similar bugs.
This is a distinct bug from #15509 and #15688
Expected behavior
The type system should require the key to exist in the original map but without constraining its value type to the replacement
Existing issue
Elixir and Erlang/OTP versions
Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]
Interactive Elixir (1.21.0-dev)
Operating system
any
Current behavior
Map update incorrectly refines original map fields with replacement type constraints
Repro 1:
Result: code works fine and prints:
but raises 2 false positive warnings:
Another repro:
Result:
False positive warnings:
Note list and tuple does not seem to be affected by similar bugs.
This is a distinct bug from #15509 and #15688
Expected behavior
The type system should require the key to exist in the original map but without constraining its value type to the replacement