[CSBindings] Look through optional types when trying to validate l-valueness of the new bindings

When bindings are picked for particular type variable, right-hand
side of the binding might be another type variable wrapped into optional
type, when trying to determine if both sides of the binding have the
same l-valueness it's imperative to look throught optional type of the
right-hand side. Otherwise new binding might be effectively unsolvable.

Resolves: rdar://problem/37291371
This commit is contained in:
Pavel Yaskevich
2018-02-08 01:17:31 -08:00
parent d9067d91c5
commit c6ff7b40cc
4 changed files with 26 additions and 4 deletions

View File

@@ -447,7 +447,8 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
// Make sure we aren't trying to equate type variables with different
// lvalue-binding rules.
if (auto otherTypeVar = type->getAs<TypeVariableType>()) {
if (auto otherTypeVar =
type->lookThroughAllOptionalTypes()->getAs<TypeVariableType>()) {
if (typeVar->getImpl().canBindToLValue() !=
otherTypeVar->getImpl().canBindToLValue())
continue;

View File

@@ -0,0 +1,21 @@
// RUN: %target-typecheck-verify-swift
extension Collection where Element: Numeric {
var v: Element {
return self.reduce(0, +)
}
}
struct R<T> {}
func ==<T: Equatable>(lhs: R<T>, rhs: T?) {}
func foo<T>(_ e: @autoclosure @escaping () throws -> T?) -> R<T> {
return R<T>()
}
func bar<T>(_ e: T?) -> R<T> {
return R<T>()
}
foo([Double(1.0)].v) == Double(1.0)
bar([Double(1.0)].v) == Double(1.0)

View File

@@ -5,6 +5,6 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// RUN: not --crash %target-swift-frontend %s -emit-ir
// REQUIRES: asserts
// RUN: not %target-swift-frontend %s -emit-ir
nil?as?Int??

View File

@@ -5,7 +5,7 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// RUN: not --crash %target-swift-frontend %s -emit-ir
// RUN: not %target-swift-frontend %s -emit-ir
[.a
[Int?as?Int
nil?