Skip to content

[NFC] Refactor @_dynamicReplacement Checking #28434

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 6 commits into from
Dec 4, 2019

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Nov 22, 2019

Refactor the way the compiler deals with @_dynamicReplacement. This started as an effort to just lazy-load the member instead of forcing the cross-reference in deserialization - this caused a cycle in name lookup.

It wound up being... a lot more.

Add a request for the original decl behind a @_dynamicReplacement attribute. The request absorbs the lazy member loading logic, the previous logic in the type checker for validating this attribute, and the logic for handling accessors. There is also a change to the way we validate and check this attribute. Rather than strip it from VarDecls and place it back onto their accessors, leave it where it is. The accessors can use the attribute attached to their storage to recover the replaced decl they need by lookup and type match. This also means we can simplify and remove some predicates that were used by IRGen and SILGen that required fanning out and iterating over all the accessors just to see if they had @_dynamicReplacement reparented onto them.

This also changes the decls we serialize this attributes for - we're no longer serializing all the accessors' replacements, and we're now serializing all the VarDecl's replacements - so bump the module format version.

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 22, 2019

@swift-ci please test

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 22, 2019

@swift-ci please test source compatibility

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - b857f488f02bbeb548c0b400a2a656bb116e007d

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 22, 2019

@swift-ci please clean test macOS platform

Copy link
Contributor

@aschwaighofer aschwaighofer left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 22, 2019

Leaving this here for the break. Will cherry-pick this to our side branch for dependency tracking.

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 23, 2019

@swift-ci please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 23, 2019

@swift-ci please clean smoke test macOS platform

@CodaFi
Copy link
Contributor Author

CodaFi commented Dec 2, 2019

@swift-ci please smoke test

To support lazy resolution of the cross-referenced function in a serialized @_dynamicReplacement(for: ...) attribute, add a utility to the LazyMemberLoader and plumb it through.  This is a more general utility than the current resolver, which relies on the type checker to strip the attribute off of VarDecls and fan it back out onto accessors, which means serialization has only ever seen AbstractFunctionDecls.
Remove a dead overload and add an overload for lazy member loading
Add DynamicallyReplacedDeclRequest to ValueDecl and plumb the request through to TypeCheckAttr where it replaces TypeChecker::findReplacedDynamicFunction.
Use the new dynamically replaced request to power this predicates.
Complete the refactoring by splitting the semantic callers for the original decl of a dynamically replaced declaration.

There's also a change to the way this attribute is validated and placed.  The old model visited the attribute on any functions and variable declarations it encountered in the primary.  Once there, it would strip the attribute off of variables and attach the corresponding attribute to each parsed accessor, then perform some additional ObjC-related validation.

The new approach instead leaves the attribute alone.  The request exists specifically to perform the lookups and type matching required to find replaced decls, and the attribute visitor no longer needs to worry about revisiting decls it has just grafted attributes onto.  This also means that a bunch of parts of IRGen and SILGen that needed to fan out to the accessors to ask for the @_dynamicReplacement attribute to undo the work the type checker had done can just look at the storage itself.  Further, syntactic requests for the attribute will now consistently succeed, where before they would fail dependending on whether or not the type checker had run - which was generally not an issue by the time we hit SIL.
We've changed *what* is serialized by changing the way
@_dynamicReplacement is type checked, but not *how* it's
serialized.  Bump the format so there aren't strange incompatibilities
because of this.
@CodaFi
Copy link
Contributor Author

CodaFi commented Dec 3, 2019

Let's try to get this in.

@swift-ci please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Dec 4, 2019

⛵️

@CodaFi CodaFi merged commit b7537cf into swiftlang:master Dec 4, 2019
@CodaFi CodaFi deleted the rialto-repls branch December 4, 2019 01:11
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