@@ -104,6 +104,7 @@ defmodule Kernel.RecordRewriter do
104104
105105 defp optimize_expr ( { :tuple , line , args } , dict ) do
106106 { args , dict , args_res } = optimize_tuple_args ( args , dict )
107+ args_res = if Enum . any? ( args_res ) , do: args_res , else: nil
107108
108109 res =
109110 case args do
@@ -116,7 +117,7 @@ defmodule Kernel.RecordRewriter do
116117
117118 defp optimize_expr ( { :var , _ , name } = var , dict ) do
118119 case :orddict . find ( name , dict ) do
119- { :ok , res } -> { var , dict , { res , nil } }
120+ { :ok , res } -> { var , dict , res }
120121 :error -> { var , dict , nil }
121122 end
122123 end
@@ -130,6 +131,38 @@ defmodule Kernel.RecordRewriter do
130131 { { :case , line , expr , clauses } , dict , res }
131132 end
132133
134+ defp optimize_expr ( { :receive , line , clauses } , dict ) do
135+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
136+ clauses = lc { clause , _ , _ } in list tuples , do: clause
137+ dict = join_dict ( tuples )
138+ res = join_result ( tuples )
139+ { { :receive , line , clauses } , dict , res }
140+ end
141+
142+ defp optimize_expr ( { :receive , line , clauses , after_key , after_value } , dict ) do
143+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
144+ clauses = lc { clause , _ , _ } in list tuples , do: clause
145+
146+ { after_key , dict , _ } = optimize_expr ( after_key , dict )
147+ { after_value , dict , res } = optimize_body ( after_value , dict , [ ] )
148+
149+ dict = join_dict ( tuples , dict )
150+ res = join_result ( tuples , res )
151+
152+ { { :receive , line , clauses , after_key , after_value } , dict , res }
153+ end
154+
155+ defp optimize_expr ( { :try , line , body , [ ] , clauses , try_after } , dict ) do
156+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
157+ clauses = lc { clause , _ , _ } in list tuples , do: clause
158+
159+ { body , _ , res } = optimize_body ( body , dict , [ ] )
160+ res = join_result ( tuples , res )
161+
162+ { try_after , _ , _ } = optimize_body ( try_after , dict , [ ] )
163+ { { :try , line , body , [ ] , clauses , try_after } , dict , res }
164+ end
165+
133166 defp optimize_expr ( { :fun , line , { :function , module , name , arity } } , dict ) do
134167 { module , dict , _ } = optimize_expr ( module , dict )
135168 { name , dict , _ } = optimize_expr ( name , dict )
@@ -179,14 +212,16 @@ defmodule Kernel.RecordRewriter do
179212 if is_record? ( value ) do
180213 dict =
181214 case :orddict . find ( key , dict ) do
182- { :ok , ^ value } ->
215+ { :ok , ^ res } ->
183216 dict
217+ { :ok , { ^ value , _ } } ->
218+ :orddict . store ( key , { value , nil } , dict )
184219 { :ok , _ } ->
185220 # We are overriding a type of an existing variable,
186221 # which means the source code is invalid.
187222 :orddict . store ( key , nil , dict )
188223 :error ->
189- :orddict . store ( key , value , dict )
224+ :orddict . store ( key , res , dict )
190225 end
191226 end
192227
@@ -232,9 +267,10 @@ defmodule Kernel.RecordRewriter do
232267
233268 defp join_dict ( [ { _ , dict , _ } | t ] , other ) do
234269 other = Enum . reduce other , other , fn
235- { key , value } , acc ->
270+ { key , { value , _ } = res } , acc ->
236271 case :orddict . find ( key , dict ) do
237- { :ok , ^ value } -> acc
272+ { :ok , ^ res } -> acc
273+ { :ok , { ^ value , _ } } -> :orddict . store ( key , { value , nil } , acc )
238274 { :ok , _ } -> :orddict . store ( key , nil , acc )
239275 :error -> :orddict . erase ( key , acc )
240276 end
@@ -255,6 +291,10 @@ defmodule Kernel.RecordRewriter do
255291 join_result ( t , res )
256292 end
257293
294+ defp join_result ( [ { _ , _ , { res , _ } } | t ] , { res , _ } ) do
295+ join_result ( t , { res , nil } )
296+ end
297+
258298 defp join_result ( [ { _ , _ , _ } | _ ] , _res ) do
259299 nil
260300 end
0 commit comments