Running into that tonight, and I’m not sure how to fix it without a dialyzer ignore.
I’m not sure I really understand the problem. Is dialyzer complaining that the given authority is not somehow inheriting the opaqueness? I tried to add nil which corresponds to the type, but I still have the error.
(When I say “we should” it’s only about making dialyzer happy again, I know it’s otherwise useless to specify the authority key to its default).
Currently my workaround is to use URI.parse which is more fragile because it involves string manipulation, or @dialyzer {:no_opaque, ...}. Is there a real proper solution to build URI structs from known data (scheme,host,etc)
For what it’s worth, we removed the opaqueness on authority (PR) on main/1.20rc but there hasn’t been a version after 1.19.5 to backport these changes.
So :no_opaque as a temporary stop-gap makes sense.
I’m wondering if I’m doing something wrong, b/c I’m still seeing errors in my project despite the related Elixir issues being closed as fixed. To test, I created a brand new mix project with this code
defmodule TmpDialyzerProject do
@spec produce() :: MapSet.t(integer())
def produce, do: MapSet.new([1, 2, 3])
@spec consume(MapSet.t(integer())) :: list(integer())
def consume(deleted) do
MapSet.new([4, 5, 6])
|> MapSet.difference(deleted)
|> MapSet.to_list()
end
def driver, do: consume(produce())
end
and the result of mix dialyzer in Elixir 1.20.1 and OTP 28.4 is
lib/tmp_dialyzer_project.ex:12:27:call_without_opaque
Function call without opaqueness type mismatch.
Call does not have expected term of type %MapSet{:map => :sets.set(_)} (with opaque subterms) in the 1st position.
TmpDialyzerProject.consume(%MapSet{:map => %{1 => [], 2 => [], 3 => []}})
________________________________________________________________________________
Are folks still using the opaque exclusions, or is there something else I can do to resolve these?
Thanks for sharing @grossvogel. This issue is un-killable
You’re not doing anything wrong. But unfortunately I fear we’re getting out of options here to deal with it in the language itself.
I managed to silence it using the following two workarounds:
def produce do
# option 1: un-inline the MapSet creation so it's not a literal anymore
list = [1, 2, 3])
MapSet.new(list)
end
or
# option 2: replace produce/0 by a module attr
@produce MapSet.new([1, 2, 3])
def driver, do: consume(@produce)
But honestly it might be better to just explicitly disable opaqueness checks when working with MapSet rather than jumping through hoops and try to trick dialyzer.