Skip to content

Commit 9cea198

Browse files
committed
Add regression test
The issue was that an uninstantiated type variable escaped the implicit search and was then affected by the quote pattern match. Fixes #15779 Fixes #16636
1 parent 4ed1c25 commit 9cea198

File tree

5 files changed

+73
-0
lines changed

5 files changed

+73
-0
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
23982398
import tpd.TreeOps
23992399
val implicitTree = ctx.typer.inferImplicitArg(tpe, Position.ofMacroExpansion.span)
24002400
// Make sure that we do not have any uninstantiated type variables.
2401+
// See tests/pos-macros/i16636.
24012402
// See tests/pos-macros/exprSummonWithTypeVar with -Xcheck-macros.
24022403
implicitTree.foreachSubTree(tree => dotc.typer.Inferencing.fullyDefinedType(tree.tpe, "", tree))
24032404
implicitTree

tests/pos-macros/i15779/Macro_1.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import scala.quoted._
2+
import scala.deriving.Mirror
3+
4+
trait Encoder[-A]
5+
6+
trait PrimitiveEncoder[A] extends Encoder[A]
7+
8+
given intOpt: PrimitiveEncoder[Option[Int]] with {}
9+
10+
given primitiveNotNull[T](using e: Encoder[Option[T]]): PrimitiveEncoder[T] =
11+
new PrimitiveEncoder[T] {}
12+
13+
transparent inline given fromMirror[A]: Any = ${ fromMirrorImpl[A] }
14+
15+
def fromMirrorImpl[A : Type](using q: Quotes): Expr[Any] =
16+
Expr.summon[Mirror.Of[A]].get match
17+
case '{ ${mirror}: Mirror.ProductOf[A] { type MirroredElemTypes = elementTypes } } =>
18+
val encoder = Type.of[elementTypes] match
19+
case '[tpe *: EmptyTuple] =>
20+
Expr.summon[Encoder[tpe]].get
21+
22+
encoder match
23+
case '{ ${encoder}: Encoder[tpe] } => // ok
24+
case _ => ???
25+
26+
encoder match
27+
case '{ ${encoder}: Encoder[tpe] } => // ok
28+
case _ => ???
29+
30+
encoder

tests/pos-macros/i15779/Test_2.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
case class JustInt(i: Int)
2+
3+
val x = fromMirror[JustInt]

tests/pos-macros/i16636/Macro_1.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import scala.quoted.*
2+
3+
trait ReproTransformer[A, B] {
4+
def transform(from: A): B
5+
}
6+
7+
object ReproTransformer {
8+
final class Identity[A, B >: A] extends ReproTransformer[A, B] {
9+
def transform(from: A): B = from
10+
}
11+
12+
given identity[A, B >: A]: Identity[A, B] = Identity[A, B]
13+
14+
inline def getTransformer[A, B]: ReproTransformer[A, B] = ${ getTransformerMacro[A, B] }
15+
16+
def getTransformerMacro[A, B](using quotes: Quotes, A: Type[A], B: Type[B]) = {
17+
import quotes.reflect.*
18+
19+
val transformer = (A -> B) match {
20+
case '[a] -> '[b] =>
21+
val summoned = Expr.summon[ReproTransformer[a, b]].get
22+
// ----------- INTERESTING STUFF STARTS HERE
23+
summoned match {
24+
case '{ $t: ReproTransformer[src, dest] } => t
25+
}
26+
// ----------- INTERESTING STUFF ENDS HERE
27+
}
28+
transformer.asExprOf[ReproTransformer[A, B]]
29+
}
30+
}

tests/pos-macros/i16636/Test_2.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
object A {
2+
case class AnotherCaseClass(name: String)
3+
4+
val errorsOut1 = ReproTransformer.getTransformer[A.AnotherCaseClass, AnotherCaseClass]
5+
val errorsOu2 = ReproTransformer.getTransformer[AnotherCaseClass, A.AnotherCaseClass]
6+
7+
val works1 = ReproTransformer.getTransformer[A.AnotherCaseClass, A.AnotherCaseClass]
8+
val works2 = ReproTransformer.getTransformer[AnotherCaseClass, AnotherCaseClass]
9+
}

0 commit comments

Comments
 (0)