Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

False positives on map literals with union/negation on variable keys

未关闭
#15,909 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
55/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
elixir, erlang
领域
compilers

调研方向

首先复现两个 Elixir 示例,并检查 issue 中提到的编译器路径:closed_map/5 和 union_negated/4。跟踪变量键域和取反的 atom 键如何变成 required 或 not_set() 条目,然后验证这些示例生成正确的类型,且不会产生误报警告。

由索引模型根据 Issue 内容生成。

描述

Existing issue
  • I have searched existing issues and could not find a duplicate.
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 literal expressions with variable keys produce too small types that do not contain observed runtime values and result in false positive warnings.

Issue 1: Map literal whose key is :a or integer() records :a as required

Repro:

    defmodule P22 do
      def fin_dom(c) do
        k = if c, do: :a, else: 5
        m = %{k => 1}
        case m do
          %{a: _} -> :has_a
          _ -> :no
        end
      end
    end

Result:

warning: the following clause cannot match because the previous clauses already matched all possible values:

    _ ->

it attempts to match on the result of:

    m

which has the already matched type:

    dynamic(%{integer() => integer(), a: integer()})

└─ iex:8: P22.fin_dom/1

Likely reason: closed_map/5 adds finite atoms as required keys even when domain_keys != []

Issue 2:

Map literals with a negated atom variable key mark the negated atom as not_set()

Repro:

    defmodule P21 do
      def neg_key(s1, s2) do
        k1 = String.to_atom(s1)
        k2 = case String.to_atom(s2) do :foo -> :not_foo; o -> o end
        m = %{k1 => :baz, k2 => :baz2}
        case m do
          %{foo: _} -> :has_foo
          _ -> :no
        end
      end

      def neg2(s1, s2) do
        k1 = case String.to_atom(s1) do :a -> :na; o -> o end
        k2 = case String.to_atom(s2) do :b -> :nb; o -> o end
        m = %{k1 => 1, k2 => 2}
        case m do
          %{b: _} -> :has_b
          _ -> :no
        end
      end
    end

Result:

warning: the following clause will never match:

    %{foo: _} ->

because it attempts to match on the result of:

    m

which has type:

    dynamic(%{atom() => :baz or :baz2, foo: not_set()})

└─ iex:9: P21.neg_key/2

warning: the following clause will never match:

    %{b: _} ->

because it attempts to match on the result of:

    m

which has type:

    dynamic(%{atom() => integer(), a: if_set(integer()), b: not_set()})

└─ iex:19: P21.neg2/2
IO.inspect({P21.neg_key("foo","bar"), P21.neg2("b","c")}) # {:has_foo, :has_b}

Note neg2 also shows the asymmetry: a is if_set (correct) but b is not_set (wrong)

Likely reason: closed_map/5 and union_negated/4 make every negated atom not_set() without consulting the :atom domain

Expected behavior

Proper types constructed, no warnings

主要语言
Elixir
星标
26.7k
派生
3.7k
平均合并
8 小时 7 分钟
30 天内合并 PR
60

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

elixir-lang/elixir 的其他 Issue

查看 elixir-lang/elixir 的全部 Issue

相似的 Issue

更多 Elixir Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。