-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
[Dialyzer] False positive: strange interaction with string()
, list()
and overloaded functions
#7624
Comments
From Dialyzer 5.1's release notes (my emphasis), here's one aspect which I think muddies the water a bit:
With this in mind, splitting the function to avoid an overload specification seems to satisfy Dialyzer:
And, indeed, changing the spec to naively simplify the overloading to:
or
seems to make Dialyzer happy too. I suspect this means the issue arrises due to how "Dialyzer takes the union of the overloaded domains" when it comes to refining the inferred success type using the specification given in the source file.
After "simplifying" the spec/inferred type, I imagine Dialyzer's reasons about
I think this is a reasonable claim, but pragmatically, I think using spec overloading is a "here be dragons" scenario. For the solution inside Dialyzer, I think we need to revisit the soundness of the handling of overloading or the warning given for certain overloaded specs. I did also try to enable the old |
The return type
The otp/erts/preloaded/src/erlang.erl Line 122 in 6674ed5
Now for why Dialyzer complains about the spec. Using OTP 26, Dialyzer gives a little more information about what Dialyzer considers wrong:
As long as there is at least some overlap between spec and code, Dialyzer will allow it. However, lists are treated specially in that there must be an overlap not only when the lists are empty. So for the following example:
Dialyzer will complain:
because the spec and the code only overlap for the empty list. I find it reasonable that there should be warning for this spec and code. Therefore, I think that Dialyzer is correct in complaining about |
Thank you for looking into this!
Is this then considered a warning (that ideally can be disabled via a flag, like the warning for overlapping domains), or something that Dialyzer thinks will definitely lead to a runtime crash? Since that list edge case will never lead to a runtime crash and Dialyzer complains anyway, which I thought Dialyzer would (should?) never do.
It's OK to complain about |
Dialyzer does not say that it will lead to a runtime crash. It is a warning that the combination of spec and code does not make much sense. |
This is a minimized function from the Gradualizer test suite:
The first part of the specification describes the list processing, the second part the tag to string conversion. This is a valid function with a valid spec.
Dialyzer complains:
The return type looks really wild, why is Dialyzer inferring a 4-times nested list?
Reproducible build with Erlang 24-26:
https://github.com/albsch/dialyzer-test
Expected behavior
Dialyzer should not complain, the type spec is valid.
The text was updated successfully, but these errors were encountered: