@@ -38,11 +38,6 @@ defmodule Module.Types.Pattern do
38
38
of_pattern ( expr , { dynamic ( ) , expr } , stack , context )
39
39
end
40
40
41
- # ^var
42
- def of_pattern ( { :^ , _meta , [ var ] } , expected_expr , stack , context ) do
43
- Of . intersect ( Of . var ( var , context ) , expected_expr , stack , context )
44
- end
45
-
46
41
# left = right
47
42
# TODO: Track variables and handle nesting
48
43
def of_pattern ( { := , _meta , [ left_expr , right_expr ] } , { expected , expr } , stack , context ) do
@@ -73,7 +68,7 @@ defmodule Module.Types.Pattern do
73
68
)
74
69
when not is_atom ( struct_var ) do
75
70
with { :ok , struct_type , context } <-
76
- of_pattern ( struct_var , { atom ( ) , expr } , % { stack | refine: false } , context ) ,
71
+ of_struct_var ( struct_var , { atom ( ) , expr } , stack , context ) ,
77
72
{ :ok , map_type , context } <-
78
73
of_open_map ( args , [ __struct__: struct_type ] , expected_expr , stack , context ) ,
79
74
{ _ , struct_type } = map_fetch ( map_type , :__struct__ ) ,
@@ -111,23 +106,8 @@ defmodule Module.Types.Pattern do
111
106
end
112
107
113
108
# var
114
- def of_pattern ( { name , meta , ctx } = var , { expected , expr } , stack , context )
115
- when is_atom ( name ) and is_atom ( ctx ) do
116
- case stack do
117
- % { refine: true } ->
118
- Of . refine_var ( var , expected , expr , stack , context )
119
-
120
- % { refine: false } ->
121
- version = Keyword . fetch! ( meta , :version )
122
-
123
- case context do
124
- % { vars: % { ^ version => % { type: type } } } ->
125
- Of . intersect ( type , { expected , expr } , stack , context )
126
-
127
- % { } ->
128
- { :ok , expected , context }
129
- end
130
- end
109
+ def of_pattern ( var , expected_expr , stack , context ) when is_var ( var ) do
110
+ Of . refine_var ( var , expected_expr , stack , context )
131
111
end
132
112
133
113
def of_pattern ( expr , expected_expr , stack , context ) do
@@ -198,21 +178,39 @@ defmodule Module.Types.Pattern do
198
178
end
199
179
end
200
180
201
- # ^var
202
- # Happens from inside size(^...) and map keys
203
- def of_guard ( { :^ , _meta , [ var ] } , expected_expr , stack , context ) do
204
- Of . intersect ( Of . var ( var , context ) , expected_expr , stack , context )
205
- end
206
-
207
181
# var
208
182
def of_guard ( var , expected_expr , stack , context ) when is_var ( var ) do
183
+ # TODO: This should be ver refinement once we have inference in guards
184
+ # Of.refine_var(var, expected_expr, stack, context)
209
185
Of . intersect ( Of . var ( var , context ) , expected_expr , stack , context )
210
186
end
211
187
212
188
def of_guard ( expr , expected_expr , stack , context ) do
213
189
of_shared ( expr , expected_expr , stack , context , & of_guard / 4 )
214
190
end
215
191
192
+ ## Helpers
193
+
194
+ defp of_struct_var ( { :_ , _ , _ } , { expected , _expr } , _stack , context ) do
195
+ { :ok , expected , context }
196
+ end
197
+
198
+ defp of_struct_var ( { :^ , _ , [ var ] } , expected_expr , stack , context ) do
199
+ Of . intersect ( Of . var ( var , context ) , expected_expr , stack , context )
200
+ end
201
+
202
+ defp of_struct_var ( { _name , meta , _ctx } , expected_expr , stack , context ) do
203
+ version = Keyword . fetch! ( meta , :version )
204
+
205
+ case context do
206
+ % { vars: % { ^ version => % { type: type } } } ->
207
+ Of . intersect ( type , expected_expr , stack , context )
208
+
209
+ % { } ->
210
+ { :ok , elem ( expected_expr , 0 ) , context }
211
+ end
212
+ end
213
+
216
214
## Shared
217
215
218
216
# :atom
@@ -269,6 +267,12 @@ defmodule Module.Types.Pattern do
269
267
of_shared ( { :{} , [ ] , [ left , right ] } , expected_expr , stack , context , fun )
270
268
end
271
269
270
+ # ^var
271
+ defp of_shared ( { :^ , _meta , [ var ] } , expected_expr , stack , context , _fun ) do
272
+ # This is by definition a variable defined outside of this pattern, so we don't track it.
273
+ Of . intersect ( Of . var ( var , context ) , expected_expr , stack , context )
274
+ end
275
+
272
276
# left | []
273
277
defp of_shared ( { :| , _meta , [ left_expr , [ ] ] } , _expected_expr , stack , context , fun ) do
274
278
fun . ( left_expr , { dynamic ( ) , left_expr } , stack , context )
@@ -303,6 +307,7 @@ defmodule Module.Types.Pattern do
303
307
end
304
308
305
309
# {...}
310
+ # TODO: Implement this
306
311
defp of_shared ( { :{} , _meta , exprs } , _expected_expr , stack , context , fun ) do
307
312
case map_reduce_ok ( exprs , context , & fun . ( & 1 , { dynamic ( ) , & 1 } , stack , & 2 ) ) do
308
313
{ :ok , types , context } -> { :ok , tuple ( types ) , context }
0 commit comments