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-5181] Protocol extension with constrained associated type doesn't work when using custom operator #47757

Open
swift-ci opened this issue Jun 10, 2017 · 5 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-5181
Radar rdar://problem/33142387
Original Reporter inamiy (JIRA User)
Type Bug
Environment

Xcode Version 9.0 beta (9M136h)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, TypeChecker
Assignee @xedin
Priority Medium

md5: 0a78b8ece4c44ce927fa4a680a607c65

is duplicated by:

  • SR-7476 Incorrect “ambiguous operator” error

Issue Description:

protocol Addable {
    associatedtype SomeType
    
    static func + (a: Self, b: Self) -> Self
    func sayHello()
    static func sayHello()
}

extension Addable {
    static func + (a: Self, b: Self) -> Self {
        print("add<default>")
        return a
    }
    
    func sayHello() {
        print("hello<default>")
    }
    
    static func sayHello() {
        print("hello<default>")
    }
}

extension Addable where SomeType == Int {
    static func + (a: Self, b: Self) -> Self {
        print("add<Int>")
        return a
    }
    
    func sayHello() {
        print("hello<Int>")
    }
    
    static func sayHello() {
        print("hello<Int>")
    }
}

struct Concrete<T>: Addable {
    typealias SomeType = T
}

let a = Concrete<Int>()

a.sayHello()             // OK: prints hello<Int>
Concrete<Int>.sayHello() // OK: prints hello<Int>

a + a                    // Not OK: prints add<default> ... why?

And when static func + (a: Self, b: Self) -> Self is commented out, a + a will work correctly.

See also: https://gist.github.com/taketo1024/88af341a8bf51af2bc133dee08cff3ae

@belkadan
Copy link
Contributor

Seems like a bug that they're inconsistent, but note that you're probably not getting the behavior you think you are:

func callSayHello<T: Addable>(_ obj: T) {
  obj.sayHello()
}
callSayHello(a) // default

What's happening is that Concrete has to pick one implementation of each requirement no matter what generic parameter it gets instantiated with. You'd have to call some method on the generic parameter or check the type with as? to get different behavior in a generic context.

I'm not sure why + is being treated different than sayHello in the fully-concrete context, though.

@belkadan
Copy link
Contributor

cc @rudkx, @xedin

@rudkx
Copy link
Member

rudkx commented Jul 5, 2017

@swift-ci create

@xedin
Copy link
Member

xedin commented Apr 11, 2018

Currently the behavior is that we consider something found in the declaration of the nominal better than anything which is declared in extension, that's why removing declaration from the protocol make everything behave as expected. I think we need to refine how we do look up and use only default implementation instead of both which would lead to a correct behavior in this case.

@xedin
Copy link
Member

xedin commented Jul 19, 2018

inamiy (JIRA User) Sorry for the delay, I had couple of PRs out to try and correct this inconsistency but unfortunately there is no easy fix for it and it requires swift evolution discussion, which might be a part of apple/swift-evolution#857

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants