Skip to content

Commit 9243c61

Browse files
committed
Handle Boolean literals as enum raw values.
Fixes rdar://problem/55384273.
1 parent a30f804 commit 9243c61

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ static LiteralExpr *cloneRawLiteralExpr(ASTContext &C, LiteralExpr *expr) {
4343
/*implicit*/ true);
4444
if (floatLit->isNegative())
4545
cast<FloatLiteralExpr>(clone)->setNegative(expr->getLoc());
46+
} else if (auto boolLit = dyn_cast<BooleanLiteralExpr>(expr)) {
47+
clone = new (C) BooleanLiteralExpr(boolLit->getValue(), expr->getLoc(),
48+
/*implicit*/true);
4649
} else {
4750
llvm_unreachable("invalid raw literal expr");
4851
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ namespace {
7575
/// Float and integer literals are additionally keyed by numeric equivalence.
7676
struct RawValueKey {
7777
enum class Kind : uint8_t {
78-
String, Float, Int, Tombstone, Empty
78+
String, Float, Int, Bool, Tombstone, Empty
7979
} kind;
8080

8181
struct IntValueTy {
@@ -101,6 +101,7 @@ struct RawValueKey {
101101
StringRef stringValue;
102102
IntValueTy intValue;
103103
FloatValueTy floatValue;
104+
bool boolValue;
104105
};
105106

106107
explicit RawValueKey(LiteralExpr *expr) {
@@ -136,6 +137,12 @@ struct RawValueKey {
136137
kind = Kind::String;
137138
stringValue = cast<StringLiteralExpr>(expr)->getValue();
138139
return;
140+
141+
case ExprKind::BooleanLiteral:
142+
kind = Kind::Bool;
143+
boolValue = cast<BooleanLiteralExpr>(expr)->getValue();
144+
return;
145+
139146
default:
140147
llvm_unreachable("not a valid literal expr for raw value");
141148
}
@@ -183,6 +190,8 @@ class DenseMapInfo<RawValueKey> {
183190
DenseMapInfo<uint64_t>::getHashValue(k.intValue.v1);
184191
case RawValueKey::Kind::String:
185192
return DenseMapInfo<StringRef>::getHashValue(k.stringValue);
193+
case RawValueKey::Kind::Bool:
194+
return DenseMapInfo<uint64_t>::getHashValue(k.boolValue);
186195
case RawValueKey::Kind::Empty:
187196
case RawValueKey::Kind::Tombstone:
188197
return 0;
@@ -204,6 +213,8 @@ class DenseMapInfo<RawValueKey> {
204213
a.intValue.v1 == b.intValue.v1;
205214
case RawValueKey::Kind::String:
206215
return a.stringValue.equals(b.stringValue);
216+
case RawValueKey::Kind::Bool:
217+
return a.boolValue == b.boolValue;
207218
case RawValueKey::Kind::Empty:
208219
case RawValueKey::Kind::Tombstone:
209220
return true;
@@ -1682,6 +1693,7 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
16821693
continue;
16831694
}
16841695

1696+
16851697
// If the raw values of the enum case are fixed, then we trust our callers
16861698
// to have set things up correctly. This comes up with imported enums
16871699
// and deserialized @objc enums which always have their raw values setup

test/decl/enum/bool_raw_value.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-typecheck-verify-swift
2+
extension Bool: ExpressibleByIntegerLiteral {
3+
public init(integerLiteral value: Int) {
4+
self = value != 0
5+
}
6+
}
7+
8+
enum IsDefinitelyRecursive : Bool, Equatable, Hashable {
9+
case recursive=false
10+
}
11+
12+
// expected-error@+1{{'IsRecursive' declares raw type 'Bool', but does not conform to RawRepresentable and conformance could not be synthesized}}
13+
enum IsRecursive : Bool, Equatable, Hashable {
14+
case recursive=false
15+
case nonrecursive // expected-error{{enum case must declare a raw value when the preceding raw value is not an integer}}
16+
}

0 commit comments

Comments
 (0)