Skip to content

Commit 1802797

Browse files
authored
Merge pull request #179 from retronym/fixup
Fix more corner cases in late expansion
2 parents 04c50a8 + 505ce22 commit 1802797

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/main/scala/scala/async/internal/AnfTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ private[async] trait AnfTransform {
118118
case MatchEnd(ld) =>
119119
deriveLabelDef(ld, branchWithAssign)
120120
case blk @ Block(thenStats, thenExpr) =>
121-
treeCopy.Block(blk, thenStats, typedAssign(thenExpr)).setType(definitions.UnitTpe)
121+
treeCopy.Block(blk, thenStats, branchWithAssign(thenExpr)).setType(definitions.UnitTpe)
122122
case _ =>
123123
typedAssign(t)
124124
}

src/main/scala/scala/async/internal/TransformUtils.scala

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,51 @@ private[async] trait TransformUtils {
524524
treeCopy.If(tree, cond1, thenp1, elsep1)
525525
case Apply(fun, args) if isLabel(fun.symbol) =>
526526
internal.setType(treeCopy.Apply(tree, api.recur(fun), args map api.recur), UnitTpe)
527+
case vd @ ValDef(mods, name, tpt, rhs) if isCaseTempVal(vd.symbol) =>
528+
def addUncheckedBounds(t: Tree) = {
529+
typingTransform(t, owner) {
530+
(tree, api) =>
531+
internal.setType(api.default(tree), uncheckedBoundsIfNeeded(tree.tpe))
532+
}
533+
534+
}
535+
val uncheckedRhs = addUncheckedBounds(api.recur(rhs))
536+
val uncheckedTpt = addUncheckedBounds(tpt)
537+
internal.setInfo(vd.symbol, uncheckedBoundsIfNeeded(vd.symbol.info))
538+
treeCopy.ValDef(vd, mods, name, uncheckedTpt, uncheckedRhs)
527539
case t => api.default(t)
528540
}
529541
}
530542
}
531543

544+
private def isExistentialSkolem(s: Symbol) = {
545+
val EXISTENTIAL: Long = 1L << 35
546+
internal.isSkolem(s) && (internal.flags(s).asInstanceOf[Long] & EXISTENTIAL) != 0
547+
}
548+
private def isCaseTempVal(s: Symbol) = {
549+
s.isTerm && s.asTerm.isVal && s.isSynthetic && s.name.toString.startsWith("x")
550+
}
551+
552+
def uncheckedBoundsIfNeeded(t: Type): Type = {
553+
var quantified: List[Symbol] = Nil
554+
var badSkolemRefs: List[Symbol] = Nil
555+
t.foreach {
556+
case et: ExistentialType =>
557+
quantified :::= et.quantified
558+
case TypeRef(pre, sym, args) =>
559+
val illScopedSkolems = args.map(_.typeSymbol).filter(arg => isExistentialSkolem(arg) && !quantified.contains(arg))
560+
badSkolemRefs :::= illScopedSkolems
561+
case _ =>
562+
}
563+
if (badSkolemRefs.isEmpty) t
564+
else t.map {
565+
case tp @ TypeRef(pre, sym, args) if args.exists(a => badSkolemRefs.contains(a.typeSymbol)) =>
566+
uncheckedBounds(tp)
567+
case t => t
568+
}
569+
}
570+
571+
532572
final def mkMutableField(tpt: Type, name: TermName, init: Tree): List[Tree] = {
533573
if (isPastTyper) {
534574
// If we are running after the typer phase (ie being called from a compiler plugin)

src/test/scala/scala/async/run/late/LateExpansion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ abstract class LatePlugin extends Plugin {
476476
}
477477
}
478478

479-
override val runsAfter: List[String] = "refchecks" :: Nil
479+
override val runsAfter: List[String] = "patmat" :: Nil
480480
override val phaseName: String = "postpatmat"
481481

482482
})

0 commit comments

Comments
 (0)