@@ -10,13 +10,15 @@ defmodule Module.Types.Expr do
1010 functions_and_macros = list ( tuple ( [ atom ( ) , list ( tuple ( [ atom ( ) , integer ( ) ] ) ) ] ) )
1111 list_of_modules = list ( atom ( ) )
1212
13+ @ try_catch atom ( [ :error , :exit , :throw ] )
14+
1315 @ caller closed_map (
1416 __struct__: atom ( [ Macro.Env ] ) ,
1517 aliases: aliases ,
1618 context: atom ( [ :match , :guard , nil ] ) ,
1719 context_modules: list_of_modules ,
1820 file: binary ( ) ,
19- function: union ( tuple ( ) , atom ( [ nil ] ) ) ,
21+ function: union ( tuple ( [ atom ( ) , integer ( ) ] ) , atom ( [ nil ] ) ) ,
2022 functions: functions_and_macros ,
2123 lexical_tracker: union ( pid ( ) , atom ( [ nil ] ) ) ,
2224 line: integer ( ) ,
@@ -108,13 +110,13 @@ defmodule Module.Types.Expr do
108110 end
109111
110112 # left = right
111- def of_expr ( { := , _meta , [ left_expr , right_expr ] } = expr , stack , context ) do
113+ def of_expr ( { := , _ , [ left_expr , right_expr ] } = expr , stack , context ) do
112114 { right_type , context } = of_expr ( right_expr , stack , context )
113115
114116 # We do not raise on underscore in case someone writes _ = raise "omg"
115117 case left_expr do
116118 { :_ , _ , ctx } when is_atom ( ctx ) -> { right_type , context }
117- _ -> Pattern . of_match ( left_expr , right_type , expr , stack , context )
119+ _ -> Pattern . of_match ( left_expr , right_type , expr , { :match , expr } , stack , context )
118120 end
119121 end
120122
@@ -245,15 +247,16 @@ defmodule Module.Types.Expr do
245247 { expr_type , context } = of_expr ( case_expr , stack , context )
246248
247249 clauses
248- |> of_clauses ( stack , [ expr_type ] , { none ( ) , context } )
250+ |> of_clauses ( [ expr_type ] , { :case , case_expr } , stack , { none ( ) , context } )
249251 |> dynamic_unless_static ( stack )
250252 end
251253
252254 # TODO: fn pat -> expr end
253255 def of_expr ( { :fn , _meta , clauses } , stack , context ) do
254- [ { :-> , _ , [ args , _ ] } | _ ] = clauses
255- expected = Enum . map ( args , fn _ -> dynamic ( ) end )
256- { _acc , context } = of_clauses ( clauses , stack , expected , { none ( ) , context } )
256+ [ { :-> , _ , [ head , _ ] } | _ ] = clauses
257+ { patterns , _guards } = extract_head ( head )
258+ expected = Enum . map ( patterns , fn _ -> dynamic ( ) end )
259+ { _acc , context } = of_clauses ( clauses , expected , :fn , stack , { none ( ) , context } )
257260 { fun ( ) , context }
258261 end
259262
@@ -280,22 +283,22 @@ defmodule Module.Types.Expr do
280283 { acc , context }
281284
282285 { :catch , clauses } , acc_context ->
283- of_clauses ( clauses , stack , [ atom ( [ :error , :exit , :throw ] ) , dynamic ( ) ] , acc_context )
286+ of_clauses ( clauses , [ @ try_catch , dynamic ( ) ] , :try_catch , stack , acc_context )
284287
285288 { :else , clauses } , acc_context ->
286- of_clauses ( clauses , stack , [ body_type ] , acc_context )
289+ of_clauses ( clauses , [ body_type ] , :try_else , stack , acc_context )
287290 end )
288291 |> dynamic_unless_static ( stack )
289292 end
290293
291294 def of_expr ( { :receive , _meta , [ blocks ] } , stack , context ) do
292295 blocks
293296 |> Enum . reduce ( { none ( ) , context } , fn
294- { :do , { :__block__ , _ , [ ] } } , { acc , context } ->
295- { acc , context }
297+ { :do , { :__block__ , _ , [ ] } } , acc_context ->
298+ acc_context
296299
297- { :do , clauses } , { acc , context } ->
298- of_clauses ( clauses , stack , [ dynamic ( ) ] , { acc , context } )
300+ { :do , clauses } , acc_context ->
301+ of_clauses ( clauses , [ dynamic ( ) ] , :receive , stack , acc_context )
299302
300303 { :after , [ { :-> , meta , [ [ timeout ] , body ] } ] } , { acc , context } ->
301304 { timeout_type , context } = of_expr ( timeout , stack , context )
@@ -318,7 +321,7 @@ defmodule Module.Types.Expr do
318321 context = Enum . reduce ( opts , context , & for_option ( & 1 , stack , & 2 ) )
319322
320323 if Keyword . has_key? ( opts , :reduce ) do
321- { _ , context } = of_clauses ( block , stack , [ dynamic ( ) ] , { none ( ) , context } )
324+ { _ , context } = of_clauses ( block , [ dynamic ( ) ] , :for_reduce , stack , { none ( ) , context } )
322325 { dynamic ( ) , context }
323326 else
324327 { _type , context } = of_expr ( block , stack , context )
@@ -441,16 +444,21 @@ defmodule Module.Types.Expr do
441444
442445 ## Comprehensions
443446
444- defp for_clause ( { :<- , meta , [ left , expr ] } , stack , context ) do
447+ defp for_clause ( { :<- , _ , [ left , right ] } = expr , stack , context ) do
445448 { pattern , guards } = extract_head ( [ left ] )
446- { _expr_type , context } = of_expr ( expr , stack , context )
447- { [ _type ] , context } = Pattern . of_head ( [ pattern ] , guards , meta , stack , context )
449+ { _ , context } = of_expr ( right , stack , context )
450+
451+ { _type , context } =
452+ Pattern . of_match ( pattern , guards , dynamic ( ) , expr , { :for , expr } , stack , context )
453+
448454 context
449455 end
450456
451- defp for_clause ( { :<<>> , _ , [ { :<- , meta , [ left , right ] } ] } , stack , context ) do
457+ defp for_clause ( { :<<>> , _ , [ { :<- , meta , [ left , right ] } ] } = expr , stack , context ) do
452458 { right_type , context } = of_expr ( right , stack , context )
453- { _pattern_type , context } = Pattern . of_match ( left , binary ( ) , left , stack , context )
459+
460+ { _pattern_type , context } =
461+ Pattern . of_match ( left , binary ( ) , expr , { :for , expr } , stack , context )
454462
455463 if binary_type? ( right_type ) do
456464 context
@@ -481,11 +489,13 @@ defmodule Module.Types.Expr do
481489
482490 ## With
483491
484- defp with_clause ( { :<- , meta , [ left , expr ] } , stack , context ) do
492+ defp with_clause ( { :<- , meta , [ left , right ] } = expr , stack , context ) do
485493 { pattern , guards } = extract_head ( [ left ] )
486494
487- { [ _type ] , context } = Pattern . of_head ( [ pattern ] , guards , meta , stack , context )
488- { _expr_type , context } = of_expr ( expr , stack , context )
495+ { [ _type ] , context } =
496+ Pattern . of_head ( [ pattern ] , guards , [ dynamic ( ) ] , { :with , expr } , meta , stack , context )
497+
498+ { _ , context } = of_expr ( right , stack , context )
489499 context
490500 end
491501
@@ -500,7 +510,7 @@ defmodule Module.Types.Expr do
500510 end
501511
502512 defp with_option ( { :else , clauses } , stack , context ) do
503- { _ , context } = of_clauses ( clauses , stack , [ dynamic ( ) ] , { none ( ) , context } )
513+ { _ , context } = of_clauses ( clauses , [ dynamic ( ) ] , :with_else , stack , { none ( ) , context } )
504514 context
505515 end
506516
@@ -532,10 +542,10 @@ defmodule Module.Types.Expr do
532542 defp dynamic_unless_static ( { _ , _ } = output , % { mode: :static } ) , do: output
533543 defp dynamic_unless_static ( { type , context } , % { mode: _ } ) , do: { dynamic ( type ) , context }
534544
535- defp of_clauses ( clauses , stack , _expected , acc_context ) do
545+ defp of_clauses ( clauses , expected , info , stack , acc_context ) do
536546 Enum . reduce ( clauses , acc_context , fn { :-> , meta , [ head , body ] } , { acc , context } ->
537547 { patterns , guards } = extract_head ( head )
538- { _types , context } = Pattern . of_head ( patterns , guards , meta , stack , context )
548+ { _types , context } = Pattern . of_head ( patterns , guards , expected , info , meta , stack , context )
539549 { body , context } = of_expr ( body , stack , context )
540550 { union ( acc , body ) , context }
541551 end )
0 commit comments