Skip to content

Commit 7187e22

Browse files
Use TermRef to distinguish distinct Type[T] instances (#17205)
We used the symbol before, but this ignored the specific path to the instance of Type[T]. Fixes #16959
2 parents 2f4cc4c + 57a6867 commit 7187e22

File tree

7 files changed

+33
-14
lines changed

7 files changed

+33
-14
lines changed

compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ class CrossStageSafety extends TreeMapWithStages {
206206
* The tag is generated by an instance of `QuoteTypeTags` directly if the splice is explicit
207207
* or indirectly by `tryHeal`.
208208
*/
209-
protected def healType(pos: SrcPos)(using Context) =
210-
new HealType(pos)
209+
protected def healType(pos: SrcPos)(tpe: Type)(using Context) =
210+
new HealType(pos).apply(tpe)
211211

212212
/** Check level consistency of terms references */
213213
private def checkLevelConsistency(tree: Ident | This)(using Context): Unit =

compiler/src/dotty/tools/dotc/staging/HealType.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap {
5151
if level == 0 then tp else getQuoteTypeTags.getTagRef(prefix)
5252
case _: NamedType | _: ThisType | NoPrefix =>
5353
if levelInconsistentRootOfPath(tp).exists then
54-
tryHeal(tp.symbol, tp, pos)
54+
tryHeal(tp)
5555
else
5656
tp
5757
case _ =>
@@ -82,7 +82,7 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap {
8282
* reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`.
8383
* Emits an error if `T` cannot be healed and returns `T`.
8484
*/
85-
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): Type = {
85+
protected def tryHeal(tp: TypeRef): Type = {
8686
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)
8787
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
8888
tag.tpe match

compiler/src/dotty/tools/dotc/staging/QuoteTypeTags.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ object QuoteTypeTags {
2727
class QuoteTypeTags(span: Span)(using Context) {
2828
import tpd.*
2929

30-
private val tags = collection.mutable.LinkedHashMap.empty[Symbol, TypeDef]
30+
private val tags = collection.mutable.LinkedHashMap.empty[TermRef, TypeDef]
3131

3232
def getTagRef(spliced: TermRef): TypeRef = {
33-
val typeDef = tags.getOrElseUpdate(spliced.symbol, mkTagSymbolAndAssignType(spliced))
33+
val typeDef = tags.getOrElseUpdate(spliced, mkTagSymbolAndAssignType(spliced))
3434
typeDef.symbol.typeRef
3535
}
3636

@@ -42,7 +42,7 @@ class QuoteTypeTags(span: Span)(using Context) {
4242
val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree(rhs, rhs), rhs, rhs, EmptyTree)
4343
val local = newSymbol(
4444
owner = ctx.owner,
45-
name = UniqueName.fresh((splicedTree.symbol.name.toString + "$_").toTermName).toTypeName,
45+
name = UniqueName.fresh(rhs.tpe.dealias.typeSymbol.name.toTypeName),
4646
flags = Synthetic,
4747
info = TypeAlias(splicedTree.tpe.select(tpnme.Underlying)),
4848
coord = span).asType

compiler/src/dotty/tools/dotc/transform/Splicing.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ class Splicing extends MacroTransform:
108108
/** Number of holes created in this quote. Used for indexing holes. */
109109
private var numHoles = 0
110110

111-
/** Mapping from the term symbol of a `Type[T]` to it's hole. Used to deduplicate type holes. */
112-
private val typeHoles = mutable.Map.empty[Symbol, Hole]
111+
/** Mapping from the term of a `Type[T]` to it's hole. Used to deduplicate type holes. */
112+
private val typeHoles = mutable.Map.empty[TermRef, Hole]
113113

114114
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
115115
tree match
@@ -127,13 +127,13 @@ class Splicing extends MacroTransform:
127127
case tree: TypeDef if tree.symbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot) =>
128128
val tp @ TypeRef(qual: TermRef, _) = tree.rhs.tpe.hiBound: @unchecked
129129
quotedDefs += tree.symbol
130-
val hole = typeHoles.get(qual.symbol) match
130+
val hole = typeHoles.get(qual) match
131131
case Some (hole) => cpy.Hole(hole)(content = EmptyTree)
132132
case None =>
133133
val holeIdx = numHoles
134134
numHoles += 1
135135
val hole = tpd.Hole(false, holeIdx, Nil, ref(qual), TypeTree(tp))
136-
typeHoles.put(qual.symbol, hole)
136+
typeHoles.put(qual, hole)
137137
hole
138138
cpy.TypeDef(tree)(rhs = hole)
139139
case Apply(Select(Apply(TypeApply(fn,_), List(code)),nme.apply),List(quotes))

compiler/src/dotty/tools/dotc/transform/Staging.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ class Staging extends MacroTransform {
3636
tree match {
3737
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
3838
val checker = new CrossStageSafety {
39-
override protected def healType(pos: SrcPos)(using Context) = new HealType(pos) {
40-
override protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): TypeRef = {
39+
override protected def healType(pos: SrcPos)(tpe: Type)(using Context) = new HealType(pos) {
40+
override protected def tryHeal(tp: TypeRef): TypeRef = {
41+
val sym = tp.symbol
4142
def symStr =
4243
if (sym.is(ModuleClass)) sym.sourceModule.show
4344
else i"${sym.name}.this"
@@ -51,7 +52,7 @@ class Staging extends MacroTransform {
5152

5253
tp
5354
}
54-
}
55+
}.apply(tpe)
5556
}
5657
checker.transform(tree)
5758
case _ =>

tests/pos-macros/i16959/Macro_1.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.quoted.*
2+
3+
inline def test = ${ testImpl }
4+
5+
def testImpl(using Quotes) =
6+
import quotes.reflect.*
7+
8+
val int = PackedType[Int]
9+
val string = PackedType[String]
10+
11+
assert(Type.show[(int.U, string.U, string.U)] == "scala.Tuple3[scala.Int, java.lang.String, java.lang.String]")
12+
13+
'{ () }
14+
15+
final class PackedType[T](using t: Type[T]):
16+
opaque type U = T
17+
given tpe: Type[U] = t

tests/pos-macros/i16959/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def app = test

0 commit comments

Comments
 (0)