diff --git a/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala b/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala index 85f2e84429c3..b958b64f7c54 100644 --- a/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala +++ b/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala @@ -203,11 +203,19 @@ class CrossStageSafety extends TreeMapWithStages { /** Check level consistency of terms references */ private def checkLevelConsistency(tree: Ident | This)(using Context): Unit = + def isStatic(pre: Type)(using Context): Boolean = pre match + case pre: NamedType => + val sym = pre.currentSymbol + sym.is(Package) || sym.isStaticOwner && isStatic(pre.prefix) + case pre: ThisType => isStatic(pre.tref) + case _ => true new TypeTraverser { def traverse(tp: Type): Unit = tp match case tp @ TermRef(NoPrefix, _) if !tp.symbol.isStatic && level != levelOf(tp.symbol) => levelError(tp.symbol, tp, tree.srcPos) + case tp: ThisType if isStatic(tp) => + // static object (OK) case tp: ThisType if level != -1 && level != levelOf(tp.cls) => levelError(tp.cls, tp, tree.srcPos) case tp: AnnotatedType => @@ -215,7 +223,7 @@ class CrossStageSafety extends TreeMapWithStages { case _ if tp.typeSymbol.is(Package) => // OK case _ => - traverseChildren(tp) + traverseChildren(tp) }.traverse(tree.tpe) private def levelError(sym: Symbol, tp: Type, pos: SrcPos)(using Context): tp.type = { diff --git a/tests/neg/i22592.scala b/tests/neg/i22592.scala new file mode 100644 index 000000000000..6a9a89cacf2a --- /dev/null +++ b/tests/neg/i22592.scala @@ -0,0 +1,14 @@ +import scala.quoted.* + +trait Foo: + def inherited = () + +class Bar extends Foo: + def local = () + def localArg(arg: Any) = () + + def macro1(using Quotes): Expr[Unit] = '{ local } // error + def macro3(using Quotes): Expr[Unit] = '{ inherited } // error + def macro4(using Quotes): Expr[Unit] = '{ this.local } // error + def macro5(using Quotes): Expr[Unit] = '{ this.inherited } // error + def macro6(using Quotes): Expr[Unit] = '{ localArg(this) } // error // error diff --git a/tests/pos/i22592.scala b/tests/pos/i22592.scala new file mode 100644 index 000000000000..f6a1f2eff696 --- /dev/null +++ b/tests/pos/i22592.scala @@ -0,0 +1,15 @@ +import scala.quoted.* + +trait Foo: + def inherited = () + +object Bar extends Foo: + def local = () + def localArg(arg: Any) = () + + def macro1(using Quotes): Expr[Unit] = '{ local } + def macro2(using Quotes): Expr[Unit] = '{ Bar.inherited } + def macro3(using Quotes): Expr[Unit] = '{ inherited } + def macro4(using Quotes): Expr[Unit] = '{ this.local } + def macro5(using Quotes): Expr[Unit] = '{ this.inherited } + def macro6(using Quotes): Expr[Unit] = '{ localArg(this) }