-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refine rules for capture parameters and members (#22000)
This PR refines rules for capture set variables (parameters and members). Fix #21999, #22005, #22030 ## Add requirements for capture set variables When a capture set is encoded as a type, the type must refer to `CapSet` and bounded by `>: CapSet <: CapSet^`. An unbounded capture parameter would be `C >: CapSet <: CapSet^`, which can be desugared from `C^`. ```scala def f[C^](io: IO^{C^}) = ??? // becomes def f[C >: CapSet <: CapSet^](io: IO^{C^}) = ??? ``` We may consider the similar desugaring for type member in the future: ```scala class A: type C^ // becomes class A: type C >: CapSet <: CapSet^ ``` Then, constaints between capture variables become possible: ```scala def test[X^, Y^, Z >: X <: Y](x: C^{X^}, y: C^{Y^}, z: C^{Z^}) = ??? // Z is still bounded by >: CapSet <: CapSet^ ``` Update definitions in the library `caps.scala`, such that a type following the rule can be used inside a capture set. ```scala // Rule out C^{(Nothing)^} during typer def capsOf[CS >: CapSet <: CapSet @retainsCap]: Any = ??? sealed trait Contains[+C >: CapSet <: CapSet @retainsCap, R <: Singleton] ``` ## Add cases to handle `CapSet` in `subsumes` ``` * X = CapSet^cx, exists rx in cx, rx subsumes y ==> X subsumes y * Y = CapSet^cy, forall ry in cy, x subsumes ry ==> x subsumes Y * X: CapSet^c1...CapSet^c2, (CapSet^c1) subsumes y ==> X subsumes y * Y: CapSet^c1...CapSet^c2, x subsumes (CapSet^c2) ==> x subsumes Y * Contains[X, y] ==> X subsumes y ``` ## Fix some issues related to overriding When deciding whether a class has a non-trivial self type, we look at the underlying type without capture set. [test_scala2_library_tasty]
- Loading branch information
Showing
22 changed files
with
193 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import caps.* | ||
|
||
class IO | ||
|
||
def f[C^](io: IO^{C^}) = ??? | ||
|
||
def test = | ||
f[CapSet](???) | ||
f[CapSet^{}](???) | ||
f[CapSet^](???) | ||
f[Nothing](???) // error | ||
f[String](???) // error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import caps.* | ||
|
||
trait Abstract[X^]: | ||
type C >: X <: CapSet^ | ||
// Don't test the return type using Unit, because it is a pure type. | ||
def boom(): AnyRef^{C^} | ||
|
||
class Concrete extends Abstract[CapSet^{}]: | ||
type C = CapSet^{} | ||
// TODO: Why do we get error without the return type here? | ||
def boom(): AnyRef = new Object | ||
|
||
class Concrete2 extends Abstract[CapSet^{}]: | ||
type C = CapSet^{} | ||
def boom(): AnyRef^ = new Object // error | ||
|
||
class Concrete3 extends Abstract[CapSet^{}]: | ||
def boom(): AnyRef = new Object | ||
|
||
class Concrete4(a: AnyRef^) extends Abstract[CapSet^{a}]: | ||
type C = CapSet // error | ||
def boom(): AnyRef^{a} = a // error | ||
|
||
class Concrete5(a: AnyRef^, b: AnyRef^) extends Abstract[CapSet^{a}]: | ||
type C = CapSet^{a} | ||
def boom(): AnyRef^{b} = b // error | ||
|
||
class Concrete6(a: AnyRef^, b: AnyRef^) extends Abstract[CapSet^{a}]: | ||
def boom(): AnyRef^{b} = b // error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import caps.* | ||
|
||
class C | ||
|
||
def test[X^, Y^, Z >: X <: Y](x: C^{X^}, y: C^{Y^}, z: C^{Z^}) = | ||
val x2z: C^{Z^} = x | ||
val z2y: C^{Y^} = z | ||
val x2y: C^{Y^} = x // error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
import caps.* | ||
|
||
trait AbstractWrong: | ||
type C <: CapSet | ||
def boom(): Unit^{C^} // error | ||
type C <: CapSet | ||
def f(): Unit^{C^} // error | ||
|
||
trait Abstract: | ||
type C <: CapSet^ | ||
def boom(): Unit^{C^} | ||
|
||
class Concrete extends Abstract: | ||
type C = Nothing | ||
def boom() = () // error | ||
trait Abstract1: | ||
type C >: CapSet <: CapSet^ | ||
def f(): Unit^{C^} | ||
|
||
// class Abstract2: | ||
// type C^ | ||
// def f(): Unit^{C^} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import language.experimental.modularity | ||
import caps.* | ||
|
||
class IO | ||
|
||
class File | ||
|
||
trait Abstract: | ||
type C >: CapSet <: CapSet^ | ||
def f(file: File^{C^}): Unit | ||
|
||
class Concrete1 extends Abstract: | ||
type C = CapSet | ||
def f(file: File) = () | ||
|
||
class Concrete2(io: IO^) extends Abstract: | ||
type C = CapSet^{io} | ||
def f(file: File^{io}) = () | ||
|
||
class Concrete3(io: IO^) extends Abstract: | ||
type C = CapSet^{io} | ||
def f(file: File) = () // error | ||
|
||
trait Abstract2(tracked val io: IO^): | ||
type C >: CapSet <: CapSet^{io} | ||
def f(file: File^{C^}): Unit | ||
|
||
class Concrete4(io: IO^) extends Abstract2(io): | ||
type C = CapSet | ||
def f(file: File) = () | ||
|
||
class Concrete5(io1: IO^, io2: IO^) extends Abstract2(io1): | ||
type C = CapSet^{io2} // error | ||
def f(file: File^{io2}) = () | ||
|
||
trait Abstract3[X^]: | ||
type C >: CapSet <: X | ||
def f(file: File^{C^}): Unit | ||
|
||
class Concrete6(io: IO^) extends Abstract3[CapSet^{io}]: | ||
type C = CapSet | ||
def f(file: File) = () | ||
|
||
class Concrete7(io1: IO^, io2: IO^) extends Abstract3[CapSet^{io1}]: | ||
type C = CapSet^{io2} // error | ||
def f(file: File^{io2}) = () | ||
|
||
class Concrete8(io1: IO^, io2: IO^) extends Abstract3[CapSet^{io1}]: | ||
def f(file: File^{io2}) = () // error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import caps.* | ||
|
||
class IO | ||
class File(io: IO^) | ||
|
||
class Handler[C^]: | ||
def f(file: File^): File^{C^} = file // error | ||
def g(file: File^{C^}): File^ = file // ok |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,19 @@ | ||
-- Error: tests/neg-custom-args/captures/use-capset.scala:7:50 --------------------------------------------------------- | ||
7 |private def g[C^] = (xs: List[Object^{C^}]) => xs.head // error | ||
-- Error: tests/neg-custom-args/captures/use-capset.scala:5:50 --------------------------------------------------------- | ||
5 |private def g[C^] = (xs: List[Object^{C^}]) => xs.head // error | ||
| ^^^^^^^ | ||
| Capture set parameter C leaks into capture scope of method g. | ||
| To allow this, the type C should be declared with a @use annotation | ||
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/use-capset.scala:13:22 ----------------------------------- | ||
13 | val _: () -> Unit = h // error: should be ->{io} | ||
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/use-capset.scala:11:22 ----------------------------------- | ||
11 | val _: () -> Unit = h // error: should be ->{io} | ||
| ^ | ||
| Found: (h : () ->{io} Unit) | ||
| Required: () -> Unit | ||
| | ||
| longer explanation available when compiling with `-explain` | ||
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/use-capset.scala:15:50 ----------------------------------- | ||
15 | val _: () -> List[Object^{io}] -> Object^{io} = h2 // error, should be ->{io} | ||
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/use-capset.scala:13:50 ----------------------------------- | ||
13 | val _: () -> List[Object^{io}] -> Object^{io} = h2 // error, should be ->{io} | ||
| ^^ | ||
| Found: (h2 : () ->? (x$0: List[box Object^]^{}) ->{io} Object^{io}) | ||
| Required: () -> List[box Object^{io}] -> Object^{io} | ||
| Found: (h2 : () ->? (x$0: List[box Object^{io}]^{}) ->{io} Object^{io}) | ||
| Required: () -> List[box Object^{io}] -> Object^{io} | ||
| | ||
| longer explanation available when compiling with `-explain` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.