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-3547] Regression with Dictionary subscript overload #46135

Open
belkadan opened this issue Jan 5, 2017 · 5 comments
Open

[SR-3547] Regression with Dictionary subscript overload #46135

belkadan opened this issue Jan 5, 2017 · 5 comments

Comments

@belkadan
Copy link
Contributor

@belkadan belkadan commented Jan 5, 2017

Previous ID SR-3547
Radar rdar://problem/29885853
Original Reporter @belkadan
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 3.1Regression, TypeChecker
Assignee None
Priority Medium

md5: e0c030c295ee74f23191f1438b5ee7c9

Issue Description:

extension Dictionary {
    internal subscript(key: String) -> Dictionary.Value? {
        get { return self[key as! Dictionary.Key] }
        set { self[key as! Dictionary.Key] = newValue }
    }
}
func test(x: [String: Any]) {
  print(x["abc"])
}

This code, presumably written before constrained generics, used to "work" in Swift 3.0 (calling the newly-defined subscript) but now produces an ambiguity error. I'm not convinced the ambiguity is wrong, but it is a source-breaking change.

@belkadan
Copy link
Contributor Author

@belkadan belkadan commented Jan 5, 2017

Note that you really do need two files to see the regression.

@belkadan
Copy link
Contributor Author

@belkadan belkadan commented Jan 5, 2017

@swift-ci create

@DougGregor
Copy link
Member

@DougGregor DougGregor commented Jan 10, 2017

I'm able to reproduce this with one file:

    struct X<T> { }

    extension X {
      func f(_: T) { }

      subscript(_: T) -> Int { return 0 }
    }

    extension X {
      func f(_: Y) { }

      subscript(_: Y) -> Int { return 0 }
    }

    struct Y { }

    func test(xy: X<Y>, y: Y) {
      _ = xy.f(y)   // okay: picks second declaration

      _ = xy[y]     // error: ambiguous subscript
    }

@DougGregor
Copy link
Member

@DougGregor DougGregor commented Jan 10, 2017

On master, the difference here is that the constraint optimizer is causing us to only consider the second "f", but the constraint optimizer doesn't kick in for subscripts, so it gets kicked over to partial ordering of declarations... and these are considered ambiguous by the partial ordering rules on master.

Back in Swift 3, these two subscript declarations were ordered, although it seems like they shouldn't be: the second is not actually more specialized than the first. Had the second been written as:

    extension X where T == Y {
      func f(_: Y) { }

      subscript(_: Y) -> Int { return 0 }
    }

then it's clearly more specialized.

@DougGregor
Copy link
Member

@DougGregor DougGregor commented Jan 10, 2017

I don't see a good way to emulate the old behavior without inventing a new overloading rule. The partial-ordering code has literally not changed, but the type checker itself is more accurately representing the language semantics.

@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
Projects
None yet
Development

No branches or pull requests

2 participants