Navigation Menu

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-7990] Using && on instance property in initializer results in confusing/incorrect error message #50523

Closed
swift-ci opened this issue Jun 13, 2018 · 6 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself definite initialization

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-7990
Radar None
Original Reporter freddyk (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate
Environment

Tested in Swift 4.2 on the Xcode 10 beta.

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

md5: 29a1e02d86cbd1e221018c402b373fab

duplicates:

  • SR-944 Cannot use 'self' in RHS of && before all properties are initialized

Issue Description:

The autoclosure of the second argument of Swift's && implementation has resulted in an error which at best is incredibly confusing, and in my opinion, actually incorrect. The code is as follows:

struct Test {
    var prop1: Bool
    var prop2: Bool
    
    init() {
        self.prop2 = false
        self.prop1 = true && self.prop2
    }
}

which results in the following error:

error: MyPlayground.playground:1:30: error: variable 'self.prop1' captured by a closure before being initialized
        self.prop1 = true && self.prop2

If I had not already been aware of the fact that the second argument of && is autoclosure'd, this error message would have been truly baffling. I never would have thought to look into the definition of the && operator as the source of the error until I had invested a long time debugging.

But this shouldn't even be an error at all! I've already initialized self.prop2, so I should be able to use it to initialize my other properties without having to resort to this workaround:

struct Test {
    var prop1: Bool
    var prop2: Bool
    
    init() {
        self.prop2 = false
        let temp = self.prop2
        self.prop1 = true && temp
    }
}

IMO, the compiler should be smart enough to realize that either we should not try to autoclosure this expression since it would capture self in an initializer, OR recognize that it only needs to capture properties of self that have already been initialized.

If this is undesired/infeasible at the moment, then the error message should at least give some indication that the reason for the capture is an autoclosure of the && operator, and that the issue is that all of self has to be captured. Note that if we make Test into a class, the error message is marginally better:

error: MyPlayground.playground:1:30: error: 'self' captured by a closure before all members were initialized
        self.prop1 = true && self.prop2

The current state of affairs makes it seem like there is somehow a closure capturing the left hand side of the = operator above.

@belkadan
Copy link
Contributor

cc @jckarter, @gottesmm, ravikandhadai (JIRA User)

@jckarter
Copy link
Member

Funny enough, this used to work in the early days when @_transparent inlining happened before definite initialization. We intentionally made that change long ago though. If we had a "runs exactly once" annotation for closures to allow definite initialization analysis through them, that would be the general feature we need to make something like this work again.

@belkadan
Copy link
Contributor

In this case we're dealing with information flowing into the closure, not out. Just having the closure not capture the entire self value would fix the problem in this case. (But it's not clear if that's generally desirable.)

@swift-ci
Copy link
Collaborator Author

Comment by Frederick Kellison-Linn (JIRA)

Would it also be an option to allow a capture of self as long as analysis can determine that any uninitialized properties are not used in the closure body?

@belkadan
Copy link
Contributor

Also possible, but tricky. And we'd have to be careful if we wanted to extend it to classes.

@gottesmm
Copy link
Member

The right way to do this is to use the ClosureScope analysis to perform definite init bottom up. That is likely to be a largish project.

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

No branches or pull requests

4 participants