Skip to content

Commit 60d9e61

Browse files
committed
prevent more synthesized conformances for move-only types
enums with only cases that have no associated values automatically get Equatable and Hashable synthesized. That's not valid for move-only enums, so we were just getting errors about broken conformances when we hadn't specified any explicitly. This PR just prevents the synthesis from the start so we don't get any errors. fixes rdar://104986597
1 parent 5b7eada commit 60d9e61

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,13 @@ void NominalTypeDecl::prepareConformanceTable() const {
10561056
if (!proto)
10571057
return;
10581058

1059+
// No synthesized conformances for move-only nominals.
1060+
if (isMoveOnly()) {
1061+
// assumption is Sendable gets synthesized elsewhere.
1062+
assert(!proto->isSpecificProtocol(KnownProtocolKind::Sendable));
1063+
return;
1064+
}
1065+
10591066
if (protocols.count(proto) == 0) {
10601067
ConformanceTable->addSynthesizedConformance(
10611068
mutableThis, proto, mutableThis);

test/Sema/moveonly_restrictions.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,33 @@ struct MoveOnlyStructP : P { // expected-error {{move-only struct 'MoveOnlyStruc
182182
}
183183
@_moveOnly
184184
enum MoveOnlyEnumP : P {} // expected-error {{move-only enum 'MoveOnlyEnumP' cannot conform to 'P'}}
185+
186+
// ensure there is no auto-synthesis of Equatable, Hashable, etc, for this move-only enum,
187+
// because it normally would be synthesized since it only has cases without associated values.
188+
@_moveOnly
189+
enum Color {
190+
case red
191+
case green
192+
case blue
193+
194+
static func same(_ c1: __shared Color, c2: __shared Color) -> Bool {
195+
return c1 == c2
196+
// expected-error@-1 {{binary operator '==' cannot be applied to two 'Color' operands}}
197+
}
198+
}
199+
200+
@_moveOnly
201+
enum StrengthLevel: Int { // ensure move-only raw enums do not conform to RawRepresentable
202+
case none = 0
203+
case low
204+
case high
205+
206+
static func lowEnergy() {
207+
_ = StrengthLevel(rawValue: 1)
208+
// expected-error@-1 {{'StrengthLevel' cannot be constructed because it has no accessible initializers}}
209+
}
210+
}
211+
212+
213+
214+

0 commit comments

Comments
 (0)