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-11024] Type mismatch diagnostic is confusing for overloaded type names #53414

Closed
swift-ci opened this issue Jun 26, 2019 · 5 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-11024
Radar None
Original Reporter erikstrottmann (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0

macOS 10.14.5 Mojave
Swift 5.0.1 bundled with Xcode 10.2.1 (10E1001)

Issue is reproducible both in Xcode and with the swift CLI.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee owenvoorhees (JIRA)
Priority Medium

md5: 208a3858c23ad1593638fecb773b9e8b

duplicates:

  • SR-8513 Confusing error messages for interactions between same-name types from different modules

Issue Description:

Swift recently added a native Result type. If a module defines another type named Result, or a file imports another module that does the same, that second type will mask the native Swift type, which can still be referred to as Swift.Result.

The Swift compiler emits a diagnostic when a return expression doesn’t match the declared return type of the function. For example, the compiler emits the diagnostic for the expression return 0 in a function declared as -> String.

The mismatched return type diagnostic doesn’t handle type masking well. It includes the simple type names, but not the modules. That results in confusing messages like cannot convert return expression of type 'Result<Int, Error>' to return type 'Result<Int, Error>'. The message I would expect is cannot convert return expression of type 'MyModule.Result<Int, Error>' to return type 'Swift.Result<Int, Error>'.

Simple example:

enum Result<Success, Failure: Error> {
    case success(Success)
    case failure(Failure)
}

func internalResult() -> Result<Int, Error> {
    return .success(0)
}

func swiftResult() -> Swift.Result<Int, Error> {
    return internalResult()
}
$ swift OverloadedTypeError.swift 
OverloadedTypeError.swift:11:12: error: cannot convert return expression of type 'Result<Int, Error>' to return type 'Result<Int, Error>'
    return internalResult()
           ^~~~~~~~~~~~~~~~
@belkadan
Copy link
Contributor

owenvoorhees (JIRA User) is working on a fix for this! Owen, do you have the dup?

@swift-ci
Copy link
Collaborator Author

Comment by Owen Voorhees (JIRA)

Yeah, this looks like the same issue as SR-8513, just appearing in a different diagnostic. Thanks for reporting erikstrottmann (JIRA User), its great to have some more easily reproducible cases! The PR which should fix the issue can be found here: #25510

@swift-ci
Copy link
Collaborator Author

Comment by Owen Voorhees (JIRA)

This is now fixed on master / 5.1 branches

@swift-ci
Copy link
Collaborator Author

Comment by Erik Strottmann (JIRA)

This diagnostic issue is mostly fixed on 5.1, but a similarly confusing diagnostic still occurs when the level of optionality differs between the expected and actual types:

enum Result<Success, Failure: Error> {
    case success(Success)
    case failure(Failure)
}

func swiftResult() -> Swift.Result<Int, Error> {
    return .success(0)
}

let result1a: Swift.Result<Int, Error> = swiftResult() // Works
let result1b: Result<Int, Error> = swiftResult() // Helpful error: Cannot convert value of type 'Swift.Result<Swift.Int, Swift.Error>' to specified type 'Playground.Result<Swift.Int, Swift.Error>'

let result2a: Swift.Result<Int, Error>? = swiftResult() // Works
let result2b: Result<Int, Error>? = swiftResult() // Unhelpful error: Cannot convert value of type 'Result<Int, Error>' to specified type 'Result<Int, Error>?'

let result3a: Swift.Result<Int, Error>?? = swiftResult() // Works
let result3b: Result<Int, Error>?? = swiftResult() // Unhelpful error: Cannot convert value of type 'Result<Int, Error>' to specified type 'Result<Int, Error>??'

@swift-ci
Copy link
Collaborator Author

Comment by Owen Voorhees (JIRA)

This is unfortunately the expected behavior (for now) since the optional and non-optional types have different spellings. Once https://bugs.swift.org/browse/SR-11166 is fixed we should be able to do a much better job here, both at qualifying Swift.Result in the second and third examples, and not unnecessarily qualifying Int and Error in the first.

I have a patch lying around somewhere to begin addressing this, I'll see if I can clean it up before 5.2 branches.

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

No branches or pull requests

2 participants