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-5735] unable to infer closure type but able to provide Fix-It #48305

Open
mattneub opened this issue Aug 22, 2017 · 5 comments
Open

[SR-5735] unable to infer closure type but able to provide Fix-It #48305

mattneub opened this issue Aug 22, 2017 · 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 4.0 type checker Area → compiler: Semantic analysis

Comments

@mattneub
Copy link

Previous ID SR-5735
Radar None
Original Reporter @mattneub
Type Bug

Attachment: Download

Environment

Xcode Version 9.0 beta 6 (9M214v)

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

md5: 4b26827cc50cd2854440c53e30a6638a

Issue Description:

As shown in the attached screen shot, I'm being told that we can't infer the type of a closure return type, but I'm also being given a Fix-It suggestion that inserts that type correctly.

Maybe I'm just being dense here, but if Fix-it can correctly tell me and insert the return type, doesn't that mean we can infer its type? If Fix-It can do this, why can't the compiler do it?

[Should have mentioned that this compiled fine in Xcode 8.1 and even Xcode 9 beta 3. So part of the bug report is that this used to compile, quite recently.]

Test code:

        var s = "yohohohoho"
        s = s.replacingOccurrences(of:"<date>", with:{
            let df = DateFormatter()
            df.dateFormat = "d MMMM yyyy"
            let us = "en_US"
            if Locale.availableIdentifiers.contains(us) {
                df.locale = Locale(identifier:us)
            }
            return df.string(from: Date())
        }())
@CodaFi
Copy link
Member

CodaFi commented Aug 23, 2017

Currently, Sema doesn't form a function type early enough to apply the contextual type and solve this kind of closure. It's something I want to look into because it stems from an odd modeling problem in CSGen around multi-statement closures.

The diagnostic is emitted because we just dive into the first return we find, hope it type checks, and hand you back a closure type that probably looks like what you want. In more generic cases, this diagnostic does actually disambiguate certain candidate solutions.

@mattneub
Copy link
Author

@CodaFi Thanks for that!

I'm still confused, though. Why did that code compile fine, with no warning or error, until now? (Compiles under Xcode 8.1, for example. Even compiles under Xcode 9 beta 3.) Was the compiler wrongly believing that it could cope when it fact it couldn't? Did it suddenly get smarter so that it realized it was stupider ("known unknowns")?

And why is the surrounding context not sufficient? Swift knows what replacingOccurrences(of:with:) expects as its second parameter — a String. And that's what I'm supplying.

I've modified my original question to provide actual test code so people can play around with it ....

@rintaro
Copy link
Mannequin

rintaro mannequin commented Aug 23, 2017

This is because the signature of replacingOccurrences(of:with:) has been changed:

public func replacingOccurrences<
Target : StringProtocol,
Replacement : StringProtocol
>(
of target: Target,
with replacement: Replacement,
options: String.CompareOptions = [],
range searchRange: Range<Index>? = nil
) -> String {

public func replacingOccurrences<                                            
  Target : StringProtocol,                                                   
  Replacement : StringProtocol                                               
>(                                                                           
  of target: Target,                                                         
  with replacement: Replacement,                                             
  options: String.CompareOptions = [],                                       
  range searchRange: Range<Index>? = nil
) -> String

StringProtocol not String so that it can receive Substring type.

@mattneub
Copy link
Author

@rintaro Aha! Thank you.

@CodaFi I think that just about covers it for me. I still find the Fix-It behavior odd, and I probably won't be the only one, but this can be closed as far as I'm concerned. Thanks again.

@belkadan
Copy link
Contributor

@xedin, any additional thoughts? Maybe it's worth noting that it's guessing based on the return, if that's what it's doing?

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

No branches or pull requests

4 participants