@@ -127,10 +127,11 @@ defmodule Module.Types.Pattern do
127127 4. Then we propagate all dependencies to refine variables
128128
129129 """
130- def of_head ( patterns , guards , expected , tag , meta , stack , % { vars: vars } = context ) do
130+ def of_head ( patterns , guards , expected , previous \\ nil , tag , meta , stack , context ) do
131+ % { vars: vars } = context
131132 stack = % { stack | meta: meta }
132133
133- case of_pattern_args ( patterns , expected , tag , stack , context ) do
134+ case of_pattern_args ( patterns , expected , previous , tag , stack , context ) do
134135 { trees , pattern_precise? , changed , context } ->
135136 { guard_precise? , context } = of_guards ( guards , changed , vars , stack , context )
136137 { trees , pattern_precise? and guard_precise? , context }
@@ -157,20 +158,23 @@ defmodule Module.Types.Pattern do
157158 [ ]
158159 end
159160
160- defp of_pattern_args ( [ ] , [ ] , _tag , _stack , context ) do
161+ defp of_pattern_args ( [ ] , [ ] , _previous , _tag , _stack , context ) do
161162 { [ ] , true , [ ] , context }
162163 end
163164
164- defp of_pattern_args ( patterns , expected , tag , stack , context ) do
165+ defp of_pattern_args ( patterns , expected , previous , tag , stack , context ) do
165166 context = init_pattern_info ( context , [ ] )
166167
167168 { trees , precise? , context } =
168169 of_pattern_args_zip ( patterns , expected , 0 , [ ] , true , stack , context )
169170
170171 { pattern_info , context } = pop_pattern_info ( context )
171172
172- case of_pattern_intersect ( trees , 0 , [ ] , pattern_info , tag , stack , context ) do
173- { _types , changed , context } -> { trees , precise? , changed , context }
173+ with { :ok , types } <- of_pattern_intersect ( trees , 0 , [ ] , pattern_info , tag , stack , context ) ,
174+ { _types , changed , context } <-
175+ of_pattern_refine ( types , previous , pattern_info , tag , stack , context ) do
176+ { trees , precise? , changed , context }
177+ else
174178 { :error , context } -> { trees , context }
175179 end
176180 end
@@ -210,8 +214,11 @@ defmodule Module.Types.Pattern do
210214 args = [ { tree , expected , expr } ]
211215 tag = { :match , expected }
212216
213- case of_pattern_intersect ( args , 0 , [ ] , pattern_info , tag , stack , context ) do
214- { [ type ] , changed , context } -> { type , of_changed ( changed , stack , context ) }
217+ with { :ok , types } <- of_pattern_intersect ( args , 0 , [ ] , pattern_info , tag , stack , context ) ,
218+ { [ type ] , changed , context } <-
219+ of_pattern_refine ( types , nil , pattern_info , tag , stack , context ) do
220+ { type , of_changed ( changed , stack , context ) }
221+ else
215222 { :error , context } -> { expected , context }
216223 end
217224 end
@@ -228,11 +235,12 @@ defmodule Module.Types.Pattern do
228235 { pattern_info , context } = pop_pattern_info ( context )
229236 args = [ { tree , expected , pattern } ]
230237
231- case of_pattern_intersect ( args , 0 , [ ] , pattern_info , tag , stack , context ) do
232- { _types , changed , context } ->
233- { _precise? , context } = of_guards ( guards , changed , vars , stack , context )
234- context
235-
238+ with { :ok , types } <- of_pattern_intersect ( args , 0 , [ ] , pattern_info , tag , stack , context ) ,
239+ { _types , changed , context } <-
240+ of_pattern_refine ( types , nil , pattern_info , tag , stack , context ) do
241+ { _precise? , context } = of_guards ( guards , changed , vars , stack , context )
242+ context
243+ else
236244 { :error , context } ->
237245 context
238246 end
@@ -251,8 +259,20 @@ defmodule Module.Types.Pattern do
251259 end
252260 end
253261
254- defp of_pattern_intersect ( [ ] , _index , acc , pattern_info , tag , stack , context ) do
255- types = Enum . reverse ( acc )
262+ defp of_pattern_intersect ( [ ] , _index , acc , _pattern_info , _tag , _stack , _context ) do
263+ { :ok , Enum . reverse ( acc ) }
264+ end
265+
266+ defp of_pattern_refine ( types , previous , pattern_info , tag , stack , context ) do
267+ types =
268+ case previous do
269+ nil ->
270+ types
271+
272+ [ previous ] ->
273+ [ type ] = types
274+ [ difference ( type , previous ) ]
275+ end
256276
257277 try do
258278 pattern_info
@@ -1381,11 +1401,11 @@ defmodule Module.Types.Pattern do
13811401 true ->
13821402 { pattern ,
13831403 """
1384- the following clause cannot match because previous clauses already matched this pattern :
1404+ the following clause is redundant :
13851405
13861406 #{ expr_to_string ( pattern ) |> indent ( 4 ) } ->
13871407
1388- the following types have already been matched:
1408+ the following types are expected (and have already been matched) :
13891409
13901410 #{ to_quoted_string ( previous_type ) |> indent ( 4 ) }
13911411 """ }
0 commit comments