Skip to content

Commit 6fe00b6

Browse files
committed
[NoncopyableGenerics] add basic end-to-end test
1 parent 3f93370 commit 6fe00b6

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -sil-verify-all -enable-experimental-feature NoncopyableGenerics)
2+
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all -enable-experimental-feature NoncopyableGenerics)
3+
4+
// REQUIRES: executable_test
5+
// REQUIRES: asserts
6+
7+
// Needed due to limitations of autoclosures and noncopyable types.
8+
func eagerAssert(_ b: Bool, _ line: Int = #line) {
9+
guard b else { fatalError("assertion failure on line \(line)") }
10+
}
11+
12+
///---------------------
13+
/// MARK: a Swift x Haskell limited-edition stdlib
14+
/// ---------------------
15+
16+
17+
18+
/// MARK: Ord aka 'Comparable'
19+
protocol Ord: ~Copyable {
20+
func compare(_ other: borrowing Self) -> Ordering
21+
}
22+
23+
enum Ordering {
24+
case LT
25+
case EQ
26+
case GT
27+
28+
static func compare<T: Comparable>(_ a: borrowing T, _ b: borrowing T) -> Ordering {
29+
if (a < b) { return .LT }
30+
if (a > b) { return .GT }
31+
eagerAssert(a == b)
32+
return .EQ
33+
}
34+
}
35+
36+
extension Ord {
37+
static func <(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
38+
return a.compare(b) == .LT
39+
}
40+
static func <=(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
41+
return !(a > b)
42+
}
43+
static func >(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
44+
return a.compare(b) == .GT
45+
}
46+
static func >=(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
47+
return !(a < b)
48+
}
49+
static func ==(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
50+
a.compare(b) == .EQ
51+
}
52+
static func !=(_ a: borrowing Self, _ b: borrowing Self) -> Bool {
53+
!(a == b)
54+
}
55+
}
56+
57+
/// MARK: Maybe aka 'Optional'
58+
enum Maybe<Val: ~Copyable>: ~Copyable {
59+
case just(Val)
60+
case none
61+
62+
// NOTE: a 'consuming' version of the unfortunately 'borrowing' map from the stdlib.
63+
consuming func consumingMap<U: ~Copyable>(_ fn: (consuming Val) throws -> U) rethrows -> Maybe<U> {
64+
// rdar://117638878 (MoveOnlyAddressChecker crashes with generic associated value in enum)
65+
fatalError("need to fix rdar://117638878")
66+
// return switch consume self {
67+
// case let .just(val): .just(try fn(val))
68+
// case .none: .none
69+
// }
70+
}
71+
}
72+
73+
// NOTE: temporary
74+
extension Maybe: Copyable where Val: Copyable {}
75+
76+
77+
/// MARK: beginning of tests
78+
79+
struct FileDescriptor: ~Copyable, Ord {
80+
let id: Int
81+
82+
func compare(_ other: borrowing FileDescriptor) -> Ordering {
83+
return .compare(id, other.id)
84+
}
85+
86+
deinit { print("calling deinit!") }
87+
}
88+
89+
class Shared<T: ~Copyable> {
90+
let value: T
91+
init(_ val: consuming T) { self.value = val }
92+
func borrow<V>(_ f: (borrowing T) throws -> V) rethrows -> V {
93+
return try f(value)
94+
}
95+
}
96+
97+
defer { testOrd() }
98+
func testOrd() {
99+
let stderr = Shared(FileDescriptor(id: 1))
100+
let stdout = Shared(FileDescriptor(id: 0))
101+
stdout.borrow { out in
102+
stderr.borrow { err in
103+
eagerAssert(err > out)
104+
eagerAssert(out < err)
105+
eagerAssert(out != err)
106+
}
107+
}
108+
}
109+
110+
defer { testMaybe() }
111+
func testMaybe() {
112+
let mayb = Maybe.just(FileDescriptor(id: 0));
113+
switch consume mayb {
114+
case let .just(fd): eagerAssert(fd.id == 0)
115+
case .none: eagerAssert(false)
116+
}
117+
}

0 commit comments

Comments
 (0)