Could be that do_validate_locale
is returning {:ok, String.t()}
or {:error, reason}
where reason
could be generated from locale_error
or other function not satisfying {:error, {module(), String.t()}}
, ? which I think the type module()
is an alias for atom()
Really appreciate all the suggestions. Really. locale_error/1
I’m pretty sure isn’t the issue. It’s just:
@spec locale_error(locale_name() | LanguageTag.t()) :: {Cldr.UnknownLocaleError, String.t()}
def locale_error(%LanguageTag{requested_locale_name: requested_locale_name}) do
locale_error(requested_locale_name)
end
def locale_error(locale_name) do
{Cldr.UnknownLocaleError, "The locale #{inspect(locale_name)} is not known."}
end
And I think thats the end of the rabbit hole. I’m out of ideas. But I’ll try to create a minimal failing case and see what that tells me.
Kind of fun to re-read this old thread - especially since somewhere in the last year I solved the issue (and I don’t really know when). I thought my dialyzer-fu was quite reasonable now but then this issue cropped up today (after a couple of weeks work so I can’t trace when it appeared).
Help very much appreciated!
Dialyzer Error:
lib/cldr/backend/cldr.ex:52:call
The function call will not succeed.
Cldr.Locale.put_gettext_locale_name(
%Cldr.LanguageTag{
:canonical_locale_name => <<101, 110, 45, 76, 97, 116, 110, 45, 85, 83>>,
:cldr_locale_name => <<101, 110>>,
:extensions => %{},
:gettext_locale_name => nil,
:language => <<101, 110>>,
:language_subtags => [],
:language_variant => nil,
:locale => %{},
:private_use => [],
:rbnf_locale_name => <<101, 110>>,
:requested_locale_name => <<101, 110>>,
:script => <<76, 97, 116, 110>>,
:territory => :US,
:transform => %{}
},
MyApp.Cldr
)
will never return since it differs in arguments with
positions 1st from the success typing arguments:
(
%Cldr.LanguageTag{
:canonical_locale_name => binary(),
:cldr_locale_name => nil | binary(),
:extensions => map(),
:gettext_locale_name => nil | binary(),
:language => binary(),
:language_subtags => [binary()],
:language_variant => nil | binary(),
:locale => map(),
:private_use => [binary()],
:rbnf_locale_name => nil | binary(),
:requested_locale_name => binary(),
:script => nil | binary(),
:territory => nil,
:transform => map()
},
atom()
)
Observations
The only difference between the function call and the success typing is:
# Call
:script => <<76, 97, 116, 110>>,
:territory => :US,
:transform => %{}
# Success type
:script => nil | binary(),
:territory => nil,
:transform => map()
In which the types for :territory
would seem to mismatch. However if I look into my types:
# This is the type for Cldr.LanguageTag
@type territory :: atom()
@type t :: %__MODULE__{
language: String.t(),
language_subtags: [String.t()] | [],
script: String.t() | nil,
territory: Cldr.territory(),
language_variant: String.t() | nil,
locale: Cldr.LanguageTag.U.t(),
transform: map(),
extensions: map(),
private_use: [String.t()] | [],
requested_locale_name: String.t(),
canonical_locale_name: String.t(),
cldr_locale_name: String.t() | nil,
rbnf_locale_name: String.t() | nil,
gettext_locale_name: String.t() | nil
}
So I’m perplexed why the success type for :territory
is nil
not atom()
. The called site is:
@spec put_gettext_locale_name(Cldr.LanguageTag.t(), Cldr.backend()) :: Cldr.LanguageTag.t()
def put_gettext_locale_name(%LanguageTag{} = language_tag, backend) do
gettext_locale_name = gettext_locale_name(language_tag, backend)
%{language_tag | gettext_locale_name: gettext_locale_name}
end
Which doesn’t obviously disturb the success type I would have thought?
Any and all suggestions welcome!
you have functions in the called site file where territory is fetched from the struct and passed to other functions where territory()
type from this file is referenced, which is a String.t() | nil
. The only atom()
for which this makes sense is nil
BTW this can be simply private_use: [String.t()],
and the same for language_subtags
Thanks very much, greatly appreciated! I’ll go diving some more. I had already adjusted the :private_use
and :language_subtags
types.
Yea I am running this on CI which is using the MIX_ENV=test, is it preferable to be running this on a different environment?
Um, running what? And with what error? Tricky to help without this information. Typically shouldn’t matter what environment you are running dialyzer in.
Hey just found this thread very helpful still today, solved the exactly same problem I was having. For future people coming here just keep in mind setting the MIX_ENV to dev
will cause the hole project to be compiled again, which maybe is not desired.
To me including :ex_unit
in plt_add_apps
seems better if the project is only/already compiled with MIX_ENV set to test
.