Skip to content

Commit fdcb08e

Browse files
committed
sema: accept enum element reference as compile-time const value
1 parent 709d9b9 commit fdcb08e

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

lib/Sema/CSFix.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,8 @@ RemoveReturn *RemoveReturn::create(ConstraintSystem &cs, Type resultTy,
11291129
NotCompileTimeConst::NotCompileTimeConst(ConstraintSystem &cs, Type paramTy,
11301130
ConstraintLocator *locator):
11311131
ContextualMismatch(cs, FixKind::NotCompileTimeConst, paramTy,
1132-
cs.getASTContext().TheEmptyTupleType, locator) {}
1132+
cs.getASTContext().TheEmptyTupleType, locator,
1133+
/*warning*/true) {}
11331134

11341135
NotCompileTimeConst *
11351136
NotCompileTimeConst::create(ConstraintSystem &cs, Type paramTy,
@@ -1138,7 +1139,14 @@ NotCompileTimeConst::create(ConstraintSystem &cs, Type paramTy,
11381139
}
11391140

11401141
bool NotCompileTimeConst::diagnose(const Solution &solution, bool asNote) const {
1141-
NotCompileTimeConstFailure failure(solution, getLocator());
1142+
auto *locator = getLocator();
1143+
// Referencing an enum element directly is considered a compile-time literal.
1144+
if (auto *d = solution.resolveLocatorToDecl(locator).getDecl()) {
1145+
if (isa<EnumElementDecl>(d)) {
1146+
return true;
1147+
}
1148+
}
1149+
NotCompileTimeConstFailure failure(solution, locator);
11421150
return failure.diagnose(asNote);
11431151
}
11441152

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,8 +1506,17 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
15061506
}
15071507
if (!argument.isCompileTimeConst() && param.isCompileTimeConst()) {
15081508
if (cs.shouldAttemptFixes()) {
1509-
cs.recordFix(NotCompileTimeConst::create(cs, paramTy,
1510-
cs.getConstraintLocator(loc)));
1509+
auto *locator = cs.getConstraintLocator(loc);
1510+
SourceRange range;
1511+
// simplify locator so the anchor is the exact argument.
1512+
locator = simplifyLocator(cs, locator, range);
1513+
if (locator->getPath().empty() &&
1514+
locator->getAnchor().isExpr(ExprKind::UnresolvedMemberChainResult)) {
1515+
locator =
1516+
cs.getConstraintLocator(cast<UnresolvedMemberChainResultExpr>(
1517+
locator->getAnchor().get<Expr*>())->getChainBase());
1518+
}
1519+
cs.recordFix(NotCompileTimeConst::create(cs, paramTy, locator));
15111520
}
15121521
}
15131522

test/Sema/const_enum_elements.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
enum CarKind {
4+
case coupe
5+
case sedan
6+
case other(String)
7+
}
8+
9+
extension CarKind {
10+
static var myCoupe: CarKind {
11+
return .coupe
12+
}
13+
}
14+
15+
func getCarKind() -> CarKind { return .sedan }
16+
17+
func drive(_ k1: _const CarKind, k2: _const CarKind) {}
18+
19+
func main() {
20+
drive(.coupe, k2: .sedan)
21+
drive(.sedan, k2: .coupe)
22+
drive(CarKind.coupe, k2: CarKind.sedan)
23+
drive(CarKind.sedan, k2: CarKind.coupe)
24+
drive(.other(""), k2: .sedan)
25+
26+
drive(.myCoupe, k2: .sedan) // expected-error {{expect a compile-time constant literal}}
27+
drive(.coupe, k2: .myCoupe) // expected-error {{expect a compile-time constant literal}}
28+
drive(.coupe, k2: getCarKind()) // expected-error {{expect a compile-time constant literal}}
29+
drive(getCarKind(), k2: .coupe) // expected-error {{expect a compile-time constant literal}}
30+
}

0 commit comments

Comments
 (0)