Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use TermRef to distinguish distinct Type[T] instances #17205

Merged
merged 2 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ class CrossStageSafety extends TreeMapWithStages {
* The tag is generated by an instance of `QuoteTypeTags` directly if the splice is explicit
* or indirectly by `tryHeal`.
*/
protected def healType(pos: SrcPos)(using Context) =
new HealType(pos)
protected def healType(pos: SrcPos)(tpe: Type)(using Context) =
new HealType(pos).apply(tpe)

/** Check level consistency of terms references */
private def checkLevelConsistency(tree: Ident | This)(using Context): Unit =
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/staging/HealType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap {
if level == 0 then tp else getQuoteTypeTags.getTagRef(prefix)
case _: NamedType | _: ThisType | NoPrefix =>
if levelInconsistentRootOfPath(tp).exists then
tryHeal(tp.symbol, tp, pos)
tryHeal(tp)
else
tp
case _ =>
Expand Down Expand Up @@ -82,7 +82,7 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap {
* reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`.
* Emits an error if `T` cannot be healed and returns `T`.
*/
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): Type = {
protected def tryHeal(tp: TypeRef): Type = {
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
tag.tpe match
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/staging/QuoteTypeTags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ object QuoteTypeTags {
class QuoteTypeTags(span: Span)(using Context) {
import tpd.*

private val tags = collection.mutable.LinkedHashMap.empty[Symbol, TypeDef]
private val tags = collection.mutable.LinkedHashMap.empty[TermRef, TypeDef]

def getTagRef(spliced: TermRef): TypeRef = {
val typeDef = tags.getOrElseUpdate(spliced.symbol, mkTagSymbolAndAssignType(spliced))
val typeDef = tags.getOrElseUpdate(spliced, mkTagSymbolAndAssignType(spliced))
typeDef.symbol.typeRef
}

Expand All @@ -42,7 +42,7 @@ class QuoteTypeTags(span: Span)(using Context) {
val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree(rhs, rhs), rhs, rhs, EmptyTree)
val local = newSymbol(
owner = ctx.owner,
name = UniqueName.fresh((splicedTree.symbol.name.toString + "$_").toTermName).toTypeName,
name = UniqueName.fresh(rhs.tpe.dealias.typeSymbol.name.toTypeName),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why this is changed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is for debugging purposes. It makes the type simpler to read.

flags = Synthetic,
info = TypeAlias(splicedTree.tpe.select(tpnme.Underlying)),
coord = span).asType
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/transform/Splicing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ class Splicing extends MacroTransform:
/** Number of holes created in this quote. Used for indexing holes. */
private var numHoles = 0

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

override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
tree match
Expand All @@ -127,13 +127,13 @@ class Splicing extends MacroTransform:
case tree: TypeDef if tree.symbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot) =>
val tp @ TypeRef(qual: TermRef, _) = tree.rhs.tpe.hiBound: @unchecked
quotedDefs += tree.symbol
val hole = typeHoles.get(qual.symbol) match
val hole = typeHoles.get(qual) match
case Some (hole) => cpy.Hole(hole)(content = EmptyTree)
case None =>
val holeIdx = numHoles
numHoles += 1
val hole = tpd.Hole(false, holeIdx, Nil, ref(qual), TypeTree(tp))
typeHoles.put(qual.symbol, hole)
typeHoles.put(qual, hole)
hole
cpy.TypeDef(tree)(rhs = hole)
case Apply(Select(Apply(TypeApply(fn,_), List(code)),nme.apply),List(quotes))
Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/Staging.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class Staging extends MacroTransform {
tree match {
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
val checker = new CrossStageSafety {
override protected def healType(pos: SrcPos)(using Context) = new HealType(pos) {
override protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): TypeRef = {
override protected def healType(pos: SrcPos)(tpe: Type)(using Context) = new HealType(pos) {
override protected def tryHeal(tp: TypeRef): TypeRef = {
val sym = tp.symbol
def symStr =
if (sym.is(ModuleClass)) sym.sourceModule.show
else i"${sym.name}.this"
Expand All @@ -51,7 +52,7 @@ class Staging extends MacroTransform {

tp
}
}
}.apply(tpe)
}
checker.transform(tree)
case _ =>
Expand Down
17 changes: 17 additions & 0 deletions tests/pos-macros/i16959/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import scala.quoted.*

inline def test = ${ testImpl }

def testImpl(using Quotes) =
import quotes.reflect.*

val int = PackedType[Int]
val string = PackedType[String]

assert(Type.show[(int.U, string.U, string.U)] == "scala.Tuple3[scala.Int, java.lang.String, java.lang.String]")

'{ () }

final class PackedType[T](using t: Type[T]):
opaque type U = T
given tpe: Type[U] = t
1 change: 1 addition & 0 deletions tests/pos-macros/i16959/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def app = test