Skip to content

Commit 43d0ec4

Browse files
authored
Don't generate a Select for a TermRef with NoPrefix (#16754)
In TreeTypeMap, don't generate a Select node if the new type of the tree is a TermRef with NoPrefix. Generate an Ident node instead. Fixes #16740
2 parents 8d0c307 + d91f66f commit 43d0ec4

File tree

4 files changed

+38
-16
lines changed

4 files changed

+38
-16
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class TreeTypeMap(
4343

4444
def copy(
4545
typeMap: Type => Type,
46-
treeMap: tpd.Tree => tpd.Tree,
46+
treeMap: Tree => Tree,
4747
oldOwners: List[Symbol],
4848
newOwners: List[Symbol],
4949
substFrom: List[Symbol],
@@ -85,13 +85,13 @@ class TreeTypeMap(
8585
updateDecls(prevStats.tail, newStats.tail)
8686
}
8787

88-
def transformInlined(tree: tpd.Inlined)(using Context): tpd.Tree =
88+
def transformInlined(tree: Inlined)(using Context): Tree =
8989
val Inlined(call, bindings, expanded) = tree
9090
val (tmap1, bindings1) = transformDefs(bindings)
9191
val expanded1 = tmap1.transform(expanded)
9292
cpy.Inlined(tree)(call, bindings1, expanded1)
9393

94-
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = treeMap(tree) match {
94+
override def transform(tree: Tree)(using Context): Tree = treeMap(tree) match {
9595
case impl @ Template(constr, _, self, _) =>
9696
val tmap = withMappedSyms(localSyms(impl :: self :: Nil))
9797
cpy.Template(impl)(
@@ -103,8 +103,24 @@ class TreeTypeMap(
103103
).withType(tmap.mapType(impl.tpe))
104104
case tree1 =>
105105
tree1.withType(mapType(tree1.tpe)) match {
106-
case id: Ident if tpd.needsSelect(id.tpe) =>
107-
ref(id.tpe.asInstanceOf[TermRef]).withSpan(id.span)
106+
case id: Ident =>
107+
if needsSelect(id.tpe) then
108+
ref(id.tpe.asInstanceOf[TermRef]).withSpan(id.span)
109+
else
110+
super.transform(id)
111+
case sel: Select =>
112+
if needsIdent(sel.tpe) then
113+
ref(sel.tpe.asInstanceOf[TermRef]).withSpan(sel.span)
114+
else
115+
super.transform(sel)
116+
case app: Apply =>
117+
super.transform(app)
118+
case blk @ Block(stats, expr) =>
119+
val (tmap1, stats1) = transformDefs(stats)
120+
val expr1 = tmap1.transform(expr)
121+
cpy.Block(blk)(stats1, expr1)
122+
case lit @ Literal(Constant(tpe: Type)) =>
123+
cpy.Literal(lit)(Constant(mapType(tpe)))
108124
case ddef @ DefDef(name, paramss, tpt, _) =>
109125
val (tmap1, paramss1) = transformAllParamss(paramss)
110126
val res = cpy.DefDef(ddef)(name, paramss1, tmap1.transform(tpt), tmap1.transform(ddef.rhs))
@@ -117,10 +133,6 @@ class TreeTypeMap(
117133
case tdef @ LambdaTypeTree(tparams, body) =>
118134
val (tmap1, tparams1) = transformDefs(tparams)
119135
cpy.LambdaTypeTree(tdef)(tparams1, tmap1.transform(body))
120-
case blk @ Block(stats, expr) =>
121-
val (tmap1, stats1) = transformDefs(stats)
122-
val expr1 = tmap1.transform(expr)
123-
cpy.Block(blk)(stats1, expr1)
124136
case inlined: Inlined =>
125137
transformInlined(inlined)
126138
case cdef @ CaseDef(pat, guard, rhs) =>
@@ -139,18 +151,16 @@ class TreeTypeMap(
139151
val content1 = transform(content)
140152
val tpt1 = transform(tpt)
141153
cpy.Hole(tree)(args = args1, content = content1, tpt = tpt1)
142-
case lit @ Literal(Constant(tpe: Type)) =>
143-
cpy.Literal(lit)(Constant(mapType(tpe)))
144154
case tree1 =>
145155
super.transform(tree1)
146156
}
147157
}
148158

149-
override def transformStats(trees: List[tpd.Tree], exprOwner: Symbol)(using Context): List[Tree] =
159+
override def transformStats(trees: List[Tree], exprOwner: Symbol)(using Context): List[Tree] =
150160
transformDefs(trees)._2
151161

152-
def transformDefs[TT <: tpd.Tree](trees: List[TT])(using Context): (TreeTypeMap, List[TT]) = {
153-
val tmap = withMappedSyms(tpd.localSyms(trees))
162+
def transformDefs[TT <: Tree](trees: List[TT])(using Context): (TreeTypeMap, List[TT]) = {
163+
val tmap = withMappedSyms(localSyms(trees))
154164
(tmap, tmap.transformSub(trees))
155165
}
156166

@@ -165,7 +175,7 @@ class TreeTypeMap(
165175
case nil =>
166176
(this, paramss)
167177

168-
def apply[ThisTree <: tpd.Tree](tree: ThisTree): ThisTree = transform(tree).asInstanceOf[ThisTree]
178+
def apply[ThisTree <: Tree](tree: ThisTree): ThisTree = transform(tree).asInstanceOf[ThisTree]
169179

170180
def apply(annot: Annotation): Annotation = annot.derivedAnnotation(apply(annot.tree))
171181

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
414414
case _ => false
415415
}
416416

417+
def needsIdent(tp: Type)(using Context): Boolean = tp match
418+
case tp: TermRef => tp.prefix eq NoPrefix
419+
case _ => false
420+
417421
/** A tree representing the same reference as the given type */
418422
def ref(tp: NamedType, needLoad: Boolean = true)(using Context): Tree =
419423
if (tp.isType) TypeTree(tp)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ object Erasure {
774774
select(qual1, sym)
775775
else
776776
val castTarget = // Avoid inaccessible cast targets, see i8661
777-
if isJvmAccessible(sym.owner)
777+
if isJvmAccessible(sym.owner) && sym.owner.isType
778778
then
779779
sym.owner.typeRef
780780
else

tests/pos/i16740.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Enclosing:
2+
object Tags:
3+
opaque type Ref[T, S <: String & Singleton] = S
4+
inline def require[T, S <: String & Singleton]: Ref[T, S] = ???
5+
import Tags.*
6+
7+
val t1 = require[Int, "t1"]
8+
val t2 = require[Double, "t2"]

0 commit comments

Comments
 (0)