diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index f3f88a764ace..da87db97b0e3 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -779,8 +779,8 @@ object Semantic: if tryReporter.errors.nonEmpty && isSyntheticApply(meth) then tryReporter.abort() val klass = meth.owner.companionClass.asClass - val outerCls = klass.owner.lexicallyEnclosingClass.asClass - val outer = resolveOuterSelect(outerCls, ref, 1) + val targetCls = klass.owner.lexicallyEnclosingClass.asClass + val outer = resolveThis(targetCls, ref, meth.owner.asClass) outer.instantiate(klass, klass.primaryConstructor, args) else reporter.reportAll(tryReporter.errors) @@ -1322,9 +1322,12 @@ object Semantic: val qual = eval(qualifier, thisV, klass) name match - case OuterSelectName(_, hops) => - val SkolemType(tp) = expr.tpe: @unchecked - withTrace(trace2) { resolveOuterSelect(tp.classSymbol.asClass, qual, hops) } + case OuterSelectName(_, _) => + val current = qualifier.tpe.classSymbol + val target = expr.tpe.widenSingleton.classSymbol.asClass + withTrace(trace2) { + resolveThis(target, qual, current.asClass) + } case _ => withTrace(trace2) { qual.select(expr.symbol) } @@ -1493,42 +1496,6 @@ object Semantic: } - /** Resolve outer select introduced during inlining. - * - * See `tpd.outerSelect` and `ElimOuterSelect`. - */ - def resolveOuterSelect(target: ClassSymbol, thisV: Value, hops: Int): Contextual[Value] = log("resolving outer " + target.show + ", this = " + thisV.show + ", hops = " + hops, printer, (_: Value).show) { - // Is `target` reachable from `cls` with the given `hops`? - def reachable(cls: ClassSymbol, hops: Int): Boolean = log("reachable from " + cls + " -> " + target + " in " + hops, printer) { - if hops == 0 then cls == target - else reachable(cls.owner.lexicallyEnclosingClass.asClass, hops - 1) - } - - thisV match - case Hot => Hot - - case ref: Ref => - val obj = ref.objekt - val curOpt = obj.klass.baseClasses.find(cls => reachable(cls, hops)) - curOpt match - case Some(cur) => - resolveThis(target, thisV, cur) - - case None => - // TODO: use error once we fix https://github.com/lampepfl/dotty/issues/15465 - report.warning("[Internal error] unexpected outerSelect, thisV = " + thisV + ", target = " + target.show + ", hops = " + hops, trace.toVector.last.srcPos) - Cold - - case RefSet(refs) => - refs.map(ref => resolveOuterSelect(target, ref, hops)).join - - case fun: Fun => - report.error("[Internal error] unexpected thisV = " + thisV + ", target = " + target.show + ", hops = " + hops, trace.toVector.last.srcPos) - Cold - - case Cold => Cold - } - /** Compute the outer value that correspond to `tref.prefix` */ def outerValue(tref: TypeRef, thisV: Ref, klass: ClassSymbol): Contextual[Value] = val cls = tref.classSymbol.asClass diff --git a/tests/init/pos/i15465.scala b/tests/init/pos/i15465.scala new file mode 100644 index 000000000000..5b99670e9027 --- /dev/null +++ b/tests/init/pos/i15465.scala @@ -0,0 +1,17 @@ +class TestSuite: + protected val it = new ItWord + + protected final class ItWord: + def should(string: String) = new ItVerbString("should", string) + + private def registerTestToRun(fun: => Any): Unit = () + + protected final class ItVerbString(verb: String, name: String): + inline def in(testFun: => Any): Unit = registerTestToRun(testFun) + +class MyTest extends TestSuite: + it should "not cause outer select errors" in { + assert(1 + 1 == 2) + } + + val n = 10