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

Change objcImpl syntax to @objc @implementation #73309

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Apr 27, 2024

This PR changes the type-checking rules for objcImpl to require an @objc attribute. It also moves the category name from the @implementation attribute to the @objc attribute. Backwards compatibility is maintained for the pre-stabilization @_objcImplementation syntax.

As part of this change, plain @objc(CustomName) on an extension now changes its category name when it is printed through PrintAsClang or IRGen'd; the name previously was parsed and partially validated but ignored. The only new diagnostic related to this is a warning in Swift 5 mode but will be an error in Swift 6 mode.

This draft currently incorporates commits from #73128 and will need to be rebased once that lands, so don't worry about the gigantic Reviewers list it has right now.

@beccadax
Copy link
Contributor Author

@swift-ci please test

This contains the category name, if there is one.
This now specifies a category name that’s used in TBDGen, IRGen, and PrintAsClang. There are also now category name conflict diagnostics; these subsume some @implementation diagnostics.

(It turns out there was already a check for @objc(CustomName) to make sure it wasn’t a selector!)
Their syntaxes are about to diverge, so let’s make sure that we maintain source compatibility for @_objcImplementation.
…for extensions. This change also removes @implementation(CategoryName); you should attach the category name to the @objc attribute instead.
@beccadax beccadax force-pushed the objcimpl-category-on-objc branch from 80b9929 to cc8edf0 Compare May 1, 2024 19:19
@beccadax
Copy link
Contributor Author

beccadax commented May 2, 2024

@swift-ci please test

Previous changes have made it so that `private let`s in an objcImpl extension are implicitly `@objc`, which changed downstream behavior in a SILOptimizer test. The new behavior is actually more correct, so codify this behavior change by modifying the test.
@beccadax
Copy link
Contributor Author

beccadax commented May 3, 2024

@swift-ci please test

@beccadax beccadax requested review from tshortli and Jumhyn May 3, 2024 19:43
@beccadax
Copy link
Contributor Author

beccadax commented May 7, 2024

@swift-ci Please Build Toolchain macOS Platform

@beccadax
Copy link
Contributor Author

beccadax commented May 7, 2024

@swift-ci Please Build Toolchain Linux Platform

return;

// Use a linear scan on the assumption that there aren't very many extensions.
for (auto *other : getExtensions()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's probably not a performance problem in practice, but I do worry about things like generated code breaking this kind of assumption. This could be pretty easily transformed into a request that caches an Obj-C category name to ExtensionDecl map.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I probably don't want the map to be per-ClassDecl because the vast majority of classes won't have any extensions with a category name, but maybe it can be per-module or something, with a std::pair<ClassDecl *, Identifier> key.

Copy link
Contributor

Choose a reason for hiding this comment

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

Request result storage goes in a DenseMap unless you choose to customize it to be inline, and you'd only need to allocate the extension map result for classes that have recordObjCCategory() called on them so in practice I think it wouldn't create much overhead to do it per-class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that adding an extension invalidates the lookup table, and recordCategory(ext) is called immediately after ext is added to its class, so it's likely the table will be incomplete. But if we defer the conflict-checking logic until after we've added all the extensions to the class, we can then use a lookup table to accelerate conflict checking. It's just a bigger redesign of this logic than "drop a lookup table into this existing function", which is what I thought you were suggesting!

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, that makes sense. If you were to delay this check to after all extensions were registered, no extra storage would be needed I guess because it can just be a single pass over the complete list of extensions.

@beccadax
Copy link
Contributor Author

beccadax commented May 8, 2024

Won't be able to build a toolchain until apple/llvm-project#8714 merges.

@@ -3614,6 +3812,18 @@ class ObjCImplementationChecker {
}
}

static SmallString<64> makeObjCAttrInsertionText(Identifier categoryName) {
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: is there a way we could share the two copies of makeObjCAttrInsertionText?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I was being a little lazy here. Let me see if I can clean this up.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you!

@beccadax
Copy link
Contributor Author

beccadax commented May 8, 2024

@swift-ci please build toolchain

@beccadax
Copy link
Contributor Author

beccadax commented May 8, 2024

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.

None yet

3 participants