mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revisit the optimization that provides a fast path for instances of `NSError` when erasing the `Error` type in `emitExistentialErasure`. It generated references to `NSError` when the `Foundation` module was loaded, no matter how it was imported. This lead to deserialization failures at reading the swiftmodule when that reference was added to inlinable code while `Foundation` was not a public dependency. Fix this crash by limiting the optimization to all non-inlinable code and only inlinable code from a module with a public dependency on `Foundation`. This is the similar check we apply to user written inlinable code, however here we use the module-wide dependency instead of per file imports. rdar://142438679
160 lines
5.7 KiB
Swift
160 lines
5.7 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: split-file %s %t --leading-lines
|
|
// REQUIRES: objc_interop
|
|
|
|
/// Build a minimal version of Foundation defining only NSError
|
|
// RUN: %target-swift-frontend -emit-module %t/Foundation.swift \
|
|
// RUN: -o %t/Foundation.swiftmodule
|
|
// RUN: %target-swift-frontend -emit-module %t/FoundationExporter.swift -I%t \
|
|
// RUN: -o %t/FoundationExporter.swiftmodule
|
|
|
|
/// Enabled existential to NSError optimization
|
|
// CHECK-OPTIMIZED: $NSError
|
|
|
|
/// Optimize Foundation itself
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/Foundation.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Public import or non-resilient modules
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/inlinable-public.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/inlinable-public.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/inlinable-internal.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Foundation is imported from a different file
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
|
|
// RUN: %t/inlinable-not-imported-fileA.swift \
|
|
// RUN: %t/inlinable-not-imported-fileB.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/inlinable-not-imported-fileA.swift \
|
|
// RUN: %t/inlinable-not-imported-fileB.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Foundation is imported via a transitive dependency
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
|
|
// RUN: %t/inlinable-imported-transitive.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Any non-inlinable uses
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/non-inlinable-public.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/non-inlinable-ioi.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/non-inlinable-internal.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
|
|
// RUN: %t/non-inlinable-not-imported-fileA.swift \
|
|
// RUN: %t/non-inlinable-not-imported-fileB.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t -module-name main \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/non-inlinable-not-imported-fileA.swift \
|
|
// RUN: %t/non-inlinable-not-imported-fileB.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Disabled existential to NSError optimization
|
|
// CHECK-NOT-OPTIMIZED-NOT: $NSError
|
|
|
|
/// Implementation-only import
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: %t/inlinable-ioi.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/inlinable-ioi.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
/// Internal import from resilient module
|
|
// RUN: %target-swift-frontend -emit-module -emit-sil -I%t \
|
|
// RUN: -swift-version 5 -enable-library-evolution \
|
|
// RUN: %t/inlinable-internal.swift > %t/main.sil
|
|
// RUN: %FileCheck --check-prefix CHECK-NOT-OPTIMIZED --input-file %t/main.sil %s
|
|
|
|
//--- Foundation.swift
|
|
|
|
class NSError {}
|
|
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- FoundationExporter.swift
|
|
|
|
@_exported import Foundation
|
|
|
|
//--- inlinable-public.swift
|
|
public import Foundation
|
|
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- inlinable-ioi.swift
|
|
@_implementationOnly import Foundation
|
|
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- inlinable-internal.swift
|
|
internal import Foundation
|
|
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- inlinable-not-imported-fileA.swift
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
//--- inlinable-not-imported-fileB.swift
|
|
import Foundation
|
|
|
|
//--- inlinable-imported-transitive.swift
|
|
public import FoundationExporter
|
|
|
|
@inlinable public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- non-inlinable-public.swift
|
|
public import Foundation
|
|
|
|
public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- non-inlinable-ioi.swift
|
|
@_implementationOnly import Foundation
|
|
|
|
public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- non-inlinable-internal.swift
|
|
internal import Foundation
|
|
|
|
public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
|
|
//--- non-inlinable-not-imported-fileA.swift
|
|
public func foo<E: Error>(e: E) -> Error {
|
|
return e
|
|
}
|
|
//--- non-inlinable-not-imported-fileB.swift
|
|
import Foundation
|