Skip to content

Commit 40f656e

Browse files
committed
[CSGen] SE-0213: Literal initialization via coercion shouldn't try bridging
`addExplicitConversionConstraint` generates a disjunction to check whether type could be coerced via bridging. That is not useful for literal initialization which could use direct equality if the type of cast is valid because necessary conformance checks have been performed before the transformation. (cherry picked from commit 45ebc56)
1 parent 38dc583 commit 40f656e

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

lib/Sema/CSGen.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,10 +2542,21 @@ namespace {
25422542
auto fromType = CS.getType(expr->getSubExpr());
25432543
auto locator = CS.getConstraintLocator(expr);
25442544

2545-
// Add a conversion constraint for the direct conversion between
2546-
// types.
2547-
CS.addExplicitConversionConstraint(fromType, toType, RememberChoice,
2548-
locator);
2545+
// Literal initialization (e.g. `UInt32(0)`) doesn't require
2546+
// a conversion because the literal is supposed to assume the
2547+
// `to` type.
2548+
//
2549+
// `to` type could be a type variable if i.e. the repr is invalid,
2550+
// in such cases a slower conversion path is a better choice to
2551+
// let it be inferred from the context and/or from the literal itself.
2552+
if (expr->isLiteralInit() && !toType->isTypeVariableOrMember()) {
2553+
CS.addConstraint(ConstraintKind::Equal, fromType, toType, locator);
2554+
} else {
2555+
// Add a conversion constraint for the direct conversion between
2556+
// types.
2557+
CS.addExplicitConversionConstraint(fromType, toType, RememberChoice,
2558+
locator);
2559+
}
25492560

25502561
// If the result type was declared IUO, add a disjunction for
25512562
// bindings for the result of the coercion.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend %s -typecheck -debug-constraints -swift-version 4 2>%t.err
2+
// RUN: %FileCheck %s < %t.err
3+
4+
// SE-0213. `UInt32(0)` and similar expressions that get transformed into
5+
// `0 as <#Type#>` should get literal bound early via equality constraint.
6+
7+
// CHECK: ---Constraint solving at [{{.*}}:12:1 - line:12:13]---
8+
// CHECK: (integer_literal_expr type='[[LITERAL_VAR:\$T[0-9]+]]' {{.*}}
9+
// CHECK: Type Variables:
10+
// CHECK: [[LITERAL_VAR]] [allows bindings to: {{.*}}] as UInt32 {{.*}}
11+
// CHECK-NOT: disjunction (remembered) \[\[locator@{{.*}} [Coerce@{{.*}}\]\]]:
12+
_ = UInt32(0)
13+
14+
// CHECK: ---Constraint solving at [{{.*}}22:1 - line:22:13]---
15+
// CHECK: (coerce_expr implicit type='[[CAST_TYPE:\$T[0-9]+]]' {{.*}}
16+
// CHECK-NEXT: (nil_literal_expr type='[[LITERAL_VAR:\$T[0-9]+]]' {{.*}}
17+
// CHECK: Type Variables:
18+
// CHECK: [[LITERAL_VAR]] [allows bindings to: {{.*}}] as Int? {{.*}}
19+
// CHECK: disjunction (remembered) {{.*}}
20+
// CHECK-NEXT: > [favored] [[CAST_TYPE]] bind Int?
21+
// CHECK-NEXT: > [[CAST_TYPE]] bind Int
22+
_ = Int!(nil)

0 commit comments

Comments
 (0)