Closed
Description
From discussions in PR #21875
Compiler version
Latest NIGHTLY
Minimized code
import language.experimental.captureChecking
import caps.*
trait Abstract[X >: Nothing]: // Concrete2 and 3 fail with this lower bound, but work with X >: CapSet^{}
type C >: X <: CapSet^
def boom(): Unit^{C^}
class Concrete extends Abstract[CapSet^{}]:
type C = CapSet^{}
def boom() = () // ok
class Concrete2 extends Abstract[CapSet^{}]:
type C = CapSet^{} & CapSet^{}
def boom() = () // error
class Concrete3 extends Abstract[CapSet^{}]:
type C = CapSet^{} | CapSet^{}
def boom() = () // error
Output
-- Error: local/i21868.scala:14:14 ---------------------------------------------
14 | def boom() = () // error
| ^
| Illegal capture reference: (caps.CapSet^{}) & (caps.CapSet^{})
-- Error: local/i21868.scala:18:14 ---------------------------------------------
18 | def boom() = () // error
| ^
| Illegal capture reference: (caps.CapSet^{}) | (caps.CapSet^{})
Expectation
- I would expect those to work even if the lower bound of
X
intrait Abstract[X]
is set toNothing
. - Can we make union and intersection on
CapSet
commute with capture set union and intersection, i.e.,CapSet^c1 | CapSet^c2 <:> CapSet^(c1 | c2)
andCapSet^c1 & CapSet^c2 <:> CapSet^(c1 & c2)
? Probably, that involves improvingnormalizeCaptures
inSetup
. - Can we let the syntax
C^
for declaring a type variable automatically desugar to the intervalCapSet^{} <: C <: CapSet^
?- Is this always airtight, or will it cause trouble?