-
-
Save BjRo/eca4de6020dc41616ebeb4ed88a85fc6 to your computer and use it in GitHub Desktop.
defmodule Messages.Time do | |
use Timex | |
@spec timestamp() :: Timex.DateTime.t | |
def timestamp, do: Timex.DateTime.now(:utc) | |
@type ts :: Timex.Convertable.t | none | |
@spec timestamp_iso8601(ts) :: binary | |
def timestamp_iso8601(ts \\ __MODULE__.timestamp) do | |
{:ok, iso8601} = Timex.format(ts, "{ISO:Extended}") | |
String.replace(iso8601, "+00:00", "Z") | |
end | |
end | |
# lib/messages/time.ex:13: Function timestamp_iso8601/0 has no local return | |
# lib/messages/time.ex:13: The call 'Elixir.Messages.Time':timestamp_iso8601(#{}) will never return since it differs in the 1st argument from the success typing arguments: ('Elixir.Timex.Convertable') |
Ah, looking a bit more, I think this is actually an error in Timex. See typespec of format. It says that the first argument is Timex.Convertable
, not Timex.Convertable.t
, which means the first argument needs to be that very atom. In fact, if you look at the second error, this is what dialyzer says. The success (inferred) typing was 'Elixir.Timex.Convertable'
, so it can't match a map to it.
Ah, I see. How would you deal normally with such situations in your code? Can I tweak Dialyzer to ignore this and use my spec?
I'd use @dialyzer
to suppress this warning. I'd also add a comment in the code about the reason, and then make a PR to timex.
You can see the list of possible options here, and a little bit about it here (search for @dialyzer
).
In your case, it would be something like:
@dialyzer {:nowarn_function, timestamp_iso8601: 1}
Or maybe even this might work:
@dialyzer {[:no_match], timestamp_iso8601: 1}
I didn't try them out (since I have no full code), but something along those lines should suppress the warning.
Btw, if making a PR, you can try to fix timex locally to verify that your fix is correct. Basically, you edit the code in deps/timex
, run mix compile timex
, and then verify that dialyzer passes.
So
Timex.Convertable.t
is just a term https://hexdocs.pm/timex/Timex.Convertable.html#t:t/0, whileTimex.DateTime.t
is a struct https://hexdocs.pm/timex/Timex.DateTime.html#t:t/0From what I see, this should be compatible. Even if I change the spec to
timestamp_iso8601(Timex.DateTime.t)
, I get the same error messages.I wonder why and how he infers the empty map
#{}
as a valid parameter