Skip to content

Commit 965589b

Browse files
committed
Fixes #22437
The check crashes the compiler when mapping over a capture variable in a type bound bound of the form CapSet^{C^} as well as path captures in function signatures. See the test capture-vars-subtyping2.scala for examples.
1 parent f7e5df5 commit 965589b

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/cc/Setup.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
570570
// For example, `(x: T, y: x.f.type) => Unit`. In this case, when we
571571
// substitute `x.f.type`, `x` becomes a `TermParamRef`. But the new method
572572
// type is still under initialization and `paramInfos` is still `null`,
573-
// so the new `NamedType` will not have a denoation.
573+
// so the new `NamedType` will not have a denotation.
574574
def adaptedInfo(psym: Symbol, info: mt.PInfo): mt.PInfo = mt.companion match
575575
case mtc: MethodTypeCompanion => mtc.adaptParamInfo(psym, info).asInstanceOf[mt.PInfo]
576576
case _ => info

Diff for: compiler/src/dotty/tools/dotc/core/Types.scala

+6
Original file line numberDiff line numberDiff line change
@@ -6073,6 +6073,9 @@ object Types extends TypeUtils {
60736073
def forward(ref: CaptureRef): CaptureRef =
60746074
val result = this(ref)
60756075
def ensureTrackable(tp: Type): CaptureRef = tp match
6076+
/* Issue #22437: handle case when info is not yet available during postProcess in CC setup */
6077+
case tp: (TypeParamRef | TermRef) if tp.underlying == NoType =>
6078+
tp
60766079
case tp: CaptureRef =>
60776080
if tp.isTrackableRef then tp
60786081
else ensureTrackable(tp.underlying)
@@ -6084,6 +6087,9 @@ object Types extends TypeUtils {
60846087

60856088
/** A restriction of the inverse to a function on tracked CaptureRefs */
60866089
def backward(ref: CaptureRef): CaptureRef = inverse(ref) match
6090+
/* Ensure bijection for issue #22437 fix in method forward above: */
6091+
case result: (TypeParamRef | TermRef) if result.underlying == NoType =>
6092+
result
60876093
case result: CaptureRef if result.isTrackableRef => result
60886094
end BiTypeMap
60896095

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import language.experimental.captureChecking
2+
import caps.*
3+
4+
trait BoundsTest:
5+
6+
trait Bar { val f: () => Unit }
7+
def bar(x: Bar^, y: () ->{x.f} Unit): Unit = ???
8+
9+
val b: Bar^ = ???
10+
11+
def testTransMixed[A^,
12+
B >: CapSet <: A,
13+
C >: CapSet <: CapSet^{B^},
14+
D >: CapSet <: C,
15+
E >: CapSet <: CapSet^{D^},
16+
F >: CapSet <: CapSet^{A^,b},
17+
X >: CapSet <: CapSet^{F^,D^},
18+
Y >: CapSet^{F^} <: CapSet^{F^,A^,b},
19+
Z >: CapSet^{b} <: CapSet^{b,Y^}] =
20+
val e: E = ???
21+
val e2: CapSet^{E^} = e
22+
val ed: D = e
23+
val ed2: CapSet^{D^} = e
24+
val ec: C = e
25+
val ec2: CapSet^{C^} = e
26+
val eb: B = e
27+
val eb2: CapSet^{B^} = e
28+
val ea: A = e
29+
val ea2: CapSet^{A^} = e
30+
val ex: X = e // error
31+
val ex2: CapSet^{X^} = e // error
32+
val f: F = ???
33+
val f2: CapSet^{F^} = f
34+
val y: Y = f
35+
val y2: CapSet^{Y^} = f
36+
val cb: CapSet^{b} = ???
37+
val z: Z = cb
38+
val z2: CapSet^{Z^} = cb
39+
40+
def callTransMixed =
41+
val x, y, z: Bar^ = ???
42+
testTransMixed[CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{x,y,z}, CapSet^{b,x,y,z}]
43+
testTransMixed[CapSet^{x,y,z}, CapSet^{x,y}, CapSet^{x,y}, CapSet^{x}, CapSet^{}, CapSet^{b,x}, CapSet^{b}, CapSet^{b,x}, CapSet^{b}]
44+
testTransMixed[CapSet^{x,y,z}, CapSet^{x,y}, CapSet^{x,y}, CapSet^{x}, CapSet^{}, CapSet^{b,x}, CapSet^{b}, CapSet^{b,x}, CapSet^{b,x,y,z}] // error

0 commit comments

Comments
 (0)