Fix map domain update - #15953
Open
gldubc wants to merge 5 commits into
Open
Fix map domain update#15953gldubc wants to merge 5 commits into
gldubc wants to merge 5 commits into
Conversation
Keep direct domain lookups and the simplified domain helper from main, retain projected-pair updates and the map emptiness cache, and preserve the force? documentation alongside the explicit missing-key policy. Adjust the mixed-key map-update regression to retain nonempty results while leaving the original map unrefined.
Contributor
|
@gldubc I checked the PR and #15594 is only partially addressed. The simple case from comment #15594 (comment) is still wrong. Besides that, the PR introduces two regressions:
Repro: defmodule CallbackUnion do
def go(flag) do
{value, fun} =
if flag do
{1.0, fn
x when is_integer(x) -> :integer_branch
x when is_float(x) -> :float_branch
end}
else
{1, fn x when is_integer(x) -> :other_branch end}
end
result = Map.update!(%{a: value}, :a, fun)
case result do
%{a: :float_branch} -> :valid
_ -> :other
end
end
end
{CallbackUnion.go(true), CallbackUnion.go(false)}
# => {:valid, :other}emits a false positive warning: On main the code compiles cleanly. Reason: Another example with disjoint domains: defmodule EmptyDomain do
def run(flag) do
{value, fun} =
if flag do
{1.0, fn x when is_float(x) -> :float_branch end}
else
{1, fn x when is_integer(x) -> :integer_branch end}
end
Map.update!(%{a: value}, :a, fun)
end
endemits a false positive:
The new Repro: defmodule Blowup do
def build(k1, k2, k3, k4, k5) do
Map.new()
|> Map.put(k1, 1) |> Map.put(k2, 2) |> Map.put(k3, 3)
|> Map.put(k4, 4) |> Map.put(k5, 5)
end
end |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15482, #15509, #15594, #15688 and #15687. Supersedes PR #15510.
This makes map key/domain operations:
We now distinguish, in the map update operation, between constant replacements (Map.put for instance) and callback ones, that require the previous value to be modified into a new type. The algorithm for constants is faster.
This also adds the following optimization: when building a map leaf, a quick check is done to see if the map is definitely non_empty, or if it could maybe be non-empty. This is stored in the lowest bit of the hash, and is used for instant map emptiness checking for leaves.
Bugfix: unfold
term()keys before splitting explicit keys from domains.Regression coverage in this PR:
Map.pop!inference;term()-key bug;Map.update/4for a struct field #15687 both variants;map_putresult depends on representation #15594 repro 1 is already on main; exact repro 2 is included here.Assisted-by: GPT-6-Astra