-
Notifications
You must be signed in to change notification settings - Fork 20
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 fixes #158
base: master
Are you sure you want to change the base?
Dialyzer fixes #158
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holy shit thank you! Will need to digest and run locally but looks awesome at a glance, good my started attempts weren't completely useless/off base!
Hmm, failing tests, but I'll see if I can fix those up, maybe less aggressive hex updates or something. Also, the remaining error is almost certainly my experiment with multiple schemas for different contexts, there's two Food schemas, one in the admin context and one in the FoodSelection context... could drop the former, or make a food selection version of the stockable type or something. |
Installing inotify-tools should fix Travis, I think. |
This seems to be working OK and passing travis on a branch I made, but there's a TON of new warnings I'd like to suppress or deal with before we merge this in, most notably from cowboy/plug related to this issue phoenixframework/phoenix#2437 Putting it on hold for now, but the passing branch is dialyzer_fixes and if anyone else wants to fix up some warnings before I get around to it, awesome, otherwise there's no huge rush to get this on, though it is much appreciated @waisbrot ! |
Ecto 2.1.x had some odd type definitions that bothered Dialyzer. Ecto 2.2.x is better. ecto_enum pins the Ecto version too tightly. Until gjaldon/ecto_enum#45 is merged, we :override ecto_enum
This looks like it's meant to be a call to render/4 but with only 3 args it becomes the (very different) render/3.
Multiple instances of `list(atom() | atom())`, which would be a list containing atoms and also atoms. Rather than correcting to `list(atom()) | atom()`, use `[atom()] | atom()` to avoid getting parentheses hypnosis.
Related to #147
Each commit here fixes one set of problems.
The main problem was Ecto 2.1 defining a bunch of opaque types and then peeking inside of them with macros. In Ecto 2.2, the types are not marked as opaque and so you don't get clobbered by giant warning messages that you're not even responsible for. This is complicated by ecto_enum insisting on Ecto 2.1 even though it doesn't seem to actually need it. I overrode ecto_enum, pending gjaldon/ecto_enum#45 getting merged, but you may prefer to avoid this and just deal with Ecto 2.1.
I think most of the dialyzer errors after that fix are pretty readable. I'll go over my other fixes in detail.
First, Dialyzer errors tend to cascade: one little error deep in the call stack will cause problems all the way up the stack. Therefore, you should generally try to work on the deepest error first and if the error you're looking at doesn't make sense, just fix some other errors and re-run to see if things become clearer.
One error we see is
This basically means "according to type analysis, this function will always crash". Which really means that there's some type problem below and so we should keep looking.
Another error is
Dialyzer is Erlang, so module names and functions look slightly different, but we can just squint. This says that you're calling
OpenPantry.UserOrder.all(:user)
but theall/1
function expects a list of atoms, not a single atom.Looking at the code, it seems like the typespec got typo'd.
list(atom() | atom())
which it's meant to belist(atom()) | atom()
.A large, scary one is
(sorry that's unreadable in Github...)
Anyway, it's mostly just printing the
Plug.Conn
struct, so you have to skim over that. The best bet is at the end:If you look it up, this is
Phoenix.Controller.render/3
that Dialyzer is talking about, but we're passing a view so this should bePhoenix.Controller.render/4
!And finally:
Again, the struct expansion makes this look harder than it is. I use iTerm2 which lets me double-click to select matching delimeters, and I use that to help visualize the error.
The error says that the success type (what Dialyzer sees will actually happen) is
This is obvious from the function, so the given typespec was just wrong. I corrected it by defining a new type
stockable()
. Defining a new type to express what's going on is almost always a good idea, since it's another form of documentation.The only remaining Dialyzer errors I see is for
OpenPantry.FoodSelection.Stock
. It's similar to the above, but I wasn't sure what was going on becauseMeal
andOffer
are the same as above butFood
is a different module.I hope this was helpful! Dialyzer can be frustrating to learn but it's caught some tricky errors for me in the past! (I think the
render/3
/render/4
error is probably a good example)