Skip to content

Commit fd950eb

Browse files
committed
Implement Tuple Comparable Conformance
Add protocol witnesses for all Comparable requirements
1 parent df9778e commit fd950eb

11 files changed

+884
-154
lines changed

include/swift/Runtime/BuiltinProtocolConformances.h

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,22 @@ namespace swift {
2525
#define XSTR(a) STR(a)
2626
#define SYMBOL(name) XSTR(__USER_LABEL_PREFIX__) name
2727

28-
// public protocol Equatable {}
29-
#define SWIFT_EQUATABLE_MANGLING SQ
30-
3128
#define PROTOCOL_DESCRIPTOR_MANGLING Mp
3229

3330
#define PROTOCOL_DESCRIPTOR_SYM(Proto) \
3431
MANGLE_SYM(MANGLING_CONCAT2(Proto, PROTOCOL_DESCRIPTOR_MANGLING))
3532

36-
#define EQUATABLE_PROTOCOL_DESCRIPTOR \
37-
PROTOCOL_DESCRIPTOR_SYM(SWIFT_EQUATABLE_MANGLING)
33+
//===----------------------------------------------------------------------===//
34+
// Tuple Equatable Conformance
35+
//===----------------------------------------------------------------------===//
36+
37+
// public protocol Equatable {}
38+
#define SWIFT_EQUATABLE_MANGLING SQ
39+
40+
#define EQUATABLE_DESCRIPTOR PROTOCOL_DESCRIPTOR_SYM(SWIFT_EQUATABLE_MANGLING)
41+
42+
#define EQUATABLE_DESCRIPTOR_SYMBOL SYMBOL("$sSQMp")
43+
#define EQUATABLE_EE_METHOD_DESCRIPTOR SYMBOL("$sSQ2eeoiySbx_xtFZTq")
3844

3945
#define TUPLE_EQUATABLE_CONF SYMBOL("_swift_tupleEquatable_conf")
4046
#define TUPLE_EQUATABLE_EQUALS SYMBOL("_swift_tupleEquatable_equals")
@@ -46,6 +52,66 @@ bool _swift_tupleEquatable_equals(OpaqueValue *tuple1, OpaqueValue *tuple2,
4652
SWIFT_CONTEXT Metadata *swiftSelf,
4753
Metadata *Self, void *witnessTable);
4854

55+
//===----------------------------------------------------------------------===//
56+
// Tuple Comparable Conformance
57+
//===----------------------------------------------------------------------===//
58+
59+
// public protocol Comparable {}
60+
#define SWIFT_COMPARABLE_MANGLING SL
61+
62+
#define COMPARABLE_DESCRIPTOR PROTOCOL_DESCRIPTOR_SYM(SWIFT_COMPARABLE_MANGLING)
63+
64+
#define COMPARABLE_DESCRIPTOR_SYMBOL SYMBOL("$sSLMp")
65+
66+
#define COMPARABLE_BASE_CONFORMANCE_DESCRIPTOR SYMBOL("$sSLSQTb")
67+
#define COMPARABLE_LT_METHOD_DESCRIPTOR SYMBOL("$sSL1loiySbx_xtFZTq")
68+
#define COMPARBALE_LTE_METHOD_DESCRIPTOR SYMBOL("$sSL2leoiySbx_xtFZTq")
69+
#define COMPARABLE_GTE_METHOD_DESCRIPTOR SYMBOL("$sSL2geoiySbx_xtFZTq")
70+
#define COMPARABLE_GT_METHOD_DESCRIPTOR SYMBOL("$sSL1goiySbx_xtFZTq")
71+
72+
#define TUPLE_COMPARABLE_CONF SYMBOL("_swift_tupleComparable_conf")
73+
#define TUPLE_COMPARABLE_ASSOCIATEDCONFORMANCE \
74+
SYMBOL("associated conformance _swift_tupleComparable")
75+
#define TUPLE_COMPARABLE_BASEACCESSOREQUATABLE \
76+
SYMBOL("_swift_tupleComparable_baseAccessorEquatable")
77+
#define TUPLE_COMPARABLE_LESSTHAN SYMBOL("_swift_tupleComparable_lessThan")
78+
#define TUPLE_COMPARABLE_LESSTHANOREQUAL \
79+
SYMBOL("_swift_tupleComparable_lessThanOrEqual")
80+
#define TUPLE_COMPARABLE_GREATERTHANOREQUAL \
81+
SYMBOL("_swift_tupleComparable_greaterThanOrEqual")
82+
#define TUPLE_COMPARABLE_GREATERTHAN \
83+
SYMBOL("_swift_tupleComparable_greaterThan")
84+
85+
/// The protocol witness for static Swift.Comparable.< infix(A, A) -> Swift.Bool
86+
/// in conformance (A...): Swift.Comparable in Swift.
87+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
88+
bool _swift_tupleComparable_lessThan(OpaqueValue *tuple1, OpaqueValue *tuple2,
89+
SWIFT_CONTEXT Metadata *swiftSelf,
90+
Metadata *Self, void *witnessTable);
91+
92+
/// The protocol witness for static Swift.Comparable.<= infix(A, A) -> Swift.Bool
93+
/// in conformance (A...): Swift.Comparable in Swift.
94+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
95+
bool _swift_tupleComparable_lessThanOrEqual(OpaqueValue *tuple1,
96+
OpaqueValue *tuple2,
97+
SWIFT_CONTEXT Metadata *swiftSelf,
98+
Metadata *Self, void *witnessTable);
99+
100+
/// The protocol witness for static Swift.Comparable.>= infix(A, A) -> Swift.Bool
101+
/// in conformance (A...): Swift.Comparable in Swift.
102+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
103+
bool _swift_tupleComparable_greaterThanOrEqual(OpaqueValue *tuple1,
104+
OpaqueValue *tuple2,
105+
SWIFT_CONTEXT Metadata *swiftSelf,
106+
Metadata *Self, void *witnessTable);
107+
108+
/// The protocol witness for static Swift.Comparable.> infix(A, A) -> Swift.Bool
109+
/// in conformance (A...): Swift.Comparable in Swift.
110+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
111+
bool _swift_tupleComparable_greaterThan(OpaqueValue *tuple1, OpaqueValue *tuple2,
112+
SWIFT_CONTEXT Metadata *swiftSelf,
113+
Metadata *Self, void *witnessTable);
114+
49115
} // end namespace swift
50116

51117
#endif

lib/AST/Module.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,25 +1014,29 @@ LookupConformanceInModuleRequest::evaluate(
10141014
return ProtocolConformanceRef(protocol);
10151015

10161016
// Tuples have builtin conformances implemented within the runtime.
1017-
// These conformances so far consist of Equatable.
1017+
// These conformances so far consist of Equatable and Comparable.
10181018
if (auto tuple = type->getAs<TupleType>()) {
1019-
if (protocol == ctx.getProtocol(KnownProtocolKind::Equatable)) {
1020-
SmallVector<ProtocolConformanceRef, 4> elementConformances;
1019+
auto equatable = ctx.getProtocol(KnownProtocolKind::Equatable);
1020+
auto comparable = ctx.getProtocol(KnownProtocolKind::Comparable);
10211021

1022-
// Ensure that every element in this tuple conforms to Equatable.
1023-
for (auto eltTy : tuple->getElementTypes()) {
1024-
auto conformance = mod->lookupConformance(eltTy, protocol);
1022+
if (protocol != equatable && protocol != comparable)
1023+
return ProtocolConformanceRef::forInvalid();
10251024

1026-
if (conformance.isInvalid())
1027-
return ProtocolConformanceRef::forInvalid();
1025+
SmallVector<ProtocolConformanceRef, 4> elementConformances;
10281026

1029-
elementConformances.push_back(conformance);
1030-
}
1027+
// Ensure that every element in this tuple conforms to said protocol.
1028+
for (auto eltTy : tuple->getElementTypes()) {
1029+
auto conformance = mod->lookupConformance(eltTy, protocol);
1030+
1031+
if (conformance.isInvalid())
1032+
return ProtocolConformanceRef::forInvalid();
10311033

1032-
auto conformance = ctx.getBuiltinConformance(tuple, protocol,
1033-
elementConformances);
1034-
return ProtocolConformanceRef(conformance);
1034+
elementConformances.push_back(conformance);
10351035
}
1036+
1037+
auto conformance = ctx.getBuiltinConformance(tuple, protocol,
1038+
elementConformances);
1039+
return ProtocolConformanceRef(conformance);
10361040
}
10371041

10381042
auto nominal = type->getAnyNominal();

lib/IRGen/IRGenMangler.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,21 @@ std::string IRGenMangler::mangleProtocolConformanceDescriptor(
156156

157157
if (conformance->getType()->is<TupleType>()) {
158158
auto equatable = ctx.getProtocol(KnownProtocolKind::Equatable);
159+
auto comparable = ctx.getProtocol(KnownProtocolKind::Comparable);
159160

160161
if (conformance->getProtocol() == equatable) {
161162
return "_swift_tupleEquatable_conf";
162163
}
163164

164-
llvm_unreachable("mangling unknown tuple witness table protocol");
165+
if (conformance->getProtocol() == comparable) {
166+
return "_swift_tupleComparable_conf";
167+
}
168+
169+
llvm_unreachable("mangling conformance descriptor for unknown tuple \
170+
protocol");
165171
}
166172

167-
llvm_unreachable("mangling unknown builtin witness table type");
173+
llvm_unreachable("mangling conformance descriptor for unknown builtin type");
168174
}
169175

170176
beginMangling();

0 commit comments

Comments
 (0)