@@ -239,13 +239,15 @@ defmodule Module.Types.Expr do
239239 # TODO: case expr do pat -> expr end
240240 def of_expr ( { :case , _meta , [ case_expr , [ { :do , clauses } ] ] } , stack , context ) do
241241 { _expr_type , context } = of_expr ( case_expr , stack , context )
242- context = of_clauses ( clauses , stack , context )
243- { dynamic ( ) , context }
242+
243+ clauses
244+ |> of_clauses ( stack , { none ( ) , context } )
245+ |> dynamic_unless_static ( stack )
244246 end
245247
246248 # TODO: fn pat -> expr end
247249 def of_expr ( { :fn , _meta , clauses } , stack , context ) do
248- context = of_clauses ( clauses , stack , context )
250+ { _acc , context } = of_clauses ( clauses , stack , { none ( ) , context } )
249251 { fun ( ) , context }
250252 end
251253
@@ -269,35 +271,34 @@ defmodule Module.Types.Expr do
269271 of_expr_context ( body , stack , context )
270272
271273 { block , clauses } , context when block in @ try_clause_blocks ->
272- of_clauses ( clauses , stack , context )
274+ { _ , context } = of_clauses ( clauses , stack , { none ( ) , context } )
275+ context
273276 end )
274277
275278 { dynamic ( ) , context }
276279 end
277280
278- # TODO: receive do pat -> expr end
279281 def of_expr ( { :receive , _meta , [ blocks ] } , stack , context ) do
280- context =
281- Enum . reduce ( blocks , context , fn
282- { :do , { :__block__ , _ , [ ] } } , context ->
283- context
284-
285- { :do , clauses } , context ->
286- of_clauses ( clauses , stack , context )
282+ blocks
283+ |> Enum . reduce ( { none ( ) , context } , fn
284+ { :do , { :__block__ , _ , [ ] } } , { acc , context } ->
285+ { acc , context }
287286
288- { :after , [ { :-> , meta , [ [ timeout ] , body ] } ] } , context ->
289- { timeout_type , context } = of_expr ( timeout , stack , context )
290- { _body_type , context } = of_expr ( body , stack , context )
287+ { :do , clauses } , { acc , context } ->
288+ of_clauses ( clauses , stack , { acc , context } )
291289
292- if integer_type? ( timeout_type ) do
293- context
294- else
295- error = { :badtimeout , timeout_type , timeout , context }
296- error ( __MODULE__ , error , meta , stack , context )
297- end
298- end )
290+ { :after , [ { :-> , meta , [ [ timeout ] , body ] } ] } , { acc , context } ->
291+ { timeout_type , context } = of_expr ( timeout , stack , context )
292+ { body_type , context } = of_expr ( body , stack , context )
299293
300- { dynamic ( ) , context }
294+ if integer_type? ( timeout_type ) do
295+ { union ( body_type , acc ) , context }
296+ else
297+ error = { :badtimeout , timeout_type , timeout , context }
298+ { union ( body_type , acc ) , error ( __MODULE__ , error , meta , stack , context ) }
299+ end
300+ end )
301+ |> dynamic_unless_static ( stack )
301302 end
302303
303304 # TODO: for pat <- expr do expr end
@@ -307,7 +308,7 @@ defmodule Module.Types.Expr do
307308 context = Enum . reduce ( opts , context , & for_option ( & 1 , stack , & 2 ) )
308309
309310 if Keyword . has_key? ( opts , :reduce ) do
310- context = of_clauses ( block , stack , context )
311+ { _ , context } = of_clauses ( block , stack , { none ( ) , context } )
311312 { dynamic ( ) , context }
312313 else
313314 { _type , context } = of_expr ( block , stack , context )
@@ -484,7 +485,8 @@ defmodule Module.Types.Expr do
484485 end
485486
486487 defp with_option ( { :else , clauses } , stack , context ) do
487- of_clauses ( clauses , stack , context )
488+ { _ , context } = of_clauses ( clauses , stack , { none ( ) , context } )
489+ context
488490 end
489491
490492 ## General helpers
@@ -515,13 +517,12 @@ defmodule Module.Types.Expr do
515517 defp dynamic_unless_static ( { _ , _ } = output , % { mode: :static } ) , do: output
516518 defp dynamic_unless_static ( { type , context } , % { mode: _ } ) , do: { dynamic ( type ) , context }
517519
518- defp of_clauses ( clauses , stack , context ) do
519- Enum . reduce ( clauses , context , fn { :-> , meta , [ head , body ] } , context ->
520+ defp of_clauses ( clauses , stack , acc_context ) do
521+ Enum . reduce ( clauses , acc_context , fn { :-> , meta , [ head , body ] } , { acc , context } ->
520522 { patterns , guards } = extract_head ( head )
521-
522523 { _types , context } = Pattern . of_head ( patterns , guards , meta , stack , context )
523- { _ , context } = of_expr ( body , stack , context )
524- context
524+ { body , context } = of_expr ( body , stack , context )
525+ { union ( acc , body ) , context }
525526 end )
526527 end
527528
0 commit comments