File tree 4 files changed +55
-20
lines changed
compiler/src/dotty/tools/dotc/cc
tests/neg-custom-args/captures
4 files changed +55
-20
lines changed Original file line number Diff line number Diff line change @@ -142,32 +142,19 @@ object CheckCaptures:
142
142
143
143
private val seen = new EqHashSet [TypeRef ]
144
144
145
- /** Check that there is at least one method containing carrier and defined
146
- * in the scope of tparam. E.g. this is OK:
147
- * def f[T] = { ... var x: T ... }
148
- * So is this:
149
- * class C[T] { def f() = { class D { var x: T }}}
150
- * But this is not OK:
151
- * class C[T] { object o { var x: T }}
152
- */
153
- extension (tparam : Symbol ) def isParametricIn (carrier : Symbol ): Boolean =
154
- carrier.exists && {
155
- val encl = carrier.owner.enclosingMethodOrClass
156
- if encl.isClass then tparam.isParametricIn(encl)
157
- else
158
- def recur (encl : Symbol ): Boolean =
159
- if tparam.owner == encl then true
160
- else if encl.isStatic || ! encl.exists then false
161
- else recur(encl.owner.enclosingMethodOrClass)
162
- recur(encl)
163
- }
164
-
165
145
def traverse (t : Type ) =
166
146
t.dealiasKeepAnnots match
167
147
case t : TypeRef =>
168
148
if ! seen.contains(t) then
169
149
seen += t
170
150
traverseChildren(t)
151
+
152
+ // Check the lower bound of path dependent types.
153
+ // See issue #19330.
154
+ val isMember = t.prefix ne NoPrefix
155
+ t.info match
156
+ case TypeBounds (lo, _) if isMember => traverse(lo)
157
+ case _ =>
171
158
case AnnotatedType (_, ann) if ann.symbol == defn.UncheckedCapturesAnnot =>
172
159
()
173
160
case t =>
Original file line number Diff line number Diff line change
1
+ import language .experimental .captureChecking
2
+
3
+ trait Logger
4
+ def usingLogger [T ](op : Logger ^ => T ): T = ???
5
+
6
+ def foo [T >: () => Logger ^ ](): T =
7
+ val leaked = usingLogger[T ]: l => // ok
8
+ val t : () => Logger ^ = () => l
9
+ t : T
10
+ leaked
11
+
12
+ def test (): Unit =
13
+ val bad : () => Logger ^ = foo[() => Logger ^ ] // error
14
+ val leaked : Logger ^ = bad() // leaked scoped capability!
Original file line number Diff line number Diff line change
1
+ import language .experimental .captureChecking
2
+
3
+ trait Logger
4
+ def usingLogger [T ](op : Logger ^ => T ): T = ???
5
+
6
+ trait Foo :
7
+ type T >: () => Logger ^
8
+
9
+ def foo : this .T =
10
+ val leaked = usingLogger[T ]: l => // error
11
+ val t : () => Logger ^ = () => l
12
+ t : T
13
+ leaked
Original file line number Diff line number Diff line change
1
+ import language .experimental .captureChecking
2
+
3
+ trait Logger
4
+ def usingLogger [T ](op : Logger ^ => T ): T = ???
5
+
6
+ trait Foo :
7
+ type T >: () => Logger ^
8
+
9
+ class Bar extends Foo :
10
+ type T = () => Logger ^
11
+
12
+ def foo (x : Foo ): x.T =
13
+ val leaked = usingLogger[x.T ]: l => // error
14
+ val t : () => Logger ^ = () => l
15
+ t : x.T
16
+ leaked
17
+
18
+ def test (): Unit =
19
+ val bar = new Bar
20
+ val bad : bar.T = foo(bar)
21
+ val leaked : Logger ^ = bad() // leaked scoped capability!
You can’t perform that action at this time.
0 commit comments