-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #3917: Properly desugar Ident
#3925
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
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.
Yep, that looks like the right fix.
This fix doesn't work. We cannot always prefix identifier by object Foo {
var verbose = false
}
object Bar {
def test = {
import Foo._
verbose = true // cannot be prefixed by this
}
} |
Someone might want to take over this PR. I am not sure what is the proper way to fix the issue |
We have code to transform Ident into Select, that may help: https://github.com/lampepfl/dotty/blob/02252a870f7eb510656632dca6d0f005d8754ee8/compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala#L152-L160 |
9f7bb74
to
3857489
Compare
this
when applied on Ident
Ident
assert(setter.exists, tree.symbol.showLocated) | ||
val qual = tree match { | ||
case id: Ident => | ||
id.tpe match { |
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.
There's already three versions of desugarIdent
in the codebase. I suggest we try to replace them by a common version in tpd.scala or something like that instead of adding one more variation.
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 am only interested in the prefix of the desugared ident. Should I still extract the functionality and do something like:
val qual = tree match {
case id: Ident =>
desugarIdent(id).get.qual
...
This would create an unnecessary Option
and Select
node
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.
we could have a desugarIdentPrefix
method.
3857489
to
6bd882e
Compare
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.
Otherwise LGTM
@@ -1012,5 +1011,21 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { | |||
val encoding = ctx.settings.encoding.value | |||
if (file != null && file.exists) new SourceFile(file, Codec(encoding)) else NoSource | |||
} | |||
|
|||
/** Desugar identifier into a select node. Return None if not possible */ |
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.
We don't usually use Option in the compiler, first, because of the allocation overhead, and second, because we usually have sentinel values that signal absence of a proper result. E.g. EmptyTree
for trees. So I would just let desugarIdent
return an EmptyTree
if no rules apply. That's more idiomatic. Hint: orElse
works on empty trees.
I see there are quite a lot of uses of desugarIdent
, and have the impression that most of these uses could be improved by going to EmptyTree. The use of Option.fold in JSCodeGen is particularly opaque.
5e7a56b
to
8652469
Compare
@OlivierBlanvillain Can you please review the last commit? |
@@ -444,8 +444,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma | |||
def desugarIdent(i: Ident): Option[tpd.Select] = { |
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 could not get rid of the Option
here since the backend expects this signature
case _ if t.symbol.is(Mutable) => true | ||
case s: Select => s.symbol.owner == defn.SystemModule | ||
case i: Ident => | ||
desugarIdent(i) match { |
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 did not understand why desugaring was needed here because it doesn't change the symbol of the tree
@@ -194,7 +194,7 @@ class Devalify extends Optimisation { | |||
readingOnlyVals(qual) | |||
|
|||
case t: Ident if !t.symbol.is(Mutable | Method) && !t.symbol.info.dealias.isInstanceOf[ExprType] => | |||
desugarIdent(t).forall(readingOnlyVals) | |||
!isEffectivelyMutable(t) |
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.
Did not understand why desugaring was needed here too
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 would keep the logic untouched then:
desugarIdent(t) match { case s: Select => readingOnlyVals(s); case _ => true }
case _ => t2 | ||
} | ||
isSimilar(t, t2i) | ||
case None => t1.symbol eq t2.symbol |
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 think the logic was wrong here. If t2
is a select then it is not enough to compare the symbols
8652469
to
2d71030
Compare
Does this mean we can close #1686, though with a different fix than planned then? |
This doesn't really fix #1686. It gives you a way to desugar |
No description provided.