Skip to content

Commit

Permalink
A more flexible scheme for handling the universal capability (#18699)
Browse files Browse the repository at this point in the history
- Start with `sealed` type parameters, extended so that class parameters
can also be `sealed`.
- Tighten the rules so that type parameter arguments for `sealed` type
parameters must themselves be `sealed`, except if the argument is from
some outer scope.
- Introduce a coercion that maps a universal capture set to a local root
that is enclosed by the owners of all free variables of the coerced
expression.


Supersedes #18566
  • Loading branch information
odersky authored Oct 23, 2023
2 parents c1c2c8e + 181d96e commit a940541
Show file tree
Hide file tree
Showing 116 changed files with 2,524 additions and 2,008 deletions.
5 changes: 2 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 @@ -85,8 +84,8 @@ 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.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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ object desugar {
private def toDefParam(tparam: TypeDef, keepAnnotations: Boolean): TypeDef = {
var mods = tparam.rawMods
if (!keepAnnotations) mods = mods.withAnnotations(Nil)
tparam.withMods(mods & EmptyFlags | Param)
tparam.withMods(mods & (EmptyFlags | Sealed) | Param)
}
private def toDefParam(vparam: ValDef, keepAnnotations: Boolean, keepDefault: Boolean): ValDef = {
var mods = vparam.rawMods
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
}
}

/** An extractor for def of a closure contained the block of the closure,
/** An extractor for the method of a closure contained the block of the closure,
* possibly with type ascriptions.
*/
object possiblyTypedClosureDef:
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 @@ -1286,6 +1286,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
19 changes: 0 additions & 19 deletions compiler/src/dotty/tools/dotc/cc/BoxedTypeCache.scala

This file was deleted.

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

0 comments on commit a940541

Please sign in to comment.