Skip to content

Static Type warning on is_struct(hd(list)) guard #15198

@tjchambers

Description

@tjchambers

Elixir and Erlang/OTP versions

Elixir 1.20.0-rc.3 (9b80ab5) (compiled with Erlang/OTP 28)
Erlang OTP 28

Operating system

MacOs 26.3

Current behavior

In rc.3 I am getting a new type checking warning for functions I have guards on lists to ensure the list contains terms of the proper type.

Example:

def filter(tags, value)
      when is_list(tags) and is_struct(hd(tags)) and is_binary(value) do
    converted_value = to_regex(value)
Enum.filter(tags, fn tag -> tag.tag =~ ~r|^#{converted_value}|i end)
end

warning: incompatible types given to Kernel.is_map_key/2:

    is_map_key(hd(tags), :__struct__)

given types:

    term(), :__struct__

but expected one of:

    #1
    %{..., __struct__: term()}, term()

    #2
    %{..., __struct__: not_set()}, term()

where "tags" was given the types:

    # type: empty_list() or non_empty_list(term(), term())
    # from: lib/sct/joe/services/tag_matcher.ex:27:12
    is_list(tags)

    # type: non_empty_list(term(), term())
    # from: lib/sct/joe/services/tag_matcher.ex:27:40
    hd(tags)

type warning found at:
│

│ when is_list(tags) and is_struct(hd(tags)) and is_binary(value) do

My guard for tags is attempting to ensure that the tags are a list, and that list is non-empty and that it contains structs. I have not specified that type of the structure since there are a number of compatible structs that this function serves.

I do not quite understand why this should result in a type check warning. Any guidance would be useful. I have dozens of similarly constructed function guards which are all emitting this type of warning.

Expected behavior

No type checking warning

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions