Skip to content

[Foundation] Measurement: Add a correct hash(into:) implementation #20879

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

Closed
wants to merge 2 commits into from

Conversation

lorentey
Copy link
Member

The new definition normalizes measurements with dimensional units to their base unit, ensuring that the generated hash values are consistent with the definition of ==. It also feeds the unit to the hasher, not just the numerical value.

The old hashValue definition was invalid, and has been removed. (I.e., replaced by a compiler-supplied implementation that works in terms of hash(into:).)

rdar://problem/46187171

(This PR was split out of #20685)

The new definition normalizes measurements with dimensional units to their base unit, ensuring that the generated hash values are consistent with the definition of ==. It also feeds the unit to the hasher, not just the numerical value.

The old hashValue definition was invalid, and has been removed. (I.e., replaced by a compiler-supplied implementation that works in terms of hash(into:).)

rdar://problem/46187171
@lorentey
Copy link
Member Author

(Tests to cover hashing are coming soon.)

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.

We won't be able to make this change on its own — we have to maintain hash values identically between Measurement and NSMeasurement for bridging; with just this side, measurements are going to disappear from bridged sets and similar.

We should probably coordinate matching changes within Foundation at the same time.

@parkera
Copy link
Contributor

parkera commented Nov 29, 2018

Hm, good point @itaiferber. I was going to suggest also making sure the change made its way to swift-corelibs too.

@itaiferber
Copy link
Contributor

We should probably have the implementation also match equality exactly: NSMeasurement does not convert two values to their base unit before comparing for equality; unless we change the definition of equality, we'll need hashing to do the same thing.

@parkera
Copy link
Contributor

parkera commented Nov 29, 2018

I wonder if we can actually change the definition of equality on either side in a source compatible way.

@lorentey
Copy link
Member Author

@itaiferber @parkera There is no need to ever match hash values between structs defined in the Swift overlay and the corresponding Cocoa classes, even if they're bridged. Values get rehashed during bridging when necessary.

Swift and Cocoa have very different approaches to hashing -- starting with the fact that Swift's hash values are explicitly unstable across executions, since they're randomly seeded. Trying to preserve specific hash values for these types is therefore unnecessary.

Differences in the definition of equality are more unfortunate, but String and NSString manages to (mostly) make it work. Set and Dictionary needs to special-case bridging to handle duplicate String keys that arise during rehashing; it looks like Measurement needs the same workaround.

If Measurement can be changed to match equality with NSMeasurement, then that would simplify matters greatly. That's a source-breaking change, though.

Note that Swift deprecated hashValue as a Hashable requirement in 4.2; the new hashing interface is hash(into:), and we'll need to migrate the overlays to using it soon. (#20685 has some experimental commits for this.)

@lorentey
Copy link
Member Author

To clarify: the issue only affects Measurement, not NSMeasurement.

Foundation proper doesn't need to be changed -- NSMeasurement's hashing is consistent with its own definition for isEqual(_:).

@lorentey
Copy link
Member Author

@swift-ci smoke test

@lorentey
Copy link
Member Author

@swift-ci please smoke test

@lorentey
Copy link
Member Author

lorentey commented Apr 6, 2019

This is now subsumed into #23832.

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.

3 participants