Skip to content

ModuleInterface: Wrap synthesized extensions in swiftinterfaces with feature guards #42276

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

tshortli
Copy link
Contributor

@tshortli tshortli commented Apr 9, 2022

When printing synthesized extensions, we need to be sure to guard them with required features if applicable. Not doing so can result in broken interfaces that do not typecheck because, for instance, a conformance can refer to a nominal type that is only declared when certain features are enabled.

Also, fix a typo where #elsif was printed into interfaces instead of #elseif.

Resolves rdar://91509673

@tshortli tshortli requested a review from rjmccall April 9, 2022 02:36
@tshortli
Copy link
Contributor Author

tshortli commented Apr 9, 2022

@rjmccall I think this may have regressed with #41399, would you mind reviewing?

[&] { printBody(); });
} else {
printBody();
}
Copy link
Contributor

@rjmccall rjmccall Apr 11, 2022

Choose a reason for hiding this comment

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

Okay, so @slavapestov removed this logic in a recent patch because (1) he realized that it's checking based on the features used by the extended declaration and not the extension itself, so it's a bit broken, and (2) it wasn't tested in any way. If we're going to put this back, we should really fix the first part. It looks like extensions are considered to use the $GlobalActors feature if they're extending a type that's a global actor, so maybe you just need to pass in the extension here instead of nominal.

Copy link
Contributor

Choose a reason for hiding this comment

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

There's no ExtensionDecl here though; these extensions are "synthesized", meaning they only exist in the imagination of the ASTPrinter.

Copy link
Contributor Author

@tshortli tshortli Apr 11, 2022

Choose a reason for hiding this comment

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

I tried restoring the logic removed with #42238 and that doesn't solve this bug (because it checked whether the protocol requires features, rather than the extended type). Given what Slava points out above (we don't have an ExtensionDecl) is there something better I can do here? Do I understand correctly that what I have currently is correct but theoretically insufficient for fixing some other bugs where the extension, rather than the extended type, depends on a conditionally available feature?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we synthesize a real ExtensionDecl, or is that difficult in practice?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do I understand correctly that what I have currently is correct but theoretically insufficient for fixing some other bugs where the extension, rather than the extended type, depends on a conditionally available feature?

At the very least, I think it probably needs to consider the availability of both the protocol and the extended type.

It will also redundantly emit the extension under different conditions if the nominal type is emitted redundantly that way, which is unnecessary but I guess not actually a problem.

Copy link
Contributor

Choose a reason for hiding this comment

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

Slava can speak to the request-evaluator parts better than I can.

Copy link
Contributor

Choose a reason for hiding this comment

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

The request evaluator parts look fine, but I'm wondering if you can remove the printBody lambda with it's bespoke printing logic and just feed the synthesized ExtensionDecl to the ASTPrinter itself?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess you'll need to attach the correct availability and SPI attributes to the synthesized extension also, but it would still be better to not duplicate the printing logic here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does seem feasible to let the ASTPrinter be responsible for the printing. I am having to handle a number of small details with care, though, to ensure that the swiftinterface contents remain unchanged after taking this approach. (I don't want this under the hood change to cause a lot of churn in interfaces for no good reason since folks diff the interfaces to understand what is being added and removed from build to build).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, I completely revamped this to use the ASTPrinter to emit the extension declaration. PTAL @slavapestov

@tshortli tshortli force-pushed the global-actor-broken-swift-interface branch 2 times, most recently from 8cb9535 to 3878df8 Compare April 11, 2022 23:47
@tshortli tshortli requested a review from rjmccall April 11, 2022 23:50
@tshortli tshortli force-pushed the global-actor-broken-swift-interface branch 3 times, most recently from 3f3c37b to 7694fa1 Compare April 13, 2022 00:48
…sure to guard them with required features if applicable. Not doing so can result in broken interfaces that do not typecheck because, for instance, a conformance can refer to a nominal type that is only declared when certain features are enabled.

Also, fix a typo where `#elsif` was printed into interfaces instead of `#elseif`.

Resolves rdar://91509673
@tshortli tshortli force-pushed the global-actor-broken-swift-interface branch from 7694fa1 to f27005b Compare April 13, 2022 00:54
@tshortli
Copy link
Contributor Author

@swift-ci please test

@tshortli tshortli requested a review from slavapestov April 13, 2022 21:48
@tshortli tshortli merged commit cc0627a into swiftlang:main Apr 14, 2022
@tshortli tshortli deleted the global-actor-broken-swift-interface branch April 25, 2022 23:38
tshortli added a commit to tshortli/swift that referenced this pull request May 27, 2022
…aces

Erroneous declaration attributes were sometimes being printed in the private swiftinterfaces of modules because the changes from swiftlang#42276 were effectively corrupting the attribute list for any decl with sythesized conformances (e.g. `Equatable`, `Hashable`). It is necessary to clone the attributes before adding them to the synthesized conformance extension decls.

Resolves rdar://94009296
tshortli added a commit to tshortli/swift that referenced this pull request May 30, 2022
…aces

Erroneous declaration attributes were sometimes being printed in the private swiftinterfaces of modules because the changes from swiftlang#42276 were effectively corrupting the attribute list for any decl with sythesized conformances (e.g. `Equatable`, `Hashable`). It is necessary to clone the attributes before adding them to the synthesized conformance extension decls.

Resolves rdar://94009296
tshortli added a commit to tshortli/swift that referenced this pull request May 31, 2022
…aces

Erroneous declaration attributes were sometimes being printed in the private swiftinterfaces of modules because the changes from swiftlang#42276 were effectively corrupting the attribute list for any decl with sythesized conformances (e.g. `Equatable`, `Hashable`). It is necessary to clone the attributes before adding them to the synthesized conformance extension decls.

Resolves rdar://94009296
amritpan pushed a commit to amritpan/swift that referenced this pull request Jun 10, 2022
…aces

Erroneous declaration attributes were sometimes being printed in the private swiftinterfaces of modules because the changes from swiftlang#42276 were effectively corrupting the attribute list for any decl with sythesized conformances (e.g. `Equatable`, `Hashable`). It is necessary to clone the attributes before adding them to the synthesized conformance extension decls.

Resolves rdar://94009296
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