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-7257] Property observers being called on a nil struct instance upon attempt to mutate a member property #49805

Open
AnthonyLatsis opened this issue Mar 22, 2018 · 8 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@AnthonyLatsis
Copy link
Collaborator

Previous ID SR-7257
Radar rdar://problem/38797312
Original Reporter @AnthonyLatsis
Type Bug
Environment

Xcode Version 9.2 (9C40b)

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

md5: 5ad4504b82dc7311d33318e3a9dbcb12

Issue Description:

struct A { 
    var foo: Int { 
        didSet { print("fooDidSet") } // not called
    }
}

var a: A? {
    didSet { print("didSet") } // called
}

a?.foo = 5

Although apparently nothing is mutated, the observers of a are always called.

Refer to this thread for the discussion.

The SIL seems to be copying the entire composite variable (Int -> A -> Optional<A>) onto the stack, the didSet invocation simply being a side-effect of running the variable’s setter to copy back the contents from the stack.

"So no, evidently the compiler is not recognizing that it’s dealing with one big composite of value types and simply figuring that it can treat them all as one lump of data. It’s repeating the same unpacking process at every layer of nesting."

Might be related to SR-7220

@belkadan
Copy link
Contributor

Hm. @rjmccall, what do you think is the right behavior here, with optional chaining involved?

@rjmccall
Copy link
Member

I think the right behavior is for things like this to abort the mutation and not call the setter. We currently can't do that consistently for all accesses because of materializeForSet, but generalized accessors will make it possible.

@belkadan
Copy link
Contributor

@swift-ci create

@swift-ci
Copy link
Collaborator

swift-ci commented May 8, 2018

Comment by Stephan Schulz (JIRA)

Please fix asap, the new behavior is annoying.

@belkadan
Copy link
Contributor

belkadan commented May 8, 2018

This isn't new behavior; it's been like this since Xcode 8.3 at least. (There have been recent regressions in didSet behavior, but this isn't one of them.)

@swift-ci
Copy link
Collaborator

swift-ci commented May 9, 2018

Comment by Stephan Schulz (JIRA)

Thanks for clarification. What kind of regressions have been made in the didSet behavior? I've experienced infinity loops connected to didSet and materializeForSet, which havn't been there in previous versions. This definitely feels like a bug to me after upgrading to Swift 4.1.

@swift-ci
Copy link
Collaborator

Comment by Stephan Schulz (JIRA)

I've created a bug report SR-7647

@rjmccall
Copy link
Member

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

No branches or pull requests

4 participants