@@ -30,7 +30,7 @@ defmodule Module.Types.Expr do
3030 versioned_vars: open_map ( )
3131 )
3232
33- # This is used temporarily until reverse arrows are defined
33+ # An annotation for terms where the reverse arrow is not yet fully defined
3434 @ pending term ( )
3535 @ atom_true atom ( [ true ] )
3636 @ exception open_map ( __struct__: atom ( ) , __exception__: @ atom_true )
@@ -90,28 +90,13 @@ defmodule Module.Types.Expr do
9090 end
9191
9292 # {left, right}
93- # PENDING: here
94- def of_expr ( { left , right } , _expected , expr , stack , context ) do
95- { left , context } = of_expr ( left , @ pending , expr , stack , context )
96- { right , context } = of_expr ( right , @ pending , expr , stack , context )
97-
98- if stack . mode == :traversal do
99- { dynamic ( ) , context }
100- else
101- { tuple ( [ left , right ] ) , context }
102- end
93+ def of_expr ( { left , right } , expected , expr , stack , context ) do
94+ of_tuple ( [ left , right ] , expected , expr , stack , context )
10395 end
10496
10597 # {...}
106- # PENDING: here
107- def of_expr ( { :{} , _meta , exprs } , _expected , expr , stack , context ) do
108- { types , context } = Enum . map_reduce ( exprs , context , & of_expr ( & 1 , @ pending , expr , stack , & 2 ) )
109-
110- if stack . mode == :traversal do
111- { dynamic ( ) , context }
112- else
113- { tuple ( types ) , context }
114- end
98+ def of_expr ( { :{} , _meta , exprs } , expected , expr , stack , context ) do
99+ of_tuple ( exprs , expected , expr , stack , context )
115100 end
116101
117102 # <<...>>>
@@ -533,6 +518,32 @@ defmodule Module.Types.Expr do
533518 end
534519 end
535520
521+ ## Tuples
522+
523+ defp of_tuple ( elems , _expected , expr , % { mode: :traversal } = stack , context ) do
524+ { _types , context } = Enum . map_reduce ( elems , context , & of_expr ( & 1 , term ( ) , expr , stack , & 2 ) )
525+ { dynamic ( ) , context }
526+ end
527+
528+ defp of_tuple ( elems , expected , expr , stack , context ) do
529+ of_tuple ( elems , 0 , [ ] , expected , expr , stack , context )
530+ end
531+
532+ defp of_tuple ( [ elem | elems ] , index , acc , expected , expr , stack , context ) do
533+ expr_expected =
534+ case tuple_fetch ( expected , index ) do
535+ { _ , type } -> type
536+ _ -> term ( )
537+ end
538+
539+ { type , context } = of_expr ( elem , expr_expected , expr , stack , context )
540+ of_tuple ( elems , index + 1 , [ type | acc ] , expected , expr , stack , context )
541+ end
542+
543+ defp of_tuple ( [ ] , _index , acc , _expected , _expr , _stack , context ) do
544+ { tuple ( Enum . reverse ( acc ) ) , context }
545+ end
546+
536547 ## Try
537548
538549 defp of_rescue ( var , exceptions , body , expr , info , meta , stack , original ) do
0 commit comments