@@ -2251,12 +2251,28 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
22512251 return SGF.emitEmptyTupleRValue (E, C);
22522252}
22532253
2254- static bool isNullableTypeInC (SILModule &M, Type ty) {
2254+ static bool isVerbatimNullableTypeInC (SILModule &M, Type ty) {
22552255 ty = ty->getLValueOrInOutObjectType ()->getReferenceStorageReferent ();
22562256
2257- // Functions, class instances, and @objc existentials are all nullable.
2258- if (ty->hasReferenceSemantics ())
2257+ // Class instances, and @objc existentials are all nullable.
2258+ if (ty->hasReferenceSemantics ()) {
2259+ // So are blocks, but we usually bridge them to Swift closures before we get
2260+ // a chance to check for optional promotion, so we're already screwed if
2261+ // an API lies about nullability.
2262+ if (auto fnTy = ty->getAs <AnyFunctionType>()) {
2263+ switch (fnTy->getRepresentation ()) {
2264+ // Carried verbatim from C.
2265+ case FunctionTypeRepresentation::Block:
2266+ case FunctionTypeRepresentation::CFunctionPointer:
2267+ return true ;
2268+ // Was already bridged.
2269+ case FunctionTypeRepresentation::Swift:
2270+ case FunctionTypeRepresentation::Thin:
2271+ return false ;
2272+ }
2273+ }
22592274 return true ;
2275+ }
22602276
22612277 // Other types like UnsafePointer can also be nullable.
22622278 const DeclContext *DC = M.getAssociatedContext ();
@@ -2287,7 +2303,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
22872303 // Functions that return non-optional reference type and were imported from
22882304 // Objective-C.
22892305 if (auto func = dyn_cast<FuncDecl>(decl)) {
2290- assert ((isNullableTypeInC (M, func->getResultType ())
2306+ assert ((isVerbatimNullableTypeInC (M, func->getResultType ())
22912307 || func->getResultType ()->hasArchetype ())
22922308 && " func's result type is not nullable?!" );
22932309 return func->hasClangNode ();
@@ -2296,7 +2312,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
22962312 // Computed properties of non-optional reference type that were imported from
22972313 // Objective-C.
22982314 if (auto var = dyn_cast<VarDecl>(decl)) {
2299- assert ((isNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
2315+ assert ((isVerbatimNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
23002316 || var->getType ()->getReferenceStorageReferent ()->hasArchetype ())
23012317 && " property's result type is not nullable?!" );
23022318 return var->hasClangNode ();
@@ -2305,7 +2321,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
23052321 // Subscripts of non-optional reference type that were imported from
23062322 // Objective-C.
23072323 if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
2308- assert ((isNullableTypeInC (M, subscript->getElementType ())
2324+ assert ((isVerbatimNullableTypeInC (M, subscript->getElementType ())
23092325 || subscript->getElementType ()->hasArchetype ())
23102326 && " subscript's result type is not nullable?!" );
23112327 return subscript->hasClangNode ();
@@ -2329,7 +2345,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
23292345 // get the function we're calling.
23302346 if (auto apply = dyn_cast<ApplyExpr>(expr)) {
23312347 // The result has to be a nullable type.
2332- if (!isNullableTypeInC (M, apply->getType ()))
2348+ if (!isVerbatimNullableTypeInC (M, apply->getType ()))
23332349 return false ;
23342350
23352351 auto getFuncDeclFromDynamicMemberLookup = [&](Expr *expr) -> FuncDecl * {
@@ -2382,25 +2398,25 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
23822398
23832399 // A reference to a member property.
23842400 if (auto member = dyn_cast<MemberRefExpr>(expr)) {
2385- return isNullableTypeInC (M, member->getType ()) &&
2401+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
23862402 mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
23872403 }
23882404
23892405 // A reference to a subscript.
23902406 if (auto subscript = dyn_cast<SubscriptExpr>(expr)) {
2391- return isNullableTypeInC (M, subscript->getType ()) &&
2407+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
23922408 mayLieAboutNonOptionalReturn (M, subscript->getDecl ().getDecl ());
23932409 }
23942410
23952411 // A reference to a member property found via dynamic lookup.
23962412 if (auto member = dyn_cast<DynamicMemberRefExpr>(expr)) {
2397- return isNullableTypeInC (M, member->getType ()) &&
2413+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
23982414 mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
23992415 }
24002416
24012417 // A reference to a subscript found via dynamic lookup.
24022418 if (auto subscript = dyn_cast<DynamicSubscriptExpr>(expr)) {
2403- return isNullableTypeInC (M, subscript->getType ()) &&
2419+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
24042420 mayLieAboutNonOptionalReturn (M, subscript->getMember ().getDecl ());
24052421 }
24062422
0 commit comments