elixir-cldr/cldr_units

Wrong Dialyzer Typing

maennchen opened this issue · 5 comments

Working Code

@task.co2_savings_kg |> Decimal.to_float |> Cldr.Unit.to_string!(unit: :kilogram)

Dialyzer Error

lib/acme/templates/challenge/task/show.html.eex:32:call
The function call will not succeed.

Acme.Cldr.Unit.to_string!(float(), [{:unit, :kilogram}])

will never return since the success typing is:
(
  %Cldr.Unit{
    :base_conversion =>
      [any()]
      | {[map(), ...], [map(), ...]}
      | %{
          :base_unit => [atom(), ...],
          :factor =>
            number() | %Ratio{:denominator => pos_integer(), :numerator => integer()},
          :offset => number()
        },
    :format_options => [],
    :unit => atom() | binary(),
    :usage => atom(),
    :value =>
      number()
      | %{
          :__struct__ => Decimal | Ratio,
          :coef => _,
          :denominator => pos_integer(),
          :exp => _,
          :numerator => integer(),
          :sign => _
        }
  },
  Keyword.t()
) :: binary()

and the contract is
(Cldr.Unit.t() | [Cldr.Unit.t(), ...], Keyword.t()) :: String.t() | no_return()

I think there's different ways to call it, maybe it was just never called this way...?

I'm not in a hurry with that problem, so take your time :)

It's not only cldr, Phoenix Router also always generates warnings :P

Fixed (I believe - I added a call of this type to a function that is checked by dialyzer in development).
Also fixed the bug whereby Decimal types weren't supported on to_string/3. Therefore you should now be able to:

# Where @task.co2_savings_kg is a Decimal
Cldr.Unit.to_string!(@task.co2_savings_kg, unit: :kilogram)

Published to hex as Cldr Units version 3.1.2. Standing by to any updates if the warning persists......