diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-01-26 14:20:18 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-02-03 15:10:10 +0100 |
commit | 12d4182cc9da27eca9d55a94d148f4a8dadbc11d (patch) | |
tree | 9d74e6ed566be48bd89916756b00f8a1b6284758 /tests/pos/tailcall | |
parent | a14af3e7bf82e793d0b687bf6e53b6bc61f1ec5a (diff) | |
download | dotty-12d4182cc9da27eca9d55a94d148f4a8dadbc11d.tar.gz dotty-12d4182cc9da27eca9d55a94d148f4a8dadbc11d.tar.bz2 dotty-12d4182cc9da27eca9d55a94d148f4a8dadbc11d.zip |
Even more careful handling of tailcalls.
See i321 doc for description of problem and decision taken.
Diffstat (limited to 'tests/pos/tailcall')
-rw-r--r-- | tests/pos/tailcall/i321.scala | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/tests/pos/tailcall/i321.scala b/tests/pos/tailcall/i321.scala index 0d32dd625..33b3075de 100644 --- a/tests/pos/tailcall/i321.scala +++ b/tests/pos/tailcall/i321.scala @@ -1,10 +1,26 @@ +import scala.annotation.tailrec +/** + * Illustrates that abstracting over type arguments without triggering Ycheck failure is tricky + * + * go1.loop refers to type parameter of i321, and captures value f + * if goo1.loop will abstract over T it will need to cast f or will trigger a Ycheck failure. + * One could decide to not abstract over type parameters in tail calls, but this leads us to go2 example + * + * In go2 we should abstract over i321.T, as we need to change it in recursive call. + * + * For now decision is such - we will abstract for top-level methods, but will not for inner ones. + */ + class i321[T >: Null <: AnyRef] { - def mapconserve(f: T => Int): Int = { - def loop(pending: T): Int = { - val head1 = f(pending) - loop(pending) - } + def go1(f: T => Int): Int = { + @tailrec def loop(pending: T): Int = { + val head1 = f(pending) + loop(pending) + } loop(null) } + + final def go2[U >: Null <: AnyRef](t: i321[U]): Int = t.go2(this) + }
\ No newline at end of file |