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-10324] Unexpected three-term "Ambiguous reference" #52724

Open
swift-ci opened this issue Apr 6, 2019 · 3 comments
Open

[SR-10324] Unexpected three-term "Ambiguous reference" #52724

swift-ci opened this issue Apr 6, 2019 · 3 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

swift-ci commented Apr 6, 2019

Previous ID SR-10324
Radar None
Original Reporter hyperjeff (JIRA User)
Type Bug
Status In Progress
Resolution
Environment

macOS 10.14.4, Swift 5.0 (Apple Swift version 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3), Target: x86_64-apple-darwin18.5.0), Xcode 10.2 (10E125)

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

md5: 7a22e1d470dc434136aab267a242fd68

Issue Description:

The following code infers types as expected:

infix operator •: MultiplicationPrecedence

struct A {}
    static func • (lhs: A, rhs: A) -> B { return B() }
    static func • (lhs: B, rhs: A) -> B { return B() }
    static func • (lhs: A, rhs: B) -> B { return B() }
}
struct B {}

let (x, y, z) = (A(), A(), A())

let w = x • y • z            // works a-ok, returns a B struct

But change the operator to the existing * operator on these structs, and it is unable to figure out how to proceed without excessive grouping and typing:

struct A {
    static func * (lhs: A, rhs: A) -> B { return B() }
    static func * (lhs: B, rhs: A) -> B { return B() }
    static func * (lhs: A, rhs: B) -> B { return B() }
}
struct B {}

let (x, y, z) = (A(), A(), A())

let w = A() * A() * A()     // works

let a = x * y * z           // Ambiguous reference to member '*'
let b = x * (y * z)         // Ambiguous reference to member '*'
let c = (x * y) * z         // Ambiguous reference to member '*'
let d = x * (y * z as B)    // works
let e = (x * y as B) * z    // works

Both have the same associativity and precedence. There's something specific to * that seems to ruin the inferences. Is it because it has to check too many possibilities? (If so, is this limitation just a temporary pragmatic one?)

@belkadan
Copy link
Contributor

belkadan commented Apr 8, 2019

Yes, it is because it has to check the other * operators, and hopefully it's something we'll be able to improve, yes. @xedin, do you want to track this separately or combine it with existing issues?

@belkadan
Copy link
Contributor

belkadan commented Apr 8, 2019

Actually, I might roll that back; we're supposed to resolve precedence first, which means this shouldn't be ambiguous.

@gregomni
Copy link
Collaborator

No, this isn't a too-many-possibilities issue, it's a bug in the constraint optimizer where it sees a series of variables of the same type in the same expression and thinks that therefore the specific overload used by each of the operators will be the same as well.

#26140

@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

3 participants