Skip to content

Introduce SWIFT_ENABLE_REFLECTION to turn on/off the support for Mirrors and reflection #33617

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
Sep 8, 2021

Conversation

kubamracek
Copy link
Contributor

No description provided.

Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

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

I'd love to see the numbers on this (if you have them) - this can be interesting for other applications.

/// A stdlib-internal protocol modeled by the intrinsic pointer types,
/// UnsafeMutablePointer, UnsafePointer, UnsafeRawPointer,
/// UnsafeMutableRawPointer, and AutoreleasingUnsafeMutablePointer.
public protocol _Pointer
: Hashable, Strideable, CustomDebugStringConvertible, CustomReflectable {
: Hashable, Strideable, CustomDebugStringConvertible, _CustomReflectableOrNone {
Copy link
Member

Choose a reason for hiding this comment

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

Can you split out the CustomReflectable into an extension instead? That avoids the need for the new protocol.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can't actually extend protocols to require conformances to protocols, but couldn't you do:

public protocol _Pointer: protocols
#if SWIFT_ENABLE_REFLECTION
, CustomReflectable
#endif 
{
}

maybe the Swift preprocessor doesn't work like C/++ one to be able to do this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alas, Swift doesn't do blind text substitutions like C does, and the contents of an #if block must be valid statements.

Copy link
Member

@compnerd compnerd Aug 25, 2020

Choose a reason for hiding this comment

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

Bleh, I missed that _Pointer itself was a protocol. I suppose you can use a typealias, but at that point Im not sure if its worth it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How would you use the typealias? I'm happy to explore better options, as I don't really like the _CustomReflectableOrNone thing either, but I couldn't come up with anything nicer that would actually work (as mentioned above, we can't just ifdef this out from the declaration, and we can't do extension on a protocol).

Copy link
Contributor

@mikeash mikeash Aug 25, 2020

Choose a reason for hiding this comment

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

This appears to work:

#if COND
typealias MaybeCustomReflectable = CustomReflectable
#else
typealias MaybeCustomReflectable = Any
#endif

protocol P: MaybeCustomReflectable {}

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, roughly what @mikeash pointed out. I was thinking that we could take the requirements and just typealias them before the definition, including/excluding the CustomReflectable instead of an Any conformance.

@3405691582
Copy link
Member

Should this include swift-reflection-dump and the associated tests, or is that not intended to be in-scope for this toggle?

@jckarter
Copy link
Contributor

@3405691582 swift-reflection-dump could still be useful, because the standard library being built without reflection metadata and Mirror does not block user binaries from still generating and consuming reflection metadata for their own purposes.

@jckarter
Copy link
Contributor

As we discussed offline, it would be nice if we could leave behind @availability(unavailable) stub declarations for the removed functionality. That will let us give better diagnostics when people try to use the APIs in configurations that don't support them, and would also help prevent subtle behavior differences caused by the missing declarations changing overload resolution, allowing retroactive conformances that would otherwise collide with standard library conformances, and so on.

@kubamracek kubamracek changed the base branch from master to main September 23, 2020 22:20
@kubamracek kubamracek force-pushed the reflection branch 3 times, most recently from cb8402a to 016ddcd Compare August 24, 2021 01:04
@kubamracek
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 016ddcde5ce333c28735dc3c90b1448e6c2b2cb3

@kubamracek
Copy link
Contributor Author

@swift-ci please test Linux platform

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 016ddcde5ce333c28735dc3c90b1448e6c2b2cb3

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 016ddcde5ce333c28735dc3c90b1448e6c2b2cb3

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 016ddcde5ce333c28735dc3c90b1448e6c2b2cb3

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 016ddcde5ce333c28735dc3c90b1448e6c2b2cb3

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@shahmishal
Copy link
Member

Errors Detected: Regression test failed

Failed Command /usr/local/bin/cmake --build /Users/buildnode/jenkins/workspace/swift-PR-macos/branch-main/buildbot_incremental/swift-macosx-x86_64 -- -j24 -v check-swift-validation-macosx-x86_64
 Swift(macosx-x86_64) :: Incremental/Dependencies/reference-dependencies-consistency-fine.swift 
 Swift(macosx-x86_64) :: Incremental/Verifier/multi-file-private/main.swift 

Build Log: Swift Pull Request Test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 42d25595fa6bbff909ea70451cb7c4325c4717f6

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 42d25595fa6bbff909ea70451cb7c4325c4717f6

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek
Copy link
Contributor Author

@yln

The patch makes sense to me, but I was a bit disheartened by the sheer number of #if SWIFT_ENABLE_REFLECTION directives needed (77 files touched).

I guess I could gather up most/all of the simple CustomReflectable and CustomDebugStringConvertible extensions on Array, Collection, Dictionary, etc. into a separate place and then it would just be a single #ifdef around that. Would that be better?

@kubamracek
Copy link
Contributor Author

Would it be possible to leave Mirror declarations and uses intact, but "compile out" its implementation and return dummy values or crash. Similarly to what we do here for String.

Not sure what you're actually proposing. I think the @available attribute is required here, otherwise your code still compiles. I need to make let m = Mirror(x) not compile. Given that we can't #ifdef-out only the attribute, I'm not sure how else can I do this?

@kubamracek
Copy link
Contributor Author

I'm kinda on the fence about this change. Conceptually, I think that the change is good, but practically, I think that I agree with @yln. I think that adding an extension to String and a few other core types might be nice. An example would be:

extension String {
  public init<T: Error>(reflecting object: T) {
    self = "\(object)"
  }
}

You already change a few places the case where you reflect error into the error's description. This would keep the standard library similar and reduce some of the sprinkled changes.

Added. Note sure what other case could be handled the same way... suggestions?

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek
Copy link
Contributor Author

I've tried exploring using @available to carve out the Mirror APIs without duplicating the declarations, perhaps based on -define-availability compiler flags, but I don't think availability system is ready for this, because it mostly works for "platforms+versions" and not really for "features", like Mirror APIs. It's definitely worth exploring extending the availability system to support this, and I'll try to figure out if we could make something like @available(reflection) work and respect a compiler flag like -disable-reflection, and have it "do the right thing", i.e. make Mirror unavailable in those cases and also make conformances to CustomStringReflectable unavailable. Then we wouldn't need the #ifs and duplication of method declarations.

But in order to make progress, I'd like to propose going forward with this current PR, i.e. using #ifs, as a path forward. Is that reasonable? @jckarter, @compnerd?

@kubamracek kubamracek force-pushed the reflection branch 2 times, most recently from d9cabb3 to c3612e6 Compare September 8, 2021 01:26
@kubamracek
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Sep 8, 2021

Build failed
Swift Test Linux Platform
Git Sha - c3612e64d85d72d476609b0a4d94d288abe9a180

@swift-ci
Copy link
Contributor

swift-ci commented Sep 8, 2021

Build failed
Swift Test OS X Platform
Git Sha - c3612e64d85d72d476609b0a4d94d288abe9a180

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek kubamracek merged commit 404badb into swiftlang:main Sep 8, 2021
@kubamracek kubamracek deleted the reflection branch September 8, 2021 20:08
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.

9 participants