mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #10832 from rjmccall/fix-function-component-bridging-import
Bridge types during import only if we are in a fully-bridgeable context.
This commit is contained in:
@@ -2303,7 +2303,7 @@ namespace {
|
||||
SwiftType = Impl.importType(ClangType,
|
||||
ImportTypeKind::Typedef,
|
||||
isInSystemModule(DC),
|
||||
ClangType->isBlockPointerType(),
|
||||
getTypedefBridgeability(ClangType),
|
||||
OTK_Optional);
|
||||
}
|
||||
|
||||
@@ -2410,7 +2410,7 @@ namespace {
|
||||
auto underlyingType = Impl.importType(decl->getIntegerType(),
|
||||
ImportTypeKind::Enum,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!underlyingType)
|
||||
return nullptr;
|
||||
|
||||
@@ -2447,7 +2447,7 @@ namespace {
|
||||
// Compute the underlying type.
|
||||
auto underlyingType = Impl.importType(
|
||||
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/ false);
|
||||
Bridgeability::None);
|
||||
if (!underlyingType)
|
||||
return nullptr;
|
||||
|
||||
@@ -3063,7 +3063,7 @@ namespace {
|
||||
auto type = Impl.importType(clangContext.getTagDeclType(clangEnum),
|
||||
ImportTypeKind::Value,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!type)
|
||||
return nullptr;
|
||||
// FIXME: Importing the type will recursively revisit this same
|
||||
@@ -3101,7 +3101,7 @@ namespace {
|
||||
Impl.getClangASTContext().getTagDeclType(clangEnum),
|
||||
ImportTypeKind::Value,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!enumType)
|
||||
return nullptr;
|
||||
|
||||
@@ -3162,7 +3162,7 @@ namespace {
|
||||
auto type = Impl.importType(decl->getType(),
|
||||
ImportTypeKind::Variable,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!type)
|
||||
return nullptr;
|
||||
|
||||
@@ -3385,7 +3385,7 @@ namespace {
|
||||
auto type = Impl.importType(decl->getType(),
|
||||
ImportTypeKind::RecordField,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!type)
|
||||
return nullptr;
|
||||
|
||||
@@ -3454,7 +3454,7 @@ namespace {
|
||||
(isAudited ? ImportTypeKind::AuditedVariable
|
||||
: ImportTypeKind::Variable),
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
|
||||
if (!type)
|
||||
return nullptr;
|
||||
@@ -4332,7 +4332,7 @@ namespace {
|
||||
superclassType = Impl.importType(clangSuperclassType,
|
||||
ImportTypeKind::Abstract,
|
||||
isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (superclassType) {
|
||||
assert(superclassType->is<ClassType>() ||
|
||||
superclassType->is<BoundGenericClassType>());
|
||||
@@ -4938,7 +4938,7 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl,
|
||||
// Import the type of the underlying storage
|
||||
auto storedUnderlyingType = Impl.importType(
|
||||
decl->getUnderlyingType(), ImportTypeKind::Value, isInSystemModule(dc),
|
||||
decl->getUnderlyingType()->isBlockPointerType(), OTK_None);
|
||||
Bridgeability::None, OTK_None);
|
||||
|
||||
if (auto objTy = storedUnderlyingType->getAnyOptionalObjectType())
|
||||
storedUnderlyingType = objTy;
|
||||
@@ -4956,7 +4956,7 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl,
|
||||
// Find a bridged type, which may be different
|
||||
auto computedPropertyUnderlyingType = Impl.importType(
|
||||
decl->getUnderlyingType(), ImportTypeKind::Property, isInSystemModule(dc),
|
||||
decl->getUnderlyingType()->isBlockPointerType(), OTK_None);
|
||||
Bridgeability::Full, OTK_None);
|
||||
if (auto objTy = computedPropertyUnderlyingType->getAnyOptionalObjectType())
|
||||
computedPropertyUnderlyingType = objTy;
|
||||
|
||||
@@ -5173,7 +5173,7 @@ SwiftDeclConverter::importAsOptionSetType(DeclContext *dc, Identifier name,
|
||||
// Compute the underlying type.
|
||||
auto underlyingType = Impl.importType(
|
||||
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
||||
/*isFullyBridgeable*/ false);
|
||||
Bridgeability::None);
|
||||
if (!underlyingType)
|
||||
return nullptr;
|
||||
|
||||
@@ -5492,7 +5492,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
|
||||
Type swiftPropertyType = Impl.importType(
|
||||
propertyType, ImportTypeKind::Property,
|
||||
Impl.shouldAllowNSUIntegerAsInt(isFromSystemModule, getter),
|
||||
/*isFullyBridgeable*/ true, OTK_ImplicitlyUnwrappedOptional);
|
||||
Bridgeability::Full, OTK_ImplicitlyUnwrappedOptional);
|
||||
if (!swiftPropertyType)
|
||||
return nullptr;
|
||||
|
||||
@@ -6406,7 +6406,8 @@ Optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(
|
||||
clangBound->stripObjCKindOfTypeAndQuals(Impl.getClangASTContext());
|
||||
Type superclassType =
|
||||
Impl.importType(clang::QualType(unqualifiedClangBound, 0),
|
||||
ImportTypeKind::Abstract, false, false);
|
||||
ImportTypeKind::Abstract, false,
|
||||
Bridgeability::None);
|
||||
if (!superclassType) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
|
||||
auto clangTy = parsed->getType();
|
||||
auto literalType = Impl.importType(clangTy, ImportTypeKind::Value,
|
||||
isInSystemModule(DC),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!literalType)
|
||||
return nullptr;
|
||||
|
||||
@@ -123,7 +123,7 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
|
||||
} else {
|
||||
constantType = Impl.importType(castType, ImportTypeKind::Value,
|
||||
isInSystemModule(DC),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!constantType)
|
||||
return nullptr;
|
||||
}
|
||||
@@ -300,7 +300,7 @@ static Optional<std::pair<llvm::APSInt, Type>>
|
||||
auto type = impl.importType(literal->getType(),
|
||||
ImportTypeKind::Value,
|
||||
isInSystemModule(DC),
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
return {{ value, type }};
|
||||
}
|
||||
|
||||
|
||||
@@ -176,14 +176,14 @@ namespace {
|
||||
{
|
||||
ClangImporter::Implementation &Impl;
|
||||
bool AllowNSUIntegerAsInt;
|
||||
bool CanFullyBridgeTypes;
|
||||
Bridgeability Bridging;
|
||||
|
||||
public:
|
||||
SwiftTypeConverter(ClangImporter::Implementation &impl,
|
||||
bool allowNSUIntegerAsInt,
|
||||
bool canFullyBridgeTypes)
|
||||
Bridgeability bridging)
|
||||
: Impl(impl), AllowNSUIntegerAsInt(allowNSUIntegerAsInt),
|
||||
CanFullyBridgeTypes(canFullyBridgeTypes) {}
|
||||
Bridging(bridging) {}
|
||||
|
||||
using TypeVisitor::Visit;
|
||||
ImportResult Visit(clang::QualType type) {
|
||||
@@ -356,7 +356,7 @@ namespace {
|
||||
pointeeType = Impl.importType(pointeeQualType,
|
||||
ImportTypeKind::Pointee,
|
||||
AllowNSUIntegerAsInt,
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
|
||||
// If the pointed-to type is unrepresentable in Swift, import as
|
||||
// OpaquePointer.
|
||||
@@ -404,7 +404,7 @@ namespace {
|
||||
Type pointeeType = Impl.importType(type->getPointeeType(),
|
||||
ImportTypeKind::Abstract,
|
||||
AllowNSUIntegerAsInt,
|
||||
CanFullyBridgeTypes);
|
||||
Bridging);
|
||||
if (!pointeeType)
|
||||
return Type();
|
||||
FunctionType *fTy = pointeeType->castTo<FunctionType>();
|
||||
@@ -443,7 +443,7 @@ namespace {
|
||||
Type elementType = Impl.importType(type->getElementType(),
|
||||
ImportTypeKind::Pointee,
|
||||
AllowNSUIntegerAsInt,
|
||||
/*isFullyBridgeable*/false);
|
||||
Bridgeability::None);
|
||||
if (!elementType)
|
||||
return Type();
|
||||
|
||||
@@ -498,7 +498,7 @@ namespace {
|
||||
auto resultTy = Impl.importType(type->getReturnType(),
|
||||
ImportTypeKind::Result,
|
||||
AllowNSUIntegerAsInt,
|
||||
CanFullyBridgeTypes,
|
||||
Bridging,
|
||||
OTK_Optional);
|
||||
if (!resultTy)
|
||||
return Type();
|
||||
@@ -509,7 +509,7 @@ namespace {
|
||||
param != paramEnd; ++param) {
|
||||
auto swiftParamTy = Impl.importType(*param, ImportTypeKind::Parameter,
|
||||
AllowNSUIntegerAsInt,
|
||||
CanFullyBridgeTypes,
|
||||
Bridging,
|
||||
OTK_Optional);
|
||||
if (!swiftParamTy)
|
||||
return Type();
|
||||
@@ -534,7 +534,7 @@ namespace {
|
||||
auto resultTy = Impl.importType(type->getReturnType(),
|
||||
ImportTypeKind::Result,
|
||||
AllowNSUIntegerAsInt,
|
||||
CanFullyBridgeTypes,
|
||||
Bridging,
|
||||
OTK_Optional);
|
||||
if (!resultTy)
|
||||
return Type();
|
||||
@@ -665,12 +665,32 @@ namespace {
|
||||
}
|
||||
// Any other interesting mapped types should be hinted here.
|
||||
|
||||
// Otherwise, recurse on the underlying type in order to compute
|
||||
// the hint correctly.
|
||||
// Otherwise, recurse on the underlying type. We need to recompute
|
||||
// the hint, and if the typedef uses different bridgeability than the
|
||||
// context then we may also need to bypass the typedef.
|
||||
} else {
|
||||
auto underlyingType = type->desugar();
|
||||
|
||||
// Figure out the bridgeability we would normally use for this typedef.
|
||||
auto typedefBridgeability = getTypedefBridgeability(underlyingType);
|
||||
|
||||
// Figure out the typedef we should actually use.
|
||||
auto underlyingBridgeability =
|
||||
(Bridging == Bridgeability::Full
|
||||
? typedefBridgeability : Bridgeability::None);
|
||||
SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt,
|
||||
/*can fully bridge*/false);
|
||||
auto underlyingResult = innerConverter.Visit(type->desugar());
|
||||
underlyingBridgeability);
|
||||
auto underlyingResult = innerConverter.Visit(underlyingType);
|
||||
|
||||
// If we used different bridgeability than this typedef normally
|
||||
// would because we're in a non-bridgeable context, and therefore
|
||||
// the underlying type is different from the mapping of the typedef,
|
||||
// use the underlying type.
|
||||
if (underlyingBridgeability != typedefBridgeability &&
|
||||
!underlyingResult.AbstractType->isEqual(mappedType)) {
|
||||
return underlyingResult;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
switch (underlyingResult.Hint) {
|
||||
case ImportHint::Block:
|
||||
@@ -960,7 +980,7 @@ namespace {
|
||||
Type importedTypeArg = Impl.importType(typeArg,
|
||||
ImportTypeKind::BridgedValue,
|
||||
AllowNSUIntegerAsInt,
|
||||
CanFullyBridgeTypes,
|
||||
Bridging,
|
||||
OTK_None);
|
||||
if (!importedTypeArg) {
|
||||
importedTypeArgs.clear();
|
||||
@@ -1146,7 +1166,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
ImportTypeKind importKind,
|
||||
ImportHint hint,
|
||||
bool allowNSUIntegerAsInt,
|
||||
bool canFullyBridgeTypes,
|
||||
Bridgeability bridging,
|
||||
OptionalTypeKind optKind,
|
||||
bool resugarNSErrorPointer) {
|
||||
if (importKind == ImportTypeKind::Abstract) {
|
||||
@@ -1261,10 +1281,14 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
importedType = outParamTy;
|
||||
}
|
||||
|
||||
// Turn block pointer types back into normal function types in any
|
||||
// context where bridging is possible, unless the block has a typedef.
|
||||
// SwiftTypeConverter turns block pointers into @convention(block) types.
|
||||
// In a bridgeable context, or in the direct structure of a typedef,
|
||||
// we would prefer to instead use the default Swift convention. But this
|
||||
// does means that, when we're using a typedef of a block pointer type in
|
||||
// an unbridgable context, we need to go back and do a fully-unbridged
|
||||
// import of the underlying type.
|
||||
if (hint == ImportHint::Block) {
|
||||
if (!canFullyBridgeTypes) {
|
||||
if (bridging == Bridgeability::None) {
|
||||
if (auto typedefType = clangType->getAs<clang::TypedefType>()) {
|
||||
// In non-bridged contexts, drop the typealias sugar for blocks.
|
||||
// FIXME: This will do the wrong thing if there's any adjustment to do
|
||||
@@ -1272,7 +1296,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
Type underlyingTy = impl.importType(typedefType->desugar(),
|
||||
importKind,
|
||||
allowNSUIntegerAsInt,
|
||||
canFullyBridgeTypes,
|
||||
bridging,
|
||||
OTK_None);
|
||||
if (Type unwrappedTy = underlyingTy->getAnyOptionalObjectType())
|
||||
underlyingTy = unwrappedTy;
|
||||
@@ -1281,7 +1305,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
}
|
||||
}
|
||||
|
||||
if (canBridgeTypes(importKind) || importKind == ImportTypeKind::Typedef) {
|
||||
if (bridging == Bridgeability::Full) {
|
||||
auto fTy = importedType->castTo<FunctionType>();
|
||||
FunctionType::ExtInfo einfo = fTy->getExtInfo();
|
||||
if (einfo.getRepresentation() != FunctionTypeRepresentation::Swift) {
|
||||
@@ -1294,7 +1318,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
// Turn BOOL and DarwinBoolean into Bool in contexts that can bridge types
|
||||
// losslessly.
|
||||
if ((hint == ImportHint::BOOL || hint == ImportHint::Boolean) &&
|
||||
canFullyBridgeTypes && canBridgeTypes(importKind)) {
|
||||
bridging == Bridgeability::Full && canBridgeTypes(importKind)) {
|
||||
return impl.SwiftContext.getBoolDecl()->getDeclaredType();
|
||||
}
|
||||
|
||||
@@ -1323,7 +1347,9 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
|
||||
// If we have a bridged Objective-C type and we are allowed to
|
||||
// bridge, do so.
|
||||
if (hint == ImportHint::ObjCBridged && canBridgeTypes(importKind) &&
|
||||
if (hint == ImportHint::ObjCBridged &&
|
||||
bridging == Bridgeability::Full &&
|
||||
canBridgeTypes(importKind) &&
|
||||
importKind != ImportTypeKind::PropertyWithReferenceSemantics) {
|
||||
// id and Any can be bridged without Foundation. There would be
|
||||
// bootstrapping issues with the ObjectiveC module otherwise.
|
||||
@@ -1373,7 +1399,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
||||
Type ClangImporter::Implementation::importType(clang::QualType type,
|
||||
ImportTypeKind importKind,
|
||||
bool allowNSUIntegerAsInt,
|
||||
bool canFullyBridgeTypes,
|
||||
Bridgeability bridging,
|
||||
OptionalTypeKind optionality,
|
||||
bool resugarNSErrorPointer) {
|
||||
if (type.isNull())
|
||||
@@ -1414,14 +1440,13 @@ Type ClangImporter::Implementation::importType(clang::QualType type,
|
||||
}
|
||||
|
||||
// Perform abstract conversion, ignoring how the type is actually used.
|
||||
SwiftTypeConverter converter(*this, allowNSUIntegerAsInt,canFullyBridgeTypes);
|
||||
SwiftTypeConverter converter(*this, allowNSUIntegerAsInt, bridging);
|
||||
auto importResult = converter.Visit(type);
|
||||
|
||||
// Now fix up the type based on we're concretely using it.
|
||||
return adjustTypeForConcreteImport(*this, type, importResult.AbstractType,
|
||||
importKind, importResult.Hint,
|
||||
allowNSUIntegerAsInt,
|
||||
canFullyBridgeTypes,
|
||||
allowNSUIntegerAsInt, bridging,
|
||||
optionality,
|
||||
resugarNSErrorPointer);
|
||||
}
|
||||
@@ -1493,7 +1518,7 @@ Type ClangImporter::Implementation::importPropertyType(
|
||||
OptionalTypeKind optionality = OTK_ImplicitlyUnwrappedOptional;
|
||||
return importType(decl->getType(), importKind,
|
||||
shouldAllowNSUIntegerAsInt(isFromSystemModule, decl),
|
||||
/*isFullyBridgeable*/ true, optionality);
|
||||
Bridgeability::Full, optionality);
|
||||
}
|
||||
|
||||
/// Apply the @noescape attribute
|
||||
@@ -1566,7 +1591,7 @@ Type ClangImporter::Implementation::importFunctionReturnType(
|
||||
(isAuditedResult ? ImportTypeKind::AuditedResult
|
||||
: ImportTypeKind::Result),
|
||||
allowNSUIntegerAsInt,
|
||||
/*isFullyBridgeable*/ true, OptionalityOfReturn);
|
||||
Bridgeability::Full, OptionalityOfReturn);
|
||||
}
|
||||
|
||||
Type ClangImporter::Implementation::
|
||||
@@ -1628,7 +1653,7 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
|
||||
// Import the parameter type into Swift.
|
||||
Type swiftParamTy =
|
||||
importType(paramTy, importKind, allowNSUIntegerAsInt,
|
||||
/*isFullyBridgeable*/ true, OptionalityOfParam);
|
||||
Bridgeability::Full, OptionalityOfParam);
|
||||
if (!swiftParamTy)
|
||||
return nullptr;
|
||||
|
||||
@@ -1919,7 +1944,7 @@ Type ClangImporter::Implementation::importMethodType(
|
||||
clang::QualType resultType = clangDecl->getReturnType();
|
||||
swiftResultTy = importType(resultType, resultKind,
|
||||
allowNSUIntegerAsIntInResult,
|
||||
/*isFullyBridgeable*/true,
|
||||
Bridgeability::Full,
|
||||
OptionalityOfReturn);
|
||||
// Adjust the result type for a throwing function.
|
||||
if (swiftResultTy && errorInfo) {
|
||||
@@ -1927,7 +1952,7 @@ Type ClangImporter::Implementation::importMethodType(
|
||||
// Get the original unbridged result type.
|
||||
origSwiftResultTy = importType(resultType, resultKind,
|
||||
allowNSUIntegerAsIntInResult,
|
||||
/*isFullyBridgeable*/false,
|
||||
Bridgeability::None,
|
||||
OptionalityOfReturn)
|
||||
->getCanonicalType();
|
||||
|
||||
@@ -2042,7 +2067,7 @@ Type ClangImporter::Implementation::importMethodType(
|
||||
// being lazier.)
|
||||
swiftParamTy = importType(paramTy, importKind,
|
||||
allowNSUIntegerAsIntInParam,
|
||||
/*isFullyBridgeable*/true,
|
||||
Bridgeability::Full,
|
||||
optionalityOfParam,
|
||||
/*resugarNSErrorPointer=*/!paramIsError);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,22 @@ enum class ImportTypeKind {
|
||||
Enum
|
||||
};
|
||||
|
||||
enum class Bridgeability {
|
||||
/// This context does not permit bridging at all. For example, the
|
||||
/// target of a C pointer.
|
||||
None,
|
||||
|
||||
/// This context permits all kinds of bridging. For example, the
|
||||
/// imported result of a method declaration.
|
||||
Full
|
||||
};
|
||||
|
||||
static inline Bridgeability getTypedefBridgeability(clang::QualType type) {
|
||||
return (type->isBlockPointerType() || type->isFunctionType())
|
||||
? Bridgeability::Full
|
||||
: Bridgeability::None;
|
||||
}
|
||||
|
||||
/// \brief Describes the kind of the C type that can be mapped to a stdlib
|
||||
/// swift type.
|
||||
enum class MappedCTypeKind {
|
||||
@@ -893,16 +909,17 @@ public:
|
||||
/// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
|
||||
/// in certain contexts. If false, it will always be imported as UInt.
|
||||
///
|
||||
/// \param canFullyBridgeTypes True if we can bridge types losslessly.
|
||||
/// This is an additional guarantee on top of the ImportTypeKind
|
||||
/// cases that allow bridging, and applies to the entire type.
|
||||
/// \param bridgeability Whether we can bridge types in this context.
|
||||
/// This may restrict the ability to bridge types even in contexts
|
||||
/// that otherwise allow bridging, such as function results and
|
||||
/// parameters.
|
||||
///
|
||||
/// \returns The imported type, or null if this type could
|
||||
/// not be represented in Swift.
|
||||
Type importType(clang::QualType type,
|
||||
ImportTypeKind kind,
|
||||
bool allowNSUIntegerAsInt,
|
||||
bool canFullyBridgeTypes,
|
||||
Bridgeability bridgeability,
|
||||
OptionalTypeKind optional = OTK_ImplicitlyUnwrappedOptional,
|
||||
bool resugarNSErrorPointer = true);
|
||||
|
||||
|
||||
@@ -24,3 +24,10 @@ idLover.takesArray(ofId: &y) // expected-error{{argument type 'Any' does not con
|
||||
|
||||
idLover.takesId(x)
|
||||
idLover.takesId(y)
|
||||
|
||||
install_global_event_handler(idLover) // expected-error {{cannot convert value of type 'NSIdLover' to expected argument type 'event_handler?' (aka 'Optional<@convention(c) (AnyObject) -> ()>')}}
|
||||
|
||||
// FIXME: this should not type-check!
|
||||
// Function conversions are not legal when converting to a thin function type.
|
||||
let handler: @convention(c) (Any) -> () = { object in () }
|
||||
install_global_event_handler(handler)
|
||||
|
||||
@@ -40,9 +40,13 @@ ObjCBoolBlock testObjCBoolFnToBlockTypedef(ObjCBoolFn);
|
||||
DarwinBooleanBlock testDarwinBooleanFnToBlockTypedef(DarwinBooleanFn);
|
||||
|
||||
typedef __typeof(testCBoolFnToBlockTypedef) CBoolFnToBlockType;
|
||||
typedef __typeof(testObjCBoolFnToBlockTypedef) ObjCCBoolFnToBlockType;
|
||||
typedef __typeof(testObjCBoolFnToBlockTypedef) ObjCBoolFnToBlockType;
|
||||
typedef __typeof(testDarwinBooleanFnToBlockTypedef) DarwinBooleanFnToBlockType;
|
||||
|
||||
extern ObjCBoolFnToBlockType *globalObjCBoolFnToBlockFP;
|
||||
extern ObjCBoolFnToBlockType * __nonnull * __nullable globalObjCBoolFnToBlockFPP;
|
||||
extern ObjCBoolFnToBlockType ^globalObjCBoolFnToBlockBP;
|
||||
|
||||
extern CBoolFn globalCBoolFn;
|
||||
extern ObjCBoolFn globalObjCBoolFn;
|
||||
extern DarwinBooleanFn globalDarwinBooleanFn;
|
||||
|
||||
@@ -43,8 +43,12 @@ func testObjCBoolFnToBlockTypedef(_: @escaping ObjCBoolFn) -> ObjCBoolBlock
|
||||
func testDarwinBooleanFnToBlockTypedef(_: @escaping DarwinBooleanFn) -> DarwinBooleanBlock
|
||||
|
||||
typealias CBoolFnToBlockType = (CBoolFn) -> CBoolBlock
|
||||
typealias ObjCCBoolFnToBlockType = (ObjCBoolFn) -> (ObjCBool) -> ObjCBool
|
||||
typealias DarwinBooleanFnToBlockType = (DarwinBooleanFn) -> (DarwinBoolean) -> DarwinBoolean
|
||||
typealias ObjCBoolFnToBlockType = (ObjCBoolFn) -> ObjCBoolBlock
|
||||
typealias DarwinBooleanFnToBlockType = (DarwinBooleanFn) -> DarwinBooleanBlock
|
||||
|
||||
var globalObjCBoolFnToBlockFP: @convention(c) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool
|
||||
var globalObjCBoolFnToBlockFPP: UnsafeMutablePointer<@convention(c) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool>?
|
||||
var globalObjCBoolFnToBlockBP: @convention(block) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool
|
||||
|
||||
var globalCBoolFn: CBoolFn
|
||||
var globalObjCBoolFn: ObjCBoolFn
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
// CHECK-FOUNDATION: func doSomethingElse(with: NSCopying & NSObjectProtocol)
|
||||
|
||||
// Note: Function type -> "Function".
|
||||
// CHECK-FOUNDATION: func sort(_: @escaping @convention(c) (Any, Any) -> Int)
|
||||
// CHECK-FOUNDATION: func sort(_: @escaping @convention(c) (AnyObject, AnyObject) -> Int)
|
||||
|
||||
// Note: Plural: NSArray without type arguments -> "Objects".
|
||||
// CHECK-FOUNDATION: func remove(_: [Any])
|
||||
|
||||
@@ -1110,3 +1110,6 @@ typedef enum __attribute__((ns_error_domain(NSLaundryErrorDomain))) __attribute_
|
||||
NSLaundryErrorTooMuchSoap = 1,
|
||||
NSLaundryErrorCatInWasher = 2
|
||||
};
|
||||
|
||||
typedef void (*event_handler)(__nonnull id);
|
||||
void install_global_event_handler(__nullable event_handler handler);
|
||||
|
||||
Reference in New Issue
Block a user