Skip to content

Commit 0e6260d

Browse files
committed
[Diagnostics] Special case assignment between nominal types with optional promotion
Skip fixing situation where source and destination of assignment are both nominal types with different optionality until restriction is attempted. Otherwise fix could be too greedy and diagnose valid code if all of the types are known in advance. Resolves: SR-13951 Resolves: rdar://problem/72166791
1 parent 23b8dba commit 0e6260d

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3722,14 +3722,15 @@ bool ConstraintSystem::repairFailures(
37223722
if (lhs->is<FunctionType>() && rhs->is<FunctionType>())
37233723
return false;
37243724

3725-
// If either object type is a bound generic or existential it means
3726-
// that follow-up to value-to-optional is going to be:
3725+
// If either object type is a generic, nominal or existential type
3726+
// it means that follow-up to value-to-optional is going to be:
37273727
//
37283728
// 1. "deep equality" check, which is handled by generic argument(s)
3729-
// mismatch fix, or
3729+
// or contextual mismatch fix, or
37303730
// 2. "existential" check, which is handled by a missing conformance
37313731
// fix.
37323732
if ((lhs->is<BoundGenericType>() && rhs->is<BoundGenericType>()) ||
3733+
(lhs->is<NominalType>() && rhs->is<NominalType>()) ||
37333734
rhs->isAnyExistentialType())
37343735
return false;
37353736
}

test/Constraints/sr13951.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol TheProtocol {}
4+
struct TheType1: TheProtocol {}
5+
6+
enum TheEnum: RawRepresentable {
7+
typealias RawValue = TheProtocol
8+
9+
case case1
10+
case case2
11+
12+
init?(rawValue: TheProtocol) {
13+
self = .case1
14+
}
15+
16+
var rawValue: TheProtocol {
17+
return TheType1()
18+
}
19+
}
20+
21+
func aTransformer(input: Int) -> TheEnum {
22+
if input % 2 == 0 {
23+
return .case1
24+
} else {
25+
return .case2
26+
}
27+
}
28+
29+
func theProblem(input: Int?) {
30+
var enumValue: TheEnum?
31+
32+
if let input = input {
33+
enumValue = aTransformer(input: input) // Ok
34+
}
35+
36+
_ = enumValue // To silence the warning
37+
}

0 commit comments

Comments
 (0)