Skip to content

[ModuleInterface] Allow conformances to be missing value witnesses #18932

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 1 commit into from
Aug 23, 2018

Conversation

jrose-apple
Copy link
Contributor

It's not clear whether we'll actually need this feature in the long run, but we certainly need it now because non-@usableFromInline members can (currently) satisfy public requirements when a @usableFromInline internal type conforms to a public protocol. In these cases, we'll treat the witnesses as present but opaque, and clients will perform dynamic dispatch when using them even when a generic function gets specialized.

With this, we're able to generate a textual interface for the standard library, compile it back to a swiftmodule, and use it to build a Hello World program!

It's not clear whether we'll actually need this feature in the long
run, but we certainly need it now because non-@usableFromInline
members can (currently) satisfy public requirements when a
@usableFromInline internal type conforms to a public protocol. In
these cases, we'll treat the witnesses as present but opaque, and
clients will perform dynamic dispatch when using them even when
a generic function gets specialized.

With this, we're able to generate a textual interface for the standard
library, compile it back to a swiftmodule, and use it to build a Hello
World program!
@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

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

I think for types, you might end up having to do something for printing internal and private things, since fixed-contents structs can still contain private fields...

// FIXME: ...but we should do something better about types.
if (conformance && !conformance->isInvalid()) {
if (auto *SF = DC->getParentSourceFile()) {
if (SF->Kind == SourceFileKind::Interface) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I’ve noticed your patches often switch over the kind or check for an interface file - maybe a convenience predicate would be handy?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doug mentioned this too in #18778, but I'm not sure the rules are consistent enough to be worth it. Sometimes the special case is just for interface files; sometimes it's interfaces or SIL; sometimes it's interface, SIL, or library (i.e. not script mode).

@@ -1060,6 +1060,23 @@ bool WitnessChecker::findBestWitness(
}

if (numViable == 0) {
// Assume any missing value witnesses for a conformance in a textual
// interface can be treated as opaque.
// FIXME: ...but we should do something better about types.
Copy link
Contributor

Choose a reason for hiding this comment

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

If we don’t expect to generate textual interfaces for Swift 4 modules, we can make it an error in Swift 5 mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We may still want to to help with incremental builds, but yes.

@slavapestov
Copy link
Contributor

Great to hear the stdlib round-trips now! How big is the file? You’re not printing bodies of inlinable functions yet either are you?

@jrose-apple
Copy link
Contributor Author

Yeah, that's completely without inlinable functions. The textual file is 652KB / 12028 lines; the reconstituted binary is 4.3MB (compared to the original Swift.swiftmodule at 20MB). I'm a little curious what's taking so much space now.

@jrose-apple
Copy link
Contributor Author

As for private members of structs, at least for resilient libraries we have a restriction that all types involved must be public or @usableFromInline, so my plan was to print the member but replace its name with _.

@slavapestov
Copy link
Contributor

@jrose-apple I wasn't aware we were planning on enforcing that restriction. If we do though, it would mean that @fixedContents has a semantic effect on the language even with resilience off. Also I was under the impression we wanted to be able to generate textual interfaces for non-resilient libraries too, but maybe not.

@jrose-apple
Copy link
Contributor Author

If we do though, it would mean that @fixedContents has a semantic effect on the language even with resilience off.

That's only if we force the restriction when resilience is off.

Also I was under the impression we wanted to be able to generate textual interfaces for non-resilient libraries too, but maybe not.

I think we do too (third-party binary frameworks), but it's definitely trickier, because we have to support non-resilient layout for everything while not adding any extra language restrictions. (Or we have to add those restrictions.)

@jrose-apple jrose-apple merged commit eeb8f33 into swiftlang:master Aug 23, 2018
@jrose-apple jrose-apple deleted the loss-of-value branch August 23, 2018 23:46
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