From 5998cd645f8bf50d0af427ceeb7b85e38019269f Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Sun, 28 May 2017 17:03:34 -0700 Subject: [PATCH] [ConstraintSolver] Penalize conversions from String to UnsafePointer There are possible situations when we find solutions with String and String -> UnsafePointer conversions at the same time for expressions with default string literals. In order to disambiguite such situations let's prefer solutions without String -> UnsafePointer conversions if possible. --- lib/Sema/CSRanking.cpp | 4 ++++ lib/Sema/CSSimplify.cpp | 4 ++++ lib/Sema/ConstraintSystem.h | 6 ++++-- test/Constraints/overload.swift | 1 + validation-test/Sema/rdar32204609.swift | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp index ba4600b1d7ab0..88277eb22992d 100644 --- a/lib/Sema/CSRanking.cpp +++ b/lib/Sema/CSRanking.cpp @@ -83,6 +83,10 @@ void ConstraintSystem::increaseScore(ScoreKind kind, unsigned value) { case SK_KeyPathSubscript: log << "key path subscript"; break; + + case SK_StringToPointerConversion: + log << "string-to-pointer conversion"; + break; } log << ")\n"; } diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index b665bcbde71f1..041895a15c5c3 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -4397,6 +4397,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( // If we haven't resolved the element type, generate constraints. if (baseType2->isTypeVariableOrMember()) { if (flags.contains(TMF_GenerateConstraints)) { + increaseScore(SK_StringToPointerConversion); + auto int8Con = Constraint::create(*this, ConstraintKind::Bind, baseType2, TC.getInt8Type(DC), getConstraintLocator(locator)); @@ -4418,6 +4420,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( if (!isStringCompatiblePointerBaseType(TC, DC, baseType2)) { return SolutionKind::Error; } + + increaseScore(SK_StringToPointerConversion); return SolutionKind::Solved; } diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index a69c5b2ffb9b5..487d65850b78a 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -416,8 +416,10 @@ enum ScoreKind { SK_EmptyExistentialConversion, /// A key path application subscript. SK_KeyPathSubscript, - - SK_LastScoreKind = SK_KeyPathSubscript, + // A conversion from a string to a pointer. + SK_StringToPointerConversion, + + SK_LastScoreKind = SK_StringToPointerConversion, }; /// The number of score kinds. diff --git a/test/Constraints/overload.swift b/test/Constraints/overload.swift index 05338ee62a9ea..4b06f4dc22127 100644 --- a/test/Constraints/overload.swift +++ b/test/Constraints/overload.swift @@ -222,3 +222,4 @@ func curry(_ f: @escaping (F, S, T) -> R) -> (F) -> (S) -> (T) -> R // Ensure that we consider these unambiguous let _ = curry(+)(1) let _ = [0].reduce(0, +) +let _ = curry(+)("string vs. pointer") diff --git a/validation-test/Sema/rdar32204609.swift b/validation-test/Sema/rdar32204609.swift index de8d6bfc5c5dc..5e14f85bbe971 100644 --- a/validation-test/Sema/rdar32204609.swift +++ b/validation-test/Sema/rdar32204609.swift @@ -8,4 +8,4 @@ let x: Int! = nil let y: Int! = 1 -print(x == y) \ No newline at end of file +print(x == y)