8000 Fix another Try expr problem · scala/scala@a7d22c3 · GitHub
[go: up one dir, main page]

Skip to content

Commit a7d22c3

Browse files
committed
Fix another Try expr problem
1 parent 40247d6 commit a7d22c3

File tree

8000

5 files changed

+47
-18
lines changed

5 files changed

+47
-18
lines changed

src/compiler/scala/tools/nsc/transform/async/AnfTransform.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,8 @@ private[async] trait AnfTransform extends TransformUtils {
173173
}
174174

175175
private def pushAssignmentIntoExpr(varSym: Symbol, t: Tree): Tree = {
176-
t match {
177-
case _ if varSym == NoSymbol || t.tpe.typeSymbol == definitions.NothingClass => t
178-
case MatchEnd(ld) => treeCopy.LabelDef(ld, ld.name, ld.params, pushAssignmentIntoExpr(varSym, ld.rhs))
179-
case b@Block(caseStats, caseExpr) => assignUnitType(treeCopy.Block(b, caseStats, pushAssignmentIntoExpr(varSym, caseExpr)))
180-
case _ => typedAssign(t, varSym)
181-
}
176+
if (varSym == NoSymbol || t.tpe.typeSymbol == definitions.NothingClass) t
177+
else deriveTree(t, definitions.UnitTpe)(t => typedAssign(t, varSym))
182178
}
183179

184180
private def transformMatchOrIf[T <: Tree](tree: Tree, needsResultVar: Boolean, nameSource: transformState.asyncNames.NameSource[TermName])(core: Symbol => T): Tree = {

src/compiler/scala/tools/nsc/transform/async/AsyncPhase.scala

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,21 +201,11 @@ abstract class AsyncPhase extends Transform with TypingTransformers with AnfTran
201201
}
202202
atPos(tree.pos)(Select(outerOrThis.setType(stateMachineClass.tpe), tree.symbol).setType(tree.symbol.tpe))
203203
}
204-
// Avoid moving a Try into expression position with a potentially non-empty stack.
205-
// Uncurry has already run and is responsible for faking try expressions! See needsTryLift.
206-
private def pushAssignmentIntoTry(lhs: Tree, rhs: Tree): Tree = rhs match {
207-
case Try(block, catches, finalizer) =>
208-
val block1 = pushAssignmentIntoTry(lhs, block)
209-
val catches1 = catches.mapConserve(cd => deriveCaseDef(cd)(body => pushAssignmentIntoTry(lhs, body)))
210-
assignUnitType(treeCopy.Try(rhs, block1, catches1, finalizer))
211-
case _ =>
212-
assignUnitType(treeCopy.Assign(rhs, lhs, adapt(rhs, lhs.symbol.tpe)))
213-
}
214204
override def transform(tree: Tree): Tree = tree match {
215205
case ValDef(_, _, _, rhs) if liftedSyms(tree.symbol) && currentOwner == applySym =>
216206
// Drop the lifted definitions from the apply method
217207
val rhs1 = transform(rhs.changeOwner(tree.symbol, currentOwner))
218-
pushAssignmentIntoTry(fieldSel(tree), rhs1)
208+
deriveTree(rhs1, definitions.UnitTpe)(t => treeCopy.Assign(rhs1, fieldSel(tree), adapt(t, tree.symbol.tpe)))
219209
case _: DefTree if liftedSyms(tree.symbol) && currentOwner == applySym =>
220210
// Drop the lifted definitions from the apply method
221211
EmptyTree

src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,9 @@ trait ExprBuilder extends TransformUtils {
528528

529529
// Comlete the Promise in the `result` field with the final successful result of this async block.
530530
private def completeSuccess(expr: Tree): Tree = {
531-
typed(Apply(currentTransformState.memberRef(currentTransformState.stateCompleteSuccess), expr :: Nil))
531+
deriveTree(expr, definitions.UnitTpe) { expr =>
532+
typed(Apply(currentTransformState.memberRef(currentTransformState.stateCompleteSuccess), expr :: Nil))
533+
}
532534
}
533535

534536
/** What trailing statements should be added to the code for this state to transition to the nest state? */

src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ private[async] trait TransformUtils extends AsyncTransformStates {
6161

6262
def assignUnitType(t: Tree): t.type = t.setType(definitions.UnitTpe)
6363

64+
// Avoid moving a Try into expression position with a potentially non-empty stack.
65+
// Uncurry has already run and is responsible for faking try expressions! See needsTryLift.
66+
final def deriveTree(tree: Tree, exprType: Type)(deriveExpr: Tree => Tree): Tree = tree match {
67+
case Try(block, catches, finalizer) =>
68+
val block1 = deriveTree(block, exprType)(deriveExpr)
69+
val catches1 = catches.mapConserve(cd => deriveCaseDef(cd)(body => deriveTree(body, exprType)(deriveExpr)))
70+
treeCopy.Try(tree, block1, catches1, finalizer).setType(exprType)
71+
case Block(stats, expr) =>
72+
treeCopy.Block(tree, stats, deriveTree(expr, exprType)(deriveExpr))
73+
case MatchEnd(ld) =>
74+
ld.symbol.modifyInfo {
75+
case MethodType(params, _) => MethodType(params, exprType)
76+
}
77+
treeCopy.LabelDef(ld, ld.name, ld.params, deriveTree(ld.rhs, exprType)(deriveExpr)).setType(exprType)
78+
case _ =>
79+
deriveExpr(tree).setType(exprType)
80+
}
81+
6482
def isUnitType(tp: Type): Boolean = tp.typeSymbol == definitions.UnitClass || tp =:= definitions.BoxedUnitTpe
6583

6684
def literalUnit: Tree = Literal(Constant(())).setType(definitions.UnitTpe) // a def to avoid sharing trees

test/junit/scala/tools/nsc/async/AnnotationDrivenAsync.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,29 @@ class AnnotationDrivenAsync {
140140
assertEquals(("body1", "body2"), run(code))
141141
}
142142

143+
@Test
144+
def avoidLiftingTryIntoExpression2(): Unit = {
145+
val code =
146+
"""
147+
|import scala.concurrent._, duration.Duration, ExecutionContext.Implicits.global
148+
|import scala.tools.partest.async.Async.{async, await}
149+
|import Future.{successful => f}
150+
|
151+
|object Test {
152+
| def test = async {
153+
| await(f(1))
< 67F4 code>154+
| try {
155+
| "body"
156+
| } catch {
157+
| case _: Throwable =>
158+
| "catch"
159+
| }
160+
| }
161+
|}
162+
|""".stripMargin
163+
assertEquals("body", run(code))
164+
}
165+
143166
@Test
144167
def avoidWhileExprPosition(): Unit = {
145168
val code =

0 commit comments

Comments
 (0)
0