Skip to content

Commit 3408345

Browse files
committed
Fix pathRoot and pathOwner
There was some accidental type confusion which made every capture root type end up with cap as pathRoot and caps as pathOwner.
1 parent 9ae20d9 commit 3408345

File tree

5 files changed

+34
-29
lines changed

5 files changed

+34
-29
lines changed

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

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,25 +192,34 @@ extension (tp: Type)
192192
case _ =>
193193
tp
194194

195-
/** The first element of this path type. Note that class parameter references
196-
* are of the form this.C but their pathroot is still this.C, not this.
195+
/** The first element of this path type, skipping selections
196+
* and qualifiers. Note that class parameter references are of
197+
* the form this.C but their pathroot is still this.C, not this.
197198
*/
198-
final def pathRoot(using Context): Type = tp.dealias match
199-
case tp1: NamedType =>
200-
if tp1.symbol.maybeOwner.isClass && tp1.symbol != defn.captureRoot && !tp1.symbol.is(TypeParam) then
201-
tp1.prefix match
202-
case pre: CaptureRef => pre.pathRoot
203-
case _ => tp1
204-
else tp1
205-
case tp1 => tp1
206-
207-
/** If this part starts with `C.this`, the class `C`.
208-
* Otherwise, if it starts with a reference `r`, `r`'s owner.
209-
* Otherwise NoSymbol.
199+
final def pathRoot(using Context): Type = tp match
200+
case root(_) => tp
201+
case QualifiedCapability(tp1) => tp1.pathRoot
202+
case _ => tp.dealias match
203+
case tp1: NamedType =>
204+
if tp1.symbol.maybeOwner.isClass && !tp1.symbol.is(TypeParam) then
205+
tp1.prefix match
206+
case pre: CaptureRef => pre.pathRoot
207+
case _ => tp1
208+
else tp1
209+
case tp1 => tp1
210+
211+
/** The logical owner of the root of this class:
212+
* - If this path starts with `C.this`, the class `C`.
213+
* - If it starts with a reference `r`, `r`'s owner.
214+
* - If it starts with cap, the `scala.caps` package class.
215+
* - If it starts with a fresh instance, its owner.
216+
* - If it starts with a ParamRef or a result root, NoSymbol.
210217
*/
211218
final def pathOwner(using Context): Symbol = pathRoot match
219+
case tp1: TermRef if tp1.isCap => defn.CapsModule.moduleClass
212220
case tp1: NamedType => tp1.symbol.owner
213221
case tp1: ThisType => tp1.cls
222+
case tp1 @ root.Fresh(_) => tp1.ccOwner
214223
case _ => NoSymbol
215224

216225
final def isParamPath(using Context): Boolean = tp.dealias match

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ sealed abstract class CaptureSet extends Showable:
313313
* will also map any elements added in the future to themselves. This assumption
314314
* can be tested to hold by setting the ccConfig.checkSkippedMaps setting to true.
315315
* - If the map is some other map that does not map all elements to themselves,
316-
* freeze the current set (i.e. make it porvisionally solved) and return
316+
* freeze the current set (i.e. make it provisionally solved) and return
317317
* the mapped elements as a constant set.
318318
*/
319319
def map(tm: TypeMap)(using Context): CaptureSet =

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@
1818
| ^ refers to the universal root capability
1919
| ^² refers to a fresh root capability in the type of value arg
2020
| cap is the universal root capability
21-
-- Error: tests/neg-custom-args/captures/i15772.scala:35:33 ------------------------------------------------------------
21+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:35:33 ---------------------------------------
2222
35 | val boxed2 : Observe[C]^ = box2(c) // error
2323
| ^^^^^^^
24-
| reference cap is not included in the allowed capture set ?
25-
| of the enclosing method main3
24+
|Found: (C{val arg: C^}^² => Unit) -> Unit
25+
|Required: (C => Unit) =>² Unit
2626
|
27-
| Note that the universal capability cap
28-
| cannot be included in capture set ?
27+
|where: => refers to the universal root capability
28+
| =>² refers to a fresh root capability in the type of value boxed2
29+
| ^ refers to a fresh root capability in the type of value arg
30+
| ^² refers to a fresh root capability created in value boxed2 when instantiating method c's type -> C^{cap}
31+
|
32+
| longer explanation available when compiling with `-explain`
2933
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:46:2 ----------------------------------------
3034
46 | x: (() -> Unit) // error
3135
| ^

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@
2121
34 | (() => f.write()) :: Nil
2222
|
2323
| longer explanation available when compiling with `-explain`
24-
-- Error: tests/neg-custom-args/captures/reaches.scala:39:31 -----------------------------------------------------------
25-
39 | val next: () => Unit = cur.head // error
26-
| ^^^^^^^^
27-
| reference cap is not included in the allowed capture set ?
28-
| of the enclosing method runAll2
29-
|
30-
| Note that the universal capability cap
31-
| cannot be included in capture set ?
3224
-- Error: tests/neg-custom-args/captures/reaches.scala:44:16 -----------------------------------------------------------
3325
44 | val cur = Ref[List[Proc]](xs) // error
3426
| ^^^^^^^^^^

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def runAll1(@use xs: List[Proc]): Unit =
3636
def runAll2(@consume xs: List[Proc]): Unit =
3737
var cur: List[Proc] = xs
3838
while cur.nonEmpty do
39-
val next: () => Unit = cur.head // error
39+
val next: () => Unit = cur.head // was error, now OK
4040
next()
4141
cur = cur.tail
4242

0 commit comments

Comments
 (0)