@@ -30,7 +30,7 @@ defmodule Module.Types.Expr do
30
30
versioned_vars: open_map ( )
31
31
)
32
32
33
- # This is used temporarily until reverse arrows are defined
33
+ # An annotation for terms where the reverse arrow is not yet fully defined
34
34
@ pending term ( )
35
35
@ atom_true atom ( [ true ] )
36
36
@ exception open_map ( __struct__: atom ( ) , __exception__: @ atom_true )
@@ -90,28 +90,13 @@ defmodule Module.Types.Expr do
90
90
end
91
91
92
92
# {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 )
103
95
end
104
96
105
97
# {...}
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 )
115
100
end
116
101
117
102
# <<...>>>
@@ -533,6 +518,32 @@ defmodule Module.Types.Expr do
533
518
end
534
519
end
535
520
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
+
536
547
## Try
537
548
538
549
defp of_rescue ( var , exceptions , body , expr , info , meta , stack , original ) do
0 commit comments