Skip to content
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

Capability class is not properly boxed in implicit type argument #16725

Closed
Linyxus opened this issue Jan 18, 2023 · 3 comments
Closed

Capability class is not properly boxed in implicit type argument #16725

Linyxus opened this issue Jan 18, 2023 · 3 comments
Assignees
Labels
area:experimental:cc Capture checking related cc-experiment Intended to be merged with cc-experiment branch on origin itype:bug

Comments

@Linyxus
Copy link
Contributor

Linyxus commented Jan 18, 2023

Compiler version

main

Minimized code

import language.experimental.captureChecking

@annotation.capability
class CanIO

def allowIO[T](op: (c: CanIO) => T): T = ???

def bad(c: CanIO): CanIO = c

def test: Unit = {
  val ok = allowIO(bad) // error
  val boom = allowIO[CanIO](bad)  // should be an error, too
}

Output

-- [E007] Type Mismatch Error: issues/capclass.scala:30:19 ---------------------------------------------------------------------------------------------------------------------------------------------
30 |  val ok = allowIO(bad) // error
   |                   ^^^
   |                   Found:    ? CanIO -> {*} CanIO
   |                   Required: (c: CanIO) => box {*} CanIO
   |
   | longer explanation available when compiling with `-explain`
1 error found

Expectation

Both ok and boom should issue an error, but now boom won't b/c of the explicit type argument. This is because in Setup the type arugment CanIO in allowIO[CanIO] will not be boxed when it is written out explicitly.

@Linyxus Linyxus added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 18, 2023
@Kordyjan Kordyjan added cc-experiment Intended to be merged with cc-experiment branch on origin and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 19, 2023
@Gedochao Gedochao added the area:experimental:cc Capture checking related label Jan 18, 2024
@noti0na1
Copy link
Member

I think this issue can be closed now since both variables cause errors as expected.

@Linyxus
Copy link
Contributor Author

Linyxus commented Feb 29, 2024

Yes you are right. The issue is not longer reproducible due to the change in the way we guard scoped capability (previously, it depends on the boxes but now there is a no-covariant-cap check on type arguments).

But the root cause of this issue (that in some cases capability classes are not recognised as impure and therefore not properly boxed) is not fixed. So it is still causing other soundness problems, like the following variant of this issue:

import language.experimental.captureChecking
@annotation.capability
class IO:
  def brewCoffee(): Unit = ???
def usingIO[T](op: IO => T): T = ???

type Wrapper[T] = [R] -> (f: T => R) -> R
def mk[T](x: T): Wrapper[T] = [R] => f => f(x)
def useWrappedIO(wrapper: Wrapper[IO]): () -> Unit =
  () =>
    wrapper: io =>
      io.brewCoffee()
def main(): Unit =
  val escaped = usingIO(io => useWrappedIO(mk(io)))
  escaped()  // boom

With a combination of mk and useWrappedIO we successfully trick the capture checker into believing that a closure that makes use of a capability is pure.

@noti0na1 noti0na1 assigned Linyxus and unassigned noti0na1 Apr 4, 2024
@Linyxus
Copy link
Contributor Author

Linyxus commented Apr 11, 2024

I checked the issue again and it turns out that actually the recent reproduction is completely a new one with a different cause. Another minimisation that is more salient:

def runOps(ops: List[() => Unit]): () -> Unit =
  () =>
    ops.foreach: op =>
      op()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:experimental:cc Capture checking related cc-experiment Intended to be merged with cc-experiment branch on origin itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants