Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7cbadac

Browse files
authored
CC: Various fixes and simplifications (#23881)
- Propagate expected type into blocks The level checking should do the proper avoidance so that local symbols would not leak into type variables of the expected type. - Don't automatically add a FreshCap owner to its hidden set - Don't use span capture sets for function types as the underlying set Based on #23874
2 parents 6b100a7 + fb45ece commit 7cbadac

30 files changed

+169
-253
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,7 @@ object CaptureSet:
15651565
// `ref` will not seem subsumed by other capabilities in a `++`.
15661566
universal
15671567
case c: CoreCapability =>
1568-
ofType(c.underlying, followResult = true)
1568+
ofType(c.underlying, followResult = ccConfig.useSpanCapset)
15691569

15701570
/** Capture set of a type
15711571
* @param followResult If true, also include capture sets of function results.

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ class CheckCaptures extends Recheck, SymTransformer:
496496
case _ => c.core match
497497
case c1: RootCapability => c1.singletonCaptureSet
498498
case c1: CoreCapability =>
499-
CaptureSet.ofType(c1.widen, followResult = true)
499+
CaptureSet.ofType(c1.widen, followResult = ccConfig.useSpanCapset)
500500
capt.println(i"Widen reach $c to $underlying in ${env.owner}")
501501
underlying.disallowBadRoots(NoSymbol): () =>
502502
report.error(em"Local capability $c${env.owner.qualString("in")} cannot have `cap` as underlying capture set", tree.srcPos)

compiler/src/dotty/tools/dotc/cc/Setup.scala

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
459459
if sym.isType then stripImpliedCaptureSet(tp2)
460460
else tp2
461461
if freshen then
462-
capToFresh(tp3, Origin.InDecl(sym)).tap(addOwnerAsHidden(_, sym))
462+
capToFresh(tp3, Origin.InDecl(sym))
463463
else tp3
464464
end transformExplicitType
465465

@@ -473,25 +473,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
473473
extension (sym: Symbol) def nextInfo(using Context): Type =
474474
atPhase(thisPhase.next)(sym.info)
475475

476-
private def addOwnerAsHidden(tp: Type, owner: Symbol)(using Context): Unit =
477-
val ref = owner.termRef
478-
def add = new TypeTraverser:
479-
var reach = false
480-
def traverse(t: Type): Unit = t match
481-
case t @ CapturingType(parent, refs) =>
482-
val saved = reach
483-
reach |= t.isBoxed
484-
try
485-
traverse(parent)
486-
for case fresh: FreshCap <- refs.elems.iterator do // TODO: what about fresh.rd elems?
487-
if reach then fresh.hiddenSet.elems += ref.reach
488-
else if ref.isTracked then fresh.hiddenSet.elems += ref
489-
finally reach = saved
490-
case _ =>
491-
traverseChildren(t)
492-
if ref.isTrackableRef then add.traverse(tp)
493-
end addOwnerAsHidden
494-
495476
/** A traverser that adds knownTypes and updates symbol infos */
496477
def setupTraverser(checker: CheckerAPI) = new TreeTraverserWithPreciseImportContexts:
497478
import checker.*

compiler/src/dotty/tools/dotc/cc/ccConfig.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ object ccConfig:
4343
*/
4444
inline val postCheckCapturesets = false
4545

46+
/** If true take as the underlying capture set of a capability of function type
47+
* the capture set along the span, including capture sets of function results.
48+
*/
49+
inline val useSpanCapset = false
50+
4651
/** If true, do level checking for FreshCap instances */
4752
def useFreshLevels(using Context): Boolean =
4853
Feature.sourceVersion.stable.isAtLeast(SourceVersion.`3.7`)

compiler/src/dotty/tools/dotc/transform/Recheck.scala

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -376,25 +376,21 @@ abstract class Recheck extends Phase, SymTransformer:
376376
recheck(tree.rhs, lhsType.widen)
377377
defn.UnitType
378378

379-
private def recheckBlock(stats: List[Tree], expr: Tree)(using Context): Type =
379+
private def recheckBlock(stats: List[Tree], expr: Tree, pt: Type)(using Context): Type =
380380
recheckStats(stats)
381-
val exprType = recheck(expr)
381+
val exprType = recheck(expr, pt)
382382
TypeOps.avoid(exprType, localSyms(stats).filterConserve(_.isTerm))
383383

384384
def recheckBlock(tree: Block, pt: Type)(using Context): Type = tree match
385-
case Block(Nil, expr: Block) => recheckBlock(expr, pt)
386385
case Block((mdef : DefDef) :: Nil, closure: Closure) =>
387386
recheckClosureBlock(mdef, closure.withSpan(tree.span), pt)
388-
case Block(stats, expr) => recheckBlock(stats, expr)
389-
// The expected type `pt` is not propagated. Doing so would allow variables in the
390-
// expected type to contain references to local symbols of the block, so the
391-
// local symbols could escape that way.
387+
case Block(stats, expr) => recheckBlock(stats, expr, pt)
392388

393389
def recheckClosureBlock(mdef: DefDef, expr: Closure, pt: Type)(using Context): Type =
394-
recheckBlock(mdef :: Nil, expr)
390+
recheckBlock(mdef :: Nil, expr, pt)
395391

396392
def recheckInlined(tree: Inlined, pt: Type)(using Context): Type =
397-
recheckBlock(tree.bindings, tree.expansion)(using inlineContext(tree))
393+
recheckBlock(tree.bindings, tree.expansion, pt)(using inlineContext(tree))
398394

399395
def recheckIf(tree: If, pt: Type)(using Context): Type =
400396
recheck(tree.cond, defn.BooleanType)

library/src/scala/collection/Iterator.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
* See the NOTICE file distributed with this work for
1010
* additional information regarding copyright ownership.
1111
*/
12-
1312
package scala.collection
1413

1514
import scala.language.`2.13`

tests/neg-custom-args/captures/capt-test.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ def handle[E <: Exception, R <: Top](op: (CT[E] @retains[caps.cap.type]) => R)(
2020
catch case ex: E => handler(ex)
2121

2222
def test: Unit =
23-
val b = handle[Exception, () => Nothing] { // error // error
24-
(x: CanThrow[Exception]) => () => raise(new Exception)(using x)
23+
val b = handle[Exception, () => Nothing] { // error
24+
(x: CanThrow[Exception]) => () => raise(new Exception)(using x) // error
2525
} {
2626
(ex: Exception) => ???
2727
}

tests/neg-custom-args/captures/capt1.check

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,31 @@
1616
| Note that capability x is not included in capture set {}.
1717
|
1818
| longer explanation available when compiling with `-explain`
19-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:15:2 -----------------------------------------
20-
15 | def f(y: Int) = if x == null then y else y // error
19+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:16:2 -----------------------------------------
20+
16 | f // error
2121
| ^
2222
| Found: (y: Int) ->{x} Int
2323
| Required: Matchable
2424
|
2525
| Note that capability x is not included in capture set {}.
26-
16 | f
2726
|
2827
| longer explanation available when compiling with `-explain`
29-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:22:2 -----------------------------------------
30-
22 | class F(y: Int) extends A: // error
31-
| ^
28+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:24:2 -----------------------------------------
29+
24 | F(22) // error
30+
| ^^^^^
3231
| Found: A^{x}
3332
| Required: A
3433
|
3534
| Note that capability x is not included in capture set {}.
36-
23 | def m() = if x == null then y else y
37-
24 | F(22)
3835
|
3936
| longer explanation available when compiling with `-explain`
40-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:27:2 -----------------------------------------
41-
27 | new A: // error
42-
| ^
43-
| Found: A^{x}
44-
| Required: A
37+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:28:40 ----------------------------------------
38+
28 | def m() = if x == null then y else y // error
39+
| ^
40+
| Found: A^{x}
41+
| Required: A
4542
|
46-
| Note that capability x is not included in capture set {}.
47-
28 | def m() = if x == null then y else y
43+
| Note that capability x is not included in capture set {}.
4844
|
4945
| longer explanation available when compiling with `-explain`
5046
-- Error: tests/neg-custom-args/captures/capt1.scala:36:16 -------------------------------------------------------------

tests/neg-custom-args/captures/capt1.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ def h1(x: C @retains[caps.cap.type], y: C): Any =
1212
() => f() // ok
1313

1414
def h2(x: C @retains[caps.cap.type]): Matchable =
15-
def f(y: Int) = if x == null then y else y // error
16-
f
15+
def f(y: Int) = if x == null then y else y
16+
f // error
1717

1818
class A
1919
type Cap = C @retains[caps.cap.type]
2020

2121
def h3(x: Cap): A =
22-
class F(y: Int) extends A: // error
22+
class F(y: Int) extends A:
2323
def m() = if x == null then y else y
24-
F(22)
24+
F(22) // error
2525

2626
def h4(x: Cap, y: Int): A =
27-
new A: // error
28-
def m() = if x == null then y else y
27+
new A:
28+
def m() = if x == null then y else y // error
2929

3030
def f1(c: Cap): () ->{c} c.type = () => c // ok
3131

tests/neg-custom-args/captures/heal-tparam-cs.check

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:10:23 -------------------------------
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:10:25 -------------------------------
22
10 | val test1 = localCap { c => // error
3-
| ^
3+
| ^
44
|Found: (c: Capp^'s1) ->'s2 () ->{c} Unit
55
|Required: (c: Capp^) => () ->'s3 Unit
66
|
@@ -9,7 +9,6 @@
99
|where: => refers to a fresh root capability created in value test1 when checking argument to parameter op of method localCap
1010
| ^ refers to the universal root capability
1111
11 | () => { c.use() }
12-
12 | }
1312
|
1413
| longer explanation available when compiling with `-explain`
1514
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:15:13 -------------------------------

0 commit comments

Comments
 (0)