Skip to content

Commit 93ab669

Browse files
committed
[ConstraintSystem] Shrink: If root expression is assignment always consider it as a candidate
If assignment expression is not considered as a top-level candidate it would mean that other candidates would be allowed to produce types inconsistent with destination type of the assignment. Resolves: rdar://problem/51413254
1 parent 6b8406c commit 93ab669

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,8 +836,12 @@ void ConstraintSystem::shrink(Expr *expr) {
836836
return expr;
837837
}
838838

839-
// Or it's a function application with other candidates present.
840-
if (isa<ApplyExpr>(expr)) {
839+
// Or it's a function application or assignment with other candidates
840+
// present. Assignment should be easy to solve because we'd get a
841+
// contextual type from the destination expression, otherwise shrink
842+
// might produce incorrect results without considering aforementioned
843+
// destination type.
844+
if (isa<ApplyExpr>(expr) || isa<AssignExpr>(expr)) {
841845
Candidates.push_back(Candidate(CS, PrimaryExpr));
842846
return expr;
843847
}

test/Constraints/generics.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,3 +770,26 @@ func rdar_50007727() {
770770
// expected-error@-1 {{generic parameter 'T' could not be inferred in cast to 'A.B'}}
771771
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{12-12=<Any>}}
772772
}
773+
774+
// rdar://problem/51413254
775+
776+
infix operator ==>
777+
778+
struct Key {
779+
init(_ key: String) {}
780+
}
781+
782+
func ==> (lhs: Any, rhs: Key) throws -> Any {
783+
return 0
784+
}
785+
786+
func ==> <A>(lhs: Any, rhs: Key) throws -> A {
787+
fatalError()
788+
}
789+
790+
struct R_51413254 {
791+
var str: String = ""
792+
mutating func test(_ anyDict: Any) throws {
793+
self.str = try anyDict ==> Key("a") // Ok
794+
}
795+
}

0 commit comments

Comments
 (0)