# Is it possible to capture a \`borrowing\` parameter in a non-escaping closure?

**URL:** <https://forums.swift.org/t/is-it-possible-to-capture-a-borrowing-parameter-in-a-non-escaping-closure/72967>\
**Category:** Using Swift\
**Tags:** borrowing\
**Created:** [July 6, 2024, 12:36am UTC](https://forums.swift.org/t/is-it-possible-to-capture-a-borrowing-parameter-in-a-non-escaping-closure/72967 "2024-07-06T00:36:18Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [July 8, 2024, 4:05pm UTC](https://forums.swift.org/t/is-it-possible-to-capture-a-borrowing-parameter-in-a-non-escaping-closure/72967/3 "2024-07-08T16:05:48Z")

</div>

Hmm... from the review on Noncopyable structs:

> [@\[Second review\] SE-0390: Noncopyable structs and enums](https://forums.swift.org/t/second-review-se-0390-noncopyable-structs-and-enums/63866/137):
>
> Nonescaping closures borrow their captures, either immutably or mutably as needed, for the duration of the call the closure is passed to, and escaping closures impose an indefinite borrow on the capture.

So I think the thing I want to do should be allowed (a nonescaping closure should borrow its capture, so it's fine that the captured value is itself also borrowed from the caller).

And from the review of borrow/take parameter modifiers:

> [@SE-0377: borrow and take parameter ownership modifiers](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/18):
>
> But I have one open question about closure capture lists. Is it possible to have `take/borrow` modifiers on capture list elements? We had this discussion over in [this thread](https://forums.swift.org/t/passing-asynciterator-to-an-async-method/61267/) where we were talking about a safe way to pass `AsyncIterator`s between `Task`s while retaining the 1:1 relation ship.

(I don't see that there was any answer to that question, but I also think it's sensible thing to allow explicit ownership modifiers in capture lists).

The fact that captures are able to perform implicit copies seems like a straight bug, as it's possible to use it to crash the compiler (nightly):

```swift
struct Foo<T: ~Copyable>: ~Copyable {}

func huh<T: ~Copyable>(_ source: borrowing Foo<T>) {
  let process: (borrowing Foo<T>) -> () -> Void = {
    s in { _ = consume s } // This should not be valid!
  }
  process(source)()
}

/swift-frontend: /home/build-user/swift/lib/SILGen/SILGenFunction.cpp:910: void swift::Lowering::SILGenFunction::emitCaptures(swift::SILLocation, swift::SILDeclRef, swift::Lowering::CaptureEmission, SmallVectorImpl<swift::Lowering::ManagedValue> &): Assertion `val->getType().isAddress() && "no address for captured var!"' failed.

```

[Godbolt](https://swift.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:swift,selection:(endColumn:2,endLineNumber:8,positionColumn:1,positionLineNumber:1,selectionStartColumn:2,selectionStartLineNumber:8,startColumn:1,startLineNumber:1),source:'struct+Foo%3CT:+~Copyable%3E:+~Copyable+%7B%7D%0A%0Afunc+huh%3CT:+~Copyable%3E(_+source:+borrowing+Foo%3CT%3E)+%7B%0A++let+process:+(borrowing+Foo%3CT%3E)+-%3E+()+-%3E+Void+%3D+%7B%0A++++s+in+%7B+_+%3D+consume+s+%7D%0A++%7D%0A++process(source)()%0A%7D'),l:'5',n:'1',o:'Swift+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:swiftnightly,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:swift,libs:!(),options:'',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+swiftc+nightly+(Editor+%231)',t:'0')),header:(),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+swiftc+5.10',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+swiftc+nightly+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

For copyable types it does not crash (as shown in the previous post), but the implicit copy behaviour is actually _less desirable_ than crashing IMO, because it means it would be a source-breaking change if we wanted to fix this and remove the implicit copying.

---

_[View the full topic](https://forums.swift.org/t/is-it-possible-to-capture-a-borrowing-parameter-in-a-non-escaping-closure/72967)._
