Skip to content

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

Merged
merged 3 commits into from
Mar 28, 2021

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Mar 27, 2021

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.

In that case we can generate directly a reference without going though
an inner this proxy and an outer accessor.

Fixes scala#11914.
@odersky
Copy link
Contributor Author

odersky commented Mar 27, 2021

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.

@odersky odersky added this to the 3.0.0-RC2 milestone Mar 27, 2021
Copy link
Contributor

@liufengyun liufengyun left a 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
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for these insights!

@odersky odersky merged commit cca5f8f into scala:master Mar 28, 2021
@odersky odersky deleted the fix-#11914 branch March 28, 2021 16:04
@Kordyjan Kordyjan modified the milestones: 3.0.0-RC2, 3.0.0 Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

assertion failed: failure to construct path from value. object foo in class Bar does not have an outer accessor
3 participants