diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8c3883cfd2f6..ddd8278e160a 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -702,9 +702,22 @@ object Types { go(tycon.resType).mapInfo(info => tycon.derivedLambdaAbstraction(tycon.paramNames, tycon.paramInfos, info).appliedTo(tp.args)) - def goThis(tp: ThisType) = { - val d = go(tp.underlying) - if (d.exists) d + def goThis(tp: ThisType) = + val underlying = tp.underlying + val d = go(underlying) + if d.exists then + if underlying.isInstanceOf[AndType] then + // The underlying type of `this` is specified in a self type clause. + // In this case we need to exclude all private members from `d` which are + // not defined in the class of the `this` type. We could do this test + // always, but the restriction to test only if `underlying` is an AndType + // is made to save execution time in the common case. See i9844.scala for test cases. + def qualifies(sd: SingleDenotation) = + !sd.symbol.is(Private) || sd.symbol.owner == tp.cls + d match + case d: SingleDenotation => if qualifies(d) then d else NoDenotation + case d => d.filterWithPredicate(qualifies) + else d else // There is a special case to handle: // trait Super { this: Sub => private class Inner {} println(this.Inner) } @@ -716,7 +729,6 @@ object Types { // As an example of this in the wild, see // loadClassWithPrivateInnerAndSubSelf in ShowClassTests go(tp.cls.typeRef) orElse d - } def goParam(tp: TypeParamRef) = { val next = tp.underlying diff --git a/tests/pos/i9844.scala b/tests/pos/i9844.scala new file mode 100644 index 000000000000..a660c5046c5b --- /dev/null +++ b/tests/pos/i9844.scala @@ -0,0 +1,41 @@ +object test1: + trait Foo[A] + + trait Baz[A] { + trait Bar { + this: Foo[A] => + def bar(a: A): Unit + } + } + +object test2: + + trait Foo: + private var f = "abc" + + trait Baz { + trait Bam: + val f = 0 + trait Bar extends Bam { + this: Foo => + val g = f + val g1: Int = g + } + } + +object test3: + object DetSkipOctree { + sealed trait Leaf [PL] + sealed trait Branch[PL] + } + trait DetSkipOctree[PL] + + class Impl[PL] extends DetSkipOctree[PL] { + final type Leaf = DetSkipOctree.Leaf[PL] + + protected trait LeftBranchImpl { + this: DetSkipOctree.Branch[PL] => + + def demoteLeaf(point: PL, leaf: Leaf): Unit = ??? + } + } \ No newline at end of file