@@ -10,13 +10,15 @@ import SwiftSyntaxMacros
10
10
enum SwiftifyExpr : Hashable {
11
11
case param( _ index: Int )
12
12
case `return`
13
+ case `self`
13
14
}
14
15
15
16
extension SwiftifyExpr : CustomStringConvertible {
16
17
var description : String {
17
18
switch self {
18
19
case . param( let index) : return " .param( \( index) ) "
19
20
case . return: return " .return "
21
+ case . self : return " .self "
20
22
}
21
23
}
22
24
}
@@ -26,7 +28,7 @@ enum DependenceType {
26
28
}
27
29
28
30
struct LifetimeDependence {
29
- let dependsOn : Int
31
+ let dependsOn : SwiftifyExpr
30
32
let type : DependenceType
31
33
}
32
34
@@ -48,6 +50,8 @@ func tryGetParamName(_ funcDecl: FunctionDeclSyntax, _ expr: SwiftifyExpr) -> To
48
50
case . param( let i) :
49
51
let funcParam = getParam ( funcDecl, i - 1 )
50
52
return funcParam. secondName ?? funcParam. firstName
53
+ case . `self`:
54
+ return . keyword( . self )
51
55
default : return nil
52
56
}
53
57
}
@@ -59,6 +63,8 @@ func getSwiftifyExprType(_ funcDecl: FunctionDeclSyntax, _ expr: SwiftifyExpr) -
59
63
return funcParam. type
60
64
case . return:
61
65
return funcDecl. signature. returnClause!. type
66
+ case . self :
67
+ return TypeSyntax ( IdentifierTypeSyntax ( name: TokenSyntax ( " Self " ) ) )
62
68
}
63
69
}
64
70
@@ -84,6 +90,8 @@ struct CxxSpan: ParamInfo {
84
90
case . return:
85
91
return CxxSpanReturnThunkBuilder ( base: base, signature: funcDecl. signature,
86
92
typeMappings: typeMappings, node: original)
93
+ case . self :
94
+ return base
87
95
}
88
96
}
89
97
}
@@ -118,6 +126,8 @@ struct CountedBy: ParamInfo {
118
126
base: base, countExpr: count,
119
127
signature: funcDecl. signature,
120
128
nonescaping: nonescaping, isSizedBy: sizedBy)
129
+ case . self :
130
+ return base
121
131
}
122
132
}
123
133
}
@@ -315,8 +325,9 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder {
315
325
} . map { ( i: Int , e: FunctionParameterSyntax ) in
316
326
e. with ( \. type, ( argTypes [ i] ?? e. type) !)
317
327
}
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
+ }
320
331
321
332
var sig = base. signature. with ( \. parameterClause. parameters, FunctionParameterListSyntax ( newParams) )
322
333
if returnType != nil {
@@ -755,9 +766,10 @@ public struct SwiftifyImportMacro: PeerMacro {
755
766
let pointerParamIndex : Int = try getIntLiteralValue ( pointerParamIndexArg. expression)
756
767
return . param( pointerParamIndex)
757
768
case " return " : return . return
769
+ case " self " : return . `self`
758
770
default :
759
771
throw DiagnosticError (
760
- " expected 'param' or 'return ', got ' \( enumName) ' " ,
772
+ " expected 'param', 'return', or 'self ', got ' \( enumName) ' " ,
761
773
node: expr)
762
774
}
763
775
}
@@ -823,7 +835,11 @@ public struct SwiftifyImportMacro: PeerMacro {
823
835
static func parseLifetimeDependence( _ enumConstructorExpr: FunctionCallExprSyntax ) throws -> ( SwiftifyExpr , LifetimeDependence ) {
824
836
let argumentList = enumConstructorExpr. arguments
825
837
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
+ }
827
843
let type = try getArgumentByName ( argumentList, " type " )
828
844
let depType : DependenceType
829
845
switch try parseEnumName ( type) {
@@ -917,8 +933,9 @@ public struct SwiftifyImportMacro: PeerMacro {
917
933
let ( expr, dependence) = try parseLifetimeDependence ( enumConstructorExpr)
918
934
lifetimeDependencies [ expr, default: [ ] ] . append ( dependence)
919
935
// 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)
922
939
}
923
940
// The escaping is controlled when a parameter is the target of a lifetimebound.
924
941
// So we want to do the transformation to Swift's Span.
@@ -987,13 +1004,16 @@ public struct SwiftifyImportMacro: PeerMacro {
987
1004
" multiple _SwiftifyInfos referring to return value: \( pointerInfo) and \( ret!) " , node: pointerInfo. original)
988
1005
}
989
1006
ret = pointerInfo
1007
+ case . self :
1008
+ throw DiagnosticError ( " do not annotate self " , node: pointerInfo. original)
990
1009
}
991
1010
}
992
1011
}
993
1012
994
1013
static func paramOrReturnIndex( _ expr: SwiftifyExpr ) -> Int {
995
1014
switch expr {
996
1015
case . param( let i) : return i
1016
+ case . `self`: return 0
997
1017
case . return: return - 1
998
1018
}
999
1019
}
@@ -1029,7 +1049,7 @@ public struct SwiftifyImportMacro: PeerMacro {
1029
1049
DeclReferenceExprSyntax ( baseName: TokenSyntax ( " borrow " ) ) ) )
1030
1050
}
1031
1051
args. append ( LabeledExprSyntax ( expression:
1032
- DeclReferenceExprSyntax ( baseName: TokenSyntax ( tryGetParamName ( funcDecl, . param ( dependence. dependsOn) ) ) !) ,
1052
+ DeclReferenceExprSyntax ( baseName: TokenSyntax ( tryGetParamName ( funcDecl, dependence. dependsOn) ) !) ,
1033
1053
trailingComma: . commaToken( ) ) )
1034
1054
}
1035
1055
args [ args. count - 1 ] = args [ args. count - 1 ] . with ( \. trailingComma, nil )
0 commit comments