diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2017-11-20 15:31:56 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-20 15:31:56 +1000 |
commit | 1802797d7485bcd68feef792817102884edd8abf (patch) | |
tree | 8fc881a3e2e4254006a969b6cd8ca75c7fc6e5a6 /src/main | |
parent | 04c50a832d5ce9b03e7f453e9af8d5cf3db11660 (diff) | |
parent | 505ce2292b3d58ed38f7670e05934b63df2c0450 (diff) | |
download | scala-async-1802797d7485bcd68feef792817102884edd8abf.tar.gz scala-async-1802797d7485bcd68feef792817102884edd8abf.tar.bz2 scala-async-1802797d7485bcd68feef792817102884edd8abf.zip |
Merge pull request #179 from retronym/fixup
Fix more corner cases in late expansion
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/scala/scala/async/internal/AnfTransform.scala | 2 | ||||
-rw-r--r-- | src/main/scala/scala/async/internal/TransformUtils.scala | 40 |
2 files changed, 41 insertions, 1 deletions
diff --git a/src/main/scala/scala/async/internal/AnfTransform.scala b/src/main/scala/scala/async/internal/AnfTransform.scala index 93297f7..0085554 100644 --- a/src/main/scala/scala/async/internal/AnfTransform.scala +++ b/src/main/scala/scala/async/internal/AnfTransform.scala @@ -118,7 +118,7 @@ private[async] trait AnfTransform { case MatchEnd(ld) => deriveLabelDef(ld, branchWithAssign) case blk @ Block(thenStats, thenExpr) => - treeCopy.Block(blk, thenStats, typedAssign(thenExpr)).setType(definitions.UnitTpe) + treeCopy.Block(blk, thenStats, branchWithAssign(thenExpr)).setType(definitions.UnitTpe) case _ => typedAssign(t) } diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index 848861c..04adf20 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -524,11 +524,51 @@ private[async] trait TransformUtils { treeCopy.If(tree, cond1, thenp1, elsep1) case Apply(fun, args) if isLabel(fun.symbol) => internal.setType(treeCopy.Apply(tree, api.recur(fun), args map api.recur), UnitTpe) + case vd @ ValDef(mods, name, tpt, rhs) if isCaseTempVal(vd.symbol) => + def addUncheckedBounds(t: Tree) = { + typingTransform(t, owner) { + (tree, api) => + internal.setType(api.default(tree), uncheckedBoundsIfNeeded(tree.tpe)) + } + + } + val uncheckedRhs = addUncheckedBounds(api.recur(rhs)) + val uncheckedTpt = addUncheckedBounds(tpt) + internal.setInfo(vd.symbol, uncheckedBoundsIfNeeded(vd.symbol.info)) + treeCopy.ValDef(vd, mods, name, uncheckedTpt, uncheckedRhs) case t => api.default(t) } } } + private def isExistentialSkolem(s: Symbol) = { + val EXISTENTIAL: Long = 1L << 35 + internal.isSkolem(s) && (internal.flags(s).asInstanceOf[Long] & EXISTENTIAL) != 0 + } + private def isCaseTempVal(s: Symbol) = { + s.isTerm && s.asTerm.isVal && s.isSynthetic && s.name.toString.startsWith("x") + } + + def uncheckedBoundsIfNeeded(t: Type): Type = { + var quantified: List[Symbol] = Nil + var badSkolemRefs: List[Symbol] = Nil + t.foreach { + case et: ExistentialType => + quantified :::= et.quantified + case TypeRef(pre, sym, args) => + val illScopedSkolems = args.map(_.typeSymbol).filter(arg => isExistentialSkolem(arg) && !quantified.contains(arg)) + badSkolemRefs :::= illScopedSkolems + case _ => + } + if (badSkolemRefs.isEmpty) t + else t.map { + case tp @ TypeRef(pre, sym, args) if args.exists(a => badSkolemRefs.contains(a.typeSymbol)) => + uncheckedBounds(tp) + case t => t + } + } + + final def mkMutableField(tpt: Type, name: TermName, init: Tree): List[Tree] = { if (isPastTyper) { // If we are running after the typer phase (ie being called from a compiler plugin) |