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-6564] Compiler seems to ignore constraint on generic type parameter #49114

Closed
jepers opened this issue Dec 8, 2017 · 8 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@jepers
Copy link

jepers commented Dec 8, 2017

Previous ID SR-6564
Radar rdar://problem/35942887
Original Reporter @jepers
Type Bug
Status Closed
Resolution Invalid
Environment

Xcode 9.2 using recent toolchain (dev snapshot 2017-12-07)

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee @DougGregor
Priority Medium

md5: b59e701f99771c6127ac5fa98073f813

Issue Description:

Compiles successfully only with recent snapshots.
Issue is described in the comments.

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 {}

// NOTE: U.T == Int is key here ...
struct Y<U> where U: P, U.T == Int {
    // because the compiler/type-checker knows that U.T == Int here so ...
    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 line § is commented out or not.
let y = Y(a: X<Int>())
y.g() // Prints "T is unknown" unless line § is commented out. Why?

// IMHO it looks like the compiler simply ignores that struct Y<U> has the constraint  U.T == Int.
@jepers
Copy link
Author

jepers commented Dec 8, 2017

cc @slavapestov @gparker42

@slavapestov
Copy link
Member

@swift-ci create

@rudkx
Copy link
Member

rudkx commented Dec 8, 2017

It looks like we quickly retire constraints to test if U.T is Int (because we statically know this from the context), but then when we alternate over the overloads of f() we're not opening the new types and attempting to constraint T by Int for each overload we test.

Doug, what's supposed to be happening here?

Should we be doing something in the solver, or in ranking, or elsewhere?

@slavapestov
Copy link
Member

@rudkx we have two overload choices for 'f', the protocol requirement and the two extension members. I think we're picking the solution with the protocol requirement and not the extension members. Since the conformance is unconstrained it dispatches to the unconstrained extension member.

@belkadan
Copy link
Contributor

Per discussion on swift-users, this behaves correcly. Overload resolution chooses the best option it can see from the call site; that may be different for a concrete type vs. a generic type because protocol requirements are considered "better" than protocol extension methods.

@jepers
Copy link
Author

jepers commented Dec 11, 2017

OK
I would appreciate any good documentation on this (one that is thorough enough to explain situations like this, yet doesn't assume the reader is a compiler engineer or type theorist).

@krilnon
Copy link
Member

krilnon commented Dec 11, 2017

You should file bugs for language documentation at https://bugreport.apple.com. (Please do!)

@jepers
Copy link
Author

jepers commented Dec 12, 2017

Done: 35989836

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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.
Projects
None yet
Development

No branches or pull requests

5 participants