@@ -204,13 +204,42 @@ func replaceBaseType(_ type: TypeSyntax, _ base: TypeSyntax) -> TypeSyntax {
204
204
return base
205
205
}
206
206
207
+ // C++ type qualifiers, `const T` and `volatile T`, are encoded as fake generic
208
+ // types, `__cxxConst<T>` and `__cxxVolatile<T>` respectively. Remove those.
209
+ func dropQualifierGenerics( _ type: TypeSyntax ) -> TypeSyntax {
210
+ guard let identifier = type. as ( IdentifierTypeSyntax . self) else { return type }
211
+ guard let generic = identifier. genericArgumentClause else { return type }
212
+ guard let genericArg = generic. arguments. first else { return type }
213
+ guard case . type( let argType) = genericArg. argument else { return type }
214
+ switch identifier. name. text {
215
+ case " __cxxConst " , " __cxxVolatile " :
216
+ return dropQualifierGenerics ( argType)
217
+ default :
218
+ return type
219
+ }
220
+ }
221
+
222
+ // The `const` type qualifier used to be encoded as a `_const` suffix on type
223
+ // names (though this causes issues for more complex types). We still drop the
224
+ // suffix here for backwards compatibility with older textual interfaces.
225
+ func dropQualifierSuffix( _ type: TypeSyntax ) -> TypeSyntax {
226
+ guard let identifier = type. as ( IdentifierTypeSyntax . self) else { return type }
227
+ let typename = identifier. name. text
228
+ if typename. hasSuffix ( " _const " ) {
229
+ return TypeSyntax ( identifier. with ( \. name, TokenSyntax . identifier (
230
+ String ( typename. dropLast ( " _const " . count) )
231
+ ) ) )
232
+ }
233
+ return type
234
+ }
235
+
207
236
// The generated type names for template instantiations sometimes contain
208
- // a `_const` suffix for diambiguation purposes. We need to remove that .
209
- func dropConstSuffix ( _ typeName : String ) -> String {
210
- if typeName . hasSuffix ( " _const " ) {
211
- return String ( typeName . dropLast ( " _const " . count ) )
237
+ // encoded qualifiers for disambiguation purposes. We need to remove those .
238
+ func dropCxxQualifiers ( _ type : TypeSyntax ) -> TypeSyntax {
239
+ if let attributed = type . as ( AttributedTypeSyntax . self ) {
240
+ return dropCxxQualifiers ( attributed . baseType )
212
241
}
213
- return typeName
242
+ return dropQualifierSuffix ( dropQualifierGenerics ( type ) )
214
243
}
215
244
216
245
func getPointerMutability( text: String ) -> Mutability ? {
@@ -405,7 +434,7 @@ struct CxxSpanThunkBuilder: ParamPointerBoundsThunkBuilder {
405
434
let genericArg = TypeSyntax ( parsedDesugaredType. as ( IdentifierTypeSyntax . self) !
406
435
. genericArgumentClause!. arguments. first!. argument) !
407
436
types [ index] = replaceBaseType ( param. type,
408
- TypeSyntax ( " Span< \( raw: dropConstSuffix ( try getTypeName ( genericArg) . text ) ) > " ) )
437
+ TypeSyntax ( " Span< \( raw: dropCxxQualifiers ( genericArg) ) )> " ) )
409
438
return try base. buildFunctionSignature ( types, returnType)
410
439
}
411
440
@@ -440,7 +469,7 @@ struct CxxSpanReturnThunkBuilder: BoundsCheckedThunkBuilder {
440
469
let genericArg = TypeSyntax ( parsedDesugaredType. as ( IdentifierTypeSyntax . self) !
441
470
. genericArgumentClause!. arguments. first!. argument) !
442
471
let newType = replaceBaseType ( signature. returnClause!. type,
443
- TypeSyntax ( " Span< \( raw: dropConstSuffix ( try getTypeName ( genericArg) . text ) ) > " ) )
472
+ TypeSyntax ( " Span< \( raw: dropCxxQualifiers ( genericArg) ) )> " ) )
444
473
return try base. buildFunctionSignature ( argTypes, newType)
445
474
}
446
475
0 commit comments