diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 6cf05fb148698..e3a268cee74a0 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -8164,6 +8164,7 @@ static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl) { // struct. return llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) { return ctor->isCopyConstructor() && !ctor->isDeleted() && + !ctor->isIneligibleOrNotSelected() && // FIXME: Support default arguments (rdar://142414553) ctor->getNumParams() == 1 && ctor->getAccess() == clang::AccessSpecifier::AS_public; diff --git a/test/Interop/Cxx/class/noncopyable-typechecker.swift b/test/Interop/Cxx/class/noncopyable-typechecker.swift new file mode 100644 index 0000000000000..535c8cbfc58ce --- /dev/null +++ b/test/Interop/Cxx/class/noncopyable-typechecker.swift @@ -0,0 +1,67 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t +// RUN: %target-swift-frontend -cxx-interoperability-mode=default -typecheck -verify - -I %t/Inputs %t/test.swift +// RUN: %target-swift-frontend -cxx-interoperability-mode=default -Xcc -std=c++20 -verify-additional-prefix cpp20- -D CPP20 -typecheck -verify -I %t/Inputs %t/test.swift + +//--- Inputs/module.modulemap +module Test { + header "noncopyable.h" + requires cplusplus +} + +//--- Inputs/noncopyable.h +#include + +struct NonCopyable { + NonCopyable() = default; + NonCopyable(const NonCopyable& other) = delete; + NonCopyable(NonCopyable&& other) = default; +}; + +template +struct OwnsT { + T element; + OwnsT() {} + OwnsT(const OwnsT &other) : element(other.element) {} + OwnsT(OwnsT&& other) {} +}; + +using OwnsNonCopyable = OwnsT; + +#if __cplusplus >= 202002L +template +struct RequiresCopyableT { + T element; + RequiresCopyableT() {} + RequiresCopyableT(const RequiresCopyableT &other) requires std::is_copy_constructible_v : element(other.element) {} + RequiresCopyableT(RequiresCopyableT&& other) {} +}; + +using NonCopyableRequires = RequiresCopyableT; + +#endif + +//--- test.swift +import Test +import CxxStdlib + +func takeCopyable(_ x: T) {} +// expected-note@-1 {{'where T: Copyable' is implicit here}} +// expected-cpp20-note@-2 {{'where T: Copyable' is implicit here}} + +func userDefinedTypes() { + let nCop = NonCopyable() + takeCopyable(nCop) // expected-error {{global function 'takeCopyable' requires that 'NonCopyable' conform to 'Copyable'}} + + let ownsT = OwnsNonCopyable() + takeCopyable(ownsT) // no error, OwnsNonCopyable imported as Copyable + +} + +#if CPP20 +func useOfRequires() { + let nCop = NonCopyableRequires() + takeCopyable(nCop) // expected-cpp20-error {{global function 'takeCopyable' requires that 'NonCopyableRequires' (aka 'RequiresCopyableT') conform to 'Copyable'}} +} +#endif +