Skip to content

Commit ed1fe6d

Browse files
committed
[CSBindings] Limit BindingSet::isViable binding skipping to stdlib collection types
This is follow-up to swiftlang#76487 It's reasonable to coalesce bindings of different kind if they don't allow implicit conversions like stdlib collection types do. Resolves: swiftlang#77003
1 parent ce78266 commit ed1fe6d

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,12 @@ bool BindingSet::isViable(PotentialBinding &binding, bool isTransitive) {
12151215
// as a binding because `$T0` could be inferred to
12161216
// `(key: String, value: Int)` and binding `$T1` to `Array<(String, Int)>`
12171217
// eagerly would be incorrect.
1218-
if (existing->Kind != binding.Kind)
1219-
continue;
1218+
if (existing->Kind != binding.Kind) {
1219+
// Array, Set and Dictionary allow conversions, everything else
1220+
// requires their generic arguments to match exactly.
1221+
if (existingType->isKnownStdlibCollectionType())
1222+
continue;
1223+
}
12201224

12211225
// If new type has a type variable it shouldn't
12221226
// be considered viable.

test/Constraints/generics.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,3 +1072,18 @@ do {
10721072
// expected-error@-1 {{referencing instance method 'compute()' on 'Dictionary' requires the types 'any P' and 'Any' be equivalent}}
10731073
}
10741074
}
1075+
1076+
// https://github.com/swiftlang/swift/issues/77003
1077+
do {
1078+
func f<T, U>(_: T.Type, _ fn: (T) -> U?, _: (U) -> ()) {}
1079+
1080+
struct Task<E> {
1081+
init(_: () -> ()) where E == Never {}
1082+
init(_: () throws -> ()) where E == Error {}
1083+
}
1084+
1085+
func test(x: Int?.Type) {
1086+
// Note that it's important that Task stays unused, using `_ = ` changes constraint generation behavior.
1087+
f(x, { $0 }, { _ in Task {} }) // expected-warning {{result of 'Task<E>' initializer is unused}}
1088+
}
1089+
}

validation-test/Sema/SwiftUI/rdar98862079.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct MyView : View {
2222

2323
var body: some View {
2424
test(value: true ? $newBounds.maxBinding : $newBounds.minBinding, in: bounds)
25-
// expected-error@-1 {{cannot convert value of type 'Binding<Binding<Double>?>' to expected argument type 'Binding<Double>'}}
26-
// expected-note@-2 {{arguments to generic parameter 'Value' ('Binding<Double>?' and 'Double') are expected to be equal}}
25+
// expected-error@-1 2 {{result values in '? :' expression have mismatching types 'Binding<Binding<Double>?>' and 'Binding<Double>'}}
26+
// expected-note@-2 2 {{arguments to generic parameter 'Value' ('Binding<Double>?' and 'Double') are expected to be equal}}
2727
}
2828
}

0 commit comments

Comments
 (0)