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

A first, incomplete implementation of polyadic capture calculus #18566

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
787e5bb
Refine "cannot have inferred type" test
odersky Sep 13, 2023
1c0a50b
Run Setup code one phase before CheckCaptures
odersky Sep 18, 2023
ffaf563
Don't shorten local roots when printing
odersky Sep 18, 2023
96b0030
Drop rhsClosure from CCState
odersky Sep 18, 2023
5992a3f
Fix computation of level owners
odersky Sep 19, 2023
f299a9b
Setup newScheme mechanism
odersky Sep 19, 2023
d1b2e34
Introduce rootTarget for mapRoots customization
odersky Sep 19, 2023
f4687df
Change result type inference of vals and defs
odersky Sep 19, 2023
3786e66
Make RecheckDef return a type
odersky Sep 19, 2023
23ab1ba
Use a separate phase to add try owners
odersky Sep 19, 2023
8968e8e
Transform infos of all symbols defined in current run in SymTransformer
odersky Sep 20, 2023
8528371
Fix bug when restoring denotations in Recheck.
odersky Sep 20, 2023
9412db8
Do fluidify when transforming symbols instead of on access
odersky Sep 20, 2023
5056a5f
Align rechecking ValDefs and DefDefs
odersky Sep 20, 2023
a10057d
Revise inferred type checking
odersky Sep 20, 2023
4a44d43
Take singleton types into account when instantiating local roots
odersky Sep 21, 2023
3160f1c
Replace some uses of CaptureSet universal to account for local roots
odersky Sep 21, 2023
c841cff
Less forcing of info when printing
odersky Sep 21, 2023
cd8b337
Also set CaptureChecked status for unpickled roots
odersky Sep 23, 2023
505efbd
Let vals be lever owners
odersky Sep 23, 2023
ed8aae3
Refactor wellformed checks
odersky Sep 23, 2023
c739ff2
Drop boxedUnlessFun and boxedIfTypeParam operations
odersky Sep 23, 2023
d123608
Fix followAlias
odersky Sep 25, 2023
4a53ed5
Also interpolate root variables in non-variable capture sets.
odersky Sep 26, 2023
5dcb064
Refactor addNewElems
odersky Sep 27, 2023
db764e0
Refactor level error reporting
odersky Sep 27, 2023
96d85bc
Make CompareResult an enum
odersky Sep 29, 2023
5020117
Add takesCappedParam criterion to isLevelOwner
odersky Sep 29, 2023
0a0eba4
Decorate inferred type aliases as inferred types
odersky Sep 29, 2023
a9d5cbd
Setup correct environment when completing definitions
odersky Oct 1, 2023
80348c0
Treat classes with universal self types as level owners
odersky Oct 1, 2023
b475268
Revamp capture roots and captureset vars
odersky Oct 1, 2023
8fb8350
Make RefiningVars level polymorphic
odersky Oct 1, 2023
ac74be8
Enable takesCappedParam criterion for level ownership
odersky Oct 1, 2023
eda563b
Use LooseCaptureRoot checking for checking bounds of applied types
odersky Oct 1, 2023
1f9bf26
Update tests can check files
odersky Oct 1, 2023
046dff9
Revert "Use LooseCaptureRoot checking for checking bounds of applied …
odersky Oct 1, 2023
29f34de
Simplification: drop ccNestingLevel
odersky Oct 1, 2023
2d07bd5
Add @sharable annotation to global counter
odersky Oct 1, 2023
8646308
Handle outer class roots when instantiating class members
odersky Oct 3, 2023
0ffba0d
Simplifications
odersky Oct 5, 2023
3d2a4cd
Make constructors level owners
odersky Oct 5, 2023
6ae1a89
Work capture root determination into AsSeenFrom
odersky Oct 6, 2023
e7d3b92
Keep track of failure traces when subCapturing fails under -Ycc-debug
odersky Oct 7, 2023
f065d75
Keep track of enclosing capture sets when comparing refined types
odersky Oct 7, 2023
1c294ef
Change owner of computed capture set for constructor applications
odersky Oct 7, 2023
7c34545
Treat added class refinements as inferred types for further processing
odersky Oct 7, 2023
b7d8047
A first attempt at level checking for classes
odersky Oct 7, 2023
bf323db
Drop instantiateOuterClassRoots
odersky Oct 8, 2023
0afe923
Disable some special cases about RefiningVars
odersky Oct 8, 2023
db68fd9
Introduce isCaptureChecking test
odersky Oct 8, 2023
7fdb6af
Restrict isUncachable
odersky Oct 8, 2023
acb8232
Move most of self type setup to transformSym
odersky Oct 9, 2023
79f0564
Make non-final impure classes level owners
odersky Oct 9, 2023
9c71611
Translate local roots when doing override checks
odersky Oct 9, 2023
2c9f5b0
Map parents of classes with the class as owner.
odersky Oct 9, 2023
5513ca2
Fix CC asSeenFrom when prefix is `this`
odersky Oct 9, 2023
a521cf1
Drop unnecessary code in transformSym
odersky Oct 10, 2023
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
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package dotc
import core._
import Contexts._
import typer.{TyperPhase, RefChecks}
import cc.CheckCaptures
import parsing.Parser
import Phases.Phase
import transform._
Expand Down Expand Up @@ -84,8 +83,9 @@ class Compiler {
new PatternMatcher) :: // Compile pattern matches
List(new TestRecheck.Pre) :: // Test only: run rechecker, enabled under -Yrecheck-test
List(new TestRecheck) :: // Test only: run rechecker, enabled under -Yrecheck-test
List(new CheckCaptures.Pre) :: // Preparations for check captures phase, enabled under captureChecking
List(new CheckCaptures) :: // Check captures, enabled under captureChecking
List(new cc.AddTryOwners) :: // Add symbols as owners of try blocks, enabled under captureChecking
List(new cc.Setup) :: // Preparations for check captures phase, enabled under captureChecking
List(new cc.CheckCaptures) :: // Check captures, enabled under captureChecking
List(new ElimOpaque, // Turn opaque into normal aliases
new sjs.ExplicitJSClasses, // Make all JS classes explicit (Scala.js only)
new ExplicitOuter, // Add accessors to outer classes from nested ones.
Expand Down
15 changes: 15 additions & 0 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,21 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
!(sym.is(Method) && sym.info.isInstanceOf[MethodOrPoly]) // if is a method it is parameterless
}

/** A tree traverser that generates the the same import contexts as original typer for statements.
* TODO: Should we align TreeMapWithPreciseStatContexts and also keep track of exprOwners?
*/
abstract class TreeTraverserWithPreciseImportContexts extends TreeTraverser:
override def apply(x: Unit, trees: List[Tree])(using Context): Unit =
def recur(trees: List[Tree]): Unit = trees match
case (imp: Import) :: rest =>
traverse(rest)(using ctx.importContext(imp, imp.symbol))
case tree :: rest =>
traverse(tree)
traverse(rest)
case Nil =>
recur(trees)
end TreeTraverserWithPreciseImportContexts

extension (xs: List[tpd.Tree])
def tpes: List[Type] = xs match {
case x :: xs1 => x.tpe :: xs1.tpes
Expand Down
46 changes: 46 additions & 0 deletions compiler/src/dotty/tools/dotc/cc/AddTryOwners.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package dotty.tools.dotc
package cc

import core.*
import DenotTransformers.IdentityDenotTransformer
import Phases.Phase
import Contexts.*, Symbols.*, Flags.*, Types.*
import config.Feature
import ast.tpd
import StdNames.nme
import Decorators.i

object AddTryOwners:
val name: String = "addTryOwners"
val description: String = "add symbols for try blocks in preparation of capture checking"

class AddTryOwners extends Phase, IdentityDenotTransformer:
thisPhase =>

import tpd.*

override def phaseName: String = AddTryOwners.name
override def description: String = AddTryOwners.description

override def isRunnable(using Context) =
super.isRunnable && Feature.ccEnabledSomewhere

override def isCheckable = false

def run(using Context): Unit =
val addTryOwners = new TreeTraverserWithPreciseImportContexts:
def traverse(tree: Tree)(using Context): Unit = tree match
case tree @ Try(expr, cases, finalizer) if Feature.enabled(Feature.saferExceptions) =>
val tryOwner = newSymbol(ctx.owner, nme.TRY_BLOCK, SyntheticMethod, MethodType(Nil, defn.UnitType))
ccState.tryBlockOwner(tree) = tryOwner
ccState.isLevelOwner(tryOwner) = true
expr.changeOwnerAfter(ctx.owner, tryOwner, thisPhase)
inContext(ctx.withOwner(tryOwner)):
traverse(expr)
traverse(cases)
traverse(finalizer)
case _ =>
traverseChildren(tree)
addTryOwners.traverse(ctx.compilationUnit.tpdTree)
end AddTryOwners

13 changes: 11 additions & 2 deletions compiler/src/dotty/tools/dotc/cc/CaptureAnnotation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ case class CaptureAnnotation(refs: CaptureSet, boxed: Boolean)(cls: Symbol) exte
import CaptureAnnotation.*
import tpd.*

/** A cache for boxed version of a capturing type with this annotation */
val boxedType = BoxedTypeCache()
/** A cache for the version of this annotation which differs in its boxed status. */
var boxDual: CaptureAnnotation | Null = null

/** A boxed annotation which is either the same annotation or its boxDual */
def boxedAnnot(using Context): CaptureAnnotation =
if boxed then this
else if boxDual != null then boxDual.nn
else
val dual = CaptureAnnotation(refs, boxed = true)(cls)
dual.boxDual = this
dual

/** Reconstitute annotation tree from capture set */
override def tree(using Context) =
Expand Down
Loading