Skip to content

Commit b24e2aa

Browse files
committed
Support lazy val members
1 parent 4886e94 commit b24e2aa

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,14 @@ class CheckCaptures extends Recheck, SymTransformer:
736736
checkUpdate(qualType, tree.srcPos):
737737
i"Cannot call update ${tree.symbol} of ${qualType.showRef}"
738738

739+
// If selecting a lazy val member, charge the qualifier since accessing
740+
// the lazy val can trigger initialization that uses the qualifier's capabilities
741+
if tree.symbol.is(Lazy) then
742+
qualType match
743+
case tr: (TermRef | ThisType) =>
744+
markPathFree(tr, pt, tree)
745+
case _ =>
746+
739747
val origSelType = recheckSelection(tree, qualType, name, disambiguate)
740748
val selType = mapResultRoots(origSelType, tree.symbol)
741749
val selWiden = selType.widen
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import language.experimental.captureChecking
2+
import caps.*
3+
4+
class Console extends SharedCapability:
5+
def println(msg: String): Unit = Predef.println("CONSOLE: " + msg)
6+
7+
class IO extends SharedCapability:
8+
def readLine(): String = scala.io.StdIn.readLine()
9+
10+
class Clazz(val console: Console^):
11+
lazy val memberLazy: () -> String = {
12+
console.println("Computing memberLazy")
13+
() => "Member Lazy Value"
14+
}
15+
16+
trait Trait:
17+
lazy val memberLazy: () -> String
18+
def memberMethod(): String
19+
20+
def client(t: Trait^, c: Clazz^): Unit =
21+
val v0: () -> () -> String = () => t.memberLazy // error
22+
val v0_1: () ->{t} () -> String = () => t.memberLazy // ok
23+
val v1: () -> String = () => t.memberLazy() // error
24+
val v2: (() -> String)^{t} = () => t.memberLazy() // ok
25+
val v3: (() -> String)^{c.console} = () => c.memberLazy() // error (but should this be allowed?)
26+
val v4: () -> String = () => t.memberMethod() // error
27+
val v5: (() -> String)^{t} = () => t.memberMethod() // ok
28+
29+
()

0 commit comments

Comments
 (0)