Skip to content

Unexpected tree could not be interpreted #5097

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

Closed
allanrenucci opened this issue Sep 12, 2018 · 4 comments
Closed

Unexpected tree could not be interpreted #5097

allanrenucci opened this issue Sep 12, 2018 · 4 comments
Assignees

Comments

@allanrenucci
Copy link
Contributor

// Foo.scala
import scala.quoted._

class Foo {
  rewrite def foo1: String = ~Foo.impl
}

object Foo {
  rewrite def foo2: String = ~Foo.impl
  private def impl: Expr[String] = '("")
}
// Test.scala
class Test {
  def test1: String = (new Foo).foo1 // error
  def test2: String = Foo.foo2       // ok
}
> dotc -d out Foo.scala
> dotc -classpath out Test.scala
-- Error: Test.scala:2:22 ---------------------------------
2 |  def test1: String = (new Foo).foo1
  |                      ^
  |                      Unexpected tree could not be interpreted: Select(Ident(Foo_this),inline$impl)

If def impl is not private, the code compiles

@odersky
Copy link
Contributor

odersky commented Sep 12, 2018

That's because of the inline accessor. We either need to "see through" such accessors or forbid them (but then a better error message would help).

@allanrenucci
Copy link
Contributor Author

But why can't we "see through" in the macro foo1 but we do in the macro foo2?

@nicolasstucki
Copy link
Contributor

The issue is that we are generating the accessor a private member of the object in the class.

If we have the following code

class Foo {
  rewrite def foo0: String = Foo.impl1
}

object Foo {
  rewrite def foo1: String = Foo.impl1
  rewrite def foo2: String = Foo.impl2

  private def impl1: String = ""
  private def impl2: String = ""
}

after typer we currently have

result of Foo.scala after frontend:
package <empty> {
  class Foo() extends Object() { 
    rewrite def foo0: String = Foo.impl1
    def inline$impl1: String = Foo.impl1
  }
  final lazy module val Foo: Foo$ = new Foo$()
  final module class Foo$() extends Object() { this: Foo.type => 
    rewrite def foo1: String = Foo.impl1
    rewrite def foo2: String = Foo.impl2
    private def impl1: String = ""
    private def impl2: String = ""
    def inline$impl1: String = Foo.impl1
    def inline$impl2: String = Foo.impl2
  }
}

Note that we generated one inline$impl1 for foo0 in class Foo and one for foo1 in object Foo. Instead we should only generate inline$impl1 in object Foo and use that one for foo0.

@biboudis
Copy link
Contributor

Check if still occurs after #5138 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants