mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
In Desktop Swift, @_implementationOnly imports allow one to hide the implementation so long as you're careful to only reference entities from the imported modules in code that gets compiled into the object file and *not* referenced by the corresponding Swift module file. Until very recently, there was no such affordance for Embedded Swift, because all functions would have their SIL serialized to the Swift module file. Using them from a client module would then attempt to deserialize the SIL, loading the @_implementationOnly-imported module and causing the compiler to abort. With the introduction of @_neverEmitIntoClient, we now have a way to say "only in the object file, never in the module file" for the definition of functions. Introduce a test that makes sure @_implementationOnly + @_neverEmitIntoClient has the desired effect of hiding the imported modules from clients. It's still brittle and hard to use, just like the existing @_implementationOnly, but this shows that it's at least possible to do this implementation hiding in Embedded Swift.
74 lines
2.7 KiB
Swift
74 lines
2.7 KiB
Swift
// This elaborate test ensures that @_implementationOnly with Embedded Swift
|
|
// can hide some dependencies if you are very, very careful.
|
|
|
|
// RUN: %empty-directory(%t)
|
|
// RUN: mkdir -p %t/Dependencies
|
|
// RUN: mkdir -p %t/Files
|
|
// RUN: mkdir -p %t/Modules
|
|
|
|
// Copy Swift file + C header + module map into a separate directory we'll use
|
|
// when building the module whose implementation we want to hide.
|
|
// RUN: cp %S/Inputs/SwiftDependency.swift %t/Dependencies/
|
|
// RUN: cp %S/Inputs/CHeader.h %t/Dependencies/
|
|
// RUN: cp %S/Inputs/module.modulemap %t/Dependencies/
|
|
|
|
// RUN: split-file %s %t/Files
|
|
|
|
// Compile the Swift dependencies into that same location.
|
|
// RUN: %target-swift-frontend -parse-as-library -emit-module %t/Dependencies/SwiftDependency.swift -enable-experimental-feature Embedded -o %t/Dependencies/SwiftDependency.swiftmodule
|
|
|
|
// Build the library (which is supposed to encapsulate those dependencies)
|
|
// against the dependencies.
|
|
// RUN: %target-swift-frontend -parse-as-library -emit-module %t/Files/Library.swift -enable-experimental-feature Embedded -I %t/Dependencies/ -o %t/Modules/Library.swiftmodule
|
|
|
|
// Remove the dependencies so there is no way we can find them later.
|
|
// RUN: rm -rf %t/Dependencies
|
|
|
|
// Build the application against the library. This is expected to work because
|
|
// @_neverEmitIntoClient hides the body of test().
|
|
// RUN: %target-swift-frontend -emit-ir -parse-as-library %t/Files/Application.swift -enable-experimental-feature Embedded -I %t/Modules -o %t/Application.ir
|
|
|
|
// Build the application against the library, but intentionally trigger
|
|
// deserialization of some serialized SIL that refers to an implementation-only
|
|
// dependency. Right now, these fail spectacularly. Over time, we want them to
|
|
// become compile-time errors or start working.
|
|
// RUN: not --crash %target-swift-frontend -emit-ir -parse-as-library %t/Files/Application.swift -enable-experimental-feature Embedded -I %t/Modules -o %t/Application.ir -DBAD_C_USAGE
|
|
// RUN: not --crash %target-swift-frontend -emit-ir -parse-as-library %t/Files/Application.swift -enable-experimental-feature Embedded -I %t/Modules -o %t/Application.ir -DBAD_SWIFT_USAGE
|
|
|
|
// REQUIRES: swift_in_compiler
|
|
// REQUIRES: swift_feature_Embedded
|
|
|
|
//--- Library.swift
|
|
@_implementationOnly import CDependency
|
|
@_implementationOnly import SwiftDependency
|
|
|
|
@_neverEmitIntoClient
|
|
public func test() {
|
|
_ = getPoint(3.14159, 2.71828)
|
|
A().doSomething()
|
|
}
|
|
|
|
public func badCLibraryUsage() {
|
|
_ = getPoint(3.14159, 2.71828)
|
|
}
|
|
|
|
public func badSwiftLibraryUsage() {
|
|
A().doSomething()
|
|
}
|
|
|
|
//--- Application.swift
|
|
|
|
import Library
|
|
|
|
public func useTest() {
|
|
test()
|
|
|
|
#if BAD_C_USAGE
|
|
badCLibraryUsage()
|
|
#endif
|
|
|
|
#if BAD_SWIFT_USAGE
|
|
badSwiftLibraryUsage()
|
|
#endif
|
|
}
|