[Pitch] Introduce a way to annotate functions that are called at most once

I think it comes down to how far we want to trust non-Swift code to actually live up to its annotations. “Trust but verify” is probably the right policy, i.e. we should add the dynamic checks that would be necessary for converting to a copyable type. It’s just a relaxed atomic flag, so pretty modest.

2 Likes

For example, a block parameter marked with NS_NOESCAPE still causes Swift to do a similar dynamic check to the one done by withoutActuallyEscaping at runtime.

2 Likes

I agree with the rest of this, but I find this idea objectionable, although it depends on definitions.

I see a "true-linear" type as being like DI, where it absolutely must happen for safety. Like DI, it should be possible for unsafe code to assume this will not happen. I'd only be inclined to call this linear:

but not this:

An asserting deinit is enough to ensure the closure is never dropped but not enough to ensure it is never "forgotten" (like you mention). We can say forgotten (meaning, not dropped, but not going to be consumed either) is safe, but it is not safe enough for things like DI. I don't see the motivation to enable this conversion to Escapable exactly once functions via a dynamic check when they would not be able to do operations like DI or consume linear values anymore. It isn't useful from a safety perspective...

AFAIK, it would not actually change what unsafe code can assume of safe code to allow Escapable "must consume" to be captured in at most once, since it already needed to assume it was possible not to use it.

If we wanted to enable this conversion such that it does allow unsafe code to make more assumptions of safe code, I think we need an external check; convert to Escapable which builds a new closure body which sets a bit locally when invoked, pass that as a parameter, then when control flow returns trap if the "consumed" bit was not set. But Task and other motivations for this conversion would fail this test afaik!

I rambled more here, I made a distinction between weakly linear and linear...