Improve error message for protocols with no implementation, closes #14364
This commit is contained in:
@@ -1031,11 +1031,21 @@ defmodule Module.Types.Apply do
|
||||
|
||||
Code.ensure_loaded?(mod) and
|
||||
Keyword.has_key?(mod.module_info(:attributes), :__protocol__) ->
|
||||
# Protocol errors can be very verbose, so we collapse structs
|
||||
"""
|
||||
but expected a type that implements the #{inspect(mod)} protocol, it must be one of:
|
||||
#{clauses_args_to_quoted_string(clauses, converter, collapse_structs: true)}
|
||||
"""
|
||||
if function_exported?(mod, :__protocol__, 1) and
|
||||
mod.__protocol__(:impls) == {:consolidated, []} do
|
||||
"""
|
||||
but the protocol was not yet implemented for any type and therefore will always fail. \
|
||||
This error typically happens within libraries that define protocols and will disappear as \
|
||||
soon as there is one implementation. If you expect the protocol to be implemented later on, \
|
||||
you can define an implementation specific for development/test.
|
||||
"""
|
||||
else
|
||||
# Protocol errors can be very verbose, so we collapse structs
|
||||
"""
|
||||
but expected a type that implements the #{inspect(mod)} protocol, it must be one of:
|
||||
#{clauses_args_to_quoted_string(clauses, converter, collapse_structs: true)}
|
||||
"""
|
||||
end
|
||||
|
||||
true ->
|
||||
"""
|
||||
|
||||
@@ -455,7 +455,7 @@ defmodule Module.Types.IntegrationTest do
|
||||
assert_no_warnings(files)
|
||||
end
|
||||
|
||||
test "mismatched impl" do
|
||||
test "mismatched implementation" do
|
||||
files = %{
|
||||
"a.ex" => """
|
||||
defprotocol Itself do
|
||||
@@ -491,6 +491,50 @@ defmodule Module.Types.IntegrationTest do
|
||||
assert_warnings(files, warnings)
|
||||
end
|
||||
|
||||
@tag :require_ast
|
||||
test "no implementation" do
|
||||
files = %{
|
||||
"a.ex" => """
|
||||
defprotocol NoImplProtocol do
|
||||
def callback(data)
|
||||
end
|
||||
""",
|
||||
"b.ex" => """
|
||||
defmodule NoImplProtocol.Caller do
|
||||
def run do
|
||||
NoImplProtocol.callback(:hello)
|
||||
end
|
||||
end
|
||||
"""
|
||||
}
|
||||
|
||||
warnings = [
|
||||
"""
|
||||
warning: incompatible types given to NoImplProtocol.callback/1:
|
||||
|
||||
NoImplProtocol.callback(:hello)
|
||||
|
||||
given types:
|
||||
|
||||
-:hello-
|
||||
|
||||
but the protocol was not yet implemented for any type and therefore will always fail. \
|
||||
This error typically happens within libraries that define protocols and will disappear as \
|
||||
soon as there is one implementation. If you expect the protocol to be implemented later on, \
|
||||
you can define an implementation specific for development/test.
|
||||
|
||||
typing violation found at:
|
||||
│
|
||||
3 │ NoImplProtocol.callback(:hello)
|
||||
│ ~
|
||||
│
|
||||
└─ b.ex:3:20: NoImplProtocol.Caller.run/0
|
||||
"""
|
||||
]
|
||||
|
||||
assert_warnings(files, warnings, consolidate_protocols: true)
|
||||
end
|
||||
|
||||
@tag :require_ast
|
||||
test "String.Chars protocol dispatch" do
|
||||
files = %{
|
||||
|
||||
Reference in New Issue
Block a user