[swift-users] Swift's method dispatch

Jens Persson jens at bitcycle.com
Fri Dec 8 15:07:04 CST 2017


Thanks Slava and Greg,

(
I'm aware that it prints "T is Int" from both calls if I remove func f()
from P itself, that's why I wrote "... unless * is commented out." in the
comment of the last line
Note that the "U.T == Int"-part of
  struct Y<U> where U: P, U.T == Int {
is key here. If it had been only
  struct Y<U> where U: P {
then I hadn't been surprised that it printed "T is unknown".
)

Filed https://bugs.swift.org/browse/SR-6564 since I think it is just
strange that the compiler should not use its knowledge of U.T == Int when
choosing between the two f()-implementations.
I think I will be a little disappointed if the solution is to deem it an
ambiguity
: )

/Jens



On Fri, Dec 8, 2017 at 9:19 PM, Greg Parker <gparker at apple.com> wrote:

> Evidence in favor of Slava's analysis: if you remove `func f()` from P
> itself, leaving it in the extensions only, then you get "T is Int" from
> both calls.
>
>
> > On Dec 8, 2017, at 12:12 PM, Slava Pestov via swift-users <
> swift-users at swift.org> wrote:
> >
> > Hi Jens,
> >
> > I think the problem is that overload ranking always prefers a protocol
> requirement to a protocol extension member, because usually you want the
> dynamic dispatch through the requirement instead of calling the default
> implementation. But it appears that this heuristic does not take into
> account the fact that the protocol extension member could be more
> constrained than the requirement.
> >
> > Please file a bug, but it is unclear what the desired behavior actually
> is here. Perhaps it should just diagnose an ambiguity.
> >
> > Slava
> >
> >> On Dec 8, 2017, at 6:25 AM, Jens Persson via swift-users <
> swift-users at swift.org> wrote:
> >>
> >> Hi all!
> >>
> >> Can someone please explain the rationale behind the last line printing
> >> "T is unknown"
> >> rather than (what I would expect):
> >> "T is Int"
> >> in the following program?
> >>
> >>
> >> protocol P {
> >>    associatedtype T
> >>    func f() // *
> >> }
> >> extension P {
> >>    func f() { print("T is unknown") }
> >> }
> >> extension P where T == Int {
> >>    func f() { print("T is Int") }
> >> }
> >>
> >> struct X<T> : P {}
> >>
> >> struct Y<U> where U: P, U.T == Int {
> >>    // NOTE: The compiler/type-checker knows that U.T == Int here so ...
> >>    typealias T = U.T
> >>    var a: U
> >>    func g() { a.f() } // ... how/why could this print anything but "T
> is Int"?
> >> }
> >>
> >> let x = X<Int>()
> >> x.f() // Prints "T is Int", no matter if * is commented out or not.
> >>
> >> let y = Y(a: X<Int>())
> >> y.g() // Prints "T is unknown" unless * is commented out. Why?
> >>
> >>
> >> IMHO this looks like the compiler simply ignores that struct Y<U> has
> the constraint  U.T == Int.
> >> How else to explain this behavior?
> >> /Jens
> >>
> >> _______________________________________________
> >> swift-users mailing list
> >> swift-users at swift.org
> >> https://lists.swift.org/mailman/listinfo/swift-users
> >
> > _______________________________________________
> > swift-users mailing list
> > swift-users at swift.org
> > https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20171208/3eeee828/attachment.html>


More information about the swift-users mailing list