Skip to content

Commit 27a59ec

Browse files
authored
Merge pull request #9847 from dotty-staging/fix-#9844
Fix #9844: Exclude private members of wrong classes from findMember
2 parents f9e2428 + e3b3789 commit 27a59ec

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,9 +702,22 @@ object Types {
702702
go(tycon.resType).mapInfo(info =>
703703
tycon.derivedLambdaAbstraction(tycon.paramNames, tycon.paramInfos, info).appliedTo(tp.args))
704704

705-
def goThis(tp: ThisType) = {
706-
val d = go(tp.underlying)
707-
if (d.exists) d
705+
def goThis(tp: ThisType) =
706+
val underlying = tp.underlying
707+
val d = go(underlying)
708+
if d.exists then
709+
if underlying.isInstanceOf[AndType] then
710+
// The underlying type of `this` is specified in a self type clause.
711+
// In this case we need to exclude all private members from `d` which are
712+
// not defined in the class of the `this` type. We could do this test
713+
// always, but the restriction to test only if `underlying` is an AndType
714+
// is made to save execution time in the common case. See i9844.scala for test cases.
715+
def qualifies(sd: SingleDenotation) =
716+
!sd.symbol.is(Private) || sd.symbol.owner == tp.cls
717+
d match
718+
case d: SingleDenotation => if qualifies(d) then d else NoDenotation
719+
case d => d.filterWithPredicate(qualifies)
720+
else d
708721
else
709722
// There is a special case to handle:
710723
// trait Super { this: Sub => private class Inner {} println(this.Inner) }
@@ -716,7 +729,6 @@ object Types {
716729
// As an example of this in the wild, see
717730
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
718731
go(tp.cls.typeRef) orElse d
719-
}
720732

721733
def goParam(tp: TypeParamRef) = {
722734
val next = tp.underlying

tests/pos/i9844.scala

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
object test1:
2+
trait Foo[A]
3+
4+
trait Baz[A] {
5+
trait Bar {
6+
this: Foo[A] =>
7+
def bar(a: A): Unit
8+
}
9+
}
10+
11+
object test2:
12+
13+
trait Foo:
14+
private var f = "abc"
15+
16+
trait Baz {
17+
trait Bam:
18+
val f = 0
19+
trait Bar extends Bam {
20+
this: Foo =>
21+
val g = f
22+
val g1: Int = g
23+
}
24+
}
25+
26+
object test3:
27+
object DetSkipOctree {
28+
sealed trait Leaf [PL]
29+
sealed trait Branch[PL]
30+
}
31+
trait DetSkipOctree[PL]
32+
33+
class Impl[PL] extends DetSkipOctree[PL] {
34+
final type Leaf = DetSkipOctree.Leaf[PL]
35+
36+
protected trait LeftBranchImpl {
37+
this: DetSkipOctree.Branch[PL] =>
38+
39+
def demoteLeaf(point: PL, leaf: Leaf): Unit = ???
40+
}
41+
}

0 commit comments

Comments
 (0)