summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala7
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala22
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala14
4 files changed, 26 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index e8abee7d06..ff45bb8fd1 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -108,7 +108,7 @@ abstract class ClosureElimination extends SubComponent {
case LOAD_LOCAL(l) if info.bindings isDefinedAt LocalVar(l) =>
val t = info.getBinding(l)
t match {
- case Deref(LocalVar(_)) | Deref(This) | Const(_) =>
+ case Deref(This) | Const(_) =>
bb.replaceInstruction(i, valueToInstruction(t));
log("replaced " + i + " with " + t)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index e91bab8367..a734b2b92b 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -707,7 +707,8 @@ abstract class Inliners extends SubComponent {
}
def isStampedForInlining(stackLength: Int) =
- !sameSymbols && inc.m.hasCode && shouldInline && isSafeToInline(stackLength) && !inc.m.symbol.hasFlag(Flags.SYNCHRONIZED)
+ !sameSymbols && inc.m.hasCode && shouldInline &&
+ isSafeToInline(stackLength) // `isSafeToInline()` must be invoked last in this AND expr bc it mutates the `knownSafe` and `knownUnsafe` maps for good.
def logFailure(stackLength: Int) = log(
"""|inline failed for %s:
@@ -765,8 +766,8 @@ abstract class Inliners extends SubComponent {
true
}
- if (!inc.m.hasCode || inc.isRecursive)
- return false
+ if (!inc.m.hasCode || inc.isRecursive) { return false }
+ if (inc.m.symbol.hasFlag(Flags.SYNCHRONIZED)) { return false }
val accessNeeded = usesNonPublics.getOrElseUpdate(inc.m, {
// Avoiding crashing the compiler if there are open blocks.
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
index 0382304bad..af0d768607 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
@@ -336,29 +336,31 @@ abstract class CPSAnnotationChecker extends CPSUtils {
def single(xs: List[AnnotationInfo]) = xs match {
case List(x) => x
case _ =>
- global.globalError("not a single cps annotation: " + xs)// FIXME: error message
+ global.globalError("not a single cps annotation: " + xs)
xs(0)
}
+
+ def emptyOrSingleList(xs: List[AnnotationInfo]) = if (xs.isEmpty) Nil else List(single(xs))
def transChildrenInOrder(tree: Tree, tpe: Type, childTrees: List[Tree], byName: List[Tree]) = {
def inspect(t: Tree): List[AnnotationInfo] = {
if (t.tpe eq null) Nil else {
val extra: List[AnnotationInfo] = t.tpe match {
case _: MethodType | _: PolyType | _: OverloadedType =>
- // method types, poly types and overloaded types do not obtain cps annotions by propagat
- // need to reconstruct transitively from their children.
- t match {
- case Select(qual, name) => inspect(qual)
- case Apply(fun, args) => (fun::args) flatMap inspect
- case TypeApply(fun, args) => (fun::args) flatMap inspect
- case _ => Nil
- }
+ // method types, poly types and overloaded types do not obtain cps annotions by propagation
+ // need to reconstruct transitively from their children.
+ t match {
+ case Select(qual, name) => inspect(qual)
+ case Apply(fun, args) => (fun::(transArgList(fun,args).flatten)) flatMap inspect
+ case TypeApply(fun, args) => (fun::(transArgList(fun,args).flatten)) flatMap inspect
+ case _ => Nil
+ }
case _ => Nil
}
val types = cpsParamAnnotation(t.tpe)
// TODO: check that it has been adapted and if so correctly
- extra ++ (if (types.isEmpty) Nil else List(single(types)))
+ extra ++ emptyOrSingleList(types)
}
}
val children = childTrees flatMap inspect
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index d98169f21a..1189cc2e38 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -97,13 +97,17 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
case vd @ ValDef(mods, name, tpt, rhs) => // object-level valdefs
debuglog("transforming valdef " + vd.symbol)
- atOwner(vd.symbol) {
+ if (getExternalAnswerTypeAnn(tpt.tpe).isEmpty) {
+
+ atOwner(vd.symbol) {
- assert(getExternalAnswerTypeAnn(tpt.tpe) == None)
+ val rhs1 = transExpr(rhs, None, None)
- val rhs1 = transExpr(rhs, None, None)
-
- treeCopy.ValDef(vd, mods, name, transform(tpt), rhs1)
+ treeCopy.ValDef(vd, mods, name, transform(tpt), rhs1)
+ }
+ } else {
+ unit.error(tree.pos, "cps annotations not allowed on by-value parameters or value definitions")
+ super.transform(tree)
}
case TypeTree() =>