Files
swift-mirror/test/SILOptimizer/moveonly_borrowing_switch_yield.swift
Kavon Farvardin 04454054b7 NCGenerics: add availability checking
Not all runtimes can correctly operate with types that use noncopyable
generics. When the generic argument of a type is noncopyable, old
runtimes can't recognize that to correctly check conformances that may
be conditional on those arguments being Copyable, etc.

resolves rdar://126239335
2024-07-07 15:38:00 -07:00

108 lines
2.3 KiB
Swift

// RUN: %target-swift-frontend -parse-as-library -O -emit-sil -verify %s -disable-availability-checking
extension List {
var peek: Element {
_read {
switch self.head {
case .empty: fatalError()
case .more(let box):
yield box.wrapped.element
}
//yield head.peek
}
}
}
struct Box<Wrapped: ~Copyable>: ~Copyable {
private let _pointer: UnsafeMutablePointer<Wrapped>
init(_ element: consuming Wrapped) {
_pointer = .allocate(capacity: 1)
print("allocatin", _pointer)
_pointer.initialize(to: element)
}
deinit {
print("not deallocatin", _pointer)
_pointer.deinitialize(count: 1)
_pointer.deallocate()
}
consuming func move() -> Wrapped {
let wrapped = _pointer.move()
print("deallocatin", _pointer)
_pointer.deallocate()
discard self
return wrapped
}
var wrapped: Wrapped {
_read { yield _pointer.pointee }
}
}
struct List<Element>: ~Copyable {
var head: Link<Element> = .empty
var bool = false
}
enum Link<Element>: ~Copyable {
case empty
case more(Box<Node<Element>>)
var peek: Element {
_read {
switch self {
case .empty: fatalError()
case .more(let box):
yield box.wrapped.element
}
}
}
}
struct Node<Element>: ~Copyable {
let element: Element
let next: Link<Element>
var bool = true
}
extension List {
mutating func append(_ element: consuming Element) {
self = List(head: .more(Box(Node(element: element, next: self.head))))
}
var isEmpty: Bool {
switch self.head {
case .empty: true
default: false
}
}
mutating func pop() -> Element {
let h = self.head
switch consume h {
case .empty: fatalError()
case .more(let box):
let node = box.move()
self = .init(head: node.next)
return node.element
}
}
}
@main
struct Main {
static func main() {
var l: List<Int> = .init()
l.append(1)
l.append(2)
l.append(3)
print(l.pop())
print(l.pop())
print(l.pop())
print(l.isEmpty)
}
}