Skip to content

[Type checker] Finalize referenced members of class extensions. #18199

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

DougGregor
Copy link
Member

When we reference a member of a class extension, we need to
compute its overrides, @objc bit, and ‘dynamic’ status because SILGen
may rely on them. Do that consistently by adding such members to the
list of declarations to “finalize”.

Rework the finalization logic to handle the computation of each of those
bits, and never remove a finalized declaration from the set: rather,
process new declarations as they enter the set, to avoid looping or
extra state bits.

Fixes rdar://problem/42440686.

When we reference a member of a class extension, we need to
compute its overrides, @objc bit, and ‘dynamic’ status because SILGen
may rely on them. Do that consistently by adding such members to the
list of declarations to “finalize”.

Rework the finalization logic to handle the computation of each of those
bits, and never remove a finalized declaration from the set: rather,
process new declarations as they enter the set, to avoid looping or
extra state bits.

Fixes rdar://problem/42440686.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

Due to some short-circuiting in the serialization logic, we never
added @objc getters/setters to a module’s Objective-C method table.
We handle layout through finalization of the declaration,
which already has its own approach to eliminating redundant work.
We don’t need an extra bit getting in the way.
@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

@available(OSX, introduced: 10.52)
func takes10_52Introduced10_52(o: OtherIntroduced10_52) {
}

// expected-error@+1{{'OtherIntroduced10_52' is only available on OS X 10.52 or newer}}
var propOf10_52: OtherIntroduced10_52 =
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be a regression. Maybe we should skip finalizing declarations if any errors have been emitted?

Copy link
Member Author

Choose a reason for hiding this comment

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

We had that, and I removed it, because it suppresses a ton of unrelated errors.

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean, this way we're doing unnecessary work in other files.

Copy link
Member Author

Choose a reason for hiding this comment

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

We're finalizing those declarations because something needed them from the other file. In this case, they're methods of a class so we are computing the layout. Prior to my change we would skip a little work once we had produced an error, but "stop doing any work if there's any error anywhere" doesn't seem like the right default policy.

Copy link
Contributor

Choose a reason for hiding this comment

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

It might be more than a little work, though—it's all structs and enums you've used throughout the file, transitively. It seems like the same reasoning to me as "don't go on to SILGen if there are errors, even though you could still get some dataflow diagnostics".

Copy link
Member Author

@DougGregor DougGregor Jul 26, 2018

Choose a reason for hiding this comment

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

I have an idea. Once we've encountered an error, we'll stop finalizing declarations from other source files. That way, you'll still get diagnostics in your own source file, but we won't do unnecessary work elsewhere. PR is up at #18259.

Copy link
Contributor

Choose a reason for hiding this comment

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

That makes a lot of sense! I forgot that finalization is now the only way to get certain diagnostics from decls within the current file.

Whenever we visit a declaration via the DeclChecker, add it to the
list of declarations to finalize. This makes sure that we can centralize
the notion of “finalize for SILGen” and that it will be called for
everything in the source file being processed.
@DougGregor DougGregor force-pushed the finalize-class-extension-members branch from 994e69b to 6a8d321 Compare July 26, 2018 03:55
@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor merged commit aa43611 into swiftlang:master Jul 26, 2018
@DougGregor DougGregor deleted the finalize-class-extension-members branch July 26, 2018 16:06
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