Skip to content

[Sema] Add dedicated fix-it for NSObject.hashValue overrides #22081

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
merged 2 commits into from
Jan 28, 2019

Conversation

lorentey
Copy link
Member

@lorentey lorentey commented Jan 24, 2019

(Note: I intend to submit this for inclusion in 5.0, too.)

NSObject.hashValue used to be declared @objc open by historical accident. Unfortunately, overrides of NSObject.hashValue never worked correctly.

Swift 4.2 deprecated such overrides (#18407), and the property has been corrected to @nonobjc public in Swift 5.0 (#20129).

Help migration of existing code by adding a dedicated error message for overrides of NSObject.hashValue, with a nice fix-it directing people to override NSObject.hash instead.

// smash.swift
import Foundation

class Foo: NSObject {
  override var hashValue: Int {
    return 42
  }
}

Before:

$ swiftc smash.swift
smash.swift:4:16: error: overriding non-open property outside of its defining module
  override var hashValue: Int {
               ^
smash.swift:4:16: error: overriding non-@objc declarations from extensions is not supported
  override var hashValue: Int {
               ^
ObjectiveC.NSObject:3:25: note: add '@objc' to make this declaration overridable
    @nonobjc public var hashValue: Int { get }
                        ^

After:

$ swiftc smash.swift
smash.swift:4:16: error: 'NSObject.hashValue' is not overridable; did you mean to override 'NSObject.hash'?
  override var hashValue: Int {
               ^~~~~~~~~
               hash

rdar://problem/45674813

NSObject.hashValue used to be declared `@objc open` by historical accident. This has been corrected to `@nonobjc public` in Swift 5’s SDK overlays, to catch accidental overrides. (These never did work correctly, and shouldn’t have been allowed.)

Help migration by adding a dedicated error message for NSObject.hashValue overrides, with a nice fix-it.

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

@swift-ci please test

@lorentey
Copy link
Member Author

Unfortunately, NSObject.hashValue is still declared open in swift-corelibs-foundation, so this is a little more complicated than it should be. (The old deprecation warning remains for now, as we need to support both variants.) Fixing that is in progress (swiftlang/swift-corelibs-foundation#1820), but it won't necessarily land in the 5.0 timeframe.

@lorentey
Copy link
Member Author

}
}
// FIXME: Remove this when NSObject.hashValue becomes non-open in
// swift-corelibs-foundation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Arguably it's correct to warn even before the corelibs-foundation change, yeah?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes! We've had this warning on all platforms since 4.2. But I see no reason to keep it once NSObject.hashValue becomes non-open everywhere; it would never trigger in practice.

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.

2 participants