From bdd4f1ffb63a28d9896c213d1bcfa17e3420f433 Mon Sep 17 00:00:00 2001
From: Andrew Trick <atrick@apple.com>
Date: Fri, 3 Jan 2025 18:47:20 -0800
Subject: [PATCH] Add test cases for Span-providing properties.

---
 .../lifetime_dependence/stdlib_span.swift     | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 test/SILOptimizer/lifetime_dependence/stdlib_span.swift

diff --git a/test/SILOptimizer/lifetime_dependence/stdlib_span.swift b/test/SILOptimizer/lifetime_dependence/stdlib_span.swift
new file mode 100644
index 0000000000000..f451a193065d2
--- /dev/null
+++ b/test/SILOptimizer/lifetime_dependence/stdlib_span.swift
@@ -0,0 +1,66 @@
+// RUN: %target-swift-frontend %s -emit-sil \
+// RUN:   -o /dev/null \
+// RUN:   -verify \
+// RUN:   -sil-verify-all \
+// RUN:   -module-name test \
+// RUN:   -disable-access-control \
+// RUN:   -enable-experimental-feature LifetimeDependence \
+// RUN:   -enable-experimental-feature Span
+
+// REQUIRES: swift_in_compiler
+// REQUIRES: swift_feature_LifetimeDependence
+// REQUIRES: swift_feature_Span
+
+// Test dependencies on the standard library Span APIs.
+
+// =============================================================================
+// Span-providing properties
+// =============================================================================
+
+extension UnsafeRawBufferPointer {
+  @available(SwiftStdlib 6.1, *)
+  public var storage: RawSpan {
+    @lifetime(borrow self)
+    get {
+      let span = RawSpan(_unsafeBytes: self)
+      return _overrideLifetime(span, borrowing: self)
+    }
+  }
+}
+
+@available(SwiftStdlib 6.1, *)
+func read(_ span: RawSpan) {}
+
+@available(SwiftStdlib 6.1, *)
+func testUBPStorage(ubp: UnsafeRawBufferPointer) {
+  // 'span' is valid within the lexical scope of variable 'ubp', which is the entire function.
+  let span = ubp.storage
+  read(span)
+}
+
+@available(SwiftStdlib 6.1, *)
+@lifetime(borrow ubp)
+func testUBPStorageReturn(ubp: UnsafeRawBufferPointer) -> RawSpan {
+  // 'storage' can be returned since the function's return value also has a dependence on 'ubp'.
+  return ubp.storage
+}
+
+@available(SwiftStdlib 6.1, *)
+@lifetime(borrow ubp)
+func testUBPStorageCopy(ubp: UnsafeRawBufferPointer) -> RawSpan {
+  let localBuffer = ubp
+  return localBuffer.storage // expected-error {{lifetime-dependent value escapes its scope}}
+                             // expected-note  @-2{{it depends on the lifetime of variable 'localBuffer'}}
+                             // expected-note  @-2{{this use causes the lifetime-dependent value to escape}}
+}
+
+@available(SwiftStdlib 6.1, *)
+func testUBPStorageEscape(array: [Int64]) {
+  var span = RawSpan()
+  array.withUnsafeBytes {
+    span = $0.storage // expected-error {{lifetime-dependent value escapes its scope}}
+                      // expected-note  @-2{{it depends on the lifetime of argument '$0'}}
+                      // expected-note  @-2{{this use causes the lifetime-dependent value to escape}}
+  }
+  read(span)
+}