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-7268] [SILGen/exclusivity] call to nonmutating setter is not a mutation. #49816

Closed
atrick opened this issue Mar 24, 2018 · 5 comments
Closed
Assignees
Labels
compiler The Swift compiler in itself improvement

Comments

@atrick
Copy link
Member

atrick commented Mar 24, 2018

Previous ID SR-7268
Radar rdar://problem/38817096
Original Reporter @atrick
Type Improvement
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement
Assignee @jckarter
Priority Medium

md5: e48aca74fdd947f40063a338b94cec45

relates to:

  • SR-7248 Simultaneous access when using non-class-bound protocol

Issue Description:

Currently, SILGen emits a nonmutating setter call as a mutation of the underlying access path. Enough jargon. This is what happens to an innocent fruit basket:

public protocol Fruit {
  var seeds: Int { get nonmutating set }
}

class Apple: Fruit {
  init() {}
  
  var seeds: Int = 0
}

public class Basket {
  var fruit: Fruit = Apple()
}

public func foo(basket: Basket) {
  basket.fruit.seeds = 3
}

foo will begin an exclusive modify of `fruit`, call materializeForSet, execute the writeback, and end the exlusive access.

However, the fruit isn't actually being modified (according to this silly class-based model, the seeds aren't part of the value). So, we should not need exclusive access to fruit, and we shouldn't need to materializeForSet or writeback. Just getting a reference to its seeds and calling the setter should be fine.

In addition to performance, this actually affects semantics. Fixing this is backward source compatible though, so this is a good improvement to make any time.

protocol P {
  var s: String? { get nonmutating set }
}

class C: P {
  init() {}
  var s: String? {
    didSet {
      foo()
    }
  }
  static var shared: P = C()
}

func foo() {
  print(C.shared.s ?? "")
}

C.shared.s = "boo"
@atrick
Copy link
Member Author

atrick commented Mar 24, 2018

@swift-ci create

@atrick
Copy link
Member Author

atrick commented Mar 24, 2018

@rjmccall does this make sense?

@rjmccall
Copy link
Member

Yes, I think that's a good description of the problem. Do we really get this wrong? Sheesh.

@atrick
Copy link
Member Author

atrick commented Jun 7, 2018

This was fixed by @jckarter in PR #​16272 Narrow exclusivity duration for existential methods, and emit default arg generators late : https://github.com/apple/swift/pull/16272.

@atrick
Copy link
Member Author

atrick commented Jun 7, 2018

I reported this, so I guess it's on me to close it.

@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
compiler The Swift compiler in itself improvement
Projects
None yet
Development

No branches or pull requests

2 participants