Skip to content

Restructure Try node. #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Nov 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dotc

import core._
import Contexts._, Periods._, Symbols._, Phases._, Decorators._
import dotty.tools.dotc.transform.TreeTransforms.TreeTransformer
import io.PlainFile
import util.{SourceFile, NoSource, Stats, SimpleMap}
import reporting.Reporter
Expand Down Expand Up @@ -60,7 +61,10 @@ class Run(comp: Compiler)(implicit ctx: Context) {

private def printTree(ctx: Context) = {
val unit = ctx.compilationUnit
println(s"result of $unit after ${ctx.phase.prev}:")
val prevPhase = ctx.phase.prev // can be a mini-phase
val squahsedPhase = ctx.squashed(prevPhase)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo


println(s"result of $unit after ${squahsedPhase}:")
println(unit.tpdTree.show(ctx))
}

Expand Down
10 changes: 10 additions & 0 deletions src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,16 @@ object desugar {
case PatDef(mods, pats, tpt, rhs) =>
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
flatTree(pats1 map (makePatDef(mods, _, rhs)))
case ParsedTry(body, handler, finalizer) =>
handler match {
case Match(EmptyTree, cases) => Try(body, cases, finalizer)
case EmptyTree => Try(body, Nil, finalizer)
case _ =>
Try(body,
List(CaseDef(Ident(nme.DEFAULT_EXCEPTION_NAME), EmptyTree, Apply(handler, Ident(nme.DEFAULT_EXCEPTION_NAME)))),
finalizer)
}

}
}.withPos(tree.pos)

Expand Down
16 changes: 8 additions & 8 deletions src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ object Trees {
*
* Match(EmptyTree, <case x: Throwable => $anonfun(x)>)
*/
case class Try[-T >: Untyped] private[ast] (expr: Tree[T], handler: Tree[T], finalizer: Tree[T])
case class Try[-T >: Untyped] private[ast] (expr: Tree[T], cases: List[CaseDef[T]], finalizer: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Try[T]
}
Expand Down Expand Up @@ -1024,9 +1024,9 @@ object Trees {
case tree: Return if (expr eq tree.expr) && (from eq tree.from) => tree
case _ => finalize(tree, untpd.Return(expr, from))
}
def Try(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = tree match {
case tree: Try if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
case _ => finalize(tree, untpd.Try(expr, handler, finalizer))
def Try(tree: Tree)(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = tree match {
case tree: Try if (expr eq tree.expr) && (cases eq tree.cases) && (finalizer eq tree.finalizer) => tree
case _ => finalize(tree, untpd.Try(expr, cases, finalizer))
}
def Throw(tree: Tree)(expr: Tree)(implicit ctx: Context): Throw = tree match {
case tree: Throw if (expr eq tree.expr) => tree
Expand Down Expand Up @@ -1128,8 +1128,8 @@ object Trees {
Closure(tree: Tree)(env, meth, tpt)
def CaseDef(tree: CaseDef)(pat: Tree = tree.pat, guard: Tree = tree.guard, body: Tree = tree.body)(implicit ctx: Context): CaseDef =
CaseDef(tree: Tree)(pat, guard, body)
def Try(tree: Try)(expr: Tree = tree.expr, handler: Tree = tree.handler, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
Try(tree: Tree)(expr, handler, finalizer)
def Try(tree: Try)(expr: Tree = tree.expr, cases: List[CaseDef] = tree.cases, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
Try(tree: Tree)(expr, cases, finalizer)
def UnApply(tree: UnApply)(fun: Tree = tree.fun, implicits: List[Tree] = tree.implicits, patterns: List[Tree] = tree.patterns): UnApply =
UnApply(tree: Tree)(fun, implicits, patterns)
def ValDef(tree: ValDef)(mods: Modifiers = tree.mods, name: TermName = tree.name, tpt: Tree = tree.tpt, rhs: Tree = tree.rhs): ValDef =
Expand Down Expand Up @@ -1181,8 +1181,8 @@ object Trees {
cpy.CaseDef(tree)(transform(pat), transform(guard), transform(body))
case Return(expr, from) =>
cpy.Return(tree)(transform(expr), transformSub(from))
case Try(block, handler, finalizer) =>
cpy.Try(tree)(transform(block), transform(handler), transform(finalizer))
case Try(block, cases, finalizer) =>
cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer))
case Throw(expr) =>
cpy.Throw(tree)(transform(expr))
case SeqLiteral(elems) =>
Expand Down
16 changes: 8 additions & 8 deletions src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Return(expr: Tree, from: Tree)(implicit ctx: Context): Return =
ta.assignType(untpd.Return(expr, from))

def Try(block: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try =
ta.assignType(untpd.Try(block, handler, finalizer), block, handler)
def Try(block: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try =
ta.assignType(untpd.Try(block, cases, finalizer), block, cases)

def Throw(expr: Tree)(implicit ctx: Context): Throw =
ta.assignType(untpd.Throw(expr))
Expand Down Expand Up @@ -457,11 +457,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
override def Return(tree: Tree)(expr: Tree, from: Tree)(implicit ctx: Context): Return =
ta.assignType(untpd.cpy.Return(tree)(expr, from))

override def Try(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = {
val tree1 = untpd.cpy.Try(tree)(expr, handler, finalizer)
override def Try(tree: Tree)(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = {
val tree1 = untpd.cpy.Try(tree)(expr, cases, finalizer)
tree match {
case tree: Try if (expr.tpe eq tree.expr.tpe) && (handler.tpe eq tree.handler.tpe) => tree1.withTypeUnchecked(tree.tpe)
case _ => ta.assignType(tree1, expr, handler)
case tree: Try if (expr.tpe eq tree.expr.tpe) && (sameTypes(cases, tree.cases)) => tree1.withTypeUnchecked(tree.tpe)
case _ => ta.assignType(tree1, expr, cases)
}
}

Expand Down Expand Up @@ -490,8 +490,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Closure(tree: Tree)(env, meth, tpt)
override def CaseDef(tree: CaseDef)(pat: Tree = tree.pat, guard: Tree = tree.guard, body: Tree = tree.body)(implicit ctx: Context): CaseDef =
CaseDef(tree: Tree)(pat, guard, body)
override def Try(tree: Try)(expr: Tree = tree.expr, handler: Tree = tree.handler, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
Try(tree: Tree)(expr, handler, finalizer)
override def Try(tree: Try)(expr: Tree = tree.expr, cases: List[CaseDef] = tree.cases, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
Try(tree: Tree)(expr, cases, finalizer)
}

implicit class TreeOps[ThisTree <: tpd.Tree](val tree: ThisTree) extends AnyVal {
Expand Down
4 changes: 3 additions & 1 deletion src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def withName(name: Name)(implicit ctx: Context) = cpy.ModuleDef(this)(mods, name.toTermName, impl)
}

case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree

case class SymbolLit(str: String) extends TermTree
case class InterpolatedString(id: TermName, strings: List[Literal], elems: List[Tree]) extends TermTree
case class Function(args: List[Tree], body: Tree) extends Tree {
Expand Down Expand Up @@ -123,7 +125,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)
def Try(expr: Tree, handler: Tree, finalizer: Tree): Try = new Try(expr, handler, finalizer)
def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree): Try = new Try(expr, cases, finalizer)
def Throw(expr: Tree): Throw = new Throw(expr)
def SeqLiteral(elems: List[Tree]): SeqLiteral = new SeqLiteral(elems)
def JavaSeqLiteral(elems: List[Tree]): JavaSeqLiteral = new JavaSeqLiteral(elems)
Expand Down
4 changes: 4 additions & 0 deletions src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ object Contexts {

/** The standard definitions */
val definitions = new Definitions

def squashed(p: Phase): Phase = {
squashedPhases.find(_.period.containsPhaseId(p.id)).getOrElse(NoPhase)
}
}

/** The essential mutable state of a context base, collected into a common class */
Expand Down
4 changes: 3 additions & 1 deletion src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Denotations._
import config.Printers._
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, MiniPhase, TreeTransform}
import dotty.tools.dotc.transform.{TreeTransforms, ExplicitOuter, Erasure, Flatten, GettersSetters}
import dotty.tools.dotc.transform._
import Periods._
import typer.{FrontEnd, RefChecks}
import ast.tpd
Expand Down Expand Up @@ -167,13 +167,15 @@ object Phases {
private val typerCache = new PhaseCache(classOf[FrontEnd])
private val refChecksCache = new PhaseCache(classOf[RefChecks])
private val erasureCache = new PhaseCache(classOf[Erasure])
private val patmatCache = new PhaseCache(classOf[PatternMatcher])
private val flattenCache = new PhaseCache(classOf[Flatten])
private val explicitOuterCache = new PhaseCache(classOf[ExplicitOuter])
private val gettersSettersCache = new PhaseCache(classOf[GettersSetters])

def typerPhase = typerCache.phase
def refchecksPhase = refChecksCache.phase
def erasurePhase = erasureCache.phase
def patmatPhase = patmatCache.phase
def flattenPhase = flattenCache.phase
def explicitOuterPhase = explicitOuterCache.phase
def gettersSettersPhase = gettersSettersCache.phase
Expand Down
1 change: 1 addition & 0 deletions src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ object StdNames {
val SUPER_PREFIX: N = "super$"
val TRAIT_SETTER_PREFIX: N = "_setter_$"
val WHILE_PREFIX: N = "while$"
val DEFAULT_EXCEPTION_NAME: N = "ex$"

// value types (and AnyRef) are all used as terms as well
// as (at least) arguments to the @specialize annotation.
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/pickling/UnPickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
val block = readTreeRef()
val finalizer = readTreeRef()
val catches = until(end, readCaseDefRef)
Try(block, Match(EmptyTree, catches), finalizer)
Try(block, catches, finalizer)

case THROWtree =>
Throw(readTreeRef())
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ object Parsers {
val finalizer =
if (handler.isEmpty || in.token == FINALLY) { accept(FINALLY); expr() }
else EmptyTree
Try(body, handler, finalizer)
ParsedTry(body, handler, finalizer)
}
case THROW =>
atPos(in.skipToken()) { Throw(expr()) }
Expand Down
13 changes: 9 additions & 4 deletions src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
super.toText(tp)
}

def blockText[T >: Untyped](trees: List[Tree[T]]): Text =
"{" ~ toText(trees, "\n") ~ "}"

override def toText[T >: Untyped](tree: Tree[T]): Text = controlled {

def optDotPrefix(name: Name) = optText(name)(_ ~ ".")
Expand All @@ -155,8 +158,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
def addVparamssText(txt: Text, vparamss: List[List[ValDef[T]]]): Text =
(txt /: vparamss)((txt, vparams) => txt ~ "(" ~ toText(vparams, ", ") ~ ")")

def blockText(trees: List[Tree[T]]): Text =
"{" ~ toText(trees, "\n") ~ "}"


def caseBlockText(tree: Tree[T]): Text = tree match {
case Block(stats, expr) => toText(stats :+ expr, "\n")
Expand Down Expand Up @@ -261,9 +263,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
"case " ~ toText(pat) ~ optText(guard)(" if " ~ _) ~ " => " ~ caseBlockText(body)
case Return(expr, from) =>
changePrec(GlobalPrec) { "return" ~ optText(expr)(" " ~ _) }
case Try(expr, handler, finalizer) =>
case Try(expr, cases, finalizer) =>
changePrec(GlobalPrec) {
"try " ~ toText(expr) ~ optText(handler)(" catch " ~ _) ~ optText(finalizer)(" finally " ~ _)
"try " ~ toText(expr) ~ optText(cases)(" catch " ~ _) ~ optText(finalizer)(" finally " ~ _)
}
case Throw(expr) =>
changePrec(GlobalPrec) {
Expand Down Expand Up @@ -461,6 +463,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
def optText[T >: Untyped](tree: Tree[T])(encl: Text => Text): Text =
if (tree.isEmpty) "" else encl(toText(tree))

def optText[T >: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text =
if (tree.exists(!_.isEmpty)) "" else encl(blockText(tree))

override protected def polyParamName(name: TypeName): TypeName =
name.unexpandedName()

Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ object Erasure extends TypeTestsCasts{
object Boxing {

def isUnbox(sym: Symbol)(implicit ctx: Context) =
sym.name == nme.unbox && (defn.ScalaBoxedClasses contains sym.owner)
sym.name == nme.unbox && (defn.ScalaBoxedClasses contains sym.owner.linkedClass)

def isBox(sym: Symbol)(implicit ctx: Context) =
sym.name == nme.box && (defn.ScalaValueClasses contains sym.owner)
sym.name == nme.box && (defn.ScalaValueClasses contains sym.owner.linkedClass)

def boxMethod(cls: ClassSymbol)(implicit ctx: Context) =
cls.linkedClass.info.member(nme.box).symbol
Expand Down
15 changes: 6 additions & 9 deletions src/dotty/tools/dotc/transform/LazyVals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,15 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
val compute = {
val handlerSymbol = ctx.newSymbol(methodSymbol, "$anonfun".toTermName, Flags.Synthetic,
MethodType(List("x$1".toTermName), List(defn.ThrowableType), defn.IntType))

val handler = Closure(handlerSymbol, {
args =>
val exception = args.head.head
val complete = setFlagState.appliedTo(thiz, offset, initState, Literal(Constant(ord)))
Block(List(complete), Throw(exception))
})
val caseSymbol = ctx.newSymbol(methodSymbol, nme.DEFAULT_EXCEPTION_NAME, Flags.Synthetic, defn.ThrowableType)
val complete = setFlagState.appliedTo(thiz, offset, initState, Literal(Constant(ord)))
val handler = CaseDef(Bind(caseSymbol, ref(caseSymbol)), EmptyTree,
Block(List(complete), Throw(ref(caseSymbol))
))

val compute = Assign(ref(resultSymbol), rhs)
val tr = Try(compute, handler, EmptyTree)
val tr = Try(compute, List(handler), EmptyTree)
val assign = Assign(ref(target), ref(resultSymbol))
val complete = setFlagState.appliedTo(thiz, offset, computedState, Literal(Constant(ord)))
val noRetry = Assign(ref(retrySymbol), Literal(Constants.Constant(false)))
val body = If(casFlag.appliedTo(thiz, offset, ref(flagSymbol), computeState, Literal(Constant(ord))),
Block(tr :: assign :: complete :: noRetry :: Nil, Literal(Constant(()))),
Expand Down
17 changes: 10 additions & 7 deletions src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans

override def transformMatch(tree: Match)(implicit ctx: Context, info: TransformerInfo): Tree = {
val translated = new Translator()(ctx).translator.translateMatch(tree)

translated.ensureConforms(tree.tpe)
}

Expand Down Expand Up @@ -778,10 +779,11 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans
// is this purely a type test, e.g. no outer check, no equality tests (used in switch emission)
//def isPureTypeTest = renderCondition(pureTypeTestChecker)

def impliesBinderNonNull(binder: Symbol):Boolean =
def impliesBinderNonNull(binder: Symbol): Boolean =
// @odersky: scalac is able to infer in this method that nonNullImpliedByTestChecker.Result,
// dotty instead infers type projection TreeMakers.this.TypeTestTreeMaker.TypeTestCondStrategy#Result
// which in turn doesn't typecheck in this method. Can you please explain why?
// dotty deviation
renderCondition(nonNullImpliedByTestChecker(binder)).asInstanceOf[Boolean]

override def toString = "TT"+((expectedTp, testedBinder.name, nextBinderTp))
Expand Down Expand Up @@ -1136,7 +1138,11 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans
* this could probably optimized... (but note that the matchStrategy must be solved for each nested patternmatch)
*/
def translateMatch(match_ : Match): Tree = {
val Match(selector, cases) = match_
val Match(sel, cases) = match_

val selectorTp = elimAnonymousClass(sel.tpe.widen/*withoutAnnotations*/)

val selectorSym = freshSym(sel.pos, selectorTp, "selector")

val (nonSyntheticCases, defaultOverride) = cases match {
case init :+ last if isSyntheticDefaultCase(last) => (init, Some(((scrut: Symbol) => last.body)))
Expand All @@ -1155,23 +1161,20 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans

//val start = if (Statistics.canEnable) Statistics.startTimer(patmatNanos) else null

val selectorTp = elimAnonymousClass(selector.tpe.widen/*withoutAnnotations*/)

// when one of the internal cps-type-state annotations is present, strip all CPS annotations
///val origPt = removeCPSFromPt(match_.tpe)
// relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
// pt is the skolemized version
val pt = match_.tpe.widen //repeatedToSeq(origPt)

// val packedPt = repeatedToSeq(typer.packedType(match_, context.owner))
val selectorSym = freshSym(selector.pos, selectorTp, "selector")
selectorSym.setFlag(Flags.SyntheticCase)

// pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental
val combined = combineCases(selector, selectorSym, nonSyntheticCases map translateCase(selectorSym, pt), pt, ctx.owner, defaultOverride)
val combined = combineCases(sel, selectorSym, nonSyntheticCases map translateCase(selectorSym, pt), pt, ctx.owner, defaultOverride)

// if (Statistics.canEnable) Statistics.stopTimer(patmatNanos, start)
Block(List(ValDef(selectorSym,selector)), combined)
Block(List(ValDef(selectorSym, sel)), combined)
}

// return list of typed CaseDefs that are supported by the backend (typed/bind/wildcard)
Expand Down
17 changes: 4 additions & 13 deletions src/dotty/tools/dotc/transform/TailRec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
def noTailTransform(tree: Tree)(implicit c: Context): Tree =
transform(tree, noTailContext)


def noTailTransforms(trees: List[Tree])(implicit c: Context) =
trees map (noTailTransform)
def noTailTransforms[Tr <: Tree](trees: List[Tr])(implicit c: Context): List[Tr] =
trees.map(noTailTransform).asInstanceOf[List[Tr]]

override def transform(tree: Tree)(implicit c: Context): Tree = {
/* A possibly polymorphic apply to be considered for tail call transformation. */
Expand Down Expand Up @@ -232,26 +231,18 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
}

def rewriteTry(tree: Try): Try = {
def transformHandlers(t: Tree): Tree = {
t match {
case Block(List((d: DefDef)), cl@Closure(Nil, _, EmptyTree)) =>
val newDef = cpy.DefDef(d)(rhs = transform(d.rhs))
Block(List(newDef), cl)
case _ => assert(false, s"failed to deconstruct try handler ${t.show}"); ???
}
}
if (tree.finalizer eq EmptyTree) {
// SI-1672 Catches are in tail position when there is no finalizer
tpd.cpy.Try(tree)(
noTailTransform(tree.expr),
transformHandlers(tree.handler),
transformSub(tree.cases),
EmptyTree
)
}
else {
tpd.cpy.Try(tree)(
noTailTransform(tree.expr),
noTailTransform(tree.handler),
noTailTransforms(tree.cases),
noTailTransform(tree.finalizer)
)
}
Expand Down
Loading