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-7209] Source compatibility regression: error: ambiguous reference to member 'min(by:)' #49757

Closed
e28eta mannequin opened this issue Mar 15, 2018 · 7 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression standard library Area: Standard library umbrella swift 4.1

Comments

@e28eta
Copy link
Mannequin

e28eta mannequin commented Mar 15, 2018

Previous ID SR-7209
Radar rdar://problem/38943957
Original Reporter @e28eta
Type Bug
Status Resolved
Resolution Done
Environment

swift-DEVELOPMENT-SNAPSHOT-2018-03-14-a, macOS

Additional Detail from JIRA
Votes 0
Component/s Compiler, Standard Library
Labels Bug, 4.1Regression
Assignee None
Priority Medium

md5: cacf8d20ac6c8b7e50ebf49a8fea1284

Issue Description:

Our codebase adds a function, clamp(Bound), to CountableRange using the min() and max() functions from Sequence. Using the latest nightly swift-DEVELOPMENT-SNAPSHOT-2018-03-14-a, it fails to compile with error: ambiguous reference to member 'min(by:)'

extension CountableRange {
    public func clamp(_ value: Bound) -> Bound? {
        return value < self.lowerBound ? self.min()
            : value < self.upperBound  ? value
            : self.max()
    }
}

It looks like any reference to min() or max() fails:

extension Range {
    var highest: Bound? { max() }
}
error: repl.swift:2:27: error: ambiguous reference to member 'max(by:)'
    var highest: Bound? { max() }
                          ^~~
@huonw
Copy link
Mannequin

huonw mannequin commented Mar 16, 2018

This is https://bugs.swift.org/browse/SR-2450 except a source compatibility regression and confusing: Range became conditionally a Sequence, which means min calls pick up the min methods from Sequence even if the conformance to that protocol doesn't apply.

The fix is to make the code more explicit about which min is called: Swift.min.

Oh, and it looks like you've defined separate min() and max() methods?

@belkadan
Copy link
Contributor

They're not going for Swift.min; they want the one on Sequence. The problem is that extension CountableRange is now treated as extension Range instead of extension Range where Bound: Stridable or whatever.

@belkadan
Copy link
Contributor

That, or we lost a Comparable somewhere.

@belkadan
Copy link
Contributor

@swift-ci create

@e28eta
Copy link
Mannequin Author

e28eta mannequin commented Mar 21, 2018

Thanks for the quick attention! @belkadan is right, we do want the ones from Sequence. Looks like I have a mistake or two in the 2nd example (missing return self.), but neither fixing that nor s/Range/CountableRange/ changes the result with the swift-DEVELOPMENT snapshot.

This is reproducible in the REPL, so it should be independent of any other code in our project:

Welcome to Apple Swift version 4.2-dev (LLVM cef3fe6d75, Clang bdc970d89c, Swift 931d06d1cc). Type :help for assistance.
  1> extension CountableRange { 
  2.     var highest: Bound? { return self.max() } 
  3. } 
warning: repl.swift:1:11: warning: 'CountableRange' is deprecated: renamed to 'Range'
extension CountableRange {
          ^

repl.swift:1:11: note: use 'Range' instead
extension CountableRange {
          ^~~~~~~~~~~~~~
          Range

error: repl.swift:2:34: error: ambiguous reference to member 'max(by:)'
    var highest: Bound? { return self.max() }
                                 ^~~~

Compared to 4.1:

Welcome to Apple Swift version 4.1-dev (LLVM 260a172ffb, Clang cd84be6c42, Swift 04baf31321). Type :help for assistance.
  1> extension CountableRange { 
  2.     var highest: Bound? { return self.max() } 
  3. } 
  4> (0..<5).highest 
$R0: Int? = 4

Assuming I'm reading :type lookup CountableRange correctly (and I'm not sure that I am), the definition of CountableRange in 4.1 is:

@e28eta
Copy link
Mannequin Author

e28eta mannequin commented Mar 21, 2018

Adding conditions to the extension to match those on the extension that adds Collection conformance gets this working:

extension Range where Bound: Strideable, Bound.Stride: SignedInteger {
    var highest: Bound? { return self.max() }
}

However, I was unable to figure out a more clean way to add an extension to Range where Range: Sequence.

@huonw
Copy link
Mannequin

huonw mannequin commented Mar 28, 2018

I believe this was fixed by #15450 . (Sorry for being misleading in my comment!)

@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. compiler The Swift compiler in itself regression standard library Area: Standard library umbrella swift 4.1
Projects
None yet
Development

No branches or pull requests

2 participants