-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Add original tree attachment #6013
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be interested to see how many such attachments are created, say when compiling the std lib. Could you do the experiment?
Also, should we eliminate the attachment at some phase? Maybe in erasure?
@@ -27,7 +27,7 @@ import scala.reflect.macros.whitebox | |||
* @author Martin Odersky | |||
* @version 1.0 | |||
*/ | |||
trait Typers extends Adaptations with Tags with TypersTracking with PatternTypers { | |||
trait Typers extends Adaptations with Tags with TypersTracking with PatternTypers with StdAttachments { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I that necessary? The self type (Analyzer
) includes StdAttachments
.
case class OriginalAdaptedTreeAttachment(original: Tree) | ||
def markOriginal(tree: Tree, original: Tree) = tree.updateAttachment(OriginalAdaptedTreeAttachment(original)) | ||
def unmarkOriginal(tree: Tree): Tree = tree.removeAttachment[OriginalAdaptedTreeAttachment] | ||
def isAdaptedTree(tree: Tree): Boolean = tree.attachments.get[OriginalAdaptedTreeAttachment].isDefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer not to have those methods, they just make you go through an indirection when reading the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done them to follow the convention. Honestly, I like it. I was hoping that there was a place in the compiler where the utils and definitions of attachments in the compiler was defined.
If we remove the attachment after erasure, we'll use both unmarkOriginal
and isAdaptedTree
, right? In any case, I'm happy to remove them if you think they should go away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also prefer the more direct style (i.e., drop the additional methods). The method names are all pretty ambiguous. Also, why Original*Adapted*
-- OriginalTreeAttachment
captures the same info (the presence of the attachment implies the tree is no longer the original).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll use the more direct style, rename methods/names and update this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, as a reminder: please do not include the ticket in the commit title/body. It should be in the PR description. (Title should be short, referencing the issue in the commit message causes noise on every push.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our CONTRIBUTING.md says
At the end of the commit message, include "Fixes scala/bug#NNNN"
Should that be changed? I think it's good to have the reference in the commit message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with keeping it, I'll get over my OCD that hates seeing the stale commit references pile up until the git GC kicks in at github :-)
Related to #4880, which WIPs the idea of keeping all trees (with |
I'm aware of this effort, hope it gets to the finish line at some point. Until that gets merged, I think this is the perfect solution for Zinc -- I would like to support incremental changes in constants for 2.12.4 codebases. |
How should I do this? Can you point me to some docs or previous examples?
Yes, this is indeed a good idea. |
For example just a
I'm not sure, I was just asking the question. |
Thanks, will try that.
I think it's a good idea, neither Zinc, scaladoc or Scalameta traverse trees after typer, so it's a good tradeoff. |
Ping! 👋 For this to ship as part of 2.12.4, it will have to be mergeable by Sep 27. |
88c4e79
to
ef66011
Compare
Adds an original tree attachment that allows external tools (compiler plugins like scalameta & zinc) to keep track of the previous, unadapted tree. The reason why this is required is explained in SD-340: scala/scala-dev#340. This change enables the incremental compiler to detect changes in `final val`s: sbt/zinc#227. It also enables a fix for scala/bug#10426 by allowing the scaladoc compiler to let the compiler adapt literals without losing the tree that will be shown in the Scaladoc UI. To maintainers: I was thinking of the best way to test this, but couldn't come up with an elegant one. Do you suggest a way I could write a test for this? Is there a precedent in testing information carried in the trees? I think @lrytz is the right person to review this, since he suggested this fix in the first place. Fixes scala/bug#7173.
ef66011
to
2e9a585
Compare
@lrytz Our little experiment gives us the following data about adapted trees:
The total includes a few adapted trees that were done by other phases but were not important enough to add to the table. |
I've added a second commit that cleans the original tree attachments in pre erasure so that we free up pointers to stale trees sooner in the pipeline. I think this hits the right trade-off, so thanks for the suggestion Lukas. The PR is now updated and ready for another review. |
/rebuild |
Seems like a real (though strange) error. |
30e021e
to
e547463
Compare
case tpe => specialScalaErasure(tpe) | ||
case Literal(ct) => | ||
val cleanLiteral = { | ||
if (tree.attachments.get[OriginalTreeAttachment].isEmpty) tree |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use contains
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or better yet, just use remove
directly. If this pattern of checking whether the attachment is there before removing is faster, we should implement it once in remove
(one method call that requires a class tag is also better than two)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in last commit!
e547463
to
92a1b91
Compare
The original tree attachment is useful for compiler plugins and macros. However, this commit constraints compiler plugins to run before erasure if they want to inspect the original trees so that we free up memory as soon as possible. This commit removes the attachment in pre erasure, taking advantage that we modified literals before.
92a1b91
to
493ab52
Compare
Adds an original tree attachment that allows external tools (compiler
plugins like scalameta & zinc) to keep track of the previous, unadapted
tree. The reason why this is required is explained in SD-340: scala/scala-dev#340.
This change enables the incremental compiler to detect changes in
final val
s: sbt/zinc#227.It also enables a fix for scala/bug#10426 by allowing the scaladoc
compiler to let the compiler adapt constants without losing the tree that
will be shown in the Scaladoc UI.
To maintainers: I was thinking of the best way to test this, but
couldn't come up with an elegant one. Do you suggest a way I could write
a test for this? Is there a precedent in testing information carried in
the trees?
I think @lrytz is the right person to review this, since he suggested
this fix in the first place.
Fixes scala/bug#7173