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-9215] Misleading error message when decoding a type #51704

Open
swift-ci opened this issue Nov 9, 2018 · 2 comments
Open

[SR-9215] Misleading error message when decoding a type #51704

swift-ci opened this issue Nov 9, 2018 · 2 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself definite initialization diagnostics QoI Bug: Diagnostics Quality of Implementation

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Nov 9, 2018

Previous ID SR-9215
Radar None
Original Reporter eimantas (JIRA User)
Type Bug

Attachment: Download

Environment

macOS 10.14.1

Xcode 10.1

Swift 4.2

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, DefiniteInitialization, DiagnosticsQoI
Assignee None
Priority Medium

md5: 89ca81b994e4cea7c9dcfc0eacc09a78

Issue Description:

All,

I have encountered a misleading error message that kept me in debugging for a few minutes until I actually realized what's the problem.

I have simplified it down to this:

import Foundation

struct S {
    var foo: Int
    var bar: String
}

extension S: Decodable {

    enum CodingKeys: String, CodingKey {
        case foo, bar
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        foo = try container.decode(Int.self, forKey: .foo)
        
        let tmpBar = try container.decode(String.self, forKey: .bar)

        bar = tmpBar.map({ (char) -> String in
        //          ^--- `bar` captured by closure error here
            return "\(char)\(foo)"
        }).joined(separator: " ")
    }
}

The problem is that I'm decoding a .bar keyed value into temporary variable tmpBar that I'm later using to derive a real bar value. And I used foo instance variable to do that. However the error message tells me that bar was actually captured by a closure before being initialised. To fix I just had to do a local copy of instance variable that I was using inside map closure.

Please find the compressed playground attached.

@belkadan
Copy link
Contributor

belkadan commented Nov 9, 2018

cc ravikandhadai (JIRA User)

@swift-ci
Copy link
Collaborator Author

Comment by Ravichandhran Kandhadai Madhavan (JIRA)

The problem here is that the closure passed to the `map` function actually captures `self` since it accessing the property `foo` of self. As such, the definite initialization phase requires all (stored) properties of a captured instance to be initialized. Since the property `bar` of self is not initialized at the time of creating the closure, we get this weird error that `self.bar` is not initialized. This is a known problem and there should be several clones of this problem. Ideally, code snippets like these that only access initialized properties of self should be allowed, but this requires an inter-procedural initialization check at the SIL level. At the very least, the error message must be improved. Probably a message like this would be better: "Variable 'self' is captured by the closure before all of its properties have been initialized. Note that 'self.bar' is not initialized before this closure.'

@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 definite initialization diagnostics QoI Bug: Diagnostics Quality of Implementation
Projects
None yet
Development

No branches or pull requests

2 participants