Files
swift-mirror/test/Serialization/modularization-error.swift
Alexis Laferrière 9804075549 [Serialization] Show contextual notes on deserialization errors
This PR makes diagnostics on deserialization errors caused by project
configuration more helpful by providing contextual information on the
issue:

- Path to the modules involved (up to 4 modules): the loaded swiftmodule
with the broken outgoing reference, the path to the module where the
decl was expected, the path to the underlying clang module, and the path
to the module where the decl was found. This information should prevent
us from having to ask for a different log with `-Rmodule-loading`.
- Hint to delete the swiftmodule files when the module is
library-evolution enabled.
- Hint that clang settings affect clang modules involved in this
scenario.
- Pointing out when a decl moved between two modules with a similar name
(where one name is a prefix of the other). This is a common issue when
headers are shared between a clang framework's public and private
modules.
- Pointing out layering issues when an SDK module imports a local
module.
- Pointing out Swift language version mismatch which may lead to the
compiler viewing the same clang decls differently when they are modified
by APINotes files.
2023-06-08 09:24:11 -07:00

73 lines
4.3 KiB
Swift

/// Simulate typical modularization issues using Swift modules.
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
/// Compile two library modules A and B, and a client.
// RUN: %target-swift-frontend %t/LibOriginal.swift -emit-module-path %t/A.swiftmodule -module-name A
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/B.swiftmodule -module-name B
// RUN: %target-swift-frontend %t/LibWithXRef.swift -emit-module-path %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t
/// Move MyType from A to B.
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/A.swiftmodule -module-name A
// RUN: %target-swift-frontend %t/LibOriginal.swift -emit-module-path %t/B.swiftmodule -module-name B
// RUN: not %target-swift-frontend -emit-sil %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t 2>&1 \
// RUN: | %FileCheck --check-prefixes CHECK,CHECK-MOVED %s
// CHECK-MOVED: LibWithXRef.swiftmodule:1:1: error: reference to type 'MyType' broken by a context change; 'MyType' was expected to be in 'A', but now a candidate is found only in 'B'
/// Force working around the broken modularization to get a result and no errors.
// RUN: %target-swift-frontend -emit-sil %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t \
// RUN: -experimental-force-workaround-broken-modules 2>&1 \
// RUN: | %FileCheck --check-prefixes CHECK-WORKAROUND %s
// CHECK-WORKAROUND: LibWithXRef.swiftmodule:1:1: warning: reference to type 'MyType' broken by a context change; 'MyType' was expected to be in 'A', but now a candidate is found only in 'B'
// CHECK-WORKAROUND-NEXT: A.MyType
// CHECK-WORKAROUND-NEXT: ^
// CHECK-WORKAROUND: <unknown>:0: note: the type was expected to be found in module 'A' at '
// CHECK-WORKAROUND-SAME: A.swiftmodule'
// CHECK-WORKAROUND: <unknown>:0: note: the type was actually found in module 'B' at '
// CHECK-WORKAROUND-SAME: B.swiftmodule'
// CHECK-WORKAROUND: <unknown>:0: note: attempting forced recovery enabled by -experimental-force-workaround-broken-modules
// CHECK-WORKAROUND: func foo() -> some Proto
/// Change MyType into a function.
// RUN: %target-swift-frontend %t/LibTypeChanged.swift -emit-module-path %t/A.swiftmodule -module-name A
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/B.swiftmodule -module-name B
// RUN: not %target-swift-frontend -emit-sil %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t 2>&1 \
// RUN: | %FileCheck --check-prefixes CHECK,CHECK-KIND-CHANGED %s
// CHECK-KIND-CHANGED: LibWithXRef.swiftmodule:1:1: error: reference to type 'MyType' broken by a context change; the declaration kind of 'MyType' from 'A' changed since building 'LibWithXRef'
/// Change MyType into a function and move it.
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/A.swiftmodule -module-name A
// RUN: %target-swift-frontend %t/LibTypeChanged.swift -emit-module-path %t/B.swiftmodule -module-name B
// RUN: not %target-swift-frontend -emit-sil %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t 2>&1 \
// RUN: | %FileCheck --check-prefixes CHECK,CHECK-KIND-CHANGED-AND-MOVED %s
// CHECK-KIND-CHANGED-AND-MOVED: LibWithXRef.swiftmodule:1:1: error: reference to type 'MyType' broken by a context change; the declaration kind of 'MyType' changed since building 'LibWithXRef', it was in 'A' and is now a candidate is found only in 'B'
/// Remove MyType from all imported modules.
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/A.swiftmodule -module-name A
// RUN: %target-swift-frontend %t/Empty.swift -emit-module-path %t/B.swiftmodule -module-name B
// RUN: not %target-swift-frontend -emit-sil %t/LibWithXRef.swiftmodule -module-name LibWithXRef -I %t 2>&1 \
// RUN: | %FileCheck --check-prefixes CHECK,CHECK-NOT-FOUND %s
// CHECK-NOT-FOUND: LibWithXRef.swiftmodule:1:1: error: reference to type 'MyType' broken by a context change; 'MyType' is not found, it was expected to be in 'A'
// CHECK: LibWithXRef.swiftmodule:1:1: note: could not deserialize extension
//--- Empty.swift
//--- LibOriginal.swift
public struct MyType {
public init() {}
}
//--- LibTypeChanged.swift
/// Make it a function to fail filtering.
public func MyType() {}
//--- LibWithXRef.swift
import A
import B
public protocol Proto {}
extension MyType : Proto {}
@available(SwiftStdlib 5.1, *)
public func foo() -> some Proto { return MyType() }