Skip to content

Turn on ‘as’ bridging on Linux. #16022

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 2 commits into from
May 17, 2018
Merged

Turn on ‘as’ bridging on Linux. #16022

merged 2 commits into from
May 17, 2018

Conversation

millenomi
Copy link
Contributor

@millenomi millenomi commented Apr 19, 2018

See https://forums.swift.org/t/bridging-for-swift-corelibs-foundation-on-linux/11994/1 for a full rationale.

This is a work-in-progress patch to enable 'as', 'as?', 'as!' bridging so that it is possible to compile more code that's valid on Darwin on Linux as well.

The final target for this patch is to enable:

  • bridging known struct types and numeric types to Foundation reference types and vice versa (NSString(…) as String, "abc" as NSString, 1.23 as NSNumber).
  • bridging arbitrary Swift values to opaque (_SwiftValue) reference types and vice versa (with struct X {}: ([X(), X(), X()] as NSArray) as! Array<X>).

(The initial push for this PR implements the former.)

This does not target enabling other as{,?,!} casts that work on Darwin but not on Linux that strictly require the ObjC runtime:

  • Any value whose type is a metatype X.self from/to AnyObject
  • Closures from/to AnyObject

Fixes https://bugs.swift.org/browse/SR-138.

@millenomi millenomi changed the title [WIP] Turn on ‘as’ bridging on Darwin. [WIP] Turn on ‘as’ bridging on Linux. Apr 19, 2018
@millenomi
Copy link
Contributor Author

The Foundation counterpart is swiftlang/swift-corelibs-foundation#1526.

expectTrue(fields[0] as! AnyObject === subject.a)
expectTrue(fields[1] as! AnyObject === subject.b)
expectTrue(fields[2] as! AnyObject === subject.c)
// expectTrue(fields[0] as! AnyObject === subject.a)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are failing without _SwiftValue (bullet 2 in the description); the intent is to reenable them before finishing.

@@ -800,7 +798,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
// A fallback to use if we don't have a more specialized approach
// for a non-class type.
auto fallbackForNonClass = [&] {
#if SWIFT_OBJC_INTEROP
#if SWIFT_OBJC_INTEROP // TODO
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The // TODOs are for the implementation of _SwiftValue (the second bullet in the PR description).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done and the TODOs need to be removed.

@slavapestov
Copy link
Contributor

@millenomi Should we consider renaming _ObjectiveCBridgeable and similar identifier to something else, now that none of this has anything to do with Objective-C?

@millenomi
Copy link
Contributor Author

I believe we should. We can investigate it as a last step in this patch or as a separate PR, given how extensively the name appears in the codebase.

Are we bound by any SE document to use that particular name, or is it free for arbitrary change?

@slavapestov
Copy link
Contributor

I think since the names in question are underscored they're not public API and are not part of the SE process.

@@ -8120,6 +8117,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
case CheckedCastKind::Coercion:
case CheckedCastKind::BridgingCoercion:
llvm_unreachable("Coercions handled in other disjunction branch");
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't necessary (or useful). llvm_unreachable exits the process.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't remember the circumstances for this. It will be removed.

@millenomi
Copy link
Contributor Author

cc @phausler

@millenomi
Copy link
Contributor Author

This new push adds preliminary _SwiftValue support on Linux with an alternate implementation that does not use the ObjC runtime.

Tests that were disabled above need to be re-enabled after this.

@millenomi
Copy link
Contributor Author

(As per comment: memory management is likely incorrect, since the new branch is not heeding the casting flags yet.)

@millenomi
Copy link
Contributor Author

cc @slavapestov @DougGregor @jckarter to sanity check before we commit to this path?

@millenomi
Copy link
Contributor Author

millenomi commented Apr 26, 2018

This is also introducing a linker error in my local tests that I'm not quite sure how to approach; making the symbol public doesn't seem to change things:

[72/74] Linking CXX executable unittests/runtime/LongTests/SwiftRuntimeLongTests
FAILED: : && /usr/bin/clang++   -Wno-unknown-warning-option -Werror=unguarded-availability-new -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fcolor-diagnostics -Werror=switch -Wdocumentation -Wimplicit-fallthrough -Wunreachable-code -Woverloaded-virtual -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -g  -latomic -fuse-ld=gold stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/AnyHashableSupport.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Array.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Casting.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/CompatibilityOverride.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/CygwinPort.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Demangle.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Enum.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ErrorObjectConstants.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ErrorObjectNative.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Errors.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ErrorDefaultImpls.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Exclusivity.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ExistentialContainer.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Heap.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/HeapObject.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ImageInspectionMachO.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ImageInspectionELF.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ImageInspectionCOFF.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/KnownMetadata.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Metadata.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/MetadataLookup.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/MutexPThread.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/MutexWin32.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Once.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/Portability.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ProtocolConformance.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/RefCount.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/RuntimeInvocationsTracking.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftDtoa.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/OldDemangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/Demangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/NodePrinter.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/Context.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/ManglingUtils.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/Punycode.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/NodeDumper.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ErrorObject.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftObject.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftValue.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/ReflectionMirror.mm.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/OldRemangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/Remangler.cpp.o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/__/__/__/lib/Demangling/TypeDecoder.cpp.o unittests/runtime/LongTests/CMakeFiles/SwiftRuntimeLongTests.dir/LongRefcounting.cpp.o unittests/runtime/LongTests/CMakeFiles/SwiftRuntimeLongTests.dir/__/Stdlib.cpp.o  -o unittests/runtime/LongTests/SwiftRuntimeLongTests -L/home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/./lib /home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/lib/libLLVMSupport.a -lpthread /home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/lib/libgtest_main.a /home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/lib/libgtest.a -lpthread lib/swift/linux/x86_64/libswiftCore.so -latomic /home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/lib/libLLVMSupport.a -lrt -ldl -ltinfo -lpthread -lm /home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/lib/libLLVMDemangle.a -lpthread -Wl,-rpath,/home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/llvm-linux-x86_64/./lib:/home/millenomi/Developer/Sources/Swift/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64 && :
/usr/bin/ld.gold: error: protected symbol 'swift_unboxFromSwiftValueWithType' is not defined locally

Since Casting.cpp.o, at a minimum, refers to other SWIFT_RUNTIME_STDLIB_INTERNAL symbols (like _swift_arrayDownCastIndirect), shouldn't this link in Swift.o or other products from the stdlib build?

@millenomi
Copy link
Contributor Author

I have found the spot in Stdlib.cpp where to add the non-Swift stub for those tests.

@millenomi
Copy link
Contributor Author

@swift-ci please test

@millenomi
Copy link
Contributor Author

(I'm not sure I can kick off tests on this repository.)

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 815d3350c1fcf5451d045dc18427620c9f8f9485

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 815d3350c1fcf5451d045dc18427620c9f8f9485

@@ -800,7 +798,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
// A fallback to use if we don't have a more specialized approach
// for a non-class type.
auto fallbackForNonClass = [&] {
#if SWIFT_OBJC_INTEROP
#if SWIFT_OBJC_INTEROP // TODO
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done and the TODOs need to be removed.

@@ -158,16 +158,6 @@ print(allToAll(type(of: C()), AnyObject.self)) // CHECK-NEXT: true
// Bridging
print(allToAll(0, AnyObject.self)) // CHECK-NEXT: true

// This will get bridged using _SwiftValue.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These need to be readded in, but I need some help figuring out how to address the NSCopying one — if it is enough to import Foundation on Linux so that Foundation can then extend _SwiftValue with NSCopying.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(This will require making Linux's _SwiftValue public as a Foundation SPI.)

@rudkx
Copy link
Contributor

rudkx commented Apr 28, 2018

@swift-ci Please smoke test

@rudkx
Copy link
Contributor

rudkx commented Apr 28, 2018

@swift-ci Please test source compatibility

Copy link
Contributor

@phausler phausler left a comment

Choose a reason for hiding this comment

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

Overall the changes look great, much reduction of #ifdefs, many unified code paths, very cross platform! 😍 the direction of this change looks good to me. I cannot speak to the full impact I. The compiler and the memory management questions but the rest of the changes seem quite reasonable.

@millenomi
Copy link
Contributor Author

This needs to build with the corresponding Foundation patch.

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please test source compatibility

@millenomi
Copy link
Contributor Author

SwiftPM failed to build without an error message. It may be a transient issue; retrying while also kicking it off locally to check.

@compnerd
Copy link
Member

compnerd commented May 2, 2018

BTW, this also will enable a handful more tests to run on Linux!

@millenomi
Copy link
Contributor Author

@compnerd Could you give the patch a once-over? I'm trying to diagnose the failures but many of them look to be memory corruption or management issues that

  1. are regressions from this patch and
  2. are in metadata fetching, an area this patch ostensibly doesn't touch

Any input is appreciated. (cc: @jrose-apple @slavapestov @jckarter)

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please test source compatibility

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

millenomi commented May 4, 2018

This last push includes a likely fix for the tests that takes into account the new ObjC-like SIL generated for casts on native.

@millenomi
Copy link
Contributor Author

NSError tests are failing.

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please test source compatibility

@millenomi
Copy link
Contributor Author

millenomi commented May 10, 2018

Something is wrong — it seems like it's trying to smoke test with a previous version of the Foundation patch (which contained fatalError("TODO").)

@millenomi
Copy link
Contributor Author

Maybe I started the test too early; starting another in case.

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

1 similar comment
@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi millenomi changed the title [WIP] Turn on ‘as’ bridging on Linux. Turn on ‘as’ bridging on Linux. May 17, 2018
@millenomi
Copy link
Contributor Author

Major update:

  • No longer WIP; passes tests locally.
  • If Foundation is available, use Foundation._SwiftValue as the wrapper type for values that can't bridge.
  • _bridgeAnything… now unpacks existentials and Optional<_> correctly instead of wrapping them in _SwiftValue
  • Bridge nil to a null placeholder and back when unwrapping an optional. If Foundation is available, this object is a NSNull to match Darwin's behavior. Otherwise, it's a private _SwiftValue constant.

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi
Copy link
Contributor Author

Test failures aren't patch-related: https://bugs.swift.org/browse/SR-7716

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please test source compatibility

@millenomi
Copy link
Contributor Author

Please test with the following PR:
swiftlang/swift-corelibs-foundation#1526

@swift-ci please smoke test

@millenomi millenomi merged commit 6e5605a into swiftlang:master May 17, 2018
@benlangmuir
Copy link
Contributor

I reverted this because it broke in CI. Please take a look.
There was a compiler crash on Ubuntu 16:
https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-16_04/4132/
and the compiler couldn't be built on Ubuntu 14.04:
https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-14_04/4231/

@jrose-apple
Copy link
Contributor

Please wait for a reviewer from Anna's team as well before merging this.

@millenomi
Copy link
Contributor Author

@jrose-apple I will fix the 14.04 issue and repost this patch. Is there anyone you would recommend look at this patch, or who would know who?

@jrose-apple
Copy link
Contributor

Mark (@rudkx) is probably still the right person for the type checker changes. @rjmccall or @jckarter would be good for the SIL and runtime side.

@millenomi
Copy link
Contributor Author

millenomi commented May 18, 2018

Thank you. I will tag people again once the 14.04 build issue is figured out and I reopen the PR.

@@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

#if _runtime(_ObjC)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we try to build the ObjectiveC module on non-ObjC-interop platforms? I didn't see a CMakeLists.txt change to that effect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can revert this if it’s unneeded. Part of the debugging cycle for this patch was building it on Darwin simulating the Linux situation so that I could iterate on it with Xcode; it may be a leftover from that.

@usableFromInline
internal class _SwiftValue {
@usableFromInline
let value: Any
Copy link
Contributor

Choose a reason for hiding this comment

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

You could avoid double-indirecting using a small class hierarchy:

open class _SwiftValue {}

internal class _SwiftValueOf<T>: _SwiftValue {
  let value: T
  init(_ value: T) { self.value = value }
}

@_silgen_name("_swift_makeSwiftValue")
func _makeSwiftValue<T>(_ value: T) -> _SwiftValue { return _SwiftValueOf(value) }

This might also let you represent null as a singleton subclass instead of as a wrapper around a specific kind of Optional. Maybe you could also make it so that Foundation's preexisting _SwiftValue and NSNull are Swift._SwiftValue subclasses, so that they're substitutable for stdlib _SwiftValues, instead of the _NSSwiftValue/_SwiftValueFlavor hacks too.

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 cannot reparent NSNull, and I would be loathe to reparent _SwiftValue for the reasons outlined below. Unless we reparent NSObject, which is possible but would be really weird.

} else {
return _SwiftValue(value)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a plan to retire Foundation._SwiftValue once this is all done?

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem is that _SwiftValue is an NSObject subclass on Apple platforms, and we probably can't undo that.

Copy link
Contributor

@jckarter jckarter May 19, 2018

Choose a reason for hiding this comment

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

How does that become important in practice? We don't promise that on Darwin even, we "just haven't gotten around" to making it an independent root class.

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 becomes important when it interacts with CF API. Right now, calling CFCopy() will go through the NSCopying conformance that all SwiftValues implicitly have to, and that is still possible on Linux as well (you can toll-free bridge swift-corelibs-foundation’s NSArray/Dictionary to CFArray/DictionaryRef the same way you can on Darwin, and these may contain _SwiftValues and be set up to copy.)

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 is also secondarily important for two reasons:

  • It allows Linux to respond to is/as? NSObject/NSCopying the same way Darwin does, which can be a subtle issue in codebases where that question is posed in code that doesn’t know it may be receiving a boxed value;
  • Existing boxing code in s-c-f already assumes that boxed values can be freely casted to NSObject (and uses its Hashable conformance to eg use them as dictionary keys); the churn was pretty big and would have introduced a number of forced casts and uses of AnyHashable, so I went instead with the solution that also he the property of being the closest match to Darwin.

Copy link
Contributor

Choose a reason for hiding this comment

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

At a high level, I don't think changing the boxing behavior dynamically based on the presence of Foundation is workable—what happens when a program that doesn't use Foundation dynamically loads a library that does? as? NSObject working is not something we want to guarantee works with plain boxed values on Darwin. We control the CF implementation corelibs uses on Linux, so could we make CFCopy do the right thing with Swift boxes?

If we really must make boxed values be NSObject subclasses when Foundation is loaded, we should look into doing so in a way that doesn't invalidate boxed values that exist before Foundation is loaded. For instance, we could make it so that boxing uses heap objects that start out with non-class heap metadata, and overwrite the metadata with an NSObject subclass when Foundation gets loaded.

}

return result
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like this would be best written in C++ to have full access to the low-level metadata APIs. Keeping the entire implementation would be cleaner, and probably lead to more understandable code, than doing the oblique things you need to approximate this in Swift slowly and opaquely, such as sprinkling new protocols like _Unwrappable for peeling optionals or new small bits of runtime/stdlib SPI like _extractDynamicValue for peeling existentials. With Optional we also need to be careful that boxing preserves the difference between different levels of .none nesting in nested Optionals—for T??, .none and .some(.none) should be able to round-trip through a box as distinct values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Part of why I went with Swift over C++ was the issue of correctness of memory management; is there documentation on the expectations and SPI? My understanding is that with the current work the documentation in the repository may no longer apply.

Copy link
Contributor

Choose a reason for hiding this comment

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

The main thing that would've changed since then is that Swift functions now take arguments +0 by default (and we have macros to try to handle both +1 and +0 conventions as a transitional/fallback mechanism, though I'm not sure whether that's important for new code, cc @gottesmm). The Darwin implementation of bridging lives largely in the C++ runtime, and we have fairly extensive runtime tests that you should be able to gradually enable that check for object lifetime issues.

@millenomi
Copy link
Contributor Author

Thanks for the initial reviews; any feedback will be applied to the new PR at #16736.

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