Skip to content

Commit b220ea1

Browse files
committed
wip
1 parent f042044 commit b220ea1

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

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

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
7474
else tpd.Block(taggedTypes.getTypeTags, body1).withSpan(body.span)
7575

7676
quote match {
77-
case quote: Apply => cpy.Apply(quote)(transform(quote.fun), body2 :: Nil)
78-
case quote: TypeApply => cpy.TypeApply(quote)(transform(quote.fun), body2 :: Nil)
77+
case quote @ Apply(tpApp @ TypeApply(fn, List(tpt)), _) =>
78+
cpy.Apply(quote)(cpy.TypeApply(tpApp)(fn, List(transform(tpt)(ctx))), body2 :: Nil)
79+
case quote: TypeApply =>
80+
cpy.TypeApply(quote)(quote.fun, body2 :: Nil)
7981
}
8082
}
8183

@@ -90,7 +92,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
9092
case Apply(fun: TypeApply, _) if splice.isTerm =>
9193
// Type of the splice itsel must also be healed
9294
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
93-
val tp = checkType(splice.sourcePos).apply(splice.tpe.widenTermRefExpr)
95+
val tp = checkType(splice.sourcePos, adaptOnly = false).apply(splice.tpe.widenTermRefExpr)
9496
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
9597
case splice: Select =>
9698
val tagRef = getQuoteTypeTags.getTagRef(splice.qualifier.tpe.asInstanceOf[TermRef])
@@ -106,36 +108,36 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
106108
* `${implicitly[quoted.Type[T]]}`.
107109
*/
108110
protected def checkLevel(tree: Tree)(implicit ctx: Context): Tree = {
109-
def checkTp(tp: Type): Type = checkType(tree.sourcePos).apply(tp)
111+
def checkTp(tp: Type, adaptOnly: Boolean): Type = checkType(tree.sourcePos, adaptOnly).apply(tp)
110112
tree match {
111113
case Quoted(_) | Spliced(_) =>
112114
tree
113115
case _: This =>
114-
assert(checkSymLevel(tree.symbol, tree.tpe, tree.sourcePos).isEmpty)
116+
assert(checkSymLevel(tree.symbol, tree.tpe, tree.sourcePos, adaptOnly = false).isEmpty)
115117
tree
116118
case Ident(name) =>
117119
if (name == nme.WILDCARD)
118-
untpd.Ident(name).withType(checkType(tree.sourcePos).apply(tree.tpe)).withSpan(tree.span)
120+
untpd.Ident(name).withType(checkType(tree.sourcePos, adaptOnly = false).apply(tree.tpe)).withSpan(tree.span)
119121
else
120-
checkSymLevel(tree.symbol, tree.tpe, tree.sourcePos) match {
122+
checkSymLevel(tree.symbol, tree.tpe, tree.sourcePos, adaptOnly = false) match {
121123
case Some(tpRef) => tpRef
122124
case _ => tree
123125
}
124-
case _: TypeTree | _: AppliedTypeTree | _: Apply | _: TypeApply | _: UnApply | Select(_, OuterSelectName(_, _)) =>
125-
tree.withType(checkTp(tree.tpe))
126+
case _: TypeTree | _: AppliedTypeTree | _: Select | _: Apply | _: TypeApply | _: UnApply | Select(_, OuterSelectName(_, _)) =>
127+
tree.withType(checkTp(tree.tpe, adaptOnly = true))
126128
case _: ValOrDefDef | _: Bind =>
127-
tree.symbol.info = checkTp(tree.symbol.info)
129+
tree.symbol.info = checkTp(tree.symbol.info, adaptOnly = false)
128130
tree
129131
case _: Template =>
130-
checkTp(tree.symbol.owner.asClass.givenSelfType)
132+
checkTp(tree.symbol.owner.asClass.givenSelfType, adaptOnly = false)
131133
tree
132134
case _ =>
133135
tree
134136
}
135137
}
136138

137139
/** Check and heal all named types and this-types in a given type for phase consistency. */
138-
private def checkType(pos: SourcePosition)(implicit ctx: Context): TypeMap = new TypeMap {
140+
private def checkType(pos: SourcePosition, adaptOnly: Boolean)(implicit ctx: Context): TypeMap = new TypeMap {
139141
def apply(tp: Type): Type = reporting.trace(i"check type level $tp at $level") {
140142
tp match {
141143
case tp: TypeRef if tp.symbol.isSplice =>
@@ -150,14 +152,14 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
150152
getQuoteTypeTags.getTagRef(tp.prefix.asInstanceOf[TermRef])
151153
else tp
152154
case tp: NamedType =>
153-
checkSymLevel(tp.symbol, tp, pos) match {
155+
checkSymLevel(tp.symbol, tp, pos, adaptOnly) match {
154156
case Some(tpRef) => tpRef.tpe
155157
case _ =>
156158
if (tp.symbol.is(Param)) tp
157159
else mapOver(tp)
158160
}
159161
case tp: ThisType =>
160-
assert(checkSymLevel(tp.cls, tp, pos).isEmpty)
162+
assert(checkSymLevel(tp.cls, tp, pos, adaptOnly).isEmpty)
161163
mapOver(tp)
162164
case tp: AnnotatedType =>
163165
derivedAnnotatedType(tp, apply(tp.parent), tp.annot)
@@ -173,7 +175,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
173175
* @return `None` if the phase is correct or cannot be healed
174176
* `Some(tree)` with the `tree` of the healed type tree for `${implicitly[quoted.Type[T]]}`
175177
*/
176-
private def checkSymLevel(sym: Symbol, tp: Type, pos: SourcePosition)(implicit ctx: Context): Option[Tree] = {
178+
private def checkSymLevel(sym: Symbol, tp: Type, pos: SourcePosition, adaptOnly: Boolean)(implicit ctx: Context): Option[Tree] = {
177179
/** Is a reference to a class but not `this.type` */
178180
def isClassRef = sym.isClass && !tp.isInstanceOf[ThisType]
179181

@@ -201,11 +203,13 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
201203
else if (!sym.isStaticOwner && !isClassRef)
202204
tp match
203205
case tp: TypeRef =>
204-
if levelOf(sym).getOrElse(0) < level then tryHeal(sym, tp, pos)
206+
if levelOf(sym).getOrElse(0) < level then tryHeal(sym, tp, pos, adaptOnly)
205207
else None
206208
case _ =>
207-
levelError(sym, tp, pos, "")
208-
else if (!sym.owner.isStaticOwner) // non-top level class reference that is phase inconsistent
209+
if !adaptOnly then
210+
levelError(sym, tp, pos, "")
211+
else None
212+
else if (!sym.owner.isStaticOwner && !adaptOnly) // non-top level class reference that is phase inconsistent
209213
levelError(sym, tp, pos, "")
210214
else
211215
None
@@ -234,25 +238,26 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
234238
* @return Some(msg) if unsuccessful where `msg` is a potentially empty error message
235239
* to be added to the "inconsistent phase" message.
236240
*/
237-
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(implicit ctx: Context): Option[Tree] = {
241+
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition, adaptOnly: Boolean)(implicit ctx: Context): Option[Tree] = {
238242
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)
239243
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
240244

241245
tag.tpe match
242246
case tp: TermRef =>
243247
checkStable(tp, pos)
244248
Some(ref(getQuoteTypeTags.getTagRef(tp)))
245-
case _: SearchFailureType =>
249+
case _: SearchFailureType if !adaptOnly =>
246250
levelError(sym, tp, pos,
247251
i"""
248252
|
249253
| The access would be accepted with the right type tag, but
250254
| ${ctx.typer.missingArgMsg(tag, reqType, "")}""")
251-
case _ =>
255+
case _ if !adaptOnly =>
252256
levelError(sym, tp, pos,
253257
i"""
254258
|
255259
| The access would be accepted with a given $reqType""")
260+
case _ => None
256261
}
257262

258263
private def levelError(sym: Symbol, tp: Type, pos: SourcePosition, errMsg: String)(using Context) = {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ class Staging extends MacroTransform {
4343
tree match {
4444
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
4545
val checker = new PCPCheckAndHeal(freshStagingContext) {
46-
override protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(implicit ctx: Context): Option[tpd.Tree] = {
46+
override protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition, adaptOnly: Boolean)(implicit ctx: Context): Option[tpd.Tree] = {
4747
def symStr =
4848
if (sym.is(ModuleClass)) sym.sourceModule.show
4949
else i"${sym.name}.this"
5050
val errMsg = s"\nin ${ctx.owner.fullName}"
5151
assert(
52+
adaptOnly ||
5253
ctx.owner.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot) ||
5354
(sym.isType && levelOf(sym).getOrElse(0) > 0),
5455
em"""access to $symStr from wrong staging level:

0 commit comments

Comments
 (0)