Skip to content

Commit 32aae69

Browse files
committed
[cxx-interop] Drop return values of +=, -=, *=, /=
These operators return `Void` in Swift, let's drop the return type of these operators when importing them from C++. This is needed for the upcoming `UnsafeCxxRandomAccessIterator` protocol: if a protocol declares `func +=` returning `Void`, but the implementation non-`Void`, that causes a typechecker error.
1 parent b0fd4c3 commit 32aae69

File tree

6 files changed

+18
-10
lines changed

6 files changed

+18
-10
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,15 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
20842084
clangDecl->hasAttr<clang::CFReturnsRetainedAttr>() ||
20852085
clangDecl->hasAttr<clang::CFReturnsNotRetainedAttr>());
20862086

2087+
// C++ operators +=, -=, *=, /= may return a reference to self. This is not
2088+
// idiomatic in Swift, let's drop these return values.
2089+
clang::OverloadedOperatorKind op = clangDecl->getOverloadedOperator();
2090+
if (op == clang::OverloadedOperatorKind::OO_PlusEqual ||
2091+
op == clang::OverloadedOperatorKind::OO_MinusEqual ||
2092+
op == clang::OverloadedOperatorKind::OO_StarEqual ||
2093+
op == clang::OverloadedOperatorKind::OO_SlashEqual)
2094+
return {SwiftContext.getVoidType(), false};
2095+
20872096
// Fix up optionality.
20882097
OptionalTypeKind OptionalityOfReturn;
20892098
if (clangDecl->hasAttr<clang::ReturnsNonNullAttr>()) {

test/Interop/Cxx/operators/member-inline-module-interface.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// CHECK: struct LoadableIntWrapper {
44
// CHECK: func successor() -> LoadableIntWrapper
55
// CHECK: static func - (lhs: inout LoadableIntWrapper, rhs: LoadableIntWrapper) -> LoadableIntWrapper
6+
// CHECK: static func += (lhs: inout LoadableIntWrapper, rhs: LoadableIntWrapper)
67
// CHECK: mutating func callAsFunction() -> Int32
78
// CHECK: mutating func callAsFunction(_ x: Int32) -> Int32
89
// CHECK: mutating func callAsFunction(_ x: Int32, _ y: Int32) -> Int32

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var lhs = LoadableIntWrapper(value: 42)
66
let rhs = LoadableIntWrapper(value: 23)
77

88
let resultPlus = lhs - rhs
9+
lhs += rhs
910
let resultCall0 = lhs()
1011
let resultCall1 = lhs(1)
1112
let resultCall2 = lhs(1, 2)

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop)
22
//
33
// REQUIRES: executable_test
4-
// TODO: Fix CxxShim for Windows.
5-
// XFAIL: OS=windows-msvc
64

75
import MemberInline
86
import StdlibUnittest
@@ -42,20 +40,18 @@ OperatorsTestSuite.test("LoadableIntWrapper.plusEqual (inline)") {
4240
var lhs = LoadableIntWrapper(value: 42)
4341
let rhs = LoadableIntWrapper(value: 42)
4442

45-
let result = lhs += rhs
43+
lhs += rhs
4644

4745
expectEqual(lhs.value, 84)
48-
expectEqual(result.value, 84)
4946
}
5047

5148
OperatorsTestSuite.test("LoadableIntWrapper.minusEqual (inline)") {
5249
var lhs = LoadableIntWrapper(value: 42)
5350
let rhs = LoadableIntWrapper(value: 42)
5451

55-
let result = lhs -= rhs
52+
lhs -= rhs
5653

5754
expectEqual(lhs.value, 0)
58-
expectEqual(result.value, 0)
5955
}
6056

6157
OperatorsTestSuite.test("LoadableIntWrapper.unaryMinus (inline)") {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ let resultExclaimEqual = lhs != rhs
2222
let resultLessEqual = lhs <= rhs
2323
let resultGreaterEqual = lhs >= rhs
2424

25+
var lhsMutable = LoadableIntWrapper(value: 42)
26+
lhsMutable /= rhs
27+
2528
public func ==(ptr: UnsafePointer<UInt8>, count: Int) -> Bool {
2629
let lhs = UnsafeBufferPointer<UInt8>(start: ptr, count: count)
2730
let rhs = UnsafeBufferPointer<UInt8>(start: ptr, count: count)

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,20 +155,18 @@ OperatorsTestSuite.test("slash equal (/=)") {
155155
var lhs = LoadableIntWrapper(value: 8)
156156
let rhs = LoadableIntWrapper(value: 2)
157157

158-
let result = lhs /= rhs
158+
lhs /= rhs
159159

160160
expectEqual(lhs.value, 4)
161-
expectEqual(result.value, 4)
162161
}
163162

164163
OperatorsTestSuite.test("star equal (*=)") {
165164
var lhs = LoadableIntWrapper(value: 8)
166165
let rhs = LoadableIntWrapper(value: 2)
167166

168-
let result = lhs *= rhs
167+
lhs *= rhs
169168

170169
expectEqual(lhs.value, 16)
171-
expectEqual(result.value, 16)
172170
}
173171

174172
OperatorsTestSuite.test("amp amp (&&)") {

0 commit comments

Comments
 (0)