@@ -1155,7 +1155,8 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
1155
1155
ImportHint hint,
1156
1156
bool allowNSUIntegerAsInt,
1157
1157
bool canFullyBridgeTypes,
1158
- OptionalTypeKind optKind) {
1158
+ OptionalTypeKind optKind,
1159
+ bool resugarNSErrorPointer) {
1159
1160
if (importKind == ImportTypeKind::Abstract) {
1160
1161
return importedType;
1161
1162
}
@@ -1223,10 +1224,16 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
1223
1224
!= elementClass->getModuleContext ()->getName ())
1224
1225
return Type ();
1225
1226
1226
- return impl.getNamedSwiftType (
1227
- foundationModule,
1228
- impl.SwiftContext .getSwiftName (
1229
- KnownFoundationEntity::NSErrorPointer));
1227
+
1228
+ if (resugarNSErrorPointer)
1229
+ return impl.getNamedSwiftType (
1230
+ foundationModule,
1231
+ impl.SwiftContext .getSwiftName (
1232
+ KnownFoundationEntity::NSErrorPointer));
1233
+
1234
+ // The imported type is AUMP<NSError?>, but the typealias is AUMP<NSError?>?
1235
+ // so we have to manually make them match.
1236
+ return OptionalType::get (importedType);
1230
1237
};
1231
1238
if (Type result = maybeImportNSErrorPointer ())
1232
1239
return result;
@@ -1390,7 +1397,8 @@ Type ClangImporter::Implementation::importType(clang::QualType type,
1390
1397
ImportTypeKind importKind,
1391
1398
bool allowNSUIntegerAsInt,
1392
1399
bool canFullyBridgeTypes,
1393
- OptionalTypeKind optionality) {
1400
+ OptionalTypeKind optionality,
1401
+ bool resugarNSErrorPointer) {
1394
1402
if (type.isNull ())
1395
1403
return Type ();
1396
1404
@@ -1437,7 +1445,8 @@ Type ClangImporter::Implementation::importType(clang::QualType type,
1437
1445
importKind, importResult.Hint ,
1438
1446
allowNSUIntegerAsInt,
1439
1447
canFullyBridgeTypes,
1440
- optionality);
1448
+ optionality,
1449
+ resugarNSErrorPointer);
1441
1450
}
1442
1451
1443
1452
bool ClangImporter::Implementation::shouldImportGlobalAsLet (
@@ -1981,8 +1990,9 @@ Type ClangImporter::Implementation::importMethodType(
1981
1990
for (size_t paramIndex = 0 ; paramIndex != params.size (); paramIndex++) {
1982
1991
auto param = params[paramIndex];
1983
1992
auto paramTy = param->getType ();
1993
+ auto paramIsError = errorInfo && paramIndex == errorInfo->ErrorParameterIndex ;
1984
1994
if (paramTy->isVoidType ()) {
1985
- assert (!errorInfo || paramIndex != errorInfo-> ErrorParameterIndex );
1995
+ assert (!paramIsError );
1986
1996
++nameIndex;
1987
1997
continue ;
1988
1998
}
@@ -2023,18 +2033,27 @@ Type ClangImporter::Implementation::importMethodType(
2023
2033
importKind = ImportTypeKind::CFRetainedOutParameter;
2024
2034
else if (param->hasAttr <clang::CFReturnsNotRetainedAttr>())
2025
2035
importKind = ImportTypeKind::CFUnretainedOutParameter;
2026
-
2036
+
2037
+ // If this is the throws error parameter, we don't need to convert any
2038
+ // NSError** arguments to the sugared NSErrorPointer typealias form,
2039
+ // because all that is done with it is retrieving the canonical
2040
+ // type. Avoiding the sugar breaks a loop in Foundation caused by method
2041
+ // on NSString that has an error parameter. FIXME: This is a work-around
2042
+ // for the specific case when the throws conversion works, but is not
2043
+ // sufficient if it fails. (The correct, overarching fix is ClangImporter
2044
+ // being lazier.)
2027
2045
swiftParamTy = importType (paramTy, importKind,
2028
2046
allowNSUIntegerAsIntInParam,
2029
2047
/* isFullyBridgeable*/ true ,
2030
- optionalityOfParam);
2048
+ optionalityOfParam,
2049
+ /* resugarNSErrorPointer=*/ !paramIsError);
2031
2050
}
2032
2051
if (!swiftParamTy)
2033
2052
return Type ();
2034
2053
2035
2054
// If this is the error parameter, remember it, but don't build it
2036
2055
// into the parameter type.
2037
- if (errorInfo && paramIndex == errorInfo-> ErrorParameterIndex ) {
2056
+ if (paramIsError ) {
2038
2057
errorParamType = swiftParamTy->getCanonicalType ();
2039
2058
2040
2059
// ...unless we're supposed to replace it with ().
0 commit comments