Skip to content

Commit c3b2f8a

Browse files
committed
Drop user-defined local roots
1 parent d29d5e3 commit c3b2f8a

File tree

6 files changed

+23
-41
lines changed

6 files changed

+23
-41
lines changed

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

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -339,24 +339,13 @@ extension (sym: Symbol)
339339
else recur(sym.owner)
340340
recur(sym)
341341

342-
/** The parameter with type caps.Cap in the leading term parameter section,
343-
* or NoSymbol, if none exists.
344-
*/
345-
def definedLocalRoot(using Context): Symbol =
346-
sym.paramSymss.dropWhile(psyms => psyms.nonEmpty && psyms.head.isType) match
347-
case psyms :: _ => psyms.find(_.info.typeSymbol == defn.Caps_Cap).getOrElse(NoSymbol)
348-
case _ => NoSymbol
349-
350342
/** The local root corresponding to sym's level owner */
351343
def localRoot(using Context): Symbol =
352344
val owner = sym.levelOwner
353345
assert(owner.exists)
354346
def newRoot = newSymbol(if owner.isClass then newLocalDummy(owner) else owner,
355347
nme.LOCAL_CAPTURE_ROOT, Synthetic, defn.Caps_Cap.typeRef)
356-
def lclRoot =
357-
if owner.isTerm then owner.definedLocalRoot.orElse(newRoot)
358-
else newRoot
359-
ccState.localRoots.getOrElseUpdate(owner, lclRoot)
348+
ccState.localRoots.getOrElseUpdate(owner, newRoot)
360349

361350
def maxNested(other: Symbol, onConflict: (Symbol, Symbol) => Context ?=> Symbol)(using Context): Symbol =
362351
if !sym.exists || other.isContainedIn(sym) then other

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
559559
case tp: (RefinedOrRecType | MatchType) =>
560560
superTypeIsImpure(tp.underlying)
561561
case tp: AndType =>
562-
superTypeIsImpure(tp.tp1) || needsVariable(tp.tp2)
562+
superTypeIsImpure(tp.tp1) || superTypeIsImpure(tp.tp2)
563563
case tp: OrType =>
564564
superTypeIsImpure(tp.tp1) && superTypeIsImpure(tp.tp2)
565565
case _ =>

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,9 +2927,7 @@ object Types {
29272927
// TODO Try to make local class roots be NonMembers owned directly by the class
29282928
val owner = symbol.maybeOwner
29292929
def normOwner = if owner.isLocalDummy then owner.owner else owner
2930-
if name == nme.LOCAL_CAPTURE_ROOT then normOwner
2931-
else if info.isRef(defn.Caps_Cap) && owner.isTerm then normOwner
2932-
else NoSymbol
2930+
if name == nme.LOCAL_CAPTURE_ROOT then normOwner else NoSymbol
29332931

29342932
override def normalizedRef(using Context): CaptureRef =
29352933
if isTrackableRef then symbol.termRef else this

tests/neg-custom-args/captures/usingLogFile-alt.scala renamed to tests/neg-custom-args/captures/usingFile.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object Test:
77
class Logger(f: OutputStream^):
88
def log(msg: String): Unit = ???
99

10-
def usingFile[T](name: String, op: (lcap: caps.Cap) ?-> OutputStream^{lcap} => T): T =
10+
def usingFile[sealed T](name: String, op: OutputStream^ => T): T =
1111
val f = new FileOutputStream(name)
1212
val result = op(f)
1313
f.close()

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,23 @@
3030
|
3131
| where: x$0 is a reference to a value parameter
3232
| x$0² is a reference to a value parameter
33-
-- Error: tests/neg-custom-args/captures/usingLogFile.scala:47:14 ------------------------------------------------------
34-
47 | val later = usingLogFile { f => () => f.write(0) } // error
35-
| ^^^^^^^^^^^^
36-
| escaping local reference local.type
37-
-- Error: tests/neg-custom-args/captures/usingLogFile.scala:62:16 ------------------------------------------------------
38-
62 | val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error
33+
-- Error: tests/neg-custom-args/captures/usingLogFile.scala:52:16 ------------------------------------------------------
34+
52 | val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error
3935
| ^^^^^^^^^
40-
| escaping local reference local.type
41-
-- Error: tests/neg-custom-args/captures/usingLogFile.scala:70:16 ------------------------------------------------------
42-
70 | val later = usingFile("logfile", // error !!! but should be ok, since we can widen `l` to `file` instead of to `cap`
36+
| reference (caps.cap : caps.Cap) is not included in the allowed capture set {x$0, x$0²}
37+
|
38+
| Note that the universal capability `cap`
39+
| cannot be included in capture set {x$0, x$0}
40+
|
41+
| where: x$0 is a reference to a value parameter
42+
| x$0² is a reference to a value parameter
43+
-- Error: tests/neg-custom-args/captures/usingLogFile.scala:60:16 ------------------------------------------------------
44+
60 | val later = usingFile("logfile", // error !!! but should be ok, since we can widen `l` to `file` instead of to `cap`
4345
| ^^^^^^^^^
44-
| reference (_$1 : java.io.OutputStream^{local}) is not included in the allowed capture set {x$0, local}
46+
| reference (_$1 : java.io.OutputStream^) is not included in the allowed capture set {x$0, x$0²}
47+
|
48+
| Note that reference (_$1 : java.io.OutputStream^), defined in method $anonfun
49+
| cannot be included in outer capture set {x$0, x$0} which is associated with method test
4550
|
46-
| Note that reference (_$1 : java.io.OutputStream^{local}), defined in method $anonfun
47-
| cannot be included in outer capture set {x$0, local} which is associated with method test
51+
| where: x$0 is a reference to a value parameter
52+
| x$0² is a reference to a value parameter

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,10 @@ object Test2:
3737
later4.x()
3838

3939
object Test3:
40-
41-
def usingLogFile[T](op: (local: caps.Cap) ?-> FileOutputStream^{local} => T) =
42-
val logFile = FileOutputStream("log")
43-
val result = op(logFile)
44-
logFile.close()
45-
result
46-
47-
val later = usingLogFile { f => () => f.write(0) } // error
48-
49-
object Test4:
5040
class Logger(f: OutputStream^):
5141
def log(msg: String): Unit = ???
5242

53-
def usingFile[T](name: String, op: (local: caps.Cap) ?-> OutputStream^{local} => T): T =
43+
def usingFile[sealed T](name: String, op: OutputStream^ => T): T =
5444
val f = new FileOutputStream(name)
5545
val result = op(f)
5646
f.close()
@@ -62,7 +52,7 @@ object Test4:
6252
val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error
6353
later(1)
6454

65-
def usingLogger[T](f: OutputStream^, op: (local: caps.Cap) ?-> Logger^{f} => T): T =
55+
def usingLogger[sealed T](f: OutputStream^, op: Logger^{f} => T): T =
6656
val logger = Logger(f)
6757
op(logger)
6858

0 commit comments

Comments
 (0)