Skip to content

Commit d721ca6

Browse files
committed
---
yaml --- r: 317422 b: refs/heads/master-rebranch c: 744c3a8 h: refs/heads/master
1 parent ac7c93a commit d721ca6

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,4 +1457,4 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14571457
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14581458
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14591459
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1460-
refs/heads/master-rebranch: 8dc7398842caac7ed5fdd8b10224844fc3eb6152
1460+
refs/heads/master-rebranch: 744c3a8d265b251606459f8fc1d238998b5f46d4

branches/master-rebranch/lib/Sema/CSBindings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,20 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
373373
case ConstraintKind::ArgumentConversion:
374374
case ConstraintKind::OperatorArgumentConversion:
375375
case ConstraintKind::OptionalObject: {
376+
// If there is a `bind param` constraint associated with
377+
// current type variable, result should be aware of that
378+
// fact. Binding set might be incomplete until
379+
// this constraint is resolved, because we currently don't
380+
// look-through constraints expect to `subtype` to try and
381+
// find related bindings.
382+
// This only affects type variable that appears one the
383+
// right-hand side of the `bind param` constraint and
384+
// represents result type of the closure body, because
385+
// left-hand side gets types from overload choices.
386+
if (constraint->getKind() == ConstraintKind::BindParam &&
387+
constraint->getSecondType()->isEqual(typeVar))
388+
result.PotentiallyIncomplete = true;
389+
376390
auto binding = getPotentialBindingForRelationalConstraint(
377391
result, constraint, hasDependentMemberRelationalConstraints,
378392
hasNonDependentMemberRelationalConstraints,

branches/master-rebranch/lib/Sema/ConstraintSystem.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,6 +2830,12 @@ class ConstraintSystem {
28302830
/// Whether the bindings of this type involve other type variables.
28312831
bool InvolvesTypeVariables = false;
28322832

2833+
/// Whether the bindings represent (potentially) incomplete set,
2834+
/// there is no way to say with absolute certainty if that's the
2835+
/// case, but that could happen when certain constraints like
2836+
/// `bind param` are present in the system.
2837+
bool PotentiallyIncomplete = false;
2838+
28332839
/// Whether this type variable has literal bindings.
28342840
LiteralBindingKind LiteralBinding = LiteralBindingKind::None;
28352841

@@ -2874,9 +2880,14 @@ class ConstraintSystem {
28742880
if (formBindingScore(y) < formBindingScore(x))
28752881
return false;
28762882

2877-
// If the only difference is default types,
2883+
// If there is a difference in number of default types,
28782884
// prioritize bindings with fewer of them.
2879-
return x.NumDefaultableBindings < y.NumDefaultableBindings;
2885+
if (x.NumDefaultableBindings != y.NumDefaultableBindings)
2886+
return x.NumDefaultableBindings < y.NumDefaultableBindings;
2887+
2888+
// As a last resort, let's check if the bindings are
2889+
// potentially incomplete, and if so, let's de-prioritize them.
2890+
return x.PotentiallyIncomplete < y.PotentiallyIncomplete;
28802891
}
28812892

28822893
void foundLiteralBinding(ProtocolDecl *proto) {
@@ -2909,6 +2920,8 @@ class ConstraintSystem {
29092920
void dump(llvm::raw_ostream &out,
29102921
unsigned indent = 0) const LLVM_ATTRIBUTE_USED {
29112922
out.indent(indent);
2923+
if (PotentiallyIncomplete)
2924+
out << "potentially_incomplete ";
29122925
if (FullyBound)
29132926
out << "fully_bound ";
29142927
if (SubtypeOfExistentialType)

branches/master-rebranch/test/Constraints/closures.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,3 +823,29 @@ func rdar_40537960() {
823823
_ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<T>'}}
824824
}
825825

826+
// rdar://problem/45659733
827+
func rdar_45659733() {
828+
func foo<T : BinaryInteger>(_: AnyHashable, _: T) {}
829+
func bar(_ a: Int, _ b: Int) {
830+
_ = (a ..< b).map { i in foo(i, i) } // Ok
831+
}
832+
833+
struct S<V> {
834+
func map<T>(
835+
get: @escaping (V) -> T,
836+
set: @escaping (inout V, T) -> Void
837+
) -> S<T> {
838+
fatalError()
839+
}
840+
841+
subscript<T>(
842+
keyPath: WritableKeyPath<V, T?>,
843+
default defaultValue: T
844+
) -> S<T> {
845+
return map(
846+
get: { $0[keyPath: keyPath] ?? defaultValue },
847+
set: { $0[keyPath: keyPath] = $1 }
848+
) // Ok, make sure that we deduce result to be S<T>
849+
}
850+
}
851+
}

0 commit comments

Comments
 (0)