blob: daa078dd5093baf76beb78a568f6783e7a65fe3d (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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 go1.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 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)
}
|