summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-19 15:01:15 -0800
committerPaul Phillips <paulp@improving.org>2012-02-19 15:01:15 -0800
commit63d9ae6dc4fccc97a35819d69c379073e6342bc1 (patch)
tree1a10c27d3f5ca3b2abcb6276bef5430b709c7c0f
parentb0ae549fcc44b068eced8d4af18044f63c2b8093 (diff)
parentb9ac439608eac6fd31082b14bac90064b42521dc (diff)
downloadscala-63d9ae6dc4fccc97a35819d69c379073e6342bc1.tar.gz
scala-63d9ae6dc4fccc97a35819d69c379073e6342bc1.tar.bz2
scala-63d9ae6dc4fccc97a35819d69c379073e6342bc1.zip
Merge remote-tracking branch 'TiarkRompf/SI-5506' into develop
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala55
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala2
-rw-r--r--test/files/continuations-run/t5506.check7
-rw-r--r--test/files/continuations-run/t5506.scala58
4 files changed, 115 insertions, 7 deletions
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
index ab1510bd7f..9930f28229 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
@@ -50,7 +50,27 @@ abstract class CPSAnnotationChecker extends CPSUtils {
// @plus @cps will fall through and compare the @cps type args
// @cps parameters must match exactly
- (annots1 corresponds annots2)(_.atp <:< _.atp)
+ if ((annots1 corresponds annots2)(_.atp <:< _.atp))
+ return true
+
+ // Need to handle uninstantiated type vars specially:
+
+ // g map (x => x) with expected type List[Int] @cps
+ // results in comparison ?That <:< List[Int] @cps
+
+ // Instantiating ?That to an annotated type would fail during
+ // transformation.
+
+ // Instead we force-compare tpe1 <:< tpe2.withoutAnnotations
+ // to trigger instantiation of the TypeVar to the base type
+
+ // This is a bit unorthodox (we're only supposed to look at
+ // annotations here) but seems to work.
+
+ if (!annots2.isEmpty && !tpe1.isGround)
+ return tpe1 <:< tpe2.withoutAnnotations
+
+ false
}
/** Refine the computed least upper bound of a list of types.
@@ -222,6 +242,9 @@ abstract class CPSAnnotationChecker extends CPSUtils {
case OverloadedType(pre, alts) =>
OverloadedType(pre, alts.map((sym: Symbol) => updateAttributes(pre.memberType(sym), annots)))
*/
+ case OverloadedType(pre, alts) => tpe //reconstruct correct annotations later
+ case MethodType(params, restpe) => tpe
+ case PolyType(params, restpe) => tpe
case _ =>
assert(childAnnots forall (_ matches MarkerCPSTypes), childAnnots)
/*
@@ -229,7 +252,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
plus + [] = plus
cps + [] = cps
plus cps + [] = plus cps
- minus cps + [] = minus cp
+ minus cps + [] = minus cps
synth cps + [] = synth cps // <- synth on left - does it happen?
[] + cps = cps
@@ -318,13 +341,27 @@ abstract class CPSAnnotationChecker extends CPSUtils {
}
def transChildrenInOrder(tree: Tree, tpe: Type, childTrees: List[Tree], byName: List[Tree]) = {
- val children = childTrees.flatMap { t =>
+ 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
+ }
+ case _ => Nil
+ }
+
val types = cpsParamAnnotation(t.tpe)
// TODO: check that it has been adapted and if so correctly
- if (types.isEmpty) Nil else List(single(types))
+ extra ++ (if (types.isEmpty) Nil else List(single(types)))
}
}
+ val children = childTrees flatMap inspect
val newtpe = updateAttributesFromChildren(tpe, children, byName)
@@ -359,9 +396,15 @@ abstract class CPSAnnotationChecker extends CPSUtils {
transChildrenInOrder(tree, tpe, qual::(transArgList(fun, args).flatten), Nil)
+ case Apply(TypeApply(fun @ Select(qual, name), targs), args) if fun.isTyped => // not trigge
+
+ vprintln("[checker] checking select apply type-apply " + tree + "/" + tpe)
+
+ transChildrenInOrder(tree, tpe, qual::(transArgList(fun, args).flatten), Nil)
+
case TypeApply(fun @ Select(qual, name), args) if fun.isTyped =>
def stripNullaryMethodType(tp: Type) = tp match { case NullaryMethodType(restpe) => restpe case tp => tp }
- vprintln("[checker] checking select apply " + tree + "/" + tpe)
+ vprintln("[checker] checking select type-apply " + tree + "/" + tpe)
transChildrenInOrder(tree, stripNullaryMethodType(tpe), List(qual, fun), Nil)
@@ -373,7 +416,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
case TypeApply(fun, args) =>
- vprintln("[checker] checking type apply " + tree + "/" + tpe)
+ vprintln("[checker] checking unknown type apply " + tree + "/" + tpe)
transChildrenInOrder(tree, tpe, List(fun), Nil)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index cea558d2d3..cbb33e68c3 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -325,7 +325,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
log("cps type error: " + expr)
//println("cps type error: " + expr + "/" + expr.tpe + "/" + getAnswerTypeAnn(expr.tpe))
- println(cpsR + "/" + spc + "/" + bot)
+ //println(cpsR + "/" + spc + "/" + bot)
unit.error(tree.pos, "found cps expression in non-cps position")
} else {
diff --git a/test/files/continuations-run/t5506.check b/test/files/continuations-run/t5506.check
new file mode 100644
index 0000000000..38b76c63f1
--- /dev/null
+++ b/test/files/continuations-run/t5506.check
@@ -0,0 +1,7 @@
+List(1, 2, 3)
+List(1, 2, 3)
+List(1, 2, 3)
+List(1, 2, 3)
+List(1, 2, 3)
+List(1, 2, 3)
+List(1, 2, 3)
diff --git a/test/files/continuations-run/t5506.scala b/test/files/continuations-run/t5506.scala
new file mode 100644
index 0000000000..2b5c1118f7
--- /dev/null
+++ b/test/files/continuations-run/t5506.scala
@@ -0,0 +1,58 @@
+import scala.util.continuations._
+
+object Test {
+
+def g: List[Int] @suspendable = List(1,2,3)
+
+def fp10: List[Int] @suspendable = {
+g.map(x => x)
+}
+
+def fp11: List[Int] @suspendable = {
+val z = g.map(x => x)
+z
+}
+
+
+def fp12: List[Int] @suspendable = {
+val z = List(1,2,3)
+z.map(x => x)
+}
+
+
+
+def fp20: List[Int] @suspendable = {
+g.map[Int,List[Int]](x => x)
+}
+
+
+def fp21: List[Int] @suspendable = {
+val z = g.map[Int,List[Int]](x => x)
+z
+}
+
+def fp22: List[Int] @suspendable = {
+val z = g.map[Int,List[Int]](x => x)(List.canBuildFrom[Int])
+z
+}
+
+def fp23: List[Int] @suspendable = {
+val z = g.map(x => x)(List.canBuildFrom[Int])
+z
+}
+
+
+def main(args: Array[String]) = {
+ reset {
+ println(fp10)
+ println(fp11)
+ println(fp12)
+
+ println(fp20)
+ println(fp21)
+ println(fp22)
+ println(fp23)
+ }
+}
+
+}