This seems like a bug to me. Edit: found it, this is SI-5712.
Section §5.3 of the 2.9 SLS says:
(ps1 ) . . . (psn ) are formal value parameter clauses for the primary constructor
of the class. The scope of a formal value parameter includes all subsequent
parameter sections and the template t .
There is an exception:
However, a formal value parameter
may not form part of the types of any of the parent classes or members of the
class template t .
But it says it cannot be part of the types of any of the parent classes or members, not of any of the following parameter sections, so it does not seems to forbid path-dependent types between argument groups.
You can go around this with a secondary constructor:
class Foo[S <: Sys] private[this] () {
def this(system: S)(global: system.Global) = this
}
Edit: this secondary constructor workaround is not very good: exposing system
or global
become very difficult because only the primary constructor can declare val
s.
An example with a cast:
class Foo[S <: Sys] private[this] () {
private[this] var _system: S = _
private[this] var _global: system.Global = _
def this(system0: S)(global0: system0.Global) = {
this
_system = system0
_global = global0.asInstanceOf[system.Global]
}
lazy val global: system.Global = _global
lazy val system: S = _system
}
But this is getting awful. @senia's suggestion is much better.
trait Foo[S :< Sys] { val system: S; val global: system.Global }
. – Tasset