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-10194] Ambiguous use of operator '>>' #52594

Closed
swift-ci opened this issue Mar 27, 2019 · 11 comments
Closed

[SR-10194] Ambiguous use of operator '>>' #52594

swift-ci opened this issue Mar 27, 2019 · 11 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 5.0 type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-10194
Radar rdar://problem/49339824
Original Reporter sofacoder (JIRA User)
Type Bug
Status Resolved
Resolution Won't Do
Environment

Apple Swift version 5.0 (swiftlang-1001.0.69.3 clang-1001.0.47).

Tested on macOS and iOS Plattform

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

md5: 432c1bba1617d7e8b17ff3a3c8b89b01

Issue Description:

Since swift 5 the following code breaks with "Ambiguous use of operator '>>'". In swift 4.2.1 this code works.

import Foundation

let zeroBits = 1
var data = Data(repeating: 127, count: 1)

data.withUnsafeMutableBytes { bytes in
    bytes[0] &= UInt8(0xff >> zeroBits) // compiler error: Ambiguous use of operator '>>'
}

data.withUnsafeMutableBytes { bytes in
    let tmp = 0xff >> zeroBits
    bytes[0] &= UInt8(tmp) // works
}

var value: UInt8 = 3
value &= UInt8(0xff >> zeroBits) // works

var values = [UInt8(3)]
values[0] &= UInt8(0xff >> zeroBits) // works
@xedin
Copy link
Member

xedin commented Apr 10, 2019

Looks like this problem has been caused by a new deprecated overload of `withUnsafeMutableBytes` method added by this commit - d030354 Since we don't rank down deprecated overloads this makes your expression truly ambiguous.

@xedin
Copy link
Member

xedin commented Apr 10, 2019

@phausler
Copy link
Member

Honestly if we are to move full steam ahead without breaking binary compatibility we need to deprecate and replace. It seems to me the compiler should down rank deprecated overloads.

@phausler
Copy link
Member

I need to break this apart more. Often times the compiler just flakes out with blocks and the diagnostic.

@xedin
Copy link
Member

xedin commented Apr 10, 2019

The choice not to down rank deprecated overloads has been a deliberate one, since we'd want the code to use the old overload if possible. Diagnostic about `>>` is indeed an incorrect one unfortunately, but should point to `withUnsafeMutableBytes` instead.

@phausler
Copy link
Member

Perhaps if the decision was made explicitly then it would be useful to have an attribute to mark them as less desirable by the solver. The deprecated method in question was marked that way not because we wanted a new interface only, it was deprecated because the old one was really unsafe (like wrong and could lead to undefined behavior and other nasties).

@itaiferber
Copy link
Contributor

I don't see what the ambiguity here has anything to do with our changes. The issue in question is 0xff >> zerobits, which has nothing to do with Data.
More so, bytes[0] &= UInt8(...) should be unambiguous regardless of what's in the UInt8 initializer, since it's a standalone subexpression.

@xedin
Copy link
Member

xedin commented Apr 11, 2019

@itaiferber The problem is that type-checker now finds 4 solutions related to `withUnsafeMutableBytes`, 3 of them have the same overload (and different overloads for `>>`):

```
Foundation.(file).Data.withUnsafeMutableBytes as @lvalue Data.withUnsafeMutableBytes: ((UnsafeMutablePointer<T>) throws -> T) throws -> T
```

The forth however has this overload:

```
Foundation.(file).Data.withUnsafeMutableBytes as @lvalue Data.withUnsafeMutableBytes: ((UnsafeMutableRawBufferPointer) throws -> T) throws -> T
```

and overload of `>>` picked from protocol requirement on BinaryInteger

Which makes this ambiguous.

@xedin
Copy link
Member

xedin commented Sep 26, 2019

After further discussion with @itaiferber we came to an understanding that unfortunately there is no way to resolve this issue because type-checker can't really distinguish this properly and old overload can't be obsoleted in Foundation. You'd have to use a temporary variable as a workaround.

@theblixguy
Copy link
Collaborator

> Perhaps if the decision was made explicitly then it would be useful to have an attribute to mark them as less desirable by the solver.

Can we use the @_disfavoredOverload attribute?

@xedin
Copy link
Member

xedin commented Sep 26, 2019

I'd rather not because that's not something we'd like to keep.

@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 swift 5.0 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

6 participants