diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 1d0ed035df09..e2e494a95074 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -176,8 +176,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( /** If the type refers to a locally defined symbol (either directly, or in a pickled type), * check that its staging level matches the current level. * - Static types and term are allowed at any level. - * - If a type reference is used a higher level, then it is inconsistent. Will attempt to heal before failing. - * - If a term reference is used a different level, then it is inconsistent. + * - If a type reference is used a higher level, then it is inconsistent. + * Will attempt to heal before failing. + * - If a term reference is used a higher level, then it is inconsistent. + * It cannot be healed because the term will not exist in any future stage. * * If `T` is a reference to a type at the wrong level, try to heal it by replacing it with * a type tag of type `quoted.Type[T]`. @@ -206,6 +208,8 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( tryHeal(prefix.symbol, tp, pos) case _ => mapOver(tp) + case tp @ TermRef(NoPrefix, _) if !tp.symbol.isStatic && level > levelOf(tp.symbol) => + levelError(tp.symbol, tp, pos) case tp: ThisType if level != -1 && level != levelOf(tp.cls) => levelError(tp.cls, tp, pos) case tp: AnnotatedType => diff --git a/tests/neg-macros/i15917.scala b/tests/neg-macros/i15917.scala new file mode 100644 index 000000000000..3eecc38b21f9 --- /dev/null +++ b/tests/neg-macros/i15917.scala @@ -0,0 +1,6 @@ +import scala.quoted.* + +def m(using Quotes): Expr[Option[_]] = + val s = 3 + type st = s.type + '{ Some(${ Expr(s) }: st) } // error diff --git a/tests/neg-macros/i16355a.scala b/tests/neg-macros/i16355a.scala new file mode 100644 index 000000000000..8870b7777263 --- /dev/null +++ b/tests/neg-macros/i16355a.scala @@ -0,0 +1,35 @@ +//> using scala "3.2.1" +import scala.quoted.Expr +import scala.quoted.Type +import scala.quoted.quotes +import scala.quoted.Quotes + +object macros { + + inline transparent def mkNames[A]: List[Any] = ${ mkNamesImpl[A] } + + def mkNamesImpl[A: Type](using Quotes): Expr[List[Any]] = { + import quotes.reflect._ + + val fieldNames = TypeRepr.of[A].typeSymbol.declaredFields.map(_.name) + + val types = fieldNames + .map { f => + val t1 = ConstantType(StringConstant(f)) + t1.asType match { + case '[t1Type] => TypeRepr.of[(t1Type, "aa")] + } + } + .reduceLeft[TypeRepr](OrType(_, _)) + + types.asType match { + case '[ttt] => + Expr.ofList[ttt]( + fieldNames.map { v => + Expr[(v.type, "aa")](v -> "aa").asExprOf[ttt] // error + } + ) + } + } + +} diff --git a/tests/neg-macros/i16355b.scala b/tests/neg-macros/i16355b.scala new file mode 100644 index 000000000000..763810979ddf --- /dev/null +++ b/tests/neg-macros/i16355b.scala @@ -0,0 +1,4 @@ +import scala.quoted._ +def test(v: String)(using Quotes): Any = + Type.of : Type[v.type] // error + Type.of[v.type] // error