summaryrefslogtreecommitdiff
path: root/test/pending/neg/t5008.scala
blob: 2b20bcfe12987b025197c6d926387d08a22cba99 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// These are members of class bar.C, completely unrelated to class foo.A.
// The types shown below include types defined within foo.A which are:
//
//   - qualified private
//   - qualified protected
//   - object protected
//
// val a : foo.A = { /* compiled code */ }
// val xprot1 : java.lang.Object with foo.A.FooProt1 = { /* compiled code */ }
// val xprot2 : java.lang.Object with foo.A.FooProt2 = { /* compiled code */ }
// val xprot3 : java.lang.Object with foo.A.FooProt3 = { /* compiled code */ }
// val xprot4 : java.lang.Object with foo.A.FooProt4 = { /* compiled code */ }
// val xpriv3 : java.lang.Object with foo.A.FooPriv3 = { /* compiled code */ }
// val xpriv4 : java.lang.Object with foo.A.FooPriv4 = { /* compiled code */ }
//
// Indeed it will tell me a type which I cannot access:
//
// scala> new bar.C
// res0: bar.C = bar.C@1339a0dc
//
// scala> res0.xpriv3
// res1: java.lang.Object with res0.a.FooPriv3 = bar.C$$anon$29@39556aec
//
// scala> new res0.a.FooPriv3
// <console>:9: error: trait FooPriv3 in class A cannot be accessed in foo.A
//               new res0.a.FooPriv3
//                          ^
// Looking at how the compiler prints the types of those vals, one
// develops a suspicion how some of it is being allowed:
//
// val xpriv4: C.this.a.FooPriv4
// val xpriv3: C.this.a.FooPriv3
// val xprot4: C.this.a.FooProt4
// val xprot3: C.this.a.FooProt3
// val xprot2: C.this.a.FooProt2
// val xprot1: C.this.a.FooProt1
//
// That is, "this" is in the prefix somewhere, it's just not a "this"
// which has any bearing.

package foo {
  class A {
    trait Foo

    protected trait FooProt1
    protected[this] trait FooProt2
    protected[foo] trait FooProt3
    protected[A] trait FooProt4

    private trait FooPriv1
    private[this] trait FooPriv2
    private[foo] trait FooPriv3
    private[A] trait FooPriv4

    type BarProt1 = FooProt1
    type BarProt2 = FooProt2
    type BarProt3 = FooProt3
    type BarProt4 = FooProt4

    // type BarPriv1 = FooPriv1
    // type BarPriv2 = FooPriv2
    type BarPriv3 = FooPriv3
    type BarPriv4 = FooPriv4

    def fprot1(x: FooProt1) = x
    def fprot2(x: FooProt2) = x
    def fprot3(x: FooProt3) = x
    def fprot4(x: FooProt4) = x

    // def fpriv1(x: FooPriv1) = x
    // def fpriv2(x: FooPriv2) = x
    def fpriv3(x: FooPriv3) = x
    def fpriv4(x: FooPriv4) = x

    val yprot1 = new FooProt1 { }
    val yprot2 = new FooProt2 { }
    val yprot3 = new FooProt3 { }
    val yprot4 = new FooProt4 { }

    // val ypriv1 = new FooPriv1 { }
    // val ypriv2 = new FooPriv2 { }
    val ypriv3 = new FooPriv3 { }
    val ypriv4 = new FooPriv4 { }

    def fpriv_alt1(x: FooPriv1) = 0 // !!! isn't the private type now in the signature of the (public) method?
    def fpriv_alt2(x: FooPriv2) = 0 // !!! isn't the private[this] type now in the signature of the (public) method?
  }
  // Same package, subclass
  class B extends A {
    val xprot1 = new BarProt1 { }
    val xprot2 = new BarProt2 { }
    val xprot3 = new BarProt3 { }
    val xprot4 = new BarProt4 { }

    // val xpriv1 = new BarPriv1 { }
    // val xpriv2 = new BarPriv2 { }
    val xpriv3 = new BarPriv3 { }
    val xpriv4 = new BarPriv4 { }

    override def fprot1(x: BarProt1) = x
    override def fprot2(x: BarProt2) = x
    override def fprot3(x: BarProt3) = x
    override def fprot4(x: BarProt4) = x

    // override def fpriv1(x: BarPriv1) = x
    // override def fpriv2(x: BarPriv2) = x
    override def fpriv3(x: BarPriv3) = x
    override def fpriv4(x: BarPriv4) = x
  }
  // Same package, unrelated class
  class C {
    val a = new A
    import a._

    val xprot1 = new BarProt1 { }
    val xprot2 = new BarProt2 { }
    val xprot3 = new BarProt3 { }
    val xprot4 = new BarProt4 { }

    // val xpriv1 = new BarPriv1 { }
    // val xpriv2 = new BarPriv2 { }
    val xpriv3 = new BarPriv3 { }
    val xpriv4 = new BarPriv4 { }
  }
}

package bar {
  // Different package, subclass
  class B extends foo.A {
    val xprot1 = new BarProt1 { }
    val xprot2 = new BarProt2 { }
    val xprot3 = new BarProt3 { }
    val xprot4 = new BarProt4 { }

    // val xpriv1 = new BarPriv1 { }
    // val xpriv2 = new BarPriv2 { }
    val xpriv3 = new BarPriv3 { }
    val xpriv4 = new BarPriv4 { }

    override def fprot1(x: BarProt1) = x
    override def fprot2(x: BarProt2) = x
    override def fprot3(x: BarProt3) = x
    override def fprot4(x: BarProt4) = x

    // override def fpriv1(x: BarPriv1) = x
    // override def fpriv2(x: BarPriv2) = x
    override def fpriv3(x: BarPriv3) = x
    override def fpriv4(x: BarPriv4) = x
  }
  // Different package, unrelated class
  class C {
    val a = new foo.A
    import a._

    val xprot1 = new BarProt1 { }
    val xprot2 = new BarProt2 { }
    val xprot3 = new BarProt3 { }
    val xprot4 = new BarProt4 { }

    // val xpriv1 = new BarPriv1 { }
    // val xpriv2 = new BarPriv2 { }
    val xpriv3 = new BarPriv3 { }
    val xpriv4 = new BarPriv4 { }
  }
}