Conversation
| 2. A function type alias that supports dependence on closure captures: | ||
|
|
||
| `typealias SpanGetter = @lifetime(self) () -> Span<T>` | ||
|
|
||
| Here, we propose repurposing the `self` keyword to refer to the closure context. Use of `self` would obviously be problematic when the function type is a method parameter, but should be reasonably clear when declaring a typealias. | ||
|
|
There was a problem hiding this comment.
Could we reuse some other keyword here?
How about func? That would avoid colliding with parameter names, be unambiguous on method parameters, and still conveys a dependence on "this function/closure".
There was a problem hiding this comment.
I don't want to propose using func in this context but it would be great to air all these alternative on the forums pitch thread once this is posted.
Here's what I have for now:
- A function type alias that supports dependence on closure captures:
typealias SpanGetter = @lifetime(<captures_identifier>) () -> Span<T>
Here, we need to choose a keyword for the <capture_identifier>. We could repurpose the self keyword to refer to the closure context. Use of self would obviously be problematic when the function type is a method parameter, but should be reasonably clear when declaring a typealias. Alternatively, we could introduce a new captures keyword for use in the context.
There was a problem hiding this comment.
As we discussed, let's completely avoid the problem of choosing a "captures identifier" by always assuming that nonescapying function types may depend on captures... I can't come up with a case where it would be important to suppress that dependency
There was a problem hiding this comment.
I came up with this example, where it could be useful to require that the result only depends on the parameters:
struct NE: ~Escapable {}
func takePicker(picker: @_lifetime(copy ne0, copy ne1) (_ ne0: NE, _ ne1: NE) -> NE) {
let x = NE()
let y = NE()
_ = picker(x, y) // Expected behaviour: pick one of x or y.
}
let ne3 = NE()
takePicker { ne0, ne1 in ne3 }I suppose this is more an issue of correctness than safety, since ne3's lifetime can extend past the call to takePicker. For this purpose it would probably always make more sense to use a predicate ((NE, NE) -> Bool) anyway.
There was a problem hiding this comment.
@aidan-hall it's not uncommon for closures to depend only on their arguments. But those closures can still be passed to a function type that depends on its context. Lifetime enforcement only needs to know about the capture dependencies within the scope that contains the closure definition. For function type parameters, it's always safe to assume a dependency on the context even if that dependency disappears in the caller.
| @lifetime(copy self) | ||
| get { ... } | ||
|
|
||
| @lifetime(self: copy newValue) |
There was a problem hiding this comment.
I'm not following this. Mustn't the elements outlive the container? I would expect self: borrow newValue here.
There was a problem hiding this comment.
No, the setter makes a copy of newValue. It doesn't borrow the value passed in.
| init(element: Element) { ... } | ||
| } | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Can the container case really be correctly specified without some form of lifetime variable? If not, then the above example could be a little misleading. We might need a disclaimer here that elaborates how the above is conservative, it fails to permit uses that should be permitted, and that the Future Directions will clarify how this might be improved in the future.
There was a problem hiding this comment.
The example here is not conservative because the "Container" is conditionally Escapable based on its element type, just like Optional. The problem was the use of the term Container, I changed it to "Wrapper"
babb49d to
de61433
Compare
- Incorporate content from previous pitches - Reorganize proposal structure and flow - Add sections covering implicit defaults, closures, and lifetime requirements
de61433 to
1ad4fd1
Compare
Consolidate and expand lifetime dependency proposal