Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-435] Less specific method recorded in the protocol witness table #43052

Open
an0 mannequin opened this issue Jan 1, 2016 · 5 comments
Open

[SR-435] Less specific method recorded in the protocol witness table #43052

an0 mannequin opened this issue Jan 1, 2016 · 5 comments

Comments

@an0
Copy link
Mannequin

@an0 an0 mannequin commented Jan 1, 2016

Previous ID SR-435
Radar rdar://problem/24031731
Original Reporter @an0
Type Bug
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: ebc1bb2c8590dd5c9b38b1264038435b

Issue Description:

When there are default protocol implementation, constrained protocol extension implementation, type implementation, constrained type extension implementation, of an API, which one is actually called is very confusing and some current behaviors are quite odd.

I think:

  1. The definite dispatching rules should specified and documented.
  2. Some of current behaviors are bugs — though I'm not sure which because I'm not sure about the dispatching rules — and should fixed.

Commented code with execution results should explain the issues more clearly:

protocol P {
    typealias T
    
    func f()
    func g()
}

extension P {
    func f() {
        print("P.f")
    }
    
    func g() {
        print("P.g")
        f() // Should call P.Equatable.f if T is Equatable, shouldn't it?
    }
}

extension P where T: Equatable {
    func f() {
        print("P.Equatable.f") // Inaccessible to P.g? Not even to P.Equatable.g but accessible to to Foo.Equatable.g — odd.
    }
    
//    func g() {
//        print("P.Equatable.g")
//        f() // Should call P.Equatable.f if T is Equatable, shouldn't it?
//    }
}

struct Foo<U>: P {
    typealias T = U
    
//    func g() {
//        print("Foo.g")
//        f()
//    }
}

extension Foo where U: Equatable {
//    func f() {
//        print("Foo.Equatable.f") // Inaccessible to P.g or Foo.g? At least accessible to Foo.Equatable.g.
//    }
    
//    func g() {
//        print("Foo.Equatable.g")
//        f()
//    }
}

let foo = Foo<Int>()
foo.f()
print("")
foo.g()

// Uncomment P.Equatable.g, Foo.g, Foo.Equatable.g, Foo.Equatable.f to see other behaviors.

The actual output:

P.Equatable.f

P.g
P.f

The expected output:

P.Equatable.f

P.g
P.Equatable.f
@gribozavr
Copy link
Collaborator

@gribozavr gribozavr commented Jan 2, 2016

Looks like the compiler selects the less specific method for the witness table. Instead of selecting the method that prints "P.Equatable.f" it selects the one that prints "P.f".

/cc @jckarter @DougGregor

@gribozavr
Copy link
Collaborator

@gribozavr gribozavr commented Jan 2, 2016

Cloned to rdar://problem/24031731.

@Dante-Broggi
Copy link
Contributor

@Dante-Broggi Dante-Broggi commented Sep 17, 2018

Is this resolved, or no longer valid? If either, this should be closed.

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Apr 26, 2020

Comment by BruceGu (JIRA)

struct Foo<U: Equatable>: P {
typealias T = U
}
If you define Foo like this, the output is your expect.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis
Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis commented Jun 21, 2022

We need a one-to-many mapping for generic conformances to support this. Currently conformances are always a one-to-one mapping.

@AnthonyLatsis AnthonyLatsis removed the bug label Jun 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants