Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ElixirLS Dialyzer (VS code) warning : The pattern 'false' can never match the type 'true' #85

Closed
relax2code opened this issue Nov 25, 2021 · 3 comments · Fixed by #92 or #93
Closed
Labels
bug Something isn't working

Comments

@relax2code
Copy link

Hi, first I want to thank you for this great library , I have some issue with Dialyzer warning but I'm not sure why , here's my settings:

Mix.exs:

      {:type_check, github: "Qqwy/elixir-type_check"}

Elixir vers:
1.12.2-otp-24

ElixirLS vs code:
0.8.1

Code:

defmodule Document.ExcelTest do
  use TypeCheck
  alias Document.ExcelTest

  defstruct [
    :name,
    :age,
    :phone
  ]

  @type! t() :: %ExcelTest{
           name: String.t(),
           age: integer(),
           phone: String.t()
         }
end
defmodule Document.Doc do

  use TypeCheck
  alias Document.ExcelTest

  @spec! parse_list(any) :: ExcelTest.t()
  def parse_list(list) do

    column = [
      :name,
      :age,
      :phone
    ]

    Enum.zip(column, list)
    |> Enum.into(%{})
    |> then( fn map -> struct(%ExcelTest{}, map) end)

  end
end

the code can be compiled and run , but there' warning from dialyzer ;

screenshot

Is there something wrong with my code ?

@Qqwy
Copy link
Owner

Qqwy commented Nov 25, 2021

🤔 Hmm, I wonder whether Dialyzer is complaining about some code inside the runtime typecheck that is generated.

Thanks for filing this bugreport, I'll look into it!

@Qqwy Qqwy added the bug Something isn't working label Nov 25, 2021
@tomekowal
Copy link
Contributor

tomekowal commented Jan 20, 2022

I have a similar issue. The code:

defmodule ExKeymap.KeymapItem do
  use TypeCheck
  defstruct [:item_name, :help, :fun]

  @type! t :: %__MODULE__{
    item_name: String.t(),
    fun: (-> any()),
    help: String.t() | nil
  }

  @spec! new(String.t(), (-> any()), String.t() | nil) :: t()
  def new(item_name, fun, help \\ nil) do
    %__MODULE__{
      item_name: item_name,
      fun: fun,
      help: help
    }
  end
end

The output:

mix dialyzer
Finding suitable PLTs
Checking PLT...
[:compiler, :elixir, :iex, :kernel, :logger, :stdlib, :type_check]
PLT is up to date!
No :ignore_warnings opt specified in mix.exs and default does not exist.

Starting Dialyzer
[
  check_plt: false,
  init_plt: '/home/tomaszkowal/experiments/ex_keymap/_build/dev/dialyxir_erlang-24.1.2_elixir-1.12.3_deps-dev.plt',
  files: ['/home/tomaszkowal/experiments/ex_keymap/_build/dev/lib/ex_keymap/ebin/Elixir.ExKeymap.Keymap.beam',
   '/home/tomaszkowal/experiments/ex_keymap/_build/dev/lib/ex_keymap/ebin/Elixir.ExKeymap.KeymapItem.beam',
   '/home/tomaszkowal/experiments/ex_keymap/_build/dev/lib/ex_keymap/ebin/Elixir.ExKeymap.beam',
   '/home/tomaszkowal/experiments/ex_keymap/_build/dev/lib/ex_keymap/ebin/Elixir.TypeCheck.Internals.UserTypes.ExKeymap.Keymap.beam',
   '/home/tomaszkowal/experiments/ex_keymap/_build/dev/lib/ex_keymap/ebin/Elixir.TypeCheck.Internals.UserTypes.ExKeymap.KeymapItem.beam'],
  warnings: [:unknown]
]
Total errors: 1, Skipped: 0, Unnecessary Skips: 0
done in 0m0.68s
lib/type_check/spec.ex:1:pattern_match
The pattern can never match the type.

Pattern:
false

Type:
true

________________________________________________________________________________
done (warnings were emitted)
Halting VM with exit status 2

type_check 0.10.5, erlang 24.1.2, elixir 1.12.3, dialyxir 1.1.0

@Qqwy
Copy link
Owner

Qqwy commented Jan 22, 2022

An even more minimal version that results in the Dialyzer warning:

defmodule ExKeymap.KeymapItem do
  use TypeCheck
  defstruct [:help]

  @type! t() :: %__MODULE__{
    help: binary() | nil
  }

  @spec! new(binary() | nil) :: t()
  def new(help) do
    %__MODULE__{
      help: help
    }
  end
end

It seems to be related with how dialyzer inspects booleans in combination with using an | to allow a nullable type.
The problem is caused by the if is_map(x) line generated by the macro expansion in type_check/builtin/fixed_map.ex.

Qqwy added a commit that referenced this issue Jan 23, 2022
and add a 'dializer :nowarn_function' option for it.
This will mean that Dialyzer will no longer complain about "patterns
that can never match" in the return-result spec (as in the happy case
the implementation of the function indeed will never trigger an error
when given correct input.

Fixes #85
@Qqwy Qqwy closed this as completed in #93 Jan 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants