Skip to content

Permit Capture Refs for Uninitialized Type and Term Params in BiTypeMap #22451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
// For example, `(x: T, y: x.f.type) => Unit`. In this case, when we
// substitute `x.f.type`, `x` becomes a `TermParamRef`. But the new method
// type is still under initialization and `paramInfos` is still `null`,
// so the new `NamedType` will not have a denoation.
// so the new `NamedType` will not have a denotation.
def adaptedInfo(psym: Symbol, info: mt.PInfo): mt.PInfo = mt.companion match
case mtc: MethodTypeCompanion => mtc.adaptParamInfo(psym, info).asInstanceOf[mt.PInfo]
case _ => info
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6073,6 +6073,9 @@ object Types extends TypeUtils {
def forward(ref: CaptureRef): CaptureRef =
val result = this(ref)
def ensureTrackable(tp: Type): CaptureRef = tp match
/* Issue #22437: handle case when info is not yet available during postProcess in CC setup */
case tp: (TypeParamRef | TermRef) if tp.underlying == NoType =>
tp
case tp: CaptureRef =>
if tp.isTrackableRef then tp
else ensureTrackable(tp.underlying)
Expand All @@ -6084,6 +6087,9 @@ object Types extends TypeUtils {

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

Expand Down
44 changes: 44 additions & 0 deletions tests/neg-custom-args/captures/capture-vars-subtyping2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import language.experimental.captureChecking
import caps.*

trait BoundsTest:

trait Bar { val f: () => Unit }
def bar(x: Bar^, y: () ->{x.f} Unit): Unit = ???

val b: Bar^ = ???

def testTransMixed[A^,
B >: CapSet <: A,
C >: CapSet <: CapSet^{B^},
D >: CapSet <: C,
E >: CapSet <: CapSet^{D^},
F >: CapSet <: CapSet^{A^,b},
X >: CapSet <: CapSet^{F^,D^},
Y >: CapSet^{F^} <: CapSet^{F^,A^,b},
Z >: CapSet^{b} <: CapSet^{b,Y^}] =
val e: E = ???
val e2: CapSet^{E^} = e
val ed: D = e
val ed2: CapSet^{D^} = e
val ec: C = e
val ec2: CapSet^{C^} = e
val eb: B = e
val eb2: CapSet^{B^} = e
val ea: A = e
val ea2: CapSet^{A^} = e
val ex: X = e // error
val ex2: CapSet^{X^} = e // error
val f: F = ???
val f2: CapSet^{F^} = f
val y: Y = f
val y2: CapSet^{Y^} = f
val cb: CapSet^{b} = ???
val z: Z = cb
val z2: CapSet^{Z^} = cb

def callTransMixed =
val x, y, z: Bar^ = ???
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}]
testTransMixed[CapSet^{x,y,z}, CapSet^{x,y}, CapSet^{x,y}, CapSet^{x}, CapSet^{}, CapSet^{b,x}, CapSet^{b}, CapSet^{b,x}, CapSet^{b}]
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
Loading