-
Notifications
You must be signed in to change notification settings - Fork 3.1k
WIP New traits lambda [ci: last-only] #5035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This is a second attempt at making this script operate when making a binary incompatible change to the compiler, such as the current effort to change the trait encoding. I have just disabled the docs when STARR_REF is provided, rather than disabling them in the first pass as I tried in c4fc2fd. scala-dev/scala#89 showed that we can't defer docs to the second pass, as the second pass isn't always run.
- Leave the members in the trait instead (these will be emitted as
default methods in the interface)
- Add the trait mixin constructor to the interface, rather than
the impl class
- Change the invocation of the mixin constructor to use an
invokespecial. This is encoded with the AST:
`Apply(Select(Super(_, _), mixinConstructor)))`
I've tried to remove all traces of the interface / implclass
distinction.
To allow us to call arbitrary super methods with invokespecial,
the backend will add a transitively inherited interface as a direct
when needed to circumvent the JVM restriction that invokespecial
can only use a direct parent as the receiver.
These manual mixins were forwarding to the impl classes have
just been removed. We can now rely on default methods instead.
Update Tests:
- Fix test/files/pos/t1237.scala, we can't have an outer field
in an interface, always use the outer method.
- Don't crash on meaningless trait early init fields
test/files/neg/t2796.scala
- Remove impl class relate parts of inner class test
- Remove impl class relate parts of elidable test
- Remove impl class related reflection test.
- Remove test solely about trait impl classes renaming
- Update check file with additional stub symbol error
- Disable unstable parts of serialization test.
- TODO explain, and reset the expectation
As built in https://scala-ci.typesafe.com/view/scala-2.12.x/job/scala-2.12.x-integrate-bootstrap/326/console To pick this up in PR validation, I've configured SBT to use the extra resolver. Once we gain some more confidence about the new STARR candidate, we'll tag it and have the bootstrap script publish it to Sonatype, at which time we can drop this change.
based on scala/scala3#1133 lambdalift updates info of trait members, so must preserve this when mixing in
class MethodNesting {
def method2method(a: Int) = {
def intermediate = {
def localmethod = a + 1
localmethod
}
intermediate
}
}
trait TraitNesting { def foo(x: Int) = { trait U { def bar = x }; (new U{}).bar } }
class ClassUseOuter {
def local(x: Int) = {
class StoreCapture {
class AccessViaOuter {
def y = x
}
}
val s = new StoreCapture
val via = (new s.AccessViaOuter)
// TODO: use reflection to ensure via's class has only an $outer field
via.y
}
}
class ConstructorCall(val x: Any)
object ConstructorCall {
def m(UGH: Any): ConstructorCall = {
class X extends ConstructorCall(Option(null).getOrElse(UGH))
new X
}
}
object Test extends App {
// def main(args: Array[String]): Unit = {
assert((new MethodNesting).method2method(1) == 2)
assert((new TraitNesting {}).foo(2) == 2)
assert((new ClassUseOuter).local(2) == 2)
assert(ConstructorCall.m(2).x == 2)
// }
}
trait EarlyInitImplRestriction {
trait Tree {
def orElse(alt: => Tree): Tree = ???
}
trait MacroContext {
val bla: Tree
def meh: Tree
}
def macroContext(local: Tree): MacroContext = {
new {
// the anon class in bla captures local
// note that bla's owner is the anon subclass of MacroContext
// we'll need to mark `local` free in things nested in the ctor (premature self weirdness)
val bla = local orElse local
} with MacroContext {
def meh = local
}
}
}
|
|
The test failure shows we of course can't escape traits that capture locals that easily. The capture could happen in the initializer or, equivalently, the RHS of a val. |
|
More specifically, dotty's approach of pushing down captures in traits to its methods (to avoid adding fields for them) doesn't work for us because our trait initialization works differently. (Dotty's lifts RHS of fields into methods, which can then get the captured locals via arguments.) For us, to compile something like this we'll need to have a getter for |
traits now do the lambada without fields