Skip to content

Commit 7eada7d

Browse files
authored
Merge pull request swiftlang#79012 from swiftlang/gaborh/disfavoredOverload
[cxx-interop] Avoid generating ambiguous wrapper functions
2 parents 0572eb9 + a57aff0 commit 7eada7d

File tree

8 files changed

+29
-19
lines changed

8 files changed

+29
-19
lines changed

lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift

+19-9
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,10 @@ func transformType(_ prev: TypeSyntax, _ generateSpan: Bool, _ isSizedBy: Bool)
289289
protocol BoundsCheckedThunkBuilder {
290290
func buildFunctionCall(_ pointerArgs: [Int: ExprSyntax]) throws -> ExprSyntax
291291
func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item]
292+
// The second component of the return value is true when only the return type of the
293+
// function signature was changed.
292294
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
293-
-> FunctionSignatureSyntax
295+
-> (FunctionSignatureSyntax, Bool)
294296
}
295297

296298
func getParam(_ signature: FunctionSignatureSyntax, _ paramIndex: Int) -> FunctionParameterSyntax {
@@ -308,6 +310,7 @@ func getParam(_ funcDecl: FunctionDeclSyntax, _ paramIndex: Int) -> FunctionPara
308310

309311
struct FunctionCallBuilder: BoundsCheckedThunkBuilder {
310312
let base: FunctionDeclSyntax
313+
311314
init(_ function: FunctionDeclSyntax) {
312315
base = function
313316
}
@@ -317,7 +320,7 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder {
317320
}
318321

319322
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
320-
-> FunctionSignatureSyntax {
323+
-> (FunctionSignatureSyntax, Bool) {
321324
var newParams = base.signature.parameterClause.parameters.enumerated().filter {
322325
let type = argTypes[$0.offset]
323326
// filter out deleted parameters, i.e. ones where argTypes[i] _contains_ nil
@@ -333,7 +336,7 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder {
333336
if returnType != nil {
334337
sig = sig.with(\.returnClause!.type, returnType!)
335338
}
336-
return sig
339+
return (sig, (argTypes.count == 0 && returnType != nil))
337340
}
338341

339342
func buildFunctionCall(_ pointerArgs: [Int: ExprSyntax]) throws -> ExprSyntax {
@@ -381,7 +384,7 @@ struct CxxSpanThunkBuilder: ParamPointerBoundsThunkBuilder {
381384
}
382385

383386
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
384-
-> FunctionSignatureSyntax {
387+
-> (FunctionSignatureSyntax, Bool) {
385388
var types = argTypes
386389
let typeName = try getTypeName(oldType).text
387390
guard let desugaredType = typeMappings[typeName] else {
@@ -417,7 +420,7 @@ struct CxxSpanReturnThunkBuilder: BoundsCheckedThunkBuilder {
417420
}
418421

419422
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
420-
-> FunctionSignatureSyntax {
423+
-> (FunctionSignatureSyntax, Bool) {
421424
assert(returnType == nil)
422425
let typeName = try getTypeName(signature.returnClause!.type).text
423426
guard let desugaredType = typeMappings[typeName] else {
@@ -490,7 +493,7 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder {
490493
}
491494

492495
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
493-
-> FunctionSignatureSyntax {
496+
-> (FunctionSignatureSyntax, Bool) {
494497
assert(returnType == nil)
495498
return try base.buildFunctionSignature(argTypes, newType)
496499
}
@@ -518,7 +521,7 @@ struct CountedOrSizedPointerThunkBuilder: ParamPointerBoundsThunkBuilder {
518521
public let skipTrivialCount: Bool
519522

520523
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
521-
-> FunctionSignatureSyntax {
524+
-> (FunctionSignatureSyntax, Bool) {
522525
var types = argTypes
523526
types[index] = try newType
524527
if skipTrivialCount {
@@ -1104,7 +1107,7 @@ public struct SwiftifyImportMacro: PeerMacro {
11041107
{ (prev, parsedArg) in
11051108
parsedArg.getBoundsCheckedThunkBuilder(prev, funcDecl, skipTrivialCount)
11061109
})
1107-
let newSignature = try builder.buildFunctionSignature([:], nil)
1110+
let (newSignature, onlyReturnTypeChanged) = try builder.buildFunctionSignature([:], nil)
11081111
let checks =
11091112
skipTrivialCount
11101113
? [] as [CodeBlockItemSyntax]
@@ -1118,6 +1121,12 @@ public struct SwiftifyImportMacro: PeerMacro {
11181121
expression: try builder.buildFunctionCall([:]))))
11191122
let body = CodeBlockSyntax(statements: CodeBlockItemListSyntax(checks + [call]))
11201123
let lifetimeAttrs = lifetimeAttributes(funcDecl, lifetimeDependencies)
1124+
let disfavoredOverload : [AttributeListSyntax.Element] = (onlyReturnTypeChanged ? [
1125+
.attribute(
1126+
AttributeSyntax(
1127+
atSign: .atSignToken(),
1128+
attributeName: IdentifierTypeSyntax(name: "_disfavoredOverload")))
1129+
] : [])
11211130
let newFunc =
11221131
funcDecl
11231132
.with(\.signature, newSignature)
@@ -1138,7 +1147,8 @@ public struct SwiftifyImportMacro: PeerMacro {
11381147
atSign: .atSignToken(),
11391148
attributeName: IdentifierTypeSyntax(name: "_alwaysEmitIntoClient")))
11401149
]
1141-
+ lifetimeAttrs)
1150+
+ lifetimeAttrs
1151+
+ disfavoredOverload)
11421152
return [DeclSyntax(newFunc)]
11431153
} catch let error as DiagnosticError {
11441154
context.diagnose(

test/Interop/C/swiftify-import/counted-by-noescape.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import CountedByNoEscapeClang
1414
// CHECK: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: MutableSpan<Int{{.*}}>)
1515
// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: MutableSpan<Int{{.*}}>)
1616
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: MutableSpan<Int{{.*}}>)
17-
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
17+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
1818
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: MutableSpan<Int{{.*}}>, _ p2: MutableSpan<Int{{.*}}>)
1919
// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: MutableSpan<Int{{.*}}>)
2020
// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: MutableSpan<Int{{.*}}>)

test/Interop/C/swiftify-import/counted-by.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import CountedByClang
1414
// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: UnsafeMutableBufferPointer<Int{{.*}}>)
1515
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: UnsafeMutableBufferPointer<Int{{.*}}>)
1616
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: UnsafeMutableBufferPointer<Int{{.*}}>?)
17-
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
17+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
1818
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: UnsafeMutableBufferPointer<Int{{.*}}>, _ p2: UnsafeMutableBufferPointer<Int{{.*}}>)
1919
// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: UnsafeMutableBufferPointer<Int{{.*}}>)
2020
// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: UnsafeMutableBufferPointer<Int{{.*}}>)

test/Interop/C/swiftify-import/sized-by-noescape.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SizedByNoEscapeClang
1414
// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: RawSpan)
1515
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: RawSpan)
1616
// CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ p: RawSpan)
17-
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnPointer(_ len: Int{{.*}}) -> UnsafeRawBufferPointer
17+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeRawBufferPointer
1818
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: RawSpan, _ p2: RawSpan)
1919
// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: RawSpan)
2020
// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: RawSpan)

test/Interop/C/swiftify-import/sized-by.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SizedByClang
1414
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: UnsafeMutableRawBufferPointer)
1515
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: UnsafeMutableRawBufferPointer?)
1616
// CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ p: UnsafeRawBufferPointer)
17-
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableRawBufferPointer
17+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableRawBufferPointer
1818
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: UnsafeMutableRawBufferPointer, _ p2: UnsafeMutableRawBufferPointer)
1919
// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: UnsafeMutableRawBufferPointer)
2020
// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: UnsafeMutableRawBufferPointer)

test/Interop/Cxx/stdlib/std-span-interface.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import CxxStdlib
1616

1717
// CHECK: struct DependsOnSelf {
1818
// CHECK: @lifetime(borrow self)
19-
// CHECK-NEXT: @_alwaysEmitIntoClient public mutating func get() -> Span<CInt>
19+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func get() -> Span<CInt>
2020
// CHECK-NEXT: mutating func get() -> ConstSpanOfInt
2121

2222
// CHECK: mutating func set(_ x: borrowing std.{{.*}}vector<CInt, std.{{.*}}allocator<CInt>>)
@@ -32,4 +32,4 @@ import CxxStdlib
3232
// CHECK-NEXT: @lifetime(s)
3333
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span<CInt>) -> Span<CInt>
3434
// CHECK-NEXT: @lifetime(borrow v)
35-
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>
35+
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>

test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ func myFunc(_ len: CInt) -> UnsafeMutablePointer<CInt> {
1010
func nonEscaping(_ len: CInt) -> UnsafePointer<CInt> {
1111
}
1212

13-
// CHECK: @_alwaysEmitIntoClient
13+
// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload
1414
// CHECK-NEXT: func myFunc(_ len: CInt) -> UnsafeMutableBufferPointer<CInt> {
1515
// CHECK-NEXT: return UnsafeMutableBufferPointer<CInt> (start: myFunc(len), count: Int(len))
1616
// CHECK-NEXT: }
1717

18-
// CHECK: @_alwaysEmitIntoClient
18+
// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload
1919
// CHECK-NEXT: func nonEscaping(_ len: CInt) -> UnsafeBufferPointer<CInt> {
2020
// CHECK-NEXT: return UnsafeBufferPointer<CInt> (start: nonEscaping(len), count: Int(len))
2121
// CHECK-NEXT: }

test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct X {
3939
// CHECK-NEXT: return Span(_unsafeCxxSpan: myFunc(SpanOfInt(span)))
4040
// CHECK-NEXT: }
4141

42-
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec)
42+
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec) @_disfavoredOverload
4343
// CHECK-NEXT: func myFunc2(_ vec: borrowing VecOfInt) -> Span<CInt> {
4444
// CHECK-NEXT: return Span(_unsafeCxxSpan: myFunc2(vec))
4545
// CHECK-NEXT: }
@@ -54,7 +54,7 @@ struct X {
5454
// CHECK-NEXT: return Span(_unsafeCxxSpan: myFunc4(vec, SpanOfInt(span)))
5555
// CHECK-NEXT: }
5656

57-
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow self)
57+
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow self) @_disfavoredOverload
5858
// CHECK-NEXT: func myFunc5() -> Span<CInt> {
5959
// CHECK-NEXT: return Span(_unsafeCxxSpan: myFunc5())
6060
// CHECK-NEXT: }

0 commit comments

Comments
 (0)