Skip to content

Commit e9d1128

Browse files
committed
Add _overrideLifetime to Span APIs
The implementation previously took advantage of a missing diagnostic. They returned a borrowed Span with a dependency on a copied argument. This illegally promotes the dependency. This is what the author intended to do (the implementation was correct) but the compiler can't know that so the code needs to be explicit about overriding the lifetime.
1 parent 49a8770 commit e9d1128

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

stdlib/public/core/Span/RawSpan.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,8 @@ extension RawSpan {
711711
public func _extracting(first maxLength: Int) -> Self {
712712
_precondition(maxLength >= 0, "Can't have a prefix of negative length")
713713
let newCount = min(maxLength, byteCount)
714-
return unsafe Self(_unchecked: _pointer, byteCount: newCount)
714+
let newSpan = unsafe Self(_unchecked: _pointer, byteCount: newCount)
715+
return unsafe _overrideLifetime(newSpan, copying: self)
715716
}
716717

717718
/// Returns a span over all but the given number of trailing bytes.
@@ -734,7 +735,8 @@ extension RawSpan {
734735
_precondition(k >= 0, "Can't drop a negative number of bytes")
735736
let droppedCount = min(k, byteCount)
736737
let count = byteCount &- droppedCount
737-
return unsafe Self(_unchecked: _pointer, byteCount: count)
738+
let newSpan = unsafe Self(_unchecked: _pointer, byteCount: count)
739+
return unsafe _overrideLifetime(newSpan, copying: self)
738740
}
739741

740742
/// Returns a span containing the trailing bytes of the span,

stdlib/public/core/Span/Span.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,8 @@ extension Span where Element: ~Copyable {
764764
public func _extracting(first maxLength: Int) -> Self {
765765
_precondition(maxLength >= 0, "Can't have a prefix of negative length")
766766
let newCount = min(maxLength, count)
767-
return unsafe Self(_unchecked: _pointer, count: newCount)
767+
let newSpan = unsafe Self(_unchecked: _pointer, count: newCount)
768+
return unsafe _overrideLifetime(newSpan, copying: self)
768769
}
769770

770771
/// Returns a span over all but the given number of trailing elements.
@@ -786,7 +787,8 @@ extension Span where Element: ~Copyable {
786787
public func _extracting(droppingLast k: Int) -> Self {
787788
_precondition(k >= 0, "Can't drop a negative number of elements")
788789
let droppedCount = min(k, count)
789-
return unsafe Self(_unchecked: _pointer, count: count &- droppedCount)
790+
let newSpan = unsafe Self(_unchecked: _pointer, count: count &- droppedCount)
791+
return unsafe _overrideLifetime(newSpan, copying: self)
790792
}
791793

792794
/// Returns a span containing the final elements of the span,

stdlib/public/core/UTF8Span.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ extension UTF8Span {
181181
public var span: Span<UInt8> {
182182
@lifetime(copy self)
183183
get {
184-
unsafe Span(_unchecked: _unsafeBaseAddress, count: self.count)
184+
let newSpan = unsafe Span<UInt8>(_unchecked: _unsafeBaseAddress, count: self.count)
185+
return unsafe _overrideLifetime(newSpan, copying: self)
185186
}
186187
}
187188

0 commit comments

Comments
 (0)