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
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to