Skip to content

Commit 7d7ef4f

Browse files
committed
Sema: Fix crash when attempting to diagnose a contextual conversion of an ambiguous expression
The fixits call back into the type checker via typeCheckCheckedCast(), which sets up a new constraint system. As a result we would hit assertions by introducing type variables from a previous "generation". It seems that if we bail out of this code path altogether, we get a better diagnostic -- in the provided test, it complains about an ambiguous member to '.value', rather than not being able to convert _? to V?. Fixes <https://bugs.swift.org/browse/SR-2592>.
1 parent d99e1b0 commit 7d7ef4f

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,6 +4114,12 @@ bool FailureDiagnosis::diagnoseContextualConversionError() {
41144114
CS))
41154115
return true;
41164116

4117+
// Don't attempt fixits if we have an unsolved type variable, since
4118+
// the recovery path's recursion into the type checker via typeCheckCast()
4119+
// will confuse matters.
4120+
if (exprType->hasTypeVariable())
4121+
return false;
4122+
41174123
// When complaining about conversion to a protocol type, complain about
41184124
// conformance instead of "conversion".
41194125
if (contextualType->is<ProtocolType>() ||

test/Constraints/diagnostics.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,3 +780,18 @@ struct rdar27891805 {
780780
try rdar27891805(contentsOfURL: nil, usedEncoding: nil)
781781
// expected-error@-1 {{argument labels '(contentsOfURL:, usedEncoding:)' do not match any available overloads}}
782782
// expected-note@-2 {{overloads for 'rdar27891805' exist with these partially matching parameter lists: (contentsOf: String, encoding: String), (contentsOf: String, usedEncoding: inout String)}}
783+
784+
// Make sure RawRepresentable fix-its don't crash in the presence of type variables
785+
class NSCache<K, V> {
786+
func object(forKey: K) -> V? {}
787+
}
788+
789+
class CacheValue {
790+
func value(x: Int) -> Int {} // expected-note {{found this candidate}}
791+
func value(y: String) -> String {} // expected-note {{found this candidate}}
792+
}
793+
794+
func valueForKey<K>(_ key: K) -> CacheValue? {
795+
let cache = NSCache<K, CacheValue>()
796+
return cache.object(forKey: key)?.value // expected-error {{ambiguous reference to member 'value(x:)'}}
797+
}

0 commit comments

Comments
 (0)