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-10279] Generic auto type incorrect for Optional #52679

Open
swift-ci opened this issue Apr 3, 2019 · 5 comments
Open

[SR-10279] Generic auto type incorrect for Optional #52679

swift-ci opened this issue Apr 3, 2019 · 5 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

swift-ci commented Apr 3, 2019

Previous ID SR-10279
Radar rdar://problem/49629055
Original Reporter ProVir (JIRA User)
Type Bug
Environment

Apple Swift version 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)

Target: x86_64-apple-darwin18.2.0

Xcode Version 10.2 (10E125)

macOS 10.14.3 (18D109)

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

md5: 18f9cb2a2ea627454dac0fb32ecf18d9

Issue Description:

In swift 4.2 printed "OneService" and return Optional<OneService>.

In swift 5.0 bug - printed "Optional<OneService>" and return Optional<Optional<OneService>> and success converted to Optional<OneService>.

func getService<ServiceType>() -> ServiceType? {
    print("\(ServiceType.self)")
    return nil
}

class OneService { }
let service: OneService? = getService()

Why ServiceType in swift 5 is Optional<OneService>, return type is Optional<Optional<OneService>>, this is BUG?

@belkadan
Copy link
Contributor

belkadan commented Apr 3, 2019

I can't reproduce this. Can you include a full playground, package, or project where this is happening, so that we can be sure we're building the same way as you?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Apr 3, 2019

Comment by Vitalii Korotkii (JIRA)

Sorry, here is the real code that reproduces my situation, did not notice that my getService method calls tryService.

struct MyError: Error { }
class OneService { }

func tryService<ServiceType>() throws -> ServiceType {
    print("\(ServiceType.self)")
    throw MyError()
}

func getService<ServiceType>() -> ServiceType? {
    return try? tryService()
}

let service: OneService? = getService()

In this example, given the change in behavior of try? Is the code working correctly and can the bug be closed?

@belkadan
Copy link
Contributor

belkadan commented Apr 3, 2019

Hm. That seems like an unintended consequence of SE-0230. @bjhomer, @xedin, any thoughts?

@bjhomer
Copy link
Contributor

bjhomer commented Apr 4, 2019

I agree that it's an unintended consequence, but I can guess why it's happening. The return type of tryService() is being inferred by its context, where the overall expression try? tryService() has to produce a ServiceType?. Prior to Swift 5, there was only one possible way for that to happen; tryService() had to produce a non-optional ServiceType so that the try? could add an extra layer of optional-ness.

Under Swift 5 with SE-0230, there are two options; tryService() could either produce a ServiceType or a ServiceType?. Either one satisfies the constraints. I suspect that the type checker is preferring the latter option because then try? doesn't have to add an implicit conversion. But it would make sense to prefer the less-optional alternative when possible.

At least, that's my guess.

@xedin
Copy link
Member

xedin commented Apr 5, 2019

Yes, it seems this way because `tryService` would like to return opened generic parameter as a result e.g. `$T0` which has to be converted to optional (e.g. $T1?) as a result of `try?` expression (that's why we add `$T0 conv $T1?` constraint), which means that only binding for `$T0` is `$T1?` which makes it - `ServiceType?` which doesn't involve any implicit conversions. It seems like we'd have to remodel how relationship of result type of try? and result of nested expression is represented.

@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
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

5 participants