I remember discussions on this list of curious situations in which a protocol doesn’t even conform to itself. This may be related.
I’ll let others who better understand the type system and its limitations weigh in. P > On Jan 17, 2018, at 1:53 PM, Saagar Jha <saa...@saagarjha.com> wrote: > > 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 >> <mailto: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 >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution