Skip to content

Commit 7193b70

Browse files
authored
Merge pull request swiftlang#66271 from apple/egorzhdan/borrow-cxx-convertible
[cxx-interop] Initializing a Swift.Array from CxxConvertibleToCollection should not copy the collection
2 parents d3d345b + cf8ac14 commit 7193b70

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

stdlib/public/Cxx/CxxConvertibleToCollection.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ extension RangeReplaceableCollection {
5656
/// be true for certain C++ types, e.g. those with a custom copy
5757
/// constructor that performs additional logic.
5858
@inlinable
59-
public init<C: CxxConvertibleToCollection>(_ elements: C)
59+
public init<C: CxxConvertibleToCollection>(_ elements: __shared C)
6060
where C.RawIterator.Pointee == Element {
6161

6262
self.init()
@@ -74,7 +74,7 @@ extension SetAlgebra {
7474
/// be true for certain C++ types, e.g. those with a custom copy
7575
/// constructor that performs additional logic.
7676
@inlinable
77-
public init<C: CxxConvertibleToCollection>(_ elements: C)
77+
public init<C: CxxConvertibleToCollection>(_ elements: __shared C)
7878
where C.RawIterator.Pointee == Element {
7979

8080
self.init()

test/Interop/Cxx/stdlib/overlay/Inputs/custom-sequence.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ struct SimpleSequenceWithOutOfLineEqualEqual {
1414
ConstIteratorOutOfLineEq end() const { return ConstIteratorOutOfLineEq(5); }
1515
};
1616

17+
static int copiesCount = 0;
18+
19+
struct SimpleCopyAwareSequence {
20+
ConstIterator begin() const { return ConstIterator(1); }
21+
ConstIterator end() const { return ConstIterator(5); }
22+
23+
SimpleCopyAwareSequence() {}
24+
SimpleCopyAwareSequence(const SimpleCopyAwareSequence &other) { copiesCount++; }
25+
};
26+
1727
struct SimpleArrayWrapper {
1828
private:
1929
int a[5] = {10, 20, 30, 40, 50};

test/Interop/Cxx/stdlib/overlay/custom-convertible-to-collection.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ CxxSequenceTestSuite.test("SimpleSequence to Swift.Array") {
1515
expectEqual([1, 2, 3, 4] as [Int32], array)
1616
}
1717

18+
#if !os(Linux) // this test crashes on Linux (https://github.com/apple/swift/issues/66363)
19+
CxxSequenceTestSuite.test("SimpleCopyAwareSequence to Swift.Array") {
20+
copiesCount = 0
21+
22+
let seq = SimpleCopyAwareSequence()
23+
24+
let seqCopy = seq
25+
expectEqual(1, copiesCount) // make sure our copy tracking mechanism works
26+
27+
let array = Array(seq)
28+
29+
expectEqual(1, copiesCount) // make sure we don't copy the C++ sequence value unnecessarily
30+
}
31+
#endif
32+
1833
CxxSequenceTestSuite.test("SimpleSequenceWithOutOfLineEqualEqual to Swift.Array") {
1934
let seq = SimpleSequenceWithOutOfLineEqualEqual()
2035
let array = Array(seq)

0 commit comments

Comments
 (0)