@@ -10,13 +10,15 @@ import SwiftSyntaxMacros
1010enum SwiftifyExpr : Hashable {
1111 case param( _ index: Int )
1212 case `return`
13+ case `self`
1314}
1415
1516extension SwiftifyExpr : CustomStringConvertible {
1617 var description : String {
1718 switch self {
1819 case . param( let index) : return " .param( \( index) ) "
1920 case . return: return " .return "
21+ case . self : return " .self "
2022 }
2123 }
2224}
@@ -26,7 +28,7 @@ enum DependenceType {
2628}
2729
2830struct LifetimeDependence {
29- let dependsOn : Int
31+ let dependsOn : SwiftifyExpr
3032 let type : DependenceType
3133}
3234
@@ -48,6 +50,8 @@ func tryGetParamName(_ funcDecl: FunctionDeclSyntax, _ expr: SwiftifyExpr) -> To
4850 case . param( let i) :
4951 let funcParam = getParam ( funcDecl, i - 1 )
5052 return funcParam. secondName ?? funcParam. firstName
53+ case . `self`:
54+ return . keyword( . self )
5155 default : return nil
5256 }
5357}
@@ -59,6 +63,8 @@ func getSwiftifyExprType(_ funcDecl: FunctionDeclSyntax, _ expr: SwiftifyExpr) -
5963 return funcParam. type
6064 case . return:
6165 return funcDecl. signature. returnClause!. type
66+ case . self :
67+ return TypeSyntax ( IdentifierTypeSyntax ( name: TokenSyntax ( " Self " ) ) )
6268 }
6369}
6470
@@ -84,6 +90,8 @@ struct CxxSpan: ParamInfo {
8490 case . return:
8591 return CxxSpanReturnThunkBuilder ( base: base, signature: funcDecl. signature,
8692 typeMappings: typeMappings, node: original)
93+ case . self :
94+ return base
8795 }
8896 }
8997}
@@ -118,6 +126,8 @@ struct CountedBy: ParamInfo {
118126 base: base, countExpr: count,
119127 signature: funcDecl. signature,
120128 nonescaping: nonescaping, isSizedBy: sizedBy)
129+ case . self :
130+ return base
121131 }
122132 }
123133}
@@ -315,8 +325,9 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder {
315325 } . map { ( i: Int , e: FunctionParameterSyntax ) in
316326 e. with ( \. type, ( argTypes [ i] ?? e. type) !)
317327 }
318- let last = newParams. popLast ( ) !
319- newParams. append ( last. with ( \. trailingComma, nil ) )
328+ if let last = newParams. popLast ( ) {
329+ newParams. append ( last. with ( \. trailingComma, nil ) )
330+ }
320331
321332 var sig = base. signature. with ( \. parameterClause. parameters, FunctionParameterListSyntax ( newParams) )
322333 if returnType != nil {
@@ -755,9 +766,10 @@ public struct SwiftifyImportMacro: PeerMacro {
755766 let pointerParamIndex : Int = try getIntLiteralValue ( pointerParamIndexArg. expression)
756767 return . param( pointerParamIndex)
757768 case " return " : return . return
769+ case " self " : return . `self`
758770 default :
759771 throw DiagnosticError (
760- " expected 'param' or 'return ', got ' \( enumName) ' " ,
772+ " expected 'param', 'return', or 'self ', got ' \( enumName) ' " ,
761773 node: expr)
762774 }
763775 }
@@ -823,7 +835,11 @@ public struct SwiftifyImportMacro: PeerMacro {
823835 static func parseLifetimeDependence( _ enumConstructorExpr: FunctionCallExprSyntax ) throws -> ( SwiftifyExpr , LifetimeDependence ) {
824836 let argumentList = enumConstructorExpr. arguments
825837 let pointer : SwiftifyExpr = try parseSwiftifyExpr ( try getArgumentByName ( argumentList, " pointer " ) )
826- let dependsOn : Int = try getIntLiteralValue ( try getArgumentByName ( argumentList, " dependsOn " ) )
838+ let dependsOnArg = try getArgumentByName ( argumentList, " dependsOn " )
839+ let dependsOn : SwiftifyExpr = try parseSwiftifyExpr ( dependsOnArg)
840+ if dependsOn == . `return` {
841+ throw DiagnosticError ( " lifetime cannot depend on the return value " , node: dependsOnArg)
842+ }
827843 let type = try getArgumentByName ( argumentList, " type " )
828844 let depType : DependenceType
829845 switch try parseEnumName ( type) {
@@ -917,8 +933,9 @@ public struct SwiftifyImportMacro: PeerMacro {
917933 let ( expr, dependence) = try parseLifetimeDependence ( enumConstructorExpr)
918934 lifetimeDependencies [ expr, default: [ ] ] . append ( dependence)
919935 // We assume pointers annotated with lifetimebound do not escape.
920- if dependence. type == DependenceType . copy {
921- nonescapingPointers. insert ( dependence. dependsOn)
936+ let fromIdx = paramOrReturnIndex ( dependence. dependsOn)
937+ if dependence. type == DependenceType . copy && fromIdx != 0 {
938+ nonescapingPointers. insert ( fromIdx)
922939 }
923940 // The escaping is controlled when a parameter is the target of a lifetimebound.
924941 // So we want to do the transformation to Swift's Span.
@@ -987,13 +1004,16 @@ public struct SwiftifyImportMacro: PeerMacro {
9871004 " multiple _SwiftifyInfos referring to return value: \( pointerInfo) and \( ret!) " , node: pointerInfo. original)
9881005 }
9891006 ret = pointerInfo
1007+ case . self :
1008+ throw DiagnosticError ( " do not annotate self " , node: pointerInfo. original)
9901009 }
9911010 }
9921011 }
9931012
9941013 static func paramOrReturnIndex( _ expr: SwiftifyExpr ) -> Int {
9951014 switch expr {
9961015 case . param( let i) : return i
1016+ case . `self`: return 0
9971017 case . return: return - 1
9981018 }
9991019 }
@@ -1029,7 +1049,7 @@ public struct SwiftifyImportMacro: PeerMacro {
10291049 DeclReferenceExprSyntax ( baseName: TokenSyntax ( " borrow " ) ) ) )
10301050 }
10311051 args. append ( LabeledExprSyntax ( expression:
1032- DeclReferenceExprSyntax ( baseName: TokenSyntax ( tryGetParamName ( funcDecl, . param ( dependence. dependsOn) ) ) !) ,
1052+ DeclReferenceExprSyntax ( baseName: TokenSyntax ( tryGetParamName ( funcDecl, dependence. dependsOn) ) !) ,
10331053 trailingComma: . commaToken( ) ) )
10341054 }
10351055 args [ args. count - 1 ] = args [ args. count - 1 ] . with ( \. trailingComma, nil )
0 commit comments