File tree Expand file tree Collapse file tree 2 files changed +60
-6
lines changed Expand file tree Collapse file tree 2 files changed +60
-6
lines changed Original file line number Diff line number Diff line change @@ -1031,11 +1031,21 @@ defmodule Module.Types.Apply do
1031
1031
1032
1032
Code . ensure_loaded? ( mod ) and
1033
1033
Keyword . has_key? ( mod . module_info ( :attributes ) , :__protocol__ ) ->
1034
- # Protocol errors can be very verbose, so we collapse structs
1035
- """
1036
- but expected a type that implements the #{ inspect ( mod ) } protocol, it must be one of:
1037
- #{ clauses_args_to_quoted_string ( clauses , converter , collapse_structs: true ) }
1038
- """
1034
+ if function_exported? ( mod , :__protocol__ , 1 ) and
1035
+ mod . __protocol__ ( :impls ) == { :consolidated , [ ] } do
1036
+ """
1037
+ but the protocol was not yet implemented for any type and therefore will always fail. \
1038
+ This error typically happens within libraries that define protocols and will disappear as \
1039
+ soon as there is one implementation. If you expect the protocol to be implemented later on, \
1040
+ you can define an implementation specific for development/test.
1041
+ """
1042
+ else
1043
+ # Protocol errors can be very verbose, so we collapse structs
1044
+ """
1045
+ but expected a type that implements the #{ inspect ( mod ) } protocol, it must be one of:
1046
+ #{ clauses_args_to_quoted_string ( clauses , converter , collapse_structs: true ) }
1047
+ """
1048
+ end
1039
1049
1040
1050
true ->
1041
1051
"""
Original file line number Diff line number Diff line change @@ -384,7 +384,7 @@ defmodule Module.Types.IntegrationTest do
384
384
assert_no_warnings ( files )
385
385
end
386
386
387
- test "mismatched impl " do
387
+ test "mismatched implementation " do
388
388
files = % {
389
389
"a.ex" => """
390
390
defprotocol Itself do
@@ -420,6 +420,50 @@ defmodule Module.Types.IntegrationTest do
420
420
assert_warnings ( files , warnings )
421
421
end
422
422
423
+ @ tag :require_ast
424
+ test "no implementation" do
425
+ files = % {
426
+ "a.ex" => """
427
+ defprotocol NoImplProtocol do
428
+ def callback(data)
429
+ end
430
+ """ ,
431
+ "b.ex" => """
432
+ defmodule NoImplProtocol.Caller do
433
+ def run do
434
+ NoImplProtocol.callback(:hello)
435
+ end
436
+ end
437
+ """
438
+ }
439
+
440
+ warnings = [
441
+ """
442
+ warning: incompatible types given to NoImplProtocol.callback/1:
443
+
444
+ NoImplProtocol.callback(:hello)
445
+
446
+ given types:
447
+
448
+ -:hello-
449
+
450
+ but the protocol was not yet implemented for any type and therefore will always fail. \
451
+ This error typically happens within libraries that define protocols and will disappear as \
452
+ soon as there is one implementation. If you expect the protocol to be implemented later on, \
453
+ you can define an implementation specific for development/test.
454
+
455
+ typing violation found at:
456
+ │
457
+ 3 │ NoImplProtocol.callback(:hello)
458
+ │ ~
459
+ │
460
+ └─ b.ex:3:20: NoImplProtocol.Caller.run/0
461
+ """
462
+ ]
463
+
464
+ assert_warnings ( files , warnings , consolidate_protocols: true )
465
+ end
466
+
423
467
@ tag :require_ast
424
468
test "String.Chars protocol dispatch" do
425
469
files = % {
You can’t perform that action at this time.
0 commit comments