Closed
Description
This is a minimization of the bug I am encountering in #1061. As @smarter predicted, it is related to TailRec.
package hello
import scala.annotation.tailrec
class Enclosing {
class SomeData(val x: Int)
def localDef(): Unit = {
def foo(data: SomeData): Int = data.x
@tailrec
def test(i: Int, data: SomeData): Unit = {
if (i != 0) {
println(foo(data))
test(i - 1, data)
}
}
test(3, new SomeData(42))
}
}
object world extends App {
println("hello dotty!")
new Enclosing().localDef()
}
Compiling with -Ycheck:tailrec
causes:
> run -Ycheck:checkReentrant,tailrec examples/hello.scala
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list
[info] Packaging /localhome/doeraene/projects/dotty/target/scala-2.11/dotty_2.11-0.1-SNAPSHOT.jar ...
[info] Done packaging.
[info] Running dotty.tools.dotc.Main -Ycheck:checkReentrant,tailrec examples/hello.scala
[error] checking examples/hello.scala after phase TreeTransform:{firstTransform, checkReentrant}
[error] checking examples/hello.scala after phase TreeTransform:{refchecks, elimRepeated, normalizeFlags, extmethods, expandSAMs, tailrec, liftTry, classOf}
[error] *** error while checking examples/hello.scala after phase classOf ***
[error] java.lang.AssertionError: assertion failed: error at examples/hello.scala:14
[error] type mismatch:
[error] found : $this.SomeData(data)
[error] required: Enclosing.this.SomeData
[error] tree = Ident(data)
[error] scala.Predef$.assert(Predef.scala:165)
[error] dotty.tools.dotc.transform.TreeChecker$Checker.adapt(TreeChecker.scala:334)
[error] dotty.tools.dotc.typer.ProtoTypes$FunProto.typedArg(ProtoTypes.scala:205)
[error] dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:513)
[error] dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:511)
[error] dotty.tools.dotc.typer.Applications$Application.addTyped$1(Applications.scala:316)
[error] dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:355)
[error] dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:192)
[error] dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:434)
[error] dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:512)
... // and many more
Changing any of the following things will make it pass Ycheck:
- Change
Enclosing
fromclass
toobject
- Use
String
instead ofSomeData
- Move
foo()
outside oflocalDef()
- Move both
foo()
andtest()
outside oflocalDef()
- Alter
test()
so that it is not tail-recursive anymore - Move
SomeData
insidelocalDef()
The presence or absence of the annotation @tailrec
has no impact. What matters is that test()
is effectively tail-recursive.
Things that