Skip to content

Commit 337b93f

Browse files
committed
sema: properly handle Array/Dictionary literals as compile-time literals
1 parent d45a0ce commit 337b93f

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

lib/AST/Expr.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,38 @@ Expr *Expr::getSemanticsProvidingExpr() {
199199
}
200200

201201
bool Expr::isSemanticallyConstExpr() const {
202-
if (auto *LE = dyn_cast<LiteralExpr>(getSemanticsProvidingExpr())) {
203-
return LE->getKind() != ExprKind::InterpolatedStringLiteral;
202+
auto E = getSemanticsProvidingExpr();
203+
if (!E) {
204+
return false;
205+
}
206+
switch(E->getKind()) {
207+
case ExprKind::IntegerLiteral:
208+
case ExprKind::NilLiteral:
209+
case ExprKind::BooleanLiteral:
210+
case ExprKind::FloatLiteral:
211+
case ExprKind::StringLiteral:
212+
return true;
213+
case ExprKind::Array:
214+
case ExprKind::Dictionary: {
215+
auto *CE = cast<CollectionExpr>(E);
216+
for (auto *EL: CE->getElements()) {
217+
if (!EL->isSemanticallyConstExpr())
218+
return false;
219+
}
220+
return true;
221+
}
222+
case ExprKind::Tuple: {
223+
auto *TE = cast<TupleExpr>(E);
224+
for (auto *EL: TE->getElements()) {
225+
if (!EL->isSemanticallyConstExpr()) {
226+
return false;
227+
}
228+
}
229+
return true;
230+
}
231+
default:
232+
return false;
204233
}
205-
return false;
206234
}
207235

208236
Expr *Expr::getValueProvidingExpr() {

test/Sema/const_pass_as_arguments.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,25 @@
33
public func takeIntConst(_ a: _const Int) {}
44
public func takeStringConst(_ a: _const String) {}
55
public func takeDoubleConst(_ a: _const Double) {}
6+
public func takeArrayConst(_ a: _const [String]) {}
7+
public func takeDictConst(_ a: _const [Int: String]) {}
68

7-
func main(_ i: Int, _ d: Double, _ s: String) {
9+
func main(_ i: Int, _ d: Double, _ s: String, arr: [String], dict: [Int: String]) {
810
takeIntConst(2)
911
takeDoubleConst(3.3)
1012
takeStringConst("")
13+
takeArrayConst([""])
14+
takeDictConst([1: "", 2: "text"])
1115

1216
takeIntConst(i) // expected-error {{expect a compile-time constant literal}}
1317
takeDoubleConst(d) // expected-error {{expect a compile-time constant literal}}
1418
takeStringConst("\(d)") // expected-error {{expect a compile-time constant literal}}
1519
takeStringConst(s) // expected-error {{expect a compile-time constant literal}}
20+
takeArrayConst(arr) // expected-error {{expect a compile-time constant literal}}
21+
takeArrayConst([s]) // expected-error {{expect a compile-time constant literal}}
22+
takeArrayConst(["", s]) // expected-error {{expect a compile-time constant literal}}
23+
takeDictConst([1: "", 2: s]) // expected-error {{expect a compile-time constant literal}}
24+
takeDictConst([1: "", i: "text"]) // expected-error {{expect a compile-time constant literal}}
1625
}
1726

1827
public struct Utils {

0 commit comments

Comments
 (0)