@@ -121,44 +121,42 @@ private[async] final case class AnfTransform[C <: Context](c: C) {
121
121
122
122
private object inline {
123
123
def transformToList (tree : Tree ): List [Tree ] = trace(" inline" , tree) {
124
+ def branchWithAssign (orig : Tree , varDef : ValDef ) = orig match {
125
+ case Block (stats, expr) => Block (stats, Assign (Ident (varDef.name), expr))
126
+ case _ => Assign (Ident (varDef.name), orig)
127
+ }
128
+
129
+ def casesWithAssign (cases : List [CaseDef ], varDef : ValDef ) = cases map {
130
+ case cd @ CaseDef (pat, guard, orig) =>
131
+ attachCopy(cd)(CaseDef (pat, guard, branchWithAssign(orig, varDef)))
132
+ }
133
+
124
134
val stats :+ expr = anf.transformToList(tree)
125
135
expr match {
136
+ // if type of if-else/try/match is Unit don't introduce assignment,
137
+ // but add Unit value to bring it into form expected by async transform
138
+ case If (_, _, _) | Try (_, _, _) | Match (_, _) if expr.tpe =:= definitions.UnitTpe =>
139
+ stats :+ expr :+ Literal (Constant (()))
140
+
126
141
case Apply (fun, args) if isAwait(fun) =>
127
142
val valDef = defineVal(name.await, expr, tree.pos)
128
143
stats :+ valDef :+ Ident (valDef.name)
129
144
130
145
case If (cond, thenp, elsep) =>
131
- // if type of if-else is Unit don't introduce assignment,
132
- // but add Unit value to bring it into form expected by async transform
133
- if (expr.tpe =:= definitions.UnitTpe ) {
134
- stats :+ expr :+ Literal (Constant (()))
135
- } else {
136
- val varDef = defineVar(name.ifRes, expr.tpe, tree.pos)
137
- def branchWithAssign (orig : Tree ) = orig match {
138
- case Block (thenStats, thenExpr) => Block (thenStats, Assign (Ident (varDef.name), thenExpr))
139
- case _ => Assign (Ident (varDef.name), orig)
140
- }
141
- val ifWithAssign = If (cond, branchWithAssign(thenp), branchWithAssign(elsep))
142
- stats :+ varDef :+ ifWithAssign :+ Ident (varDef.name)
143
- }
146
+ val varDef = defineVar(name.ifRes, expr.tpe, tree.pos)
147
+ val ifWithAssign = If (cond, branchWithAssign(thenp, varDef), branchWithAssign(elsep, varDef))
148
+ stats :+ varDef :+ ifWithAssign :+ Ident (varDef.name)
149
+
150
+ case Try (body, catches, finalizer) =>
151
+ val varDef = defineVar(name.tryRes, expr.tpe, tree.pos)
152
+ val tryWithAssign = Try (branchWithAssign(body, varDef), casesWithAssign(catches, varDef), finalizer)
153
+ stats :+ varDef :+ tryWithAssign :+ Ident (varDef.name)
144
154
145
155
case Match (scrut, cases) =>
146
- // if type of match is Unit don't introduce assignment,
147
- // but add Unit value to bring it into form expected by async transform
148
- if (expr.tpe =:= definitions.UnitTpe ) {
149
- stats :+ expr :+ Literal (Constant (()))
150
- }
151
- else {
152
- val varDef = defineVar(name.matchRes, expr.tpe, tree.pos)
153
- val casesWithAssign = cases map {
154
- case cd@ CaseDef (pat, guard, Block (caseStats, caseExpr)) =>
155
- attachCopy(cd)(CaseDef (pat, guard, Block (caseStats, Assign (Ident (varDef.name), caseExpr))))
156
- case cd@ CaseDef (pat, guard, body) =>
157
- attachCopy(cd)(CaseDef (pat, guard, Assign (Ident (varDef.name), body)))
158
- }
159
- val matchWithAssign = attachCopy(tree)(Match (scrut, casesWithAssign))
160
- stats :+ varDef :+ matchWithAssign :+ Ident (varDef.name)
161
- }
156
+ val varDef = defineVar(name.matchRes, expr.tpe, tree.pos)
157
+ val matchWithAssign = attachCopy(tree)(Match (scrut, casesWithAssign(cases, varDef)))
158
+ stats :+ varDef :+ matchWithAssign :+ Ident (varDef.name)
159
+
162
160
case _ =>
163
161
stats :+ expr
164
162
}
@@ -225,6 +223,11 @@ private[async] final case class AnfTransform[C <: Context](c: C) {
225
223
val stats :+ expr = inline.transformToList(rhs)
226
224
stats :+ attachCopy(tree)(Assign (lhs, expr))
227
225
226
+ case Try (body, catches, finalizer) if containsAwait =>
227
+ val stats :+ expr = inline.transformToList(body)
228
+ val tryType = c.typeCheck(Try (Block (stats, expr), catches, finalizer)).tpe
229
+ List (attachCopy(tree)(Try (Block (stats, expr), catches, finalizer)).setType(tryType))
230
+
228
231
case If (cond, thenp, elsep) if containsAwait =>
229
232
val condStats :+ condExpr = inline.transformToList(cond)
230
233
val thenBlock = inline.transformToBlock(thenp)
0 commit comments