Skip to content

Commit 45ebc56

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.
1 parent 57ceb50 commit 45ebc56

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
@@ -3284,10 +3284,21 @@ namespace {
32843284
auto fromType = CS.getType(expr->getSubExpr());
32853285
auto locator = CS.getConstraintLocator(expr);
32863286

3287-
// Add a conversion constraint for the direct conversion between
3288-
// types.
3289-
CS.addExplicitConversionConstraint(fromType, toType, RememberChoice,
3290-
locator);
3287+
// Literal initialization (e.g. `UInt32(0)`) doesn't require
3288+
// a conversion because the literal is supposed to assume the
3289+
// `to` type.
3290+
//
3291+
// `to` type could be a type variable if i.e. the repr is invalid,
3292+
// in such cases a slower conversion path is a better choice to
3293+
// let it be inferred from the context and/or from the literal itself.
3294+
if (expr->isLiteralInit() && !toType->isTypeVariableOrMember()) {
3295+
CS.addConstraint(ConstraintKind::Equal, fromType, toType, locator);
3296+
} else {
3297+
// Add a conversion constraint for the direct conversion between
3298+
// types.
3299+
CS.addExplicitConversionConstraint(fromType, toType, RememberChoice,
3300+
locator);
3301+
}
32913302

32923303
// If the result type was declared IUO, add a disjunction for
32933304
// 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)