Skip to content

Separation Checker: Crash when prefixing a read-only capture-variable through a self-type annotation #23235

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

Open
bracevac opened this issue May 22, 2025 · 2 comments
Assignees

Comments

@bracevac
Copy link
Contributor

bracevac commented May 22, 2025

Compiler version

Current nightly at b078f6d

Minimized code

import language.experimental.captureChecking
import caps.*

trait Zone extends Capability:
  self =>
    type R^
    def alloc: Any^{self.R.rd}

Output (click arrow to expand)

Exception in thread "main" scala.MatchError: TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),trait Zone)),type R) (of class dotty.tools.dotc.core.Types$CachedTypeRef)

  unhandled exception while running cc on tests/pending/regions.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Xno-enrich-error-messages.


     while compiling: tests/pending/regions.scala
        during phase: cc
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.16
    compiler version: version 3.7.2-RC1-bin-SNAPSHOT-nonbootstrapped-git-b078f6d
            settings: -classpath /Users/oliver/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.16/scala-library-2.13.16.jar:/Users/oliver/projects/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.7.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.7.2-RC1-bin-SNAPSHOT.jar -d /Users/oliver/projects/dotty/compiler/../out/default-last-scalac-out.jar
        at dotty.tools.dotc.cc.Capabilities$Capability.readOnly(Capability.scala:258)
        at dotty.tools.dotc.cc.Capabilities$Capability.readOnly$(Capability.scala:235)
        at dotty.tools.dotc.core.Types$TypeRef.readOnly(Types.scala:2943)
        at dotty.tools.dotc.cc.CaptureOps$package$.toCapabilities$$anonfun$2(CaptureOps.scala:61)
        at scala.collection.immutable.List.map(List.scala:247)
        at dotty.tools.dotc.cc.CaptureOps$package$.toCapabilities(CaptureOps.scala:61)
        at dotty.tools.dotc.cc.CaptureOps$package$.$anonfun$1(CaptureOps.scala:82)
        at scala.collection.immutable.List.flatMap(List.scala:294)
        at dotty.tools.dotc.cc.CaptureOps$package$.toCaptureSet(CaptureOps.scala:82)
        at dotty.tools.dotc.cc.Setup$toCapturing$2$.innerApply(Setup.scala:449)
        at dotty.tools.dotc.cc.Setup$SetupTypeMap.apply(Setup.scala:210)
        at dotty.tools.dotc.cc.Setup$SetupTypeMap.apply$(Setup.scala:196)
        at dotty.tools.dotc.cc.Setup$toCapturing$2$.apply(Setup.scala:378)
        at dotty.tools.dotc.cc.Setup.transform$1(Setup.scala:476)
        at dotty.tools.dotc.cc.Setup.dotty$tools$dotc$cc$Setup$$transformExplicitType(Setup.scala:482)
        at dotty.tools.dotc.cc.Setup$$anon$3.transformTT(Setup.scala:537)
        at dotty.tools.dotc.cc.Setup$$anon$3.transformResultType(Setup.scala:547)
        at dotty.tools.dotc.cc.Setup$$anon$3.traverse(Setup.scala:576)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1346)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverse(Trees.scala:1806)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1347)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverse(Trees.scala:1806)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1347)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1766)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1808)
        at dotty.tools.dotc.cc.Setup$$anon$3.traverse(Setup.scala:622)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1807)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.apply(Trees.scala:1807)
        at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1763)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1808)
        at dotty.tools.dotc.cc.Setup$$anon$3.traverse(Setup.scala:601)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1346)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverse(Trees.scala:1806)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1344)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverse(Trees.scala:1806)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.recur$2(tpd.scala:1344)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1349)
        at dotty.tools.dotc.ast.tpd$TreeTraverserWithPreciseImportContexts.apply(tpd.scala:1341)
        at dotty.tools.dotc.ast.Trees$Instance$TreeAccumulator.foldOver(Trees.scala:1772)
        at dotty.tools.dotc.ast.Trees$Instance$TreeTraverser.traverseChildren(Trees.scala:1808)
        at dotty.tools.dotc.cc.Setup$$anon$3.traverse(Setup.scala:622)
        at dotty.tools.dotc.cc.Setup.setupUnit(Setup.scala:927)
        at dotty.tools.dotc.cc.CheckCaptures$CaptureChecker.checkUnit(CheckCaptures.scala:1759)
        at dotty.tools.dotc.transform.Recheck.run(Recheck.scala:147)
        at dotty.tools.dotc.cc.CheckCaptures.run(CheckCaptures.scala:231)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:383)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:334)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:376)
        at dotty.tools.dotc.transform.Recheck.runOn(Recheck.scala:151)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:368)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1324)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:361)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$2(Run.scala:408)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$adapted$1(Run.scala:408)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at dotty.tools.dotc.Run.showProgress(Run.scala:470)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:408)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:420)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:420)
        at dotty.tools.dotc.Run.compileSources(Run.scala:307)
        at dotty.tools.dotc.Run.compile(Run.scala:292)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
        at dotty.tools.dotc.Driver.process(Driver.scala:201)
        at dotty.tools.dotc.Driver.process(Driver.scala:169)
        at dotty.tools.dotc.Driver.process(Driver.scala:181)
        at dotty.tools.dotc.Driver.main(Driver.scala:211)
        at dotty.tools.dotc.Main.main(Main.scala)
@bracevac bracevac added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label area:experimental:cc Capture checking related and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 22, 2025
@bracevac
Copy link
Contributor Author

The same happens with this.R.rd. At least, it should behave as if we did not provide the prefix

-- Error: tests/pending/regions.scala:79:20 ------------------------------------
79 |    def alloc: Any^{R.rd}
   |                    ^^^^
   |_root_.scala.caps.internal.capsOf[Zone.this.R] cannot be tracked since it is not a parameter or local value
1 error found

But more generally, it's not so clear why we get the error here. Should this not be allowed?

@bracevac
Copy link
Contributor Author

There seem to be more issues regarding this and self-type annotations:

trait Zone extends caps.Capability:
    type R^
    def alloc: Any^{this}

Will compile just fine, but

trait Zone extends caps.Capability:
  self =>
    type R^
    def alloc: Any^{self}

results in a warning:

-- Warning: tests/pending/regions.scala:79:20 ----------------------------------
79 |    def alloc: Any^{self}
   |                    ^^^^
   |          redundant capture: Any already accounts for (Zone.this : Zone)
1 warning found

@bracevac bracevac self-assigned this May 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant