@@ -61,24 +61,26 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
6161 super .transform(tree)
6262 else tree match {
6363
64- case _ : TypeTree | _ : RefTree if tree.isType =>
64+ case _ : TypeTree | _ : RefTree if tree.isType =>
6565 val healedType = healType(tree.srcPos)(tree.tpe)
6666 if healedType == tree.tpe then tree
6767 else TypeTree (healedType).withSpan(tree.span)
68+ case tree : Ident if isWildcardArg(tree) =>
69+ tree.withType(healType(tree.srcPos)(tree.tpe))
70+ case tree : Ident => // this is a term Ident
71+ checkLevelConsistency(tree)
72+ tree
73+ case tree : This =>
74+ checkLevelConsistency(tree)
75+ tree
6876 case _ : AppliedTypeTree =>
6977 super .transform(tree) match
7078 case tree1 : AppliedTypeTree if tree1 ne tree =>
7179 // propagate healed types
7280 tree1.withType(tree1.tpt.tpe.appliedTo(tree1.args.map(_.tpe)))
7381 case tree1 => tree1
74-
75- case _ : Ident | _ : This =>
76- tree.withType(healTypeOfTerm(tree.srcPos)(tree.tpe))
77-
78- // Remove inline defs in quoted code. Already fully inlined.
7982 case tree : DefDef if tree.symbol.is(Inline ) && level > 0 =>
80- EmptyTree
81-
83+ EmptyTree // Remove inline defs in quoted code. Already fully inlined.
8284 case tree : ValOrDefDef =>
8385 checkAnnotations(tree)
8486 healInfo(tree, tree.tpt.srcPos)
@@ -88,7 +90,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
8890 healInfo(tree, tree.srcPos)
8991 super .transform(tree)
9092 case tree : UnApply =>
91- super .transform(tree).withType(healTypeOfTerm (tree.srcPos)(tree.tpe))
93+ super .transform(tree).withType(healType (tree.srcPos)(tree.tpe))
9294 case tree : TypeDef if tree.symbol.is(Case ) && level > 0 =>
9395 report.error(reporting.CaseClassInInlinedCode (tree), tree)
9496 super .transform(tree)
@@ -118,7 +120,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
118120 if body.isTerm then
119121 // `quoted.runtime.Expr.quote[T](<body>)` --> `quoted.runtime.Expr.quote[T2](<body2>)`
120122 val TypeApply (fun, targs) = quote.fun: @ unchecked
121- val targs2 = targs.map(targ => TypeTree (healTypeOfTerm (quote.fun.srcPos)(stripAnnotsDeep(targ.tpe))))
123+ val targs2 = targs.map(targ => TypeTree (healType (quote.fun.srcPos)(stripAnnotsDeep(targ.tpe))))
122124 cpy.Apply (quote)(cpy.TypeApply (quote.fun)(fun, targs2), body2 :: Nil )
123125 else
124126 val quotes = quote.args.mapConserve(transform)
@@ -193,61 +195,57 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
193195 def apply (tp : Type ): Type =
194196 tp match
195197 case tp : TypeRef =>
196- tp.prefix match
197- case NoPrefix if level > levelOf(tp.symbol) && ! tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) =>
198- tryHealTypeOfType(tp.symbol, tp, pos)
199- case prefix : ThisType if ! tp.symbol.isStatic && level > levelOf(prefix.cls) =>
200- tryHealTypeOfType(tp.symbol, tp, pos)
201- case prefix : TermRef if tp.symbol.isTypeSplice =>
202- prefix.symbol.info.argInfos match
203- case (tb : TypeBounds ) :: _ =>
204- report.error(em " Cannot splice $tp because it is a wildcard type " , pos)
205- case _ =>
206- // Heal explicit type splice in the code
207- if level > 0 then getQuoteTypeTags.getTagRef(prefix) else tp
208- case prefix : TermRef if ! prefix.symbol.isStatic && level > levelOf(prefix.symbol) =>
209- tryHealTypeOfType(prefix.symbol, tp, pos)
210- case _ =>
211- mapOver(tp)
198+ healTypeRef(tp)
212199 case tp @ TermRef (NoPrefix , _) if ! tp.symbol.isStatic && level > levelOf(tp.symbol) =>
213200 levelError(tp.symbol, tp, pos)
214- case tp : ThisType if level != - 1 && level != levelOf(tp.cls) =>
215- levelError(tp.cls, tp, pos)
216201 case tp : AnnotatedType =>
217202 val newAnnotTree = transform(tp.annot.tree)
218203 derivedAnnotatedType(tp, apply(tp.parent), tp.annot.derivedAnnotation(newAnnotTree))
219204 case _ =>
220205 mapOver(tp)
221206
222- /** Try to dealias or heal reference to type `T` used in a higher level than its definition.
223- * Returns a reference to a type tag generated by `QuoteTypeTags` that contains a
224- * reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`.
225- * Emits and error if `T` cannot be healed and returns `T`.
226- */
227- private def tryHealTypeOfType (sym : Symbol , tp : TypeRef , pos : SrcPos )(using Context ): Type = {
207+ private def healTypeRef (tp : TypeRef ): Type =
208+ tp.prefix match
209+ case prefix : TermRef if tp.symbol.isTypeSplice =>
210+ checkNotWildcardSplice(tp)
211+ if level == 0 then tp else getQuoteTypeTags.getTagRef(prefix)
212+ case prefix : TermRef if ! prefix.symbol.isStatic && level > levelOf(prefix.symbol) =>
213+ dealiasAndTryHeal(prefix.symbol, tp, pos)
214+ case NoPrefix if level > levelOf(tp.symbol) && ! tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) =>
215+ dealiasAndTryHeal(tp.symbol, tp, pos)
216+ case prefix : ThisType if level > levelOf(prefix.cls) && ! tp.symbol.isStatic =>
217+ dealiasAndTryHeal(tp.symbol, tp, pos)
218+ case _ =>
219+ mapOver(tp)
220+
221+ private def dealiasAndTryHeal (sym : Symbol , tp : TypeRef , pos : SrcPos )(using Context ): Type =
228222 val tp1 = tp.dealias
229223 if tp1 != tp then apply(tp1)
230224 else tryHeal(tp.symbol, tp, pos)
231- }
232- }
233225
234- /** Check phase consistency of terms and heal inconsistent type references. */
235- private def healTypeOfTerm (pos : SrcPos )(using Context ) = new TypeMap {
236- def apply (tp : Type ): Type =
237- tp match
238- case tp @ TypeRef (NoPrefix , _) if level > levelOf(tp.symbol) =>
239- tryHeal(tp.symbol, tp, pos)
240- case tp @ TermRef (NoPrefix , _) if ! tp.symbol.isStatic && level != levelOf(tp.symbol) =>
241- levelError(tp.symbol, tp, pos)
242- case tp : ThisType if level != - 1 && level != levelOf(tp.cls) =>
243- levelError(tp.cls, tp, pos)
244- case tp : AnnotatedType =>
245- derivedAnnotatedType(tp, apply(tp.parent), tp.annot)
226+ private def checkNotWildcardSplice (splice : TypeRef )(using Context ): Unit =
227+ splice.prefix.termSymbol.info.argInfos match
228+ case (tb : TypeBounds ) :: _ => report.error(em " Cannot splice $splice because it is a wildcard type " , pos)
246229 case _ =>
247- if tp.typeSymbol.is(Package ) then tp
248- else mapOver(tp)
249230 }
250231
232+ /** Check level consistency of terms references */
233+ private def checkLevelConsistency (tree : Ident | This )(using Context ): Unit =
234+ new TypeTraverser {
235+ def traverse (tp : Type ): Unit =
236+ tp match
237+ case tp @ TermRef (NoPrefix , _) if ! tp.symbol.isStatic && level != levelOf(tp.symbol) =>
238+ levelError(tp.symbol, tp, tree.srcPos)
239+ case tp : ThisType if level != - 1 && level != levelOf(tp.cls) =>
240+ levelError(tp.cls, tp, tree.srcPos)
241+ case tp : AnnotatedType =>
242+ traverse(tp.parent)
243+ case _ if tp.typeSymbol.is(Package ) =>
244+ // OK
245+ case _ =>
246+ traverseChildren(tp)
247+ }.traverse(tree.tpe)
248+
251249 /** Try to heal reference to type `T` used in a higher level than its definition.
252250 * Returns a reference to a type tag generated by `QuoteTypeTags` that contains a
253251 * reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`.
0 commit comments