diff --git a/compiler/src/dotty/tools/dotc/transform/Splicing.scala b/compiler/src/dotty/tools/dotc/transform/Splicing.scala index 7ecde9400445..47b65ba767bb 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicing.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicing.scala @@ -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 + 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 diff --git a/tests/neg-macros/i17103.scala b/tests/neg-macros/i17103.scala new file mode 100644 index 000000000000..bd4b41d8b559 --- /dev/null +++ b/tests/neg-macros/i17103.scala @@ -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 + } + } \ No newline at end of file diff --git a/tests/pos-macros/i17103a.scala b/tests/pos-macros/i17103a.scala new file mode 100644 index 000000000000..ffd0c15f28b2 --- /dev/null +++ b/tests/pos-macros/i17103a.scala @@ -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 + } + } diff --git a/tests/pos-macros/i17103b.scala b/tests/pos-macros/i17103b.scala new file mode 100644 index 000000000000..0fbe86f0cf73 --- /dev/null +++ b/tests/pos-macros/i17103b.scala @@ -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 + } + } diff --git a/tests/pos-macros/i7405b.scala b/tests/pos-macros/i7405b.scala index df7218608e88..6c73c275e15f 100644 --- a/tests/pos-macros/i7405b.scala +++ b/tests/pos-macros/i7405b.scala @@ -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 = ??? } @@ -17,3 +17,7 @@ class Foo { } } } + +trait A: + type Y + def y: Y = ???