Skip to content
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

Fix references to class members defined in quotes #17107

Merged
merged 1 commit into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/Splicing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ class Splicing extends MacroTransform:

override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
tree match
case tree: Select if tree.isTerm && isCaptured(tree.symbol) =>
tree.symbol.allOverriddenSymbols.find(sym => !isCaptured(sym.owner)) match
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it matter if there are multiple overridden symbols that are not captured? I think it doesn't but just want to make sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should no matter.

case Some(sym) =>
// virtualize call on overridden symbol that is not defined in a non static class
transform(tree.qualifier.select(sym))
case _ =>
report.error(em"Can not use reference to staged local ${tree.symbol} defined in an outer quote.\n\nThis can work if ${tree.symbol.owner} would extend a top level interface that defines ${tree.symbol}.", tree)
tree
case tree: RefTree =>
if tree.isTerm then
if isCaptured(tree.symbol) then
Expand Down
16 changes: 16 additions & 0 deletions tests/neg-macros/i17103.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import scala.quoted.*

def test(using Quotes): Expr[Unit] =
'{
trait C:
def d: Int
val c: C = ???
${
val expr = '{
val cRef: c.type = ???
cRef.d // error
()
}
expr
}
}
21 changes: 21 additions & 0 deletions tests/pos-macros/i17103a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import scala.quoted.*

trait C0:
def d: Int

def test(using Quotes): Expr[Unit] =
'{
trait C1 extends C0:
def d: Int
trait C extends C1:
def d: Int
val c: C = ???
${
val expr = '{
val cRef: C = ???
cRef.d // calls C0.d
()
}
expr
}
}
21 changes: 21 additions & 0 deletions tests/pos-macros/i17103b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import scala.quoted.*

trait C0:
def d: Int

def test(using Quotes): Expr[Unit] =
'{
trait C1 extends C0:
def d: Int
trait C extends C1:
def d: Int
val c: C = ???
${
val expr = '{
val cRef: c.type = ???
cRef.d // calls C0.d
()
}
expr
}
}
6 changes: 5 additions & 1 deletion tests/pos-macros/i7405b.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import scala.quoted.*
class Foo {
def f(using Quotes): Expr[Any] = {
'{
trait X {
trait X extends A {
type Y
def y: Y = ???
}
Expand All @@ -17,3 +17,7 @@ class Foo {
}
}
}

trait A:
type Y
def y: Y = ???