-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Don't generate paths with outer accessors to stable references #11918
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
In that case we can generate directly a reference without going though an inner this proxy and an outer accessor. Fixes scala#11914.
I think this would be good to get into RC2. I don't see a particular risk, and it avoids an annoying crash in code generation. |
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.
LGTM
ref(info) | ||
case _ => | ||
ref(lastSelf).outerSelect(lastLevel - level, selfSym.info) | ||
else if rhsClsSym.is(Module) && rhsClsSym.isStatic then |
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.
Since we are at the code, I've a question regarding the code just above L511-L517:
val sortedProxies = thisProxy.toList.map {
case (cls, proxy) =>
// The class that the this-proxy `selfSym` represents
def classOf(selfSym: Symbol) = selfSym.info.classSymbol
// The total nesting depth of the class represented by `selfSym`.
def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length
(outerLevel(cls), proxy.symbol)
}.sortBy(-_._1)
It seems to me that the call classOf(selfSym)
is useless, as selfSym
is already a class 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.
The following line (L531) for static objects look dubious, as it is not effective if lastSelf.exists
:
else if rhsClsSym.is(Module) && rhsClsSym.isStatic then
I expect it to be before the branch lastSelf.exists
, thus always generate optimized code.
Currently, it's not the case, as can be seen from the example below:
object Wrapper:
type E <: Throwable
class C:
object syntax:
extension [A <: Matchable](a: E | A)
transparent inline def foreach(f: A => Any): Unit =
a match
case e: E =>
Wrapper.this.n + m
case a: A => f(a)
val m: Int = 4
def _catch[A](a: => A): E | A =
try a
catch case e: E => e
val n: Int = 3
object throwables extends Wrapper.C
import throwables.syntax.*
@main def Test(): Unit =
for x <- Wrapper._catch(1/1) do println(x)
The proxy generated for Wrapper
is the following:
val Wrapper$_this: (Wrapper : Wrapper.type) = syntax$_this.2_<outer>
And the example crashes the compiler with the current 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.
Thanks for these insights!
In that case we can generate directly a reference without going though
an inner this proxy and an outer accessor.
This optimization is necessary since outer accessors are not generated for objects.
Fixes #11914.