Hi all,
I thought I’d take a look at SR-153 "Bad fix suggestion for changing value of
capture list constants" <https://bugs.swift.org/browse/SR-153>, and I’d really
appreciate it if someone more familiar with the code could check my thoughts,
rather than me jumping straight to submitting a pull request that might be
going in the wrong direction.
First, an entry in a capture list should always be semantically a constant,
correct? Right now, the VarDecl ‘isLet’ flag is being set to ownershipKind !=
Ownership::Weak, which means that a capture of [a] is treated as constant by
the type checker, but a capture of [weak a] is not. Thus, this code compiles
without error (and prints “nil” and “A" when run), which is certainly
unexpected behavior to me:
class A {}
var a = A()
let f = {
[weak a] in
a = A()
print(a)
}
f()
print(a)
I can imagine there being a good reason why a weak var shouldn’t be marked as
isLet for optimization purposes, etc, since you can’t assume that it won’t
change, but surely the programmer shouldn’t be explicitly using it as an
lvalue, right?
I think the solution here is to add a VarDecl flag bit for
InClosureCaptureList, set that when setting up the VarDecl in ParseExpr, and
then return false from isSettable() (to fix the issue shown here), and early
return from emitLetToVarNoteIfSimple() (to fix the original issue 153). These
would be similar and in the same places as the existing isa<ParamDecl> checks.
Does all that sound okay?
Thanks!
- Greg
_______________________________________________
swift-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-dev