-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Compile from Tasty #507
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
Compile from Tasty #507
Conversation
To be able able to post process pickled TASTY tree we let ClassfileParser#run return any embedded unpickler. The unpickler is further propagated by a new method ClassFileLoader#load in SymbolLoaders.
`FromTasty` is a main module which compiles TASTY info instead of sources.
Previously, the empty package was always initialized with the empty scope. This means that separate compilation between files in the empty package was not possible.
So far: Only one source file is recorded. Should evaluate whether more are needed. Will programs composed from several source files be pickled? They will certainly be generated after inlining, but maybe all that happens after pickling?
A missing delta position signifies that the node has the same position as its parent. Once that case was added, we can now enable positions when reading from Tasty.
@odersky is it ready to be tested? |
That depends whether macros are expanded before or after pickling. Either is possible IMO. |
Currently, we can only test classes, not objects. The problem is that the backend puts the TASTY information in the wrong file. For a top-level object like Labels, it should be put in Labels.class, but it is put in Labels$.class. @DarkDimius can you add a commit for this? |
@DarkDimius What would you prefer? Before or after pickling? Expanding before would allow to report errors early. |
Ok, I will. |
Usage information is in FromTasty. I have not got around to write test infrastructure for this. Essentially you need to compile first a Scala file, then call FromTasty with the output directory on the classpath. Currently tested that this works: In directory pickling (where classes needs to be on the classpath): dotc -d classes Coder succeeds with 6 warnings. dotc extmethods.scala succeeds. @VladimirNik Can you try some other files and add tests to tests.scala? |
@xeno-by Early or late is actually not so much of a concern. The normal compiler will anyway immediately proceed after pickling, so expansion will happen anyway then. It's more a question And I think that settles it: We do not want to be forced to touch trees of dependencies except for their top-level symbols. the linker will read them, but that should be optional. So We will need to cope with multi-source units. |
That's a hard question. As |
These only exist if there was a pickler, and they are not unique per CompilationUnit.
Actually, that's something that I wanted to discuss. Can we revisit the point of inline redoing overload resolution? I'm afraid that it might cause problems later on and this is one of the examples. @odersky, are we open to alternatives? |
@odersky Yes, I'll try other tests. |
I tried to run FromTasty with I tried to use FromTasty with simplified example (based on Coder) and it works: class mytest {
private val mnemonics = Map('2' -> "ABC")
val str = "abc"
} If modify example: class mytest {
private val mnemonics = Map('2' -> "ABC")
val str = "abc"
for ((digit, str) <- mnemonics; ltr <- str ) {}
} it fails with: error lambda lifting Simple(mytest.scala): value x22 is not visible from <none>
error lambda lifting Simple(mytest.scala): value x22 is not visible from class mytest
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing x22
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing x22._2
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing x22._2()
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing x22._2().asInstanceOf
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing x22._2().asInstanceOf[String]
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing val str: String = x22._2().asInstanceOf[String]
dotty.tools.dotc.transform.LambdaLift$NoPath while traversing {
val str: String = x22._2().asInstanceOf[String]
{
augmentString(str).foreach({
def $anonfun(ltr: Char): Unit = {
()
}
closure($anonfun)
})
}
}
...
...
Exception in thread "main" dotty.tools.dotc.transform.LambdaLift$NoPath
at dotty.tools.dotc.transform.LambdaLift$LambdaLifter.dotty$tools$dotc$transform$LambdaLift$LambdaLifter$$markFree(LambdaLift.scala:148)
at dotty.tools.dotc.transform.LambdaLift$LambdaLifter.dotty$tools$dotc$transform$LambdaLift$LambdaLifter$$markFree(LambdaLift.scala:155)
at dotty.tools.dotc.transform.LambdaLift$LambdaLifter$CollectDependencies.traverse(LambdaLift.scala:204)
at dotty.tools.dotc.ast.tpd$EnclosingMethodTraverser.apply(tpd.scala:827)
at dotty.tools.dotc.ast.tpd$EnclosingMethodTraverser.apply(tpd.scala:820)
at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1198)
at dotty.tools.dotc.transform.LambdaLift$LambdaLifter$CollectDependencies.traverse(LambdaLift.scala:221)
at dotty.tools.dotc.ast.tpd$EnclosingMethodTraverser.apply(tpd.scala:827)
at dotty.tools.dotc.ast.tpd$EnclosingMethodTraverser.apply(tpd.scala:820)
at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1204)
at dotty.tools.dotc.transform.LambdaLift$LambdaLifter$CollectDependencies.traverse(LambdaLift.scala:221) In this case it seems that the problem is with the usage of Also it seems that error: class mytest cannot be unpickled because its class file ./mytest.class does not have a TASTY attribute. |
Did you run with -Ycheck:frontend? That would likely tell you of errors On Thu, Apr 30, 2015 at 4:03 AM, Vladimir Nikolaev <[email protected]
Martin Odersky |
I'd recommend to run with |
@odersky , @DarkDimius With these options there are no errors. Other issue is that after the first run of FromTasty, the same, previously correct error: class mytest cannot be unpickled because its class file ./mytest.class does not have a TASTY attribute. |
Wow. Need to investigate.
That will be hard to fix. I recommend to run FromTasty with an output directory that does not override the classpath. Let's also add a comment to FromTasty's docs that clarifies this point. |
We want to ensure that the whole tree is read at phase frontend. To achieve this, we run an empty traverser over the tree.
@VladimirNik The problem with the crash in lambdalift should be fixed now. |
Should we merge this? It will help @VladimirNik progress. |
New compiler main module: FromTasty.