Skip to content

Commit 351930e

Browse files
authored
Merge pull request #61385 from apple/egorzhdan/cxx-inout-subscript
[cxx-interop] Allow using `std::map` subscript
2 parents 00d86f4 + e28605c commit 351930e

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3200,9 +3200,13 @@ namespace {
32003200
if (importedName.isSubscriptAccessor()) {
32013201
assert(func->getParameters()->size() == 1);
32023202
auto typeDecl = dc->getSelfNominalTypeDecl();
3203-
auto parameterType = func->getParameters()->get(0)->getType();
3203+
auto parameter = func->getParameters()->get(0);
3204+
auto parameterType = parameter->getType();
32043205
if (!typeDecl || !parameterType)
32053206
return nullptr;
3207+
if (parameter->isInOut())
3208+
// Subscripts with inout parameters are not allowed in Swift.
3209+
return nullptr;
32063210

32073211
auto &getterAndSetter = Impl.cxxSubscripts[{ typeDecl,
32083212
parameterType }];

test/Interop/Cxx/operators/Inputs/member-inline.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,32 @@ struct WriteOnlyIntArray {
159159
}
160160
};
161161

162+
struct ReadOnlyRvalueParam {
163+
private:
164+
int values[5] = {1, 2, 3, 4, 5};
165+
166+
public:
167+
const int &operator[](int &&x) const { return values[x]; }
168+
};
169+
170+
struct ReadWriteRvalueParam {
171+
private:
172+
int values[5] = {1, 2, 3, 4, 5};
173+
174+
public:
175+
const int &operator[](int &&x) const { return values[x]; }
176+
int &operator[](int&& x) { return values[x]; }
177+
};
178+
179+
struct ReadWriteRvalueGetterParam {
180+
private:
181+
int values[5] = {1, 2, 3, 4, 5};
182+
183+
public:
184+
const int &operator[](int &&x) const { return values[x]; }
185+
int &operator[](int x) { return values[x]; }
186+
};
187+
162188
struct DifferentTypesArray {
163189
private:
164190
int values[3] = { 1, 2, 3 };

test/Interop/Cxx/operators/member-inline-typechecker.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ var writeOnlyIntArray = WriteOnlyIntArray()
3030
writeOnlyIntArray[2] = 654
3131
let writeOnlyValue = writeOnlyIntArray[2]
3232

33+
var readOnlyRvalueParam = ReadOnlyRvalueParam()
34+
let readOnlyRvalueVal = readOnlyRvalueParam[1] // expected-error {{value of type 'ReadOnlyRvalueParam' has no subscripts}}
35+
36+
var readWriteRvalueParam = ReadWriteRvalueParam()
37+
let readWriteRvalueVal = readWriteRvalueParam[1] // expected-error {{value of type 'ReadWriteRvalueParam' has no subscripts}}
38+
39+
var readWriteRvalueGetterParam = ReadWriteRvalueGetterParam()
40+
let readWriteRvalueGetterVal = readWriteRvalueGetterParam[1]
41+
3342
var diffTypesArray = DifferentTypesArray()
3443
let diffTypesResultInt: Int32 = diffTypesArray[0]
3544
let diffTypesResultDouble: Double = diffTypesArray[0.5]

test/Interop/Cxx/stdlib/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ module StdString {
77
header "std-string.h"
88
requires cplusplus
99
}
10+
11+
module StdMap {
12+
header "std-map.h"
13+
requires cplusplus
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_STD_MAP_H
2+
#define TEST_INTEROP_CXX_STDLIB_INPUTS_STD_MAP_H
3+
4+
#include <map>
5+
6+
using Map = std::map<int, int>;
7+
8+
inline Map initMap() { return {{1, 3}, {2, 2}, {3, 3}}; }
9+
10+
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_MAP_H
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop)
2+
//
3+
// REQUIRES: executable_test
4+
//
5+
// Enable this everywhere once we have a solution for modularizing other C++ stdlibs: rdar://87654514
6+
// REQUIRES: OS=macosx || OS=linux-gnu
7+
8+
import StdlibUnittest
9+
import StdMap
10+
11+
var StdMapTestSuite = TestSuite("StdMap")
12+
13+
#if !os(Linux) // https://github.com/apple/swift/issues/61412
14+
StdMapTestSuite.test("init") {
15+
let m = Map()
16+
expectEqual(m.size(), 0)
17+
expectTrue(m.empty())
18+
}
19+
#endif
20+
21+
StdMapTestSuite.test("subscript") {
22+
var m = initMap()
23+
let at1 = m[1]
24+
expectEqual(at1, 3)
25+
expectEqual(m[2], 2)
26+
expectEqual(m[3], 3)
27+
}
28+
29+
runAllTests()

0 commit comments

Comments
 (0)