@@ -31,39 +31,52 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap {
31
31
*/
32
32
def apply (tp : Type ): Type =
33
33
tp match
34
- case tp : TypeRef =>
35
- tp.underlying match
36
- case TypeAlias (alias)
37
- if ! tp.symbol.isTypeSplice && ! tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) =>
38
- this .apply(alias)
39
- case _ =>
40
- healTypeRef(tp)
41
- case tp @ TermRef (NoPrefix , _) if ! tp.symbol.isStatic && level > levelOf(tp.symbol) =>
42
- levelError(tp.symbol, tp, pos)
34
+ case NonSpliceAlias (aliased) => this .apply(aliased)
35
+ case tp : TypeRef => healTypeRef(tp)
36
+ case tp : TermRef =>
37
+ val inconsistentRoot = levelInconsistentRootOfPath(tp)
38
+ if inconsistentRoot.exists then levelError(inconsistentRoot, tp, pos)
39
+ else tp
43
40
case tp : AnnotatedType =>
44
41
derivedAnnotatedType(tp, apply(tp.parent), tp.annot)
45
42
case _ =>
46
43
mapOver(tp)
47
44
48
45
private def healTypeRef (tp : TypeRef ): Type =
49
46
tp.prefix match
47
+ case NoPrefix if tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) =>
48
+ tp
50
49
case prefix : TermRef if tp.symbol.isTypeSplice =>
51
50
checkNotWildcardSplice(tp)
52
51
if level == 0 then tp else getQuoteTypeTags.getTagRef(prefix)
53
- case prefix : TermRef if ! prefix.symbol.isStatic && level > levelOf(prefix.symbol) =>
54
- tryHeal(prefix.symbol, tp, pos)
55
- case NoPrefix if level > levelOf(tp.symbol) && ! tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) =>
56
- tryHeal(tp.symbol, tp, pos)
57
- case prefix : ThisType if level > levelOf(prefix.cls) && ! tp.symbol.isStatic =>
58
- tryHeal(tp.symbol, tp, pos)
52
+ case _ : NamedType | _ : ThisType | NoPrefix =>
53
+ if levelInconsistentRootOfPath(tp).exists then
54
+ tryHeal(tp.symbol, tp, pos)
55
+ else
56
+ tp
59
57
case _ =>
60
58
mapOver(tp)
61
59
60
+ private object NonSpliceAlias :
61
+ def unapply (tp : TypeRef )(using Context ): Option [Type ] = tp.underlying match
62
+ case TypeAlias (alias) if ! tp.symbol.isTypeSplice && ! tp.typeSymbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot ) => Some (alias)
63
+ case _ => None
64
+
62
65
private def checkNotWildcardSplice (splice : TypeRef ): Unit =
63
66
splice.prefix.termSymbol.info.argInfos match
64
67
case (tb : TypeBounds ) :: _ => report.error(em " Cannot splice $splice because it is a wildcard type " , pos)
65
68
case _ =>
66
69
70
+ /** Return the root of this path if it is a variable defined in a previous level.
71
+ * If the path is consistent, return NoSymbol.
72
+ */
73
+ private def levelInconsistentRootOfPath (tp : Type )(using Context ): Symbol =
74
+ tp match
75
+ case tp @ NamedType (NoPrefix , _) if level > levelOf(tp.symbol) => tp.symbol
76
+ case tp : NamedType if ! tp.symbol.isStatic => levelInconsistentRootOfPath(tp.prefix)
77
+ case tp : ThisType if level > levelOf(tp.cls) => tp.cls
78
+ case _ => NoSymbol
79
+
67
80
/** Try to heal reference to type `T` used in a higher level than its definition.
68
81
* Returns a reference to a type tag generated by `QuoteTypeTags` that contains a
69
82
* reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`.
0 commit comments