Skip to content

Address exclusivity warnings in JSONEncoder #1512

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

Merged

Conversation

devincoughlin
Copy link
Contributor

An idiom used in JSONEncoder is violating Swift's rules about exclusive
access to memory. The 'with(pushedKey:)' family of mutating functions
on EncodingContainers modify 'self' by pushing a key, executing a
passed-in closure, and popping the key. However, when the passed-in closure
refers to 'self' this violates the rules for exclusive access since the
closure reads self while with(pushedKey:) has an already in-progress
modification of 'self'.

return self.with(pushedKey: _JSONKey(index: self.count - 1)) {
// Referring to 'self.codingPath' violates rules for exclusive access.
...
}

The compiler is warning about this. To address these warnings, change
the callback to with(pushKey:) to accept an additional parameter: the
modified encoding container. This enables the closure to safely refer to it
without accessing via the captured self and avoids the violation of
exclusive access to memory. This also makes it explicit that in the body the
body of the closure the value of .codingPath read is the mutated one and
not the original.

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@devincoughlin
Copy link
Contributor Author

@itaiferber Would you be willing to take a look?

Copy link
Contributor

@itaiferber itaiferber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look at this and putting this together! In swiftlang/swift#10821 we eliminated the issue by simply removing with<T> altogether (this was preferred because we need to defer in case something throws and not corrupt the coding path), and unfortunately, it looks like we forgot to port those changes over.

To keep things in line, do you think we could match suit here instead?

@parkera
Copy link
Contributor

parkera commented Apr 12, 2018

Porting those changes is where I ran into the bridging issues in #1347.

@parkera
Copy link
Contributor

parkera commented Apr 12, 2018

I agree we should not diverge further here.

@itaiferber
Copy link
Contributor

@parkera I don't think the specific changes made in swiftlang/swift#10821 caused the bridging issues in #1347; they don't touch any of the code surrounding that. I think it should be possible to apply those pretty cleanly.

@parkera
Copy link
Contributor

parkera commented Apr 12, 2018

All I did there was merge in the same changes (before any of the key strategy stuff), but if we're more successful here then -- great!

Bring in changes from the Swift overlays to avoid exclusivity warnings. These
changes come from: swiftlang/swift#10821
@devincoughlin devincoughlin force-pushed the exclusivity-json-encoder-fix branch from 130a174 to 3c1c32d Compare April 13, 2018 03:53
@devincoughlin
Copy link
Contributor Author

Updated to bring in the changes from swiftlang/swift#10821 instead.

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

1 similar comment
@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@devincoughlin
Copy link
Contributor Author

@itaiferber is this OK to merge? The only interesting conflicts I had to resolve were making sure the encode() functions continue to call '._bridgeToObjectiveC()' (they didn't in swiftlang/swift#10821).

@ianpartridge
Copy link
Contributor

Thanks for working on this! There are still quite a large number of differences between the version in the overlay and the result of this PR: https://www.diffchecker.com/XV65PeTY

Our goal is to bring the file in this repo back in sync with the overlay, as far as possible. Would you be willing to do that under this PR?

@ikesyo
Copy link
Member

ikesyo commented Apr 13, 2018

@ianpartridge JSON key strategy part should not be included in this PR; that should be tracked separately in #1347.

@devincoughlin
Copy link
Contributor Author

@ianpartridge I'm doing this to unblock a needed compiler change (swiftlang/swift#15915). I don't think we should generally block compiler changes on swift-corelibs-foundation being in sync with the overlays.

@ianpartridge
Copy link
Contributor

I see - I wasn't aware of the compiler work. Thanks for the info. In that case, if @itaiferber is happy we should merge this as-is.

Copy link
Contributor

@itaiferber itaiferber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for taking care of this!

@itaiferber itaiferber merged commit f406f74 into swiftlang:master Apr 13, 2018
@devincoughlin
Copy link
Contributor Author

@ianpartridge To be clear, I think the criterion that the divergence shouldn't get any worse makes a lot of sense!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants