jeremyjh / dialyxir

Mix tasks to simplify use of Dialyzer in Elixir projects.
Apache License 2.0
1.69k stars 141 forks source link

Illegal atom key in tuple list is not detected #408

Closed RobertDober closed 4 years ago

RobertDober commented 4 years ago

Precheck

╰─> λ mix hex.search dialyxir                                                                                                                                [12:08:10]
Package   Description                                            Version  URL                               
dialyxir  Mix tasks to simplify use of Dialyzer in Elixir pr...  1.0.0    https://hex.pm/packages/dialyxir  

╭─>robert@roma ~/tmp/typestest                                                                                                                ❰1.10.4➤23.0.1❱ ⬡ 12.16.3 
╰─> λ mix hex.search erlex                                                                                                                                   [12:08:23]
Package  Description                                            Version  URL                              
erlex    Convert Erlang style structs and error messages to...  0.2.6    https://hex.pm/packages/erlex    
erlexec  OS Process Manager                                     1.17.5   https://hex.pm/packages/erlexec  

╭─>robert@roma ~/tmp/typestest                                                                                                                ❰1.10.4➤23.0.1❱ ⬡ 12.16.3 
╰─> λ mix deps                                                                                                                                               [12:08:30]
* erlex 0.2.6 (Hex package) (mix)
  locked at 0.2.6 (erlex) 2ed2e257
  ok
* dialyxir 1.0.0 (Hex package) (mix)
  locked at 1.0.0 (dialyxir) aeb06588
  ok

Environment

iex                                                                                                                                                    [12:09:45]
Erlang/OTP 23 [erts-11.0.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help)
cat mix.lock | grep dialyxir                                                                                                                           [12:08:35]
  "dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},

Current behavior

defmodule Typestest do
  @moduledoc """
  Documentation for `Typestest`.
  """

  @type amap :: %{atom() => atom()}
  @type keys :: :alpha | :omega
  @type kwds :: [{keys(), integer()}]

  @spec dispatch(integer()) :: amap()
  def dispatch(n)
  def dispatch(0), do: %{zero: true}
  def dispatch(_), do: %{infinity: tru

  @spec kwds(integer()) :: kwds()
  def kwds(n)
  def kwds(0), do: [alpha: 1]
  def kwds(1), do: [beta: 2]
  def kwds(_), do: [omega: 24]

end

Expected behavior

The returned value [beta: 2] does not trigger a warning.

Trying to shrink the error triggering case.... please stand by

RobertDober commented 4 years ago

Still no warning:

defmodule Typestest do
  @moduledoc false

  @type keys :: :alpha

  @spec key(integer()) :: keys()
  def key(n)
  def key(0), do: :alpha
  def key(_), do: :beta

end

I am beginning to believe that I miss something obvious here :face_with_head_bandage:

RobertDober commented 4 years ago

Ok feeling better now, as the following code

defmodule Typestest do
  @moduledoc false

  @type keys :: :alpha

  @spec key() :: keys()
  def key(), do: :beta

end

does indeed trigger

lib/typestest.ex:6:invalid_contract
The @spec for the function does not match the success typing of the function.

Function:
Typestest.key/0

Success typing:
@spec key() :: :beta
asummers commented 4 years ago

Dialyxir does not originate warnings, only calls and reformast ones spit out by Dialyzer for Elixir. Any missing Dialyzer features or incorrect behavior are issues with Erlang core and dialyzer.erl. There are unfortunately illegal problems Dialyzer will still accept. Playing with the Dialyzer flags (-Wunmatched and friends) increases the number of warnings you get.

RobertDober commented 4 years ago

I see sorry for having bothered you.

asummers commented 4 years ago

No trouble!