// RUN: %empty-directory(%t) // RUN: split-file %s %t // RUN: %target-swift-frontend %t/Library.swift -g -enable-experimental-feature Embedded -enable-experimental-feature Lifetimes -c -parse-as-library -o %t/Library.o -emit-module // RUN: %target-swift-frontend -I %t %t/Application.swift -g -enable-experimental-feature Embedded -enable-experimental-feature Lifetimes -c -o %t/main.o // RUN: %target-clang %target-clang-resource-dir-opt %t/main.o -o %t/a.out -dead_strip // RUN: %target-run %t/a.out | %FileCheck %s // REQUIRES: swift_in_compiler // REQUIRES: executable_test // REQUIRES: swift_feature_Embedded // REQUIRES: swift_feature_Lifetimes //--- Library.swift @safe public struct UniqueBuffer: ~Copyable { @usableFromInline let buffer: UnsafeMutableBufferPointer private init(_uninitializedCount count: Int) { buffer = UnsafeMutableBufferPointer.allocate(capacity: count) } @inline(__always) @_alwaysEmitIntoClient deinit { buffer.deinitialize().deallocate() } /// Allocate a new buffer with `count` elements and call the given `body` function to produce an element /// for each entry. public init(count: Int, body: (Int) throws(E) -> Element) throws(E) { self.init(_uninitializedCount: count) for i in 0.. Element { unsafeAddress { precondition(i >= 0 && i < count) return UnsafePointer(buffer.baseAddress! + i) } unsafeMutableAddress { precondition(i >= 0 && i < count) return buffer.baseAddress! + i } } /// Index into this data structure. public typealias Index = Int /// Indices into this buffer. public var indices: Range { 0.. { @_lifetime(borrow self) borrowing get { buffer.span } } /// Produce a mutable span covering all of the elements in the buffer. public var mutableSpan: MutableSpan { @_lifetime(&self) mutating get { buffer.mutableSpan } } /// Run the body closure with an unsafe buffer pointer referencing the storage of this unique buffer. /// /// Clients should prefer the `mutableSpan` property, which provides memory safety. @unsafe public mutating func withUnsafeMutableBufferPointer(_ body: (UnsafeMutableBufferPointer) throws(E) -> T) throws(E) -> T { try body(buffer) } } extension UniqueBuffer { /// Allocate a buffer with `count` elements, all of which are a copy of `Element`. public init(repeating element: Element, count: Int) { self.init(_uninitializedCount: count) buffer.initialize(repeating: element) } /// Allocate a buffer that contains a copy of the elements in the given collection. public init(_ collection: some Collection) { self.init(_uninitializedCount: collection.count) _ = buffer.initialize(fromContentsOf: collection) } } public enum BufferWrapper: ~Copyable { case buffer(UniqueBuffer) case empty } extension BufferWrapper { public init(repeating: Int, count: Int) { self = .buffer(UniqueBuffer(repeating: 17, count: 15)) } public var count: Int { switch self { case .buffer(let unique): unique.count case .empty: 0 } } public subscript(index: Int) -> Int { switch self { case .buffer(let unique): unique[index] case .empty: fatalError("boom") } } } public struct BufferOfWrappers: ~Copyable { let inner: UniqueBuffer public init() { inner = UniqueBuffer(count: 17) { index in .empty } } public func countEm() -> Int { return inner.count } } //--- Application.swift import Library func test() { let bufferWrapper = BufferWrapper(repeating: 17, count: 16) var sum = 0 for i in 0..