Skip to content

Commit

Permalink
Disallow local term references in staged types
Browse files Browse the repository at this point in the history
Fixes #16355
Fixes #15917
  • Loading branch information
nicolasstucki committed Jan 9, 2023
1 parent a1729b0 commit 7d731dc
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
* 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 term reference is used a higher level, then it is inconsistent.
*
* 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]`.
Expand Down Expand Up @@ -206,6 +206,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 =>
Expand Down
6 changes: 6 additions & 0 deletions tests/neg-macros/i15917.scala
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions tests/neg-macros/i16355a.scala
Original file line number Diff line number Diff line change
@@ -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
}
)
}
}

}
4 changes: 4 additions & 0 deletions tests/neg-macros/i16355b.scala
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7d731dc

Please sign in to comment.