You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two are fixes needed in most of the `RawSpan` and `Span` initializers. For example:
```
let baseAddress = buffer.baseAddress
let span = RawSpan(_unchecked: baseAddress, byteCount: buffer.count)
// As a trivial value, 'baseAddress' does not formally depend on the
// lifetime of 'buffer'. Make the dependence explicit.
self = _overrideLifetime(span, borrowing: buffer)
```
Fix#1. baseAddress needs to be a variable
`span` has a lifetime dependence on `baseAddress` via its
initializer. Therefore, the lifetime of `baseAddress` needs to include the call
to `_overrideLifetime`. The override sets the lifetime dependency of its result,
not its argument. It's argument still needs to be non-escaping when it is passed
in.
Alternatives:
- Make the RawSpan initializer `@_unsafeNonescapableResult`.
Any occurrence of `@_unsafeNonescapableResult` actually signals a bug. We never
want to expose this annotation.
In addition to being gross, it would totally disable enforcement of the
initialized span. But we really don't want to side-step `_overrideLifetime`
where it makes sense. We want the library author to explicitly indicate that
they understand exactly which dependence is unsafe. And we do want to
eventually expose the `_overrideLifetime` API, which needs to be well
understood, supported, and tested.
- Add lifetime annotations to a bunch of `UnsafePointer`-family APIs so the
compiler can see that the resulting pointer is derived from self, where self is
an incoming `Unsafe[Buffer]Pointer`. This would create a massive lifetime
annotation burden on the `UnsafePointer`-family APIs, which don't really have
anything to do with lifetime dependence. It makes more sense for the author of
`Span`-like APIs to reason about pointer lifetimes.
Fix#2. `_overrideLifetime` changes the lifetime dependency of span to be on an
incoming argument rather than a local variable.
This makes it legal to escape the function (by assigning it to self). Remember
that self is implicitly returned, so the `@lifetime(borrow buffer)` tells the
compiler that `self` is valid within `buffer`'s borrow scope.
0 commit comments