@@ -148,12 +148,13 @@ defmodule Module.Types.Pattern do
148148 [ var , { :arg , index , expected , expr } | path ] , { var_changed? , context } ->
149149 actual = Enum . fetch! ( types , index )
150150
151- case of_pattern_var ( path , actual , info , context ) do
152- { :ok , type } ->
151+ case of_pattern_var ( path , actual , true , info , context ) do
152+ { type , reachable_var? } ->
153153 case Of . refine_var ( var , type , expr , stack , context ) do
154154 { :ok , type , context } ->
155- { var_changed? or current_type == nil or not equal? ( current_type , type ) ,
156- context }
155+ { var_changed? or
156+ ( reachable_var? and
157+ ( current_type == nil or not equal? ( current_type , type ) ) ) , context }
157158
158159 { :error , _type , context } ->
159160 throw ( { types , context } )
@@ -226,44 +227,46 @@ defmodule Module.Types.Pattern do
226227 end
227228 end
228229
229- defp of_pattern_var ( [ ] , type , _info , _context ) do
230- { :ok , type }
230+ defp of_pattern_var ( [ ] , type , reachable_var? , _info , _context ) do
231+ { type , reachable_var? }
231232 end
232233
233- defp of_pattern_var ( [ { :elem , index } | rest ] , type , info , context ) when is_integer ( index ) do
234+ defp of_pattern_var ( [ { :elem , index } | rest ] , type , reachable_var? , info , context )
235+ when is_integer ( index ) do
234236 case tuple_fetch ( type , index ) do
235- { _optional? , type } -> of_pattern_var ( rest , type , info , context )
237+ { _optional? , type } -> of_pattern_var ( rest , type , reachable_var? , info , context )
236238 _reason -> :error
237239 end
238240 end
239241
240- defp of_pattern_var ( [ { :key , field } | rest ] , type , info , context ) when is_atom ( field ) do
242+ defp of_pattern_var ( [ { :key , field } | rest ] , type , reachable_var? , info , context )
243+ when is_atom ( field ) do
241244 case map_fetch ( type , field ) do
242- { _optional? , type } -> of_pattern_var ( rest , type , info , context )
245+ { _optional? , type } -> of_pattern_var ( rest , type , reachable_var? , info , context )
243246 _reason -> :error
244247 end
245248 end
246249
247250 # TODO: Implement domain key types
248- defp of_pattern_var ( [ { :key , _key } | rest ] , _type , info , context ) do
249- of_pattern_var ( rest , dynamic ( ) , info , context )
251+ defp of_pattern_var ( [ { :key , _key } | rest ] , _type , reachable_var? , info , context ) do
252+ of_pattern_var ( rest , dynamic ( ) , reachable_var? , info , context )
250253 end
251254
252- defp of_pattern_var ( [ { :head , counter } | rest ] , type , info , context ) do
255+ defp of_pattern_var ( [ { :head , counter } | rest ] , type , _reachable_var? , info , context ) do
253256 case list_hd ( type ) do
254257 { _ , head } ->
255258 tree = Map . fetch! ( info , - counter )
256259 type = intersection ( of_pattern_tree ( tree , context ) , head )
257- of_pattern_var ( rest , type , info , context )
260+ of_pattern_var ( rest , type , false , info , context )
258261
259262 _ ->
260263 :error
261264 end
262265 end
263266
264- defp of_pattern_var ( [ :tail | rest ] , type , info , context ) do
267+ defp of_pattern_var ( [ :tail | rest ] , type , reachable_var? , info , context ) do
265268 case list_tl ( type ) do
266- { _ , tail } -> of_pattern_var ( rest , tail , info , context )
269+ { _ , tail } -> of_pattern_var ( rest , tail , reachable_var? , info , context )
267270 _ -> :error
268271 end
269272 end
0 commit comments