<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi<div class=""><br class=""></div><div class="">I had the need recently to mark a value-type as @noescape, but we only allow that for closure-types. I would like to propose that we allow any parameter to any function to be marked @noescape (by default, unlike closures, they would be potentially-escaping).</div><div class=""><br class=""></div><div class="">The standard library has several locations where this could be useful, for example Array’s withUnsafeBufferPointer() method:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">let&nbsp;array = [1,&nbsp;2,&nbsp;3]</font></div><div class=""><font face="Courier" class="">var&nbsp;ptr :&nbsp;UnsafeBufferPointer&lt;Int&gt;</font></div><div class=""><font face="Courier" class="">array.withUnsafeBufferPointer&nbsp;{ ptr = $0 }</font></div><div class=""><font face="Courier" class="">ptr.count // has escaped the withUnsafeBufferPointer context</font></div><div class=""><font face="Courier" class=""><br class=""></font></div></blockquote>If we could mark the pointer as @noescape, the assignment to ptr would be a compile-time error.<div class=""><br class=""></div><div class="">My own (non-stdlib) case was rather complex: we had a class with a big data-table, and clients could asynchronously request data. They would get a callback inside a synchronised window during which they could access the data, but by that time they may have moved on and not care any more. So we decided the callback should tell the clients which data was available, and rather than pass the data itself, pass an accessor which they can use if they still care. Over time, we added more operations that they could perform within their little slice of exclusive access, and wrapped those accessors up in a struct (with a private initialiser). Unfortunately, it’s now no-longer a closure type, and we can’t annotate that the view object clients receive is only valid for the duration of the callback and should not be captured.</div><div class=""><br class=""></div><div class="">Something like this:</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><br class=""></div><div class=""><font face="Courier" class="">class Database&lt;Value&gt; {</font></div><div class=""><br class=""></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; public func editRecord&lt;T&gt;(at index: RecordIndex, with block: (Record&lt;Value&gt;)-&gt;T) -&gt; T {</font></div></blockquote><div class=""><span style="font-family: Courier;" class="">&nbsp; &nbsp; &nbsp;&nbsp;</span></div><div class=""><span style="font-family: Courier;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Must be synchronised to the DB’s internal queue</span></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dbQueue.sync {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let view = Record(database: self, index: index)</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return block(view)</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; fileprivate func _editValue(at index: RecordIndex, newValue: Value) {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; // precondition: on queue&nbsp;‘dbQueue'</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; fileprivate func _deleteRecord(at index: RecordIndex) {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; // precondition: on queue&nbsp;‘dbQueue'</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div></div><div class=""><span style="font-family: Courier;" class="">}</span></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">struct Record&lt;Value&gt; {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; private let database: DB</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; private let index: RecordIdx</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; public var value : Value {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; get { return database._getValue(at: index) }</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;nonmutating&nbsp;set { database._deleteValue(at: index) }</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div><div class=""><span style="font-family: Courier;" class="">&nbsp; &nbsp; public func delete() { database._deleteValue(at: index) }</span></div><div class=""><font face="Courier" class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">// Usage example.</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">let recordIdx = database.queryRecord(...)</font></div><div class=""><font face="Courier" class="">database.editRecord(at: recordIdx) {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; $0.value = “Hello!”</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; // $0 (‘Record’) could escape this closure and be used to make&nbsp;non-synchronised edits</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><br class=""></div></blockquote><div class=""><br class=""></div><div class="">Maybe the new memory-model will solve these problems; I can’t find a single, clear proposal (that I can understand…)</div><div class=""><br class=""></div><div class="">Since it has standard-library consequences, it would be ABI-breaking.</div><div class=""><div class=""><br class=""></div><div class="">- Karl</div><div class=""><br class=""></div></div></body></html>