mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "[cxx-interop] Implicitly defined copy constructors"
This reverts commit 1c5bbe0290.
This commit is contained in:
@@ -733,12 +733,6 @@ ValueDecl *getImportedMemberOperator(const DeclBaseName &name,
|
|||||||
/// as permissive as the input C++ access.
|
/// as permissive as the input C++ access.
|
||||||
AccessLevel convertClangAccess(clang::AccessSpecifier access);
|
AccessLevel convertClangAccess(clang::AccessSpecifier access);
|
||||||
|
|
||||||
/// Lookup and return the copy constructor of \a decl
|
|
||||||
///
|
|
||||||
/// Returns nullptr if \a decl doesn't have a valid copy constructor
|
|
||||||
const clang::CXXConstructorDecl *
|
|
||||||
findCopyConstructor(const clang::CXXRecordDecl *decl);
|
|
||||||
|
|
||||||
/// Read file IDs from 'private_fileid' Swift attributes on a Clang decl.
|
/// Read file IDs from 'private_fileid' Swift attributes on a Clang decl.
|
||||||
///
|
///
|
||||||
/// May return >1 fileID when a decl is annotated more than once, which should
|
/// May return >1 fileID when a decl is annotated more than once, which should
|
||||||
|
|||||||
@@ -8322,39 +8322,16 @@ bool importer::isViewType(const clang::CXXRecordDecl *decl) {
|
|||||||
return !hasOwnedValueAttr(decl) && hasPointerInSubobjects(decl);
|
return !hasOwnedValueAttr(decl) && hasPointerInSubobjects(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const clang::CXXConstructorDecl *
|
static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl) {
|
||||||
importer::findCopyConstructor(const clang::CXXRecordDecl *decl) {
|
if (decl->hasSimpleCopyConstructor())
|
||||||
for (auto ctor : decl->ctors()) {
|
|
||||||
if (ctor->isCopyConstructor() &&
|
|
||||||
// FIXME: Support default arguments (rdar://142414553)
|
|
||||||
ctor->getNumParams() == 1 && ctor->getAccess() == clang::AS_public &&
|
|
||||||
!ctor->isDeleted() && !ctor->isIneligibleOrNotSelected())
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl,
|
|
||||||
ClangImporter::Implementation *importerImpl) {
|
|
||||||
if (!decl->hasSimpleCopyConstructor()) {
|
|
||||||
auto *copyCtor = findCopyConstructor(decl);
|
|
||||||
if (!copyCtor)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!copyCtor->isDefaulted())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// If the copy constructor is defaulted or implicitly declared, we should only
|
return llvm::any_of(decl->ctors(), [](clang::CXXConstructorDecl *ctor) {
|
||||||
// import the type as copyable if all its fields are also copyable
|
return ctor->isCopyConstructor() && !ctor->isDeleted() &&
|
||||||
// FIXME: we should also look at the bases
|
!ctor->isIneligibleOrNotSelected() &&
|
||||||
return llvm::none_of(decl->fields(), [&](clang::FieldDecl *field) {
|
// FIXME: Support default arguments (rdar://142414553)
|
||||||
if (const auto *rd = field->getType()->getAsRecordDecl()) {
|
ctor->getNumParams() == 1 &&
|
||||||
return (!field->getType()->isReferenceType() &&
|
ctor->getAccess() == clang::AccessSpecifier::AS_public;
|
||||||
!field->getType()->isPointerType() &&
|
|
||||||
recordHasMoveOnlySemantics(rd, importerImpl));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8554,7 +8531,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isCopyable = !hasNonCopyableAttr(cxxRecordDecl) &&
|
bool isCopyable = !hasNonCopyableAttr(cxxRecordDecl) &&
|
||||||
hasCopyTypeOperations(cxxRecordDecl, importerImpl);
|
hasCopyTypeOperations(cxxRecordDecl);
|
||||||
bool isMovable = hasMoveTypeOperations(cxxRecordDecl);
|
bool isMovable = hasMoveTypeOperations(cxxRecordDecl);
|
||||||
|
|
||||||
if (!hasDestroyTypeOperations(cxxRecordDecl) || (!isCopyable && !isMovable)) {
|
if (!hasDestroyTypeOperations(cxxRecordDecl) || (!isCopyable && !isMovable)) {
|
||||||
|
|||||||
@@ -186,15 +186,6 @@ bool importer::recordHasReferenceSemantics(
|
|||||||
return semanticsKind == CxxRecordSemanticsKind::Reference;
|
return semanticsKind == CxxRecordSemanticsKind::Reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool importer::recordHasMoveOnlySemantics(
|
|
||||||
const clang::RecordDecl *decl,
|
|
||||||
ClangImporter::Implementation *importerImpl) {
|
|
||||||
auto semanticsKind = evaluateOrDefault(
|
|
||||||
importerImpl->SwiftContext.evaluator,
|
|
||||||
CxxValueSemantics({decl->getTypeForDecl(), importerImpl}), {});
|
|
||||||
return semanticsKind == CxxValueSemanticsKind::MoveOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool importer::hasImmortalAttrs(const clang::RecordDecl *decl) {
|
bool importer::hasImmortalAttrs(const clang::RecordDecl *decl) {
|
||||||
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
|
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
|
||||||
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
|
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
|
||||||
@@ -2104,7 +2095,10 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool recordHasMoveOnlySemantics(const clang::RecordDecl *decl) {
|
bool recordHasMoveOnlySemantics(const clang::RecordDecl *decl) {
|
||||||
return importer::recordHasMoveOnlySemantics(decl, &Impl);
|
auto semanticsKind = evaluateOrDefault(
|
||||||
|
Impl.SwiftContext.evaluator,
|
||||||
|
CxxValueSemantics({decl->getTypeForDecl(), &Impl}), {});
|
||||||
|
return semanticsKind == CxxValueSemanticsKind::MoveOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void markReturnsUnsafeNonescapable(AbstractFunctionDecl *fd) {
|
void markReturnsUnsafeNonescapable(AbstractFunctionDecl *fd) {
|
||||||
@@ -2283,10 +2277,14 @@ namespace {
|
|||||||
loc, ArrayRef<InheritedEntry>(), nullptr, dc);
|
loc, ArrayRef<InheritedEntry>(), nullptr, dc);
|
||||||
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
|
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
|
||||||
|
|
||||||
if (decl->isInStdNamespace() && decl->getName() == "promise" && recordHasMoveOnlySemantics(decl)) {
|
if (recordHasMoveOnlySemantics(decl)) {
|
||||||
|
if (decl->isInStdNamespace() && decl->getName() == "promise") {
|
||||||
// Do not import std::promise.
|
// Do not import std::promise.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
result->addAttribute(new (Impl.SwiftContext)
|
||||||
|
MoveOnlyAttr(/*Implicit=*/true));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Figure out what to do with superclasses in C++. One possible
|
// FIXME: Figure out what to do with superclasses in C++. One possible
|
||||||
// solution would be to turn them into members and add conversion
|
// solution would be to turn them into members and add conversion
|
||||||
@@ -2532,11 +2530,6 @@ namespace {
|
|||||||
cxxRecordDecl->ctors().empty());
|
cxxRecordDecl->ctors().empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recordHasMoveOnlySemantics(decl)) {
|
|
||||||
result->getAttrs().add(new (Impl.SwiftContext)
|
|
||||||
MoveOnlyAttr(/*Implicit=*/true));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: builtin "zeroInitializer" does not work with non-escapable
|
// TODO: builtin "zeroInitializer" does not work with non-escapable
|
||||||
// types yet. Don't generate an initializer.
|
// types yet. Don't generate an initializer.
|
||||||
if (hasZeroInitializableStorage && needsEmptyInitializer &&
|
if (hasZeroInitializableStorage && needsEmptyInitializer &&
|
||||||
@@ -3132,10 +3125,11 @@ namespace {
|
|||||||
// instantiate its copy constructor.
|
// instantiate its copy constructor.
|
||||||
bool isExplicitlyNonCopyable = hasNonCopyableAttr(decl);
|
bool isExplicitlyNonCopyable = hasNonCopyableAttr(decl);
|
||||||
|
|
||||||
|
clang::CXXConstructorDecl *copyCtor = nullptr;
|
||||||
clang::CXXConstructorDecl *moveCtor = nullptr;
|
clang::CXXConstructorDecl *moveCtor = nullptr;
|
||||||
clang::CXXConstructorDecl *defaultCtor = nullptr;
|
clang::CXXConstructorDecl *defaultCtor = nullptr;
|
||||||
if (decl->needsImplicitCopyConstructor() && !isExplicitlyNonCopyable) {
|
if (decl->needsImplicitCopyConstructor() && !isExplicitlyNonCopyable) {
|
||||||
clangSema.DeclareImplicitCopyConstructor(
|
copyCtor = clangSema.DeclareImplicitCopyConstructor(
|
||||||
const_cast<clang::CXXRecordDecl *>(decl));
|
const_cast<clang::CXXRecordDecl *>(decl));
|
||||||
}
|
}
|
||||||
if (decl->needsImplicitMoveConstructor()) {
|
if (decl->needsImplicitMoveConstructor()) {
|
||||||
@@ -3156,7 +3150,10 @@ namespace {
|
|||||||
// Note: we use "doesThisDeclarationHaveABody" here because
|
// Note: we use "doesThisDeclarationHaveABody" here because
|
||||||
// that's what "DefineImplicitCopyConstructor" checks.
|
// that's what "DefineImplicitCopyConstructor" checks.
|
||||||
!declCtor->doesThisDeclarationHaveABody()) {
|
!declCtor->doesThisDeclarationHaveABody()) {
|
||||||
if (declCtor->isMoveConstructor()) {
|
if (declCtor->isCopyConstructor()) {
|
||||||
|
if (!copyCtor && !isExplicitlyNonCopyable)
|
||||||
|
copyCtor = declCtor;
|
||||||
|
} else if (declCtor->isMoveConstructor()) {
|
||||||
if (!moveCtor)
|
if (!moveCtor)
|
||||||
moveCtor = declCtor;
|
moveCtor = declCtor;
|
||||||
} else if (declCtor->isDefaultConstructor()) {
|
} else if (declCtor->isDefaultConstructor()) {
|
||||||
@@ -3166,6 +3163,11 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (copyCtor && !isExplicitlyNonCopyable &&
|
||||||
|
!decl->isAnonymousStructOrUnion()) {
|
||||||
|
clangSema.DefineImplicitCopyConstructor(clang::SourceLocation(),
|
||||||
|
copyCtor);
|
||||||
|
}
|
||||||
if (moveCtor && !decl->isAnonymousStructOrUnion()) {
|
if (moveCtor && !decl->isAnonymousStructOrUnion()) {
|
||||||
clangSema.DefineImplicitMoveConstructor(clang::SourceLocation(),
|
clangSema.DefineImplicitMoveConstructor(clang::SourceLocation(),
|
||||||
moveCtor);
|
moveCtor);
|
||||||
|
|||||||
@@ -1974,11 +1974,6 @@ namespace importer {
|
|||||||
bool recordHasReferenceSemantics(const clang::RecordDecl *decl,
|
bool recordHasReferenceSemantics(const clang::RecordDecl *decl,
|
||||||
ClangImporter::Implementation *importerImpl);
|
ClangImporter::Implementation *importerImpl);
|
||||||
|
|
||||||
/// Returns true if the given C/C++ record should be imported as non-copyable into
|
|
||||||
/// Swift.
|
|
||||||
bool recordHasMoveOnlySemantics(const clang::RecordDecl *decl,
|
|
||||||
ClangImporter::Implementation *importerImpl);
|
|
||||||
|
|
||||||
/// Whether this is a forward declaration of a type. We ignore forward
|
/// Whether this is a forward declaration of a type. We ignore forward
|
||||||
/// declarations in certain cases, and instead process the real declarations.
|
/// declarations in certain cases, and instead process the real declarations.
|
||||||
bool isForwardDeclOfType(const clang::Decl *decl);
|
bool isForwardDeclOfType(const clang::Decl *decl);
|
||||||
|
|||||||
@@ -553,7 +553,15 @@ namespace {
|
|||||||
const auto *cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(ClangDecl);
|
const auto *cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(ClangDecl);
|
||||||
if (!cxxRecordDecl)
|
if (!cxxRecordDecl)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return importer::findCopyConstructor(cxxRecordDecl);
|
for (auto ctor : cxxRecordDecl->ctors()) {
|
||||||
|
if (ctor->isCopyConstructor() &&
|
||||||
|
// FIXME: Support default arguments (rdar://142414553)
|
||||||
|
ctor->getNumParams() == 1 &&
|
||||||
|
ctor->getAccess() == clang::AS_public && !ctor->isDeleted() &&
|
||||||
|
!ctor->isIneligibleOrNotSelected())
|
||||||
|
return ctor;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clang::CXXConstructorDecl *findMoveConstructor() const {
|
const clang::CXXConstructorDecl *findMoveConstructor() const {
|
||||||
@@ -622,17 +630,6 @@ namespace {
|
|||||||
auto &ctx = IGF.IGM.Context;
|
auto &ctx = IGF.IGM.Context;
|
||||||
auto *importer = static_cast<ClangImporter *>(ctx.getClangModuleLoader());
|
auto *importer = static_cast<ClangImporter *>(ctx.getClangModuleLoader());
|
||||||
|
|
||||||
if (copyConstructor->isDefaulted() &&
|
|
||||||
copyConstructor->getAccess() == clang::AS_public &&
|
|
||||||
!copyConstructor->isDeleted() &&
|
|
||||||
// Note: we use "doesThisDeclarationHaveABody" here because
|
|
||||||
// that's what "DefineImplicitCopyConstructor" checks.
|
|
||||||
!copyConstructor->doesThisDeclarationHaveABody()) {
|
|
||||||
importer->getClangSema().DefineImplicitCopyConstructor(
|
|
||||||
clang::SourceLocation(),
|
|
||||||
const_cast<clang::CXXConstructorDecl *>(copyConstructor));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &diagEngine = importer->getClangSema().getDiagnostics();
|
auto &diagEngine = importer->getClangSema().getDiagnostics();
|
||||||
clang::DiagnosticErrorTrap trap(diagEngine);
|
clang::DiagnosticErrorTrap trap(diagEngine);
|
||||||
auto clangFnAddr =
|
auto clangFnAddr =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// RUN: %empty-directory(%t)
|
||||||
// RUN: split-file %s %t
|
// RUN: split-file %s %t
|
||||||
// RUN: %target-swift-frontend -cxx-interoperability-mode=default -typecheck -verify -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t%{fs-sep}Inputs %t%{fs-sep}test.swift -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}noncopyable.h -verify-ignore-unrelated
|
// RUN: %target-swift-frontend -cxx-interoperability-mode=default -typecheck -verify -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t%{fs-sep}Inputs %t%{fs-sep}test.swift -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}noncopyable.h
|
||||||
// RUN: %target-swift-frontend -cxx-interoperability-mode=default -Xcc -std=c++20 -verify-additional-prefix cpp20- -D CPP20 -typecheck -verify -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t%{fs-sep}Inputs %t%{fs-sep}test.swift -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}noncopyable.h -verify-ignore-unrelated
|
// RUN: %target-swift-frontend -cxx-interoperability-mode=default -Xcc -std=c++20 -verify-additional-prefix cpp20- -D CPP20 -typecheck -verify -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t%{fs-sep}Inputs %t%{fs-sep}test.swift -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}noncopyable.h
|
||||||
|
|
||||||
//--- Inputs/module.modulemap
|
//--- Inputs/module.modulemap
|
||||||
module Test {
|
module Test {
|
||||||
@@ -15,7 +15,7 @@ module Test {
|
|||||||
|
|
||||||
struct NonCopyable {
|
struct NonCopyable {
|
||||||
NonCopyable() = default;
|
NonCopyable() = default;
|
||||||
NonCopyable(const NonCopyable& other) = delete; // expected-note {{'NonCopyable' has been explicitly marked deleted here}}
|
NonCopyable(const NonCopyable& other) = delete;
|
||||||
NonCopyable(NonCopyable&& other) = default;
|
NonCopyable(NonCopyable&& other) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,44 +79,6 @@ struct SWIFT_NONCOPYABLE NonCopyableNonMovable { // expected-note {{record 'NonC
|
|||||||
NonCopyableNonMovable(NonCopyableNonMovable&& other) = delete;
|
NonCopyableNonMovable(NonCopyableNonMovable&& other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImplicitCopyConstructor {
|
|
||||||
NonCopyable element;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename P, typename R>
|
|
||||||
struct TemplatedImplicitCopyConstructor {
|
|
||||||
T element;
|
|
||||||
P *pointer;
|
|
||||||
R &reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
using NonCopyableT = TemplatedImplicitCopyConstructor<NonCopyable, int, int>;
|
|
||||||
using NonCopyableP = TemplatedImplicitCopyConstructor<int, NonCopyable, int>;
|
|
||||||
using NonCopyableR = TemplatedImplicitCopyConstructor<int, int, NonCopyable>;
|
|
||||||
|
|
||||||
struct DefaultedCopyConstructor {
|
|
||||||
NonCopyable element; // expected-note {{copy constructor of 'DefaultedCopyConstructor' is implicitly deleted because field 'element' has a deleted copy constructor}}
|
|
||||||
DefaultedCopyConstructor(const DefaultedCopyConstructor&) = default;
|
|
||||||
// expected-warning@-1 {{explicitly defaulted copy constructor is implicitly deleted}}
|
|
||||||
// expected-note@-2 {{replace 'default' with 'delete'}}
|
|
||||||
DefaultedCopyConstructor(DefaultedCopyConstructor&&) = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct TemplatedDefaultedCopyConstructor {
|
|
||||||
T element;
|
|
||||||
TemplatedDefaultedCopyConstructor(const TemplatedDefaultedCopyConstructor&) = default;
|
|
||||||
TemplatedDefaultedCopyConstructor(TemplatedDefaultedCopyConstructor&&) = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct DerivedTemplatedDefaultedCopyConstructor : TemplatedDefaultedCopyConstructor<T> {};
|
|
||||||
|
|
||||||
using CopyableDefaultedCopyConstructor = TemplatedDefaultedCopyConstructor<NonCopyableP>;
|
|
||||||
using NonCopyableDefaultedCopyConstructor = TemplatedDefaultedCopyConstructor<NonCopyable>;
|
|
||||||
using CopyableDerived = DerivedTemplatedDefaultedCopyConstructor<NonCopyableR>;
|
|
||||||
using NonCopyableDerived = DerivedTemplatedDefaultedCopyConstructor<NonCopyable>;
|
|
||||||
|
|
||||||
template<typename T> struct SWIFT_COPYABLE_IF(T) DisposableContainer {};
|
template<typename T> struct SWIFT_COPYABLE_IF(T) DisposableContainer {};
|
||||||
struct POD { int x; float y; }; // special members are implicit, but should be copyable
|
struct POD { int x; float y; }; // special members are implicit, but should be copyable
|
||||||
using DisposablePOD = DisposableContainer<POD>; // should also be copyable
|
using DisposablePOD = DisposableContainer<POD>; // should also be copyable
|
||||||
@@ -171,23 +133,6 @@ func missingLifetimeOperation() {
|
|||||||
takeCopyable(s)
|
takeCopyable(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func implicitCopyConstructor(i: borrowing ImplicitCopyConstructor, t: borrowing NonCopyableT, p: borrowing NonCopyableP, r: borrowing NonCopyableR) {
|
|
||||||
takeCopyable(i) // expected-error {{global function 'takeCopyable' requires that 'ImplicitCopyConstructor' conform to 'Copyable'}}
|
|
||||||
takeCopyable(t) // expected-error {{global function 'takeCopyable' requires that 'NonCopyableT' (aka 'TemplatedImplicitCopyConstructor<NonCopyable, CInt, CInt>') conform to 'Copyable'}}
|
|
||||||
|
|
||||||
// References and pointers to non-copyable types are still copyable
|
|
||||||
takeCopyable(p)
|
|
||||||
takeCopyable(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultCopyConstructor(d: borrowing DefaultedCopyConstructor, d1: borrowing CopyableDefaultedCopyConstructor, d2: borrowing NonCopyableDefaultedCopyConstructor, d3: borrowing CopyableDerived, d4: borrowing NonCopyableDerived) {
|
|
||||||
takeCopyable(d) // expected-error {{global function 'takeCopyable' requires that 'DefaultedCopyConstructor' conform to 'Copyable'}}
|
|
||||||
takeCopyable(d1)
|
|
||||||
takeCopyable(d2) // expected-error {{global function 'takeCopyable' requires that 'NonCopyableDefaultedCopyConstructor' (aka 'TemplatedDefaultedCopyConstructor<NonCopyable>') conform to 'Copyable'}}
|
|
||||||
takeCopyable(d3)
|
|
||||||
takeCopyable(d4) // expected-error {{global function 'takeCopyable' requires that 'NonCopyableDerived' (aka 'DerivedTemplatedDefaultedCopyConstructor<NonCopyable>') conform to 'Copyable'}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyableDisposablePOD(p: DisposablePOD) {
|
func copyableDisposablePOD(p: DisposablePOD) {
|
||||||
takeCopyable(p)
|
takeCopyable(p)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,9 +89,4 @@ struct CountCopies {
|
|||||||
|
|
||||||
inline std::unique_ptr<CountCopies> getCopyCountedUniquePtr() { return std::make_unique<CountCopies>(); }
|
inline std::unique_ptr<CountCopies> getCopyCountedUniquePtr() { return std::make_unique<CountCopies>(); }
|
||||||
|
|
||||||
struct HasUniqueIntVector {
|
|
||||||
HasUniqueIntVector() = default;
|
|
||||||
std::vector<std::unique_ptr<int>> x;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_UNIQUE_PTR_H
|
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_UNIQUE_PTR_H
|
||||||
|
|||||||
@@ -10,9 +10,3 @@ func takeCopyable<T: Copyable>(_ x: T) {}
|
|||||||
let vecUniquePtr = getVectorNonCopyableUniquePtr()
|
let vecUniquePtr = getVectorNonCopyableUniquePtr()
|
||||||
takeCopyable(vecUniquePtr)
|
takeCopyable(vecUniquePtr)
|
||||||
// CHECK: error: global function 'takeCopyable' requires that 'std{{.*}}vector{{.*}}unique_ptr{{.*}}NonCopyable{{.*}}' conform to 'Copyable'
|
// CHECK: error: global function 'takeCopyable' requires that 'std{{.*}}vector{{.*}}unique_ptr{{.*}}NonCopyable{{.*}}' conform to 'Copyable'
|
||||||
|
|
||||||
let uniqueIntVec = HasUniqueIntVector()
|
|
||||||
takeCopyable(uniqueIntVec)
|
|
||||||
// CHECK: error: global function 'takeCopyable' requires that 'HasUniqueIntVector' conform to 'Copyable'
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user