@@ -72,7 +72,8 @@ defmodule Module.Types.Pattern do
7272 stack ,
7373 context
7474 ) do
75- with { :ok , type , context } <- of_pattern_intersect ( tree , type , pattern , tag , stack , context ) do
75+ with { :ok , type , context } <-
76+ of_pattern_intersect ( tree , type , pattern , index , tag , stack , context ) do
7677 acc = [ type | acc ]
7778 of_pattern_args_tree ( tail , expected_types , changed , index + 1 , acc , tag , stack , context )
7879 end
@@ -115,7 +116,7 @@ defmodule Module.Types.Pattern do
115116 { [ type ] , context } =
116117 of_pattern_recur ( [ expected ] , tag , stack , context , fn [ type ] , [ 0 ] , context ->
117118 with { :ok , type , context } <-
118- of_pattern_intersect ( tree , type , expr , tag , stack , context ) do
119+ of_pattern_intersect ( tree , type , expr , 0 , tag , stack , context ) do
119120 { :ok , [ type ] , context }
120121 end
121122 end )
@@ -177,7 +178,7 @@ defmodule Module.Types.Pattern do
177178 end
178179
179180 :error ->
180- throw ( { types , badpattern_error ( expr , tag , stack , context ) } )
181+ throw ( { types , badpattern_error ( expr , index , tag , stack , context ) } )
181182 end
182183 end )
183184
@@ -216,23 +217,23 @@ defmodule Module.Types.Pattern do
216217 end )
217218 end
218219
219- defp badpattern_error ( expr , tag , stack , context ) do
220+ defp badpattern_error ( expr , index , tag , stack , context ) do
220221 meta =
221222 if meta = get_meta ( expr ) do
222223 meta ++ Keyword . take ( stack . meta , [ :generated , :line ] )
223224 else
224225 stack . meta
225226 end
226227
227- error ( __MODULE__ , { :badpattern , expr , tag , context } , meta , stack , context )
228+ error ( __MODULE__ , { :badpattern , expr , index , tag , context } , meta , stack , context )
228229 end
229230
230- defp of_pattern_intersect ( tree , expected , expr , tag , stack , context ) do
231+ defp of_pattern_intersect ( tree , expected , expr , index , tag , stack , context ) do
231232 actual = of_pattern_tree ( tree , context )
232233 type = intersection ( actual , expected )
233234
234235 if empty? ( type ) do
235- { :error , badpattern_error ( expr , tag , stack , context ) }
236+ { :error , badpattern_error ( expr , index , tag , stack , context ) }
236237 else
237238 { :ok , type , context }
238239 end
@@ -750,8 +751,8 @@ defmodule Module.Types.Pattern do
750751 #
751752 # The match pattern ones have the whole expression instead
752753 # of a single pattern.
753- def format_diagnostic ( { :badpattern , pattern_or_expr , tag , context } ) do
754- { to_trace , message } = badpattern ( tag , pattern_or_expr )
754+ def format_diagnostic ( { :badpattern , pattern_or_expr , index , tag , context } ) do
755+ { to_trace , message } = badpattern ( tag , pattern_or_expr , index )
755756 traces = collect_traces ( to_trace , context )
756757
757758 % {
@@ -760,7 +761,7 @@ defmodule Module.Types.Pattern do
760761 }
761762 end
762763
763- defp badpattern ( { :try_else , type } , pattern ) do
764+ defp badpattern ( { :try_else , type } , pattern , _ ) do
764765 { pattern ,
765766 """
766767 the following clause will never match:
@@ -773,7 +774,7 @@ defmodule Module.Types.Pattern do
773774 """ }
774775 end
775776
776- defp badpattern ( { :case , meta , type , expr } , pattern ) do
777+ defp badpattern ( { :case , meta , type , expr } , pattern , _ ) do
777778 if meta [ :type_check ] == :expr do
778779 { expr ,
779780 """
@@ -799,7 +800,7 @@ defmodule Module.Types.Pattern do
799800 end
800801 end
801802
802- defp badpattern ( { :match , type } , expr ) do
803+ defp badpattern ( { :match , type } , expr , _ ) do
803804 { expr ,
804805 """
805806 the following pattern will never match:
@@ -812,7 +813,32 @@ defmodule Module.Types.Pattern do
812813 """ }
813814 end
814815
815- defp badpattern ( _tag , pattern_or_expr ) do
816+ defp badpattern ( { :infer , types } , pattern_or_expr , index ) do
817+ type = Enum . fetch! ( types , index )
818+
819+ if type == dynamic ( ) do
820+ { pattern_or_expr ,
821+ """
822+ the #{ integer_to_ordinal ( index + 1 ) } pattern in clause will never match:
823+
824+ #{ expr_to_string ( pattern_or_expr ) |> indent ( 4 ) }
825+ """ }
826+ else
827+ # This can only happen in protocol implementations
828+ { pattern_or_expr ,
829+ """
830+ the #{ integer_to_ordinal ( index + 1 ) } pattern in clause will never match:
831+
832+ #{ expr_to_string ( pattern_or_expr ) |> indent ( 4 ) }
833+
834+ because it is expected to receive type:
835+
836+ #{ to_quoted_string ( type ) |> indent ( 4 ) }
837+ """ }
838+ end
839+ end
840+
841+ defp badpattern ( :default , pattern_or_expr , _ ) do
816842 { pattern_or_expr ,
817843 """
818844 the following pattern will never match:
0 commit comments