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

Missing line and column information leads to confusing Dialyzer warning #13555

Closed
michallepicki opened this issue May 13, 2024 · 7 comments
Closed

Comments

@michallepicki
Copy link
Contributor

Elixir and Erlang/OTP versions

Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Elixir 1.17.0-dev (1fec26d) (compiled with Erlang/OTP 26)

Operating system

Ubuntu 22.04

Current behavior

Since 3d7f4dd I'm seeing a Dialyzer issue in https://github.com/michallepicki/elixir-lang-dialyzer-runs , but it gets reported without concrete line and column:

Potential issue: 
lib/calendar/iso.ex:1: The pattern 
          'false' can never match the type 
          'true'

(it's at the bottom of github actions output, e.g. https://github.com/michallepicki/elixir-lang-dialyzer-runs/actions/runs/9055239495/job/24876064704 )

The warning itself may or may not be a false positive, and I can spend some time looking into it, but the problem I want to highlight here is that the line number in the Dialyzer warning is set to 1, which is not helpful and makes it hard to debug.

Expected behavior

Dialyzer can report the actual line number on which it detects a problem, instead of pointing to the line 1 of the file

@michallepicki
Copy link
Contributor Author

Now I realize it's also probably hard to fix this without knowing on which line Dialyzer sees the issue, so I can spend some time this evening trying to figure that out.

@michallepicki
Copy link
Contributor Author

The issue is on line 1367. After the change of the is_year(year) guard definition to expand to just is_integer(year), thanks to an already present is_integer guard on the function head, Dialyzer can see that the is_year call in the function body is redundant and will always succeed.

Now the question is, why is the line number set to 1 there, and can something be done about this

@michallepicki
Copy link
Contributor Author

This module results in the same dialyzer warning pointing to line number 1 instead of 3:

defmodule Mod do
  def fun(x) when is_integer(x) do
    is_integer(x) and x > 10
  end
end

@michallepicki
Copy link
Contributor Author

michallepicki commented May 13, 2024

A minimal way to run Dialyzer on this module would be:

# build some minimal plt file, this only has to be done once
dialyzer --build_plt --apps erts --output_plt my.plt
# compile the module
elixirc mod.ex
# run dialyzer analysis and inspect the data it would use to print the warning
elixir -e "IO.inspect(:dialyzer.run(init_plt: ~c\"my.plt\", files: [~c\"Elixir.Mod.beam\"]))"

It will print

[
  {:warn_matching, {~c"mod.ex", 1},
   {:pattern_match, [~c"pattern 'false'", ~c"'true'"]}}
]

but we want the number 1 to be 3 instead

@josevalim
Copy link
Member

This happens because Dialyzer finds the error in the literal and literals in Elixir do not carry line information when compiled to Erlang, so there isn't much we can do here. :(

In any case, do you want to send a PR that addresses the warning by removing the duplicated guard? :) Thank you!

@michallepicki
Copy link
Contributor Author

literals in Elixir do not carry line information

Ah, I remember this problem! Didn't expect it applies here, what is the literal in question here?

do you want to send a PR that addresses the warning by removing the duplicated guard?

sent #13556

@michallepicki michallepicki closed this as not planned Won't fix, can't repro, duplicate, stale May 13, 2024
@josevalim
Copy link
Member

The booleans true/false that and compiles down to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants