Skip to content

Type error on Elixir 1.19.0-dev with OTP 28 #14359

Closed
@kipcole9

Description

@kipcole9

Elixir and Erlang/OTP versions

  • OTP 28.0-rc2
  • Elixir 1.19.0-dev

Operating system

MacOS

Current behavior

The following module produces a type warning that (as best I can tell) is not correct. Note that replacing the interpolated value #{known_locale_count} with #{inspect known_locale_count} result in no type warning. Somehow the interpolation is affecting the assumption of the type of known_locale_count - the relevant part of the warning seems to be:

# from: lib/type_check.ex:17
to_string(known_locale_count)

Example module

defmodule TypeCheck do
  @warn_if_greater_than 100

  @locales [
    :ar, :ca, :"ca-ES-valencia", :de, :doi, :en, :"en-001", :"en-AU", :"en-GB",
    :es, :fr, :"fr-CA", :it, :ja, :nb, :no, :pl, :th, :und
  ]

  def install_locales(config) do
    known_locale_count =
      @locales
      |> Enum.count()

    locale_string = if known_locale_count > 1, do: "locales named ", else: "locale named "

    IO.puts(
      "Generating #{inspect(config.backend)} for #{known_locale_count} " <>
        locale_string <>
        "#{inspect(@locales, limit: 5)} with " <>
        "a default locale named #{:en}"
    )

    if known_locale_count > @warn_if_greater_than do
      IO.puts("Please be patient, generating functions for many locales " <> "can take some time")
    end
  end
end

Type message

iex -S mix
Erlang/OTP 28 [RELEASE CANDIDATE 2] [erts-16.0] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

    warning: comparison with structs found:

        known_locale_count > 100

    given types:

        dynamic(
          %Date{} or %DateTime{} or %NaiveDateTime{} or %Time{} or %URI{} or %Version{} or
            %Version.Requirement{} or atom() or binary() or float() or integer() or list(term())
        ) > integer()

    where "known_locale_count" was given the type:

        # type: dynamic(
          %Date{} or %DateTime{} or %NaiveDateTime{} or %Time{} or %URI{} or %Version{} or
            %Version.Requirement{} or atom() or binary() or float() or integer() or list(term())
        )
        # from: lib/type_check.ex:17
        to_string(known_locale_count)

    Comparison operators (>, <, >=, <=, min, and max) perform structural and not semantic comparison. Comparing with a struct won't give meaningful results. Structs that can be compared typically define a compare/2 function within their modules that can be used for semantic comparison.

    typing violation found at:
    │
 23 │     if known_locale_count > @warn_if_greater_than do
    │                           ~
    │
    └─ lib/type_check.ex:23:27: TypeCheck.install_locales/1

Expected behavior

No type error is expected since:

    known_locale_count =
      @locales
      |> Enum.count()

is determined by the result of Enum.count/1.

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