Skip to content

Commit 6f6ab4a

Browse files
committed
[NCGenerics] add basic end-to-end test
1 parent afb6685 commit 6f6ab4a

File tree

1 file changed

+118
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)