Repository: elixir-lang/elixir

Issue #13227: Set-theoretic types: inference of patterns and guards
Created: 2024-01-05T16:56:40Z
The goal of this issue is to track the main tasks for the first milestone of set theoretic types: type inference of patterns and guards, followed by body checking.
Typing description:

 Non-divisible types (integer, floats, pids, etc)
 Dynamic
 Atoms
 Maps

 Domain key-types
 map_fetch
 map_put
 map_delete
 map_keys
 map_values


 Tuples

 Generalize :open / :closed
 tuple_fetch
 tuple_insert
 tuple_delete
 tuple_values


 Lists

 list_hd
 list_tl


 Functions

 apply/2 and fun.(args...)
 fn ... -> ... end
 Capture
 Unions of closures



Type inference and checking:

 Tracking of variables
 Type inference of patterns
 Type inference of guards
 Type inference of return types
 Map and struct updates
 Checking of all inlined functions from Kernel
 Checking of all inlined conversion functions
 Checking of __STACKTRACE__ and raising functions
 Tuple module
 Map module
 Storing of inferred types in .beam files
 Support for local calls
 Support for remote calls

These are additional features not required for the first milestone:

 Support for __info__, module_info, and behaviour_info
 Typing of :erlang inlined functions
 for comprehensions

 generators
 :into
 :reduce


 with comprehensions
 Detect never matching clauses and patterns (cond, case, try)
 Track precision in case and inferred clauses to perform elimination
 Detect overlapping clauses (case, receive, try, reduce)
 Exhaustiveness checks (case, try, cond, reduce)
 Unused clauses in private functions
 Tracking of mismatches in equality operators
 Tracking of structs in ordered comparison operators
 Move compile.protocols to parallel compiler
 Type checking of protocol dispatch
 Type checking of impls
 Get rid of Of.compatible and Pattern.of_match_var
 Infer based on all loaded applications
 Infer all Elixir modules at once

For the second and third milestones, see #13881.

Duplicate issue #14347: Elixir 1.19 inconsistent typing warning
Created: 2025-03-19T12:36:40Z
Elixir and Erlang/OTP versions
Erlang/OTP 27 [erts-15.1.2] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]
Elixir 1.19.0-dev (b601b1c) (compiled with Erlang/OTP 27)
Operating system
mac
Current behavior
I know 1.19 is not released yet so feel free to close this ticket.
I only got this warning when running mix compile, not with elixirc. Both with  1.19-dev using asdf install elixir main-otp-27
git repo which shows the problem https://github.com/nwjlyons/foo/blob/main/lib/foo.ex
comparison with structs warning
["foo-#{i}": i > 0]

full compiler warning
  warning: comparison with structs found:

      i > 0

  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 "i" 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/foo.ex:3
      to_string(i)

  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:
  │
3 │     ["foo-#{i}": i > 0]
  │                    ~
  │
  └─ lib/foo.ex:3:20: Foo.error/1

no warning for
if(i > 0, do: "foo-#{i}")

# or

if(i > 0, do: :"foo-#{i}")
Expected behavior
To be consistent with the if expressions. So consistently no warnings or all warnings.

Closing comment (2025-03-19T16:06:43Z): Closing as duplicate of #13227 for now. We may revisit to not emit this warning in the future.