Interestingly, it seems like Swift allows for contravariance for subclassing, in that this is valid code:
protocol A {} protocol B: A {} class C { // Notice this is a class, not a protocol func test(x: B) {} } class M: C { func test(x: A) {} } Is it an oversight that this doesn’t apply to protocols? Saagar Jha > On Jan 17, 2018, at 11:38, Paul Cantrell <cantr...@pobox.com> wrote: > > Note that it would be sound for the language to allow the opposite, which is > called “contravariance” (the more specific type takes a more general input): > > protocol A {} > protocol B: A {} > > protocol C { > func test(x: B) // was A > } > > class M: C { > func test(x: A) {} // was B > } > > It could also allow covariant return types (the more specific type returns a > more specific output): > > protocol C { > func test() -> A > } > > class M: C { > func test() -> B { > fatalError("just a stub") > } > } > > Some languages support this, and Swift certainly could — though I don’t know > that it’s a frequently request feature. > > It would also be interesting if associated type constraints allowed this, > which I don’t think they currently do: > > protocol C { > associatedtype TestInput where B: TestInput // error here > > func test(x: TestInput) > } > > Curiously, the following does not work, although it seems like it should: > > protocol A {} > protocol B: A {} > > protocol C { > associatedtype TestOutput: A > > func test() -> TestOutput > } > > class M: C { > func test() -> B { > fatalError("just a stub") > } > } > > It gives the error “inferred type 'B' (by matching requirement 'test()') is > invalid: does not conform to ‘A’” even though B does conform to A. Huh. > > Cheers, P > > >> On Jan 17, 2018, at 2:43 AM, Saagar Jha via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> If we have: >> >> class N: A {} >> >> you can pass an N into C’s test(x:), since N is an A, but not M’s test(x:), >> since N is not a B. Thus, it’s not a valid conformance. >> >> Saagar Jha >> >>> On Jan 17, 2018, at 00:04, Roshan via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> >>> Hi, >>> >>> Cross posting from swift-users in case this behaviour isn't part of >>> the language and might be interesting to you folks. >>> >>> Here is some sample code that gives a protocol conformance error in a >>> playground: >>> >>> protocol A {} >>> protocol B: A {} >>> >>> protocol C { >>> func test(x: A) >>> } >>> >>> class M: C { >>> func test(x: B) {} >>> } >>> >>> Is there a reason why the compiler doesn't infer that ((B) -> ()) >>> matches ((A) -> ()) because of inheritance? >>> >>> -- >>> Warm regards >>> Roshan >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution