From d1a35ccf001301881dac2baca972234d8e4d8d25 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 8 Oct 2012 16:23:36 -0700 Subject: Possible fix for continuations bug. It comes looking for an implicit from (A @foo) => B and gives up, despite the fact that there is an implicit from A => B. Maybe there is some good reason for this, and/or I would fully believe there is a better way to fix it, but I'll propose this and wait to hear about the good reason and/or better way. --- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- .../implicit-infer-annotations.check | 5 ++ .../implicit-infer-annotations.scala | 59 ++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 test/files/continuations-run/implicit-infer-annotations.check create mode 100644 test/files/continuations-run/implicit-infer-annotations.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c832987de5..688b4b5160 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -194,7 +194,7 @@ trait Typers extends Modes with Adaptations with Tags { case PolyType(_, _) => EmptyTree case _ => def wrapImplicit(from: Type): Tree = { - val result = inferImplicit(tree, functionType(from :: Nil, to), reportAmbiguous, true, context, saveErrors) + val result = inferImplicit(tree, functionType(from.withoutAnnotations :: Nil, to), reportAmbiguous, true, context, saveErrors) if (result.subst != EmptyTreeTypeSubstituter) { result.subst traverse tree notifyUndetparamsInferred(result.subst.from, result.subst.to) diff --git a/test/files/continuations-run/implicit-infer-annotations.check b/test/files/continuations-run/implicit-infer-annotations.check new file mode 100644 index 0000000000..e8206c4319 --- /dev/null +++ b/test/files/continuations-run/implicit-infer-annotations.check @@ -0,0 +1,5 @@ +Range(5, 6, 7, 8, 9, 10) +Range(5, 6, 7, 8, 9, 10) +15 +List(10, 1, 2, 3) +Range(5, 6, 7, 8, 9, 10) diff --git a/test/files/continuations-run/implicit-infer-annotations.scala b/test/files/continuations-run/implicit-infer-annotations.scala new file mode 100644 index 0000000000..3f0e959f60 --- /dev/null +++ b/test/files/continuations-run/implicit-infer-annotations.scala @@ -0,0 +1,59 @@ +import annotation._ + +object A { + class foo[-B,+C] extends StaticAnnotation with TypeConstraint + + def shift[A, B, C](fun: (A => B) => C): A @foo[B, C] = ??? + def reset[A, C](ctx: => (A @foo[A, C])): C = ??? + + def m1 = reset { shift { f: (Int => Range) => f(5) }.to(10) } +} + +object B { + import scala.util.continuations._ + + def m1 = reset { shift { f: (Int => Range) => f(5) }.to(10) } + def m2 = reset { val a = shift { f: (Int => Range) => f(5) } ; a.to(10) } + + val x1 = reset{ + shift{ cont: (Int => Range) => + cont(5) + }.to(10) + } + + val x2 = reset{ + val a = shift{ cont: (Int => Range) => + cont(5) + } + a.to(10) + } // x is now Range(5, 6, 7, 8, 9, 10) + + val x3 = reset{ + shift{ cont: (Int => Int) => + cont(5) + } + 10 + } // x is now 15 + + val x4 = reset{ + 10 :: shift{ cont: (List[Int] => List[Int]) => + cont(List(1, 2, 3)) + } + } // x is List(10, 1, 2, 3) + + val x5 = reset{ + new scala.runtime.RichInt(shift{ cont: (Int => Range) => + cont(5) + }) to 10 + } +} + +object Test { + def main(args: Array[String]): Unit = { + import B._ + println(x1) + println(x2) + println(x3) + println(x4) + println(x5) + } +} -- cgit v1.2.3