SE-0446: Nonescapable Types

Hello, I'd be interested in hearing thoughts about the interaction of non-Escapable Types and Region-Based Isolation. I known this escapes the focus of the proposal, but, well, I ask anyway.

According to SE-0414, Rules for Merging Isolation Regions:

Given a function f with arguments ai and result that is assigned to
variable y:

y = f(a0, ..., an)
  1. All regions of non-Sendable arguments ai are merged into one larger
    region after f executes.
  2. If any of ai are non-Sendable and y is non-Sendable, then y is in
    the same merged region as ai. If all of the ai are Sendable,
    then y is within a new disconnected region that consists only of y.
  3. [...]

Should the rule 2 still hold if an argument is non-Sendable, and non-Escapable?

The reason why I ask is that it is currently impossible to write the following method when Resource is not Sendable:

func accessResource<T>(
  _ work: sending @escaping (Resource) -> sending T
) async throw -> sending T

The reason why it is not possible is that at use site, all values grabbed from the "resource" are in its Region, and can not be sent out:

accessResource { rez in
    let value = makeValue(resource: rez)
    return value // warning or error
}

The only way this API must be written today if full of Sendable constraints:

func accessResource<T: Sendable>(
  _ work: @escaping @Sendable (Resource) -> T
) async throw -> T

We know "sending" was invented in order to help dealing with non-Sendable types, so this version is strictly inferior to the previous one that uses sending (but can't be made to work when Resource is not Sendable).

If the Resource type was made non-Escapable as well, would it be a sufficient guarantee that it can't "pollute" the value according to Region-Based Isolation, and could thus be "sent" without compiler warning or error?

2 Likes