From 1d53ecedfd2e995b4555054181f1dadab7e27e17 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Fri, 10 Nov 2023 09:37:58 -0800 Subject: [PATCH] [cxx-interop] make sure a const `operator []` is imported as a mutable setter --- lib/ClangImporter/ImportDecl.cpp | 7 +++++++ .../Cxx/foreign-reference/member-inheritance.swift | 2 +- test/Interop/Cxx/operators/Inputs/member-inline.h | 13 +++++++++++++ test/Interop/Cxx/operators/member-inline.swift | 5 +++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 972a5bb6fe5d3..b746516551a14 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -3569,6 +3569,13 @@ namespace { if (parameter->isInOut()) // Subscripts with inout parameters are not allowed in Swift. return nullptr; + // Subscript setter is marked as mutating in Swift even if the + // C++ `operator []` is `const`. + if (importedName.getAccessorKind() == + ImportedAccessorKind::SubscriptSetter && + !dc->isModuleScopeContext() && + !typeDecl->getDeclaredType()->isForeignReferenceType()) + func->setSelfAccessKind(SelfAccessKind::Mutating); auto &getterAndSetter = Impl.cxxSubscripts[{ typeDecl, parameterType }]; diff --git a/test/Interop/Cxx/foreign-reference/member-inheritance.swift b/test/Interop/Cxx/foreign-reference/member-inheritance.swift index 12dcb928e70a5..62ae5023ec677 100644 --- a/test/Interop/Cxx/foreign-reference/member-inheritance.swift +++ b/test/Interop/Cxx/foreign-reference/member-inheritance.swift @@ -49,7 +49,7 @@ FunctionsTestSuite.test("base member FRT subscript access") { FunctionsTestSuite.test("base member FRT subscript accessing reference FRT") { let copyCounter = getCopyCounter().pointee - let base = makeBaseReturningFRTFromSubscript()! + var base = makeBaseReturningFRTFromSubscript()! var frt = base[1] expectEqual(frt.getX(), 1) diff --git a/test/Interop/Cxx/operators/Inputs/member-inline.h b/test/Interop/Cxx/operators/Inputs/member-inline.h index 2f07261258636..07647ac16b6a7 100644 --- a/test/Interop/Cxx/operators/Inputs/member-inline.h +++ b/test/Interop/Cxx/operators/Inputs/member-inline.h @@ -418,4 +418,17 @@ struct DerivedFromConstIterator : public ConstIterator {}; struct DerivedFromConstIteratorPrivately : private ConstIterator {}; +class SubscriptSetterConst { +public: + using T = int; + + SubscriptSetterConst() : p(new T[10]) {} + + T& operator[](int i) const { + return p[i]; + } +private: + T *p; +}; + #endif diff --git a/test/Interop/Cxx/operators/member-inline.swift b/test/Interop/Cxx/operators/member-inline.swift index 7c2586c5492c9..235f77a0e778b 100644 --- a/test/Interop/Cxx/operators/member-inline.swift +++ b/test/Interop/Cxx/operators/member-inline.swift @@ -378,4 +378,9 @@ OperatorsTestSuite.test("DerivedFromConstIterator.pointee") { expectEqual(234, res) } +OperatorsTestSuite.test("SubscriptSetterConst") { + var setterConst = SubscriptSetterConst() + setterConst[0] = 10 +} + runAllTests()