diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 626455da63d1..2ac7b5cf323d 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -66,8 +66,14 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( checkAnnotations(tree) super.transform(tree) else tree match { - - case _: TypeTree | _: RefTree if tree.isType => + case tree: TypeTree => + val tree1 = treeify(tree) + if tree ne tree1 then transform(tree1.withSpan(tree.span)) + else + val healedType = healType(tree.srcPos)(tree.tpe) + if healedType == tree.tpe then tree + else TypeTree(healedType).withSpan(tree.span) + case _: RefTree if tree.isType => val healedType = healType(tree.srcPos)(tree.tpe) if healedType == tree.tpe then tree else TypeTree(healedType).withSpan(tree.span) @@ -275,6 +281,18 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( tp } + /** Transform a TypeTree into a tree that contains the structure of the type */ + private def treeify(tree: TypeTree)(using Context): Tree = + tree.tpe.stripTypeVar.dealias match + case tpe @ TypeRef(path: TermRef, _) => + // Expand TypeTree(`x.T`) to Select(`x`, `T`) + // Needed in PickleQuotes in case x refers to a captured reference. + ref(path).select(tpe) + case AppliedType(tycon, args) => + AppliedTypeTree(treeify(TypeTree(tycon)), args.map(TypeTree)) + case _ => + tree + } object PCPCheckAndHeal { diff --git a/tests/pos-macros/i12440.scala b/tests/pos-macros/i12440.scala new file mode 100644 index 000000000000..4b4c56fef568 --- /dev/null +++ b/tests/pos-macros/i12440.scala @@ -0,0 +1,21 @@ +import scala.quoted.* + +trait Mirror: + type ElemTypes <: Tuple + +class Eq: + + def test1(using Quotes): Unit = '{ + val m: Mirror = ??? + ${ summonType[m.ElemTypes]; ??? } + ${ summonType[List[m.ElemTypes]]; ??? } + } + + def test2(using Quotes): Unit = '{ + val m: Mirror = ??? + type ET = m.ElemTypes + ${ summonType[ET]; ??? } + ${ summonType[List[ET]]; ??? } + } + + def summonType[X](using Type[X]) = ??? diff --git a/tests/pos-macros/i8100.scala b/tests/pos-macros/i8100.scala index 0cf80fe920ee..6ceafeef1965 100644 --- a/tests/pos-macros/i8100.scala +++ b/tests/pos-macros/i8100.scala @@ -14,8 +14,8 @@ def f[T: Type](using Quotes) = ${ g[m.E](using Type.of[ME]) } ${ g[ME](using Type.of[m.E]) } ${ g[m.E](using Type.of[m.E]) } - // ${ g[ME] } // FIXME: issue seems to be in PickleQuotes - // ${ g[m.E] } // FIXME: issue seems to be in PickleQuotes + ${ g[ME] } + ${ g[m.E] } } -def g[T](using Type[T]) = ??? +def g[T](using Type[T]) = ??? \ No newline at end of file