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-8155] Improve the error message when using existentials as inout arguments #50687

Closed
hartbit opened this issue Jun 29, 2018 · 7 comments
Closed
Assignees
Labels
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation improvement type checker Area → compiler: Semantic analysis

Comments

@hartbit
Copy link
Collaborator

hartbit commented Jun 29, 2018

Previous ID SR-8155
Radar None
Original Reporter @hartbit
Type Improvement
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, DiagnosticsQoI, TypeChecker
Assignee @beccadax
Priority Medium

md5: 3df8965b95eb9d162d2df0ab15306f99

is duplicated by:

  • SR-8148 inout is not working with subclass object throws Cannot pass immutable value

Issue Description:

I was puzzled by the following error:

func myPrint(to stream: inout TextOutputStream) {
    stream.write("myPrint")
}

var s = ""
myPrint(to: &s) // error: Cannot pass immutable value as inout argument: implicit conversion from 'String' to 'TextOutputStream' requires a temporary

I then understood, thanks to Slava (https://twitter.com/slava_pestov/status/1012747139951222785) that you can't pass an existential as an inout argument, because they need to be invariant.

Several ideas for improving the diagnostics:

  • Generate an error at the function declaration ("Cannot use protocols as inout arguments: consider using a generic argument instead")

  • Generate a better error at the use site ("Cannot pass protocols as inout arguments")

@beccadax
Copy link
Contributor

A small correction: You can pass an existential as an inout argument; you just can’t implicitly convert a concrete type to an existential when you pass it to an inout argument. If you wrote this code, it would be fine:

var temporary = s as TextOutputStream
myPrint(to: &temporary)
s = temporary as![]( String // But there’s no guarantee that this as) will succeed

I think there’s definitely something wrong with this error message—it’s just not conveying the problem in a way users can understand. Just last night, I talked to someone else in SR-8148 who was equally confused by it. We ought to find a way to address it.

@beccadax
Copy link
Contributor

Would this message have been better?

"cannot pass implicitly converted value of type 'String' as inout argument: use a temporary variable of exact type 'TextOutputStream' instead"

@beccadax
Copy link
Contributor

Or:

"inout argument could be set to a value which cannot be converted to type 'String': use a temporary variable of type 'TextOutputStream' instead"

@hartbit
Copy link
Collaborator Author

hartbit commented Jun 30, 2018

> "cannot pass implicitly converted value of type 'String' as inout argument: use a temporary variable of exact type 'TextOutputStream' instead"

I prefer this one

@beccadax
Copy link
Contributor

Adding a dupe for the other issue where someone didn't understand this error.

@beccadax
Copy link
Contributor

Pull request changing to that error messsage: #17656

@beccadax
Copy link
Contributor

Resolved by #17656.

@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
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation improvement type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants