ideally i think you'd use an ~Escapable type since that's the tool being designed to support these use cases (~Copyable does enforce nonescaping use in many instances, but in general the concepts are distinct). but per my understanding, such types still require use of the -enable-experimental-feature Lifetimes flag so that lifetime dependencies can be recorded and enforced. without that feature, it seems you can't even initialize such types in many (all?) cases. if you have a tolerance for that, you could try turning it on and using a non-escapable wrapper to vend to your closure. i was playing with that here, but i'm not sure it does quite what you want.
if you can't get the static checking to work, you could potentially try runtime enforcement. you'd pass a reference type wrapper to your clients, and then when the closure has run, perform the isKnownUniquelyReferenced check on it to infer whether it escaped.
Thank you for the example - I played a bit and seems that actually might work for my cases.
I guess ~Escapable attribute is something that I am looking for and seems works in 6.2 to some extent (maybe with less diagnostics and some things to improve like in godbolt example)...
Though, I am a bit confused that this is an attribute for an object rather than for argument in a function signature. I would expect that to be similar to sending for arguments or @escaping for closures, e.g. (nonescapable S) -> () and that it would work for classes as well.
But I guess I need to read the thread about ~Escapable to understand the reasoning for that...