Skip to content

Commit 03b7ad6

Browse files
authored
Merge pull request #64004 from artemcm/ConstExtractFixes
[Compile Time Constant Extraction] Look through Optional injection and underlying-to-opaque conversions
2 parents f1ff695 + 76b9281 commit 03b7ad6

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ extractFunctionArguments(const ArgumentList *args) {
142142
if (decl->hasDefaultExpr()) {
143143
argExpr = decl->getTypeCheckedDefaultExpr();
144144
}
145+
} else if (auto optionalInject = dyn_cast<InjectIntoOptionalExpr>(argExpr)) {
146+
argExpr = optionalInject->getSubExpr();
145147
}
146148
parameters.push_back({label, type, extractCompileTimeValue(argExpr)});
147149
}
@@ -308,6 +310,30 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
308310
return std::make_shared<TypeValue>(dotSelfExpr->getType());
309311
}
310312

313+
case ExprKind::UnderlyingToOpaque: {
314+
auto underlyingToOpaque = cast<UnderlyingToOpaqueExpr>(expr);
315+
return extractCompileTimeValue(underlyingToOpaque->getSubExpr());
316+
}
317+
318+
case ExprKind::DefaultArgument: {
319+
auto defaultArgExpr = cast<DefaultArgumentExpr>(expr);
320+
auto *decl = defaultArgExpr->getParamDecl();
321+
// If there is a default expr, we should have looked through to it
322+
assert(!decl->hasDefaultExpr());
323+
switch (decl->getDefaultArgumentKind()) {
324+
case DefaultArgumentKind::NilLiteral:
325+
return std::make_shared<RawLiteralValue>("nil");
326+
case DefaultArgumentKind::EmptyArray:
327+
return std::make_shared<ArrayValue>(
328+
std::vector<std::shared_ptr<CompileTimeValue>>());
329+
case DefaultArgumentKind::EmptyDictionary:
330+
return std::make_shared<DictionaryValue>(
331+
std::vector<std::shared_ptr<TupleValue>>());
332+
default:
333+
break;
334+
}
335+
} break;
336+
311337
default: {
312338
break;
313339
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: echo "[MyProto]" > %t/protocols.json
3+
4+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractLiterals.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s
5+
// RUN: cat %t/ExtractLiterals.swiftconstvalues 2>&1 | %FileCheck %s
6+
7+
protocol MyProto {}
8+
struct InjectablePropertyStruct : MyProto {
9+
let init1 = Bat(buz: "hello", fuz: 4)
10+
}
11+
12+
public struct Bat {
13+
let buz: String?
14+
let fuz: Int
15+
16+
init(buz: String? = "", fuz: Int = 0) {
17+
self.buz = buz
18+
self.fuz = fuz
19+
}
20+
}
21+
22+
// CHECK: "arguments": [
23+
// CHECK-NEXT: {
24+
// CHECK-NEXT: "label": "buz",
25+
// CHECK-NEXT: "type": "Swift.Optional<Swift.String>",
26+
// CHECK-NEXT: "valueKind": "RawLiteral",
27+
// CHECK-NEXT: "value": "hello"
28+
// CHECK-NEXT: },
29+
// CHECK-NEXT: {
30+
// CHECK-NEXT: "label": "fuz",
31+
// CHECK-NEXT: "type": "Swift.Int",
32+
// CHECK-NEXT: "valueKind": "RawLiteral",
33+
// CHECK-NEXT: "value": "4"
34+
// CHECK-NEXT: }
35+
// CHECK-NEXT: ]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: echo "[MyProto]" > %t/protocols.json
3+
4+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractLiterals.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s
5+
// RUN: cat %t/ExtractLiterals.swiftconstvalues 2>&1 | %FileCheck %s
6+
7+
protocol MyProto {}
8+
protocol Bird {}
9+
10+
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
11+
struct UnderlyingToOpaquePropertyStruct : MyProto {
12+
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
13+
var warbler: some Bird {
14+
Warbler("blue")
15+
}
16+
}
17+
18+
public struct Warbler : Bird {
19+
let belly: String = "yellow"
20+
init(_ color: String = "red") {
21+
self.belly = color
22+
}
23+
}
24+
25+
// CHECK: "valueKind": "InitCall",
26+
// CHECK-NEXT: "value": {
27+
// CHECK-NEXT: "type": "ExtractUnderlyingToOpaque.Warbler",
28+
// CHECK-NEXT: "arguments": [
29+
// CHECK-NEXT: {
30+
// CHECK-NEXT: "label": "",
31+
// CHECK-NEXT: "type": "Swift.String",
32+
// CHECK-NEXT: "valueKind": "RawLiteral",
33+
// CHECK-NEXT: "value": "blue"
34+
// CHECK-NEXT: }
35+
// CHECK-NEXT: ]
36+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)