diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index e66fc7ee9d495..87add5a72f154 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1215,8 +1215,12 @@ bool BindingSet::isViable(PotentialBinding &binding, bool isTransitive) { // as a binding because `$T0` could be inferred to // `(key: String, value: Int)` and binding `$T1` to `Array<(String, Int)>` // eagerly would be incorrect. - if (existing->Kind != binding.Kind) - continue; + if (existing->Kind != binding.Kind) { + // Array, Set and Dictionary allow conversions, everything else + // requires their generic arguments to match exactly. + if (existingType->isKnownStdlibCollectionType()) + continue; + } // If new type has a type variable it shouldn't // be considered viable. diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift index 3971a818ae592..5eac86f190674 100644 --- a/test/Constraints/generics.swift +++ b/test/Constraints/generics.swift @@ -1072,3 +1072,18 @@ do { // expected-error@-1 {{referencing instance method 'compute()' on 'Dictionary' requires the types 'any P' and 'Any' be equivalent}} } } + +// https://github.com/swiftlang/swift/issues/77003 +do { + func f(_: T.Type, _ fn: (T) -> U?, _: (U) -> ()) {} + + struct Task { + init(_: () -> ()) where E == Never {} + init(_: () throws -> ()) where E == Error {} + } + + func test(x: Int?.Type) { + // Note that it's important that Task stays unused, using `_ = ` changes constraint generation behavior. + f(x, { $0 }, { _ in Task {} }) // expected-warning {{result of 'Task' initializer is unused}} + } +} diff --git a/validation-test/Sema/SwiftUI/rdar98862079.swift b/validation-test/Sema/SwiftUI/rdar98862079.swift index 40a2030539118..dcc99e335a17d 100644 --- a/validation-test/Sema/SwiftUI/rdar98862079.swift +++ b/validation-test/Sema/SwiftUI/rdar98862079.swift @@ -22,7 +22,7 @@ struct MyView : View { var body: some View { test(value: true ? $newBounds.maxBinding : $newBounds.minBinding, in: bounds) - // expected-error@-1 {{cannot convert value of type 'Binding?>' to expected argument type 'Binding'}} - // expected-note@-2 {{arguments to generic parameter 'Value' ('Binding?' and 'Double') are expected to be equal}} + // expected-error@-1 2 {{result values in '? :' expression have mismatching types 'Binding?>' and 'Binding'}} + // expected-note@-2 2 {{arguments to generic parameter 'Value' ('Binding?' and 'Double') are expected to be equal}} } }