[swift-users] Implicitly capture a mutating self

Joe Groff jgroff at apple.com
Fri Dec 16 12:41:40 CST 2016


> On Dec 15, 2016, at 11:46 PM, Richard Wei via swift-users <swift-users at swift.org> wrote:
> 
> Hi,
> 
> Swift 3.0.2 seems to have broken my code due to mutating self capture. But I have to pass inout self to the closure. Any workaround?
> 
>     let blockSize = min(512, count)
>     let blockCount = (count+blockSize-1)/blockSize
>     device.sync { // Launch CUDA kernel
>         try! fill<<<(blockSize, blockCount)>>>[
>             .pointer(to: &self), .value(value), .value(Int64(count))
>         ]
>     }

This looks like a compiler bug. Assuming `sync`'s closure is not @escaping, it should be allowed to capture self. If you haven't yet, would you be able to file a bug at bugs.swift.org? Does making a shadow copy work as a workaround, something like:

var tmpSelf = self
device.sync {... &tmpSelf ...}
self = tmpSelf

Note that, independently, this part looks fishy:

> try! fill<<<(blockSize, blockCount)>>>[
>             .pointer(to: &self)

UnsafePointers formed by passing an argument inout are not valid after the called function returns, so if this function is forming and returning a pointer, it will likely result in undefined behavior. You should use `withUnsafePointer(&self) { p in ... }` to get a usable pointer.

-Joe


More information about the swift-users mailing list