Files
swift-mirror/test/ClangImporter/requirement-conflict.swift
Robert Widmann 79e2060aa6 Exempt Swift Interface Files From Whole-Module ObjC Errors
We don't expect swiftinterface files to have anything meaningful to
report from these checks anyhow - they will have been run at module
generation time anyways.

In fact, the linked radar demonstrates how this kind of checking can be
detrimental to the usability of the compiler. The test committed here
declares the CoreFeatures framework, an Objective-c (root) class and a
set of Objective-C protocols. Now for the fun part: The Objective-C
class is made to conform to the Objective-C protocols in a Swift
extension. This extension is then printed into the generated
CoreFeatures-Swift header and made available to clients of the module.

Now, because we have an Objective-C protocol and a base class that is
imported from Objective-C, we mirror-in the members of RootProtocol.
The sum total of the monster we have built is that we now have a Swift
class that implements some requirements, and an Objective-C protocol
that has requirements mirrored into that same class. The result is
a raft of spurious selector conflict diagnostics that the user cannot
work around unless they own both the class and the protocol.

Exempt swiftinterface files from this checking.

rdar://69550935
2020-11-09 17:05:29 -08:00

29 lines
1.4 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: mkdir -p %t/clang-module-cache
// RUN: %target-swift-frontend -typecheck -F %S/Inputs/requirement-conflict -module-cache-path %t/clang-module-cache %s
// REQUIRES: objc_interop
// N.B. technically only need objc_interop here, but CoreFeatures would have to
// be cross-compiled for more architectures. It's sufficient to verify this
// works for macOS alone since we only care that we don't emit errors.
// REQUIRES: OS=macosx
import CoreFeatures
// The RootObject class in CoreFeatures is intentionally quite strange.
// Formally, RootObject declares a conformance to an Objective-C protocol called
// 'ReactiveRootProtocol', but in Swift instead of ObjC. When we go to import
// the ObjC side of the framework, we notice this and mirror-in the requirements
// from its ancestor 'RootProtocol'. With that accomplished, we now have an ObjC
// class imported through Swift with ObjC members mirrored on top. This combo
// used to be toxic - we would see the very members we synthesized during the
// shadowing pass and would diagnose them as directly conflicting with the
// protocol conformance we had declared in Swift. That is - we would say
// a requirement conflicted directly... with itself!
//
// Nowadays we just exempt interface files from this kind of checking, which is
// the same behavior one would get if they had set up this very scenario with
// a plain swiftmodule file.
let root = CoreFeatures.RootObject()
print(root)