Skip to content

Commit ae83f76

Browse files
authored
Merge pull request #15606 from dotty-staging/fix-15465
Fix #15465: Use resolveThis for outerSelect resolution
2 parents 22080c5 + b274576 commit ae83f76

File tree

2 files changed

+25
-41
lines changed

2 files changed

+25
-41
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

+8-41
Original file line numberDiff line numberDiff line change
@@ -779,8 +779,8 @@ object Semantic:
779779
if tryReporter.errors.nonEmpty && isSyntheticApply(meth) then
780780
tryReporter.abort()
781781
val klass = meth.owner.companionClass.asClass
782-
val outerCls = klass.owner.lexicallyEnclosingClass.asClass
783-
val outer = resolveOuterSelect(outerCls, ref, 1)
782+
val targetCls = klass.owner.lexicallyEnclosingClass.asClass
783+
val outer = resolveThis(targetCls, ref, meth.owner.asClass)
784784
outer.instantiate(klass, klass.primaryConstructor, args)
785785
else
786786
reporter.reportAll(tryReporter.errors)
@@ -1322,9 +1322,12 @@ object Semantic:
13221322
val qual = eval(qualifier, thisV, klass)
13231323

13241324
name match
1325-
case OuterSelectName(_, hops) =>
1326-
val SkolemType(tp) = expr.tpe: @unchecked
1327-
withTrace(trace2) { resolveOuterSelect(tp.classSymbol.asClass, qual, hops) }
1325+
case OuterSelectName(_, _) =>
1326+
val current = qualifier.tpe.classSymbol
1327+
val target = expr.tpe.widenSingleton.classSymbol.asClass
1328+
withTrace(trace2) {
1329+
resolveThis(target, qual, current.asClass)
1330+
}
13281331
case _ =>
13291332
withTrace(trace2) { qual.select(expr.symbol) }
13301333

@@ -1493,42 +1496,6 @@ object Semantic:
14931496

14941497
}
14951498

1496-
/** Resolve outer select introduced during inlining.
1497-
*
1498-
* See `tpd.outerSelect` and `ElimOuterSelect`.
1499-
*/
1500-
def resolveOuterSelect(target: ClassSymbol, thisV: Value, hops: Int): Contextual[Value] = log("resolving outer " + target.show + ", this = " + thisV.show + ", hops = " + hops, printer, (_: Value).show) {
1501-
// Is `target` reachable from `cls` with the given `hops`?
1502-
def reachable(cls: ClassSymbol, hops: Int): Boolean = log("reachable from " + cls + " -> " + target + " in " + hops, printer) {
1503-
if hops == 0 then cls == target
1504-
else reachable(cls.owner.lexicallyEnclosingClass.asClass, hops - 1)
1505-
}
1506-
1507-
thisV match
1508-
case Hot => Hot
1509-
1510-
case ref: Ref =>
1511-
val obj = ref.objekt
1512-
val curOpt = obj.klass.baseClasses.find(cls => reachable(cls, hops))
1513-
curOpt match
1514-
case Some(cur) =>
1515-
resolveThis(target, thisV, cur)
1516-
1517-
case None =>
1518-
// TODO: use error once we fix https://github.com/lampepfl/dotty/issues/15465
1519-
report.warning("[Internal error] unexpected outerSelect, thisV = " + thisV + ", target = " + target.show + ", hops = " + hops, trace.toVector.last.srcPos)
1520-
Cold
1521-
1522-
case RefSet(refs) =>
1523-
refs.map(ref => resolveOuterSelect(target, ref, hops)).join
1524-
1525-
case fun: Fun =>
1526-
report.error("[Internal error] unexpected thisV = " + thisV + ", target = " + target.show + ", hops = " + hops, trace.toVector.last.srcPos)
1527-
Cold
1528-
1529-
case Cold => Cold
1530-
}
1531-
15321499
/** Compute the outer value that correspond to `tref.prefix` */
15331500
def outerValue(tref: TypeRef, thisV: Ref, klass: ClassSymbol): Contextual[Value] =
15341501
val cls = tref.classSymbol.asClass

tests/init/pos/i15465.scala

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class TestSuite:
2+
protected val it = new ItWord
3+
4+
protected final class ItWord:
5+
def should(string: String) = new ItVerbString("should", string)
6+
7+
private def registerTestToRun(fun: => Any): Unit = ()
8+
9+
protected final class ItVerbString(verb: String, name: String):
10+
inline def in(testFun: => Any): Unit = registerTestToRun(testFun)
11+
12+
class MyTest extends TestSuite:
13+
it should "not cause outer select errors" in {
14+
assert(1 + 1 == 2)
15+
}
16+
17+
val n = 10

0 commit comments

Comments
 (0)