@@ -88,6 +88,9 @@ struct CxxSpan: ParamInfo {
88
88
return CxxSpanThunkBuilder ( base: base, index: i - 1 , signature: funcDecl. signature,
89
89
typeMappings: typeMappings, node: original, nonescaping: nonescaping)
90
90
case . return:
91
+ if dependencies. isEmpty {
92
+ return base
93
+ }
91
94
return CxxSpanReturnThunkBuilder ( base: base, signature: funcDecl. signature,
92
95
typeMappings: typeMappings, node: original)
93
96
case . self :
@@ -125,7 +128,7 @@ struct CountedBy: ParamInfo {
125
128
return CountedOrSizedReturnPointerThunkBuilder (
126
129
base: base, countExpr: count,
127
130
signature: funcDecl. signature,
128
- nonescaping: nonescaping, isSizedBy: sizedBy)
131
+ nonescaping: nonescaping, isSizedBy: sizedBy, dependencies : dependencies )
129
132
case . self :
130
133
return base
131
134
}
@@ -184,11 +187,13 @@ func getTypeName(_ type: TypeSyntax) throws -> TokenSyntax {
184
187
}
185
188
}
186
189
187
- func replaceTypeName( _ type: TypeSyntax , _ name: TokenSyntax ) -> TypeSyntax {
190
+ func replaceTypeName( _ type: TypeSyntax , _ name: TokenSyntax ) throws -> TypeSyntax {
188
191
if let memberType = type. as ( MemberTypeSyntax . self) {
189
192
return TypeSyntax ( memberType. with ( \. name, name) )
190
193
}
191
- let idType = type. as ( IdentifierTypeSyntax . self) !
194
+ guard let idType = type. as ( IdentifierTypeSyntax . self) else {
195
+ throw DiagnosticError ( " unexpected type \( type) with kind \( type. kind) " , node: type)
196
+ }
192
197
return TypeSyntax ( idType. with ( \. name, name) )
193
198
}
194
199
@@ -264,6 +269,10 @@ func transformType(_ prev: TypeSyntax, _ generateSpan: Bool, _ isSizedBy: Bool)
264
269
if let impOptType = prev. as ( ImplicitlyUnwrappedOptionalTypeSyntax . self) {
265
270
return try transformType ( impOptType. wrappedType, generateSpan, isSizedBy)
266
271
}
272
+ if let attrType = prev. as ( AttributedTypeSyntax . self) {
273
+ return TypeSyntax (
274
+ attrType. with ( \. baseType, try transformType ( attrType. baseType, generateSpan, isSizedBy) ) )
275
+ }
267
276
let name = try getTypeName ( prev)
268
277
let text = name. text
269
278
let isRaw = isRawPointerType ( text: text)
@@ -283,7 +292,7 @@ func transformType(_ prev: TypeSyntax, _ generateSpan: Bool, _ isSizedBy: Bool)
283
292
if isSizedBy {
284
293
return TypeSyntax ( IdentifierTypeSyntax ( name: token) )
285
294
}
286
- return replaceTypeName ( prev, token)
295
+ return try replaceTypeName ( prev, token)
287
296
}
288
297
289
298
protocol BoundsCheckedThunkBuilder {
@@ -485,8 +494,9 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder {
485
494
public let signature : FunctionSignatureSyntax
486
495
public let nonescaping : Bool
487
496
public let isSizedBy : Bool
497
+ public let dependencies : [ LifetimeDependence ]
488
498
489
- var generateSpan : Bool = false // needs more lifetime information
499
+ var generateSpan : Bool { !dependencies . isEmpty }
490
500
491
501
var oldType : TypeSyntax {
492
502
return signature. returnClause!. type
@@ -504,9 +514,14 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder {
504
514
505
515
func buildFunctionCall( _ pointerArgs: [ Int : ExprSyntax ] ) throws -> ExprSyntax {
506
516
let call = try base. buildFunctionCall ( pointerArgs)
517
+ let startLabel = if generateSpan {
518
+ " _unsafeStart "
519
+ } else {
520
+ " start "
521
+ }
507
522
return
508
523
"""
509
- \( raw: try newType) (start : \( call) , count: Int( \( countExpr) ))
524
+ \( raw: try newType) ( \( raw : startLabel ) : \( call) , count: Int( \( countExpr) ))
510
525
"""
511
526
}
512
527
}
@@ -1102,6 +1117,11 @@ public struct SwiftifyImportMacro: PeerMacro {
1102
1117
}
1103
1118
}
1104
1119
try checkArgs ( parsedArgs, funcDecl)
1120
+ parsedArgs. sort { a, b in
1121
+ // make sure return value cast to Span happens last so that withUnsafeBufferPointer
1122
+ // doesn't return a ~Escapable type
1123
+ ( a. pointerIndex != . return && b. pointerIndex == . return) || paramOrReturnIndex ( a. pointerIndex) < paramOrReturnIndex ( b. pointerIndex)
1124
+ }
1105
1125
let baseBuilder = FunctionCallBuilder ( funcDecl)
1106
1126
1107
1127
let skipTrivialCount = hasTrivialCountVariants ( parsedArgs)
0 commit comments