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-5172] lazy variable resetting no longer works, but breaking change wasn't documented #47748

Closed
swift-ci opened this issue Jun 9, 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

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jun 9, 2017

Previous ID SR-5172
Radar rdar://problem/32687168
Original Reporter BenLeggiero (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Relevant environment:

  • macOS 10.12.5 (16F73)

  • Xcode Version 9.0 beta (9M136h)

  • Apple Swift version 4.0 (swiftlang-900.0.43 clang-900.0.22.8)

  • Target: x86_64-apple-macosx10.9

Comparison environment:

  • macOS 10.12.5 (16F73)

  • Xcode Version 8.3.3 (8E3004b)

  • Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)

  • Target: x86_64-apple-macosx10.9

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

md5: e9898aa0b915c8f6d135352f3e2b59b8

Issue Description:

As of Swift 3.2, the behavior described here was possible and reliable. In Swift 4, it results in the value being `nil` forever.

While I agree this change makes the language more consistent and predictable, it wasn't documented anywhere I can find.


Test:

class Lazy {
    lazy var test: String! = "original value"
}

let l = Lazy()

l.test // "original value"
l.test = "new"
l.test // "new"
l.test = nil
assert(l.test != nil, "In Swift 3, lazy value is re-initialized")
@belkadan
Copy link
Contributor

Yikes. This was certainly never intended behavior, as evidenced by the fact that it only works with ImplicitlyUnwrappedOptional and not regular Optional.

@swift-ci create

@belkadan
Copy link
Contributor

You're right that it should be documented at least.

@slavapestov
Copy link
Member

Something changed around IUOs and optionals nested inside of another. We don't normally allow you to write a type like 'String!?', but it comes up in the synthesized lazy property setter.

I agree the new behavior is more consistent but this was not an intentional change so we should figure out what changed and add some detailed tests at least.

Here is an example demonstrating the problem that doesn't use 'lazy':

typealias S = String!

var t: S? = "hello"

func setT(value: S) {
  t = value
}

func foo() {
  if let tt = t {
    print(tt)
  }

  setT(value: nil)

  if let tt = t {
    print(tt)
  }
}

foo()

@slavapestov
Copy link
Member

#10911

@rjmccall
Copy link
Member

It could be a combination of several different things. I fixed a bug (commit 7bb2631) involving optional-to-optional conversions where CSApply used to produce ASTs that would incorrectly translate some(nil) into nil. The synthesized AST for a lazy var setter contains a conversion from the parameter type (presumably T to the backing storage type (presumably T)?). CSApply should just use InjectIntoOptionalExpr for that, but if it did something weird like added the injection and then somehow did a multi-level conversion, then an incoming value (nil) would've been injected (some(nil)) and then converted into nil, which if stored into the property would have the effect of resetting it. But I don't have an old compiler around to look at the type-checked generated AST for the lazy setter.

@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 regression swift 4.0
Projects
None yet
Development

No branches or pull requests

5 participants