@@ -2251,12 +2251,28 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
2251
2251
return SGF.emitEmptyTupleRValue (E, C);
2252
2252
}
2253
2253
2254
- static bool isNullableTypeInC (SILModule &M, Type ty) {
2254
+ static bool isVerbatimNullableTypeInC (SILModule &M, Type ty) {
2255
2255
ty = ty->getLValueOrInOutObjectType ()->getReferenceStorageReferent ();
2256
2256
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
+ }
2259
2274
return true ;
2275
+ }
2260
2276
2261
2277
// Other types like UnsafePointer can also be nullable.
2262
2278
const DeclContext *DC = M.getAssociatedContext ();
@@ -2287,7 +2303,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2287
2303
// Functions that return non-optional reference type and were imported from
2288
2304
// Objective-C.
2289
2305
if (auto func = dyn_cast<FuncDecl>(decl)) {
2290
- assert ((isNullableTypeInC (M, func->getResultType ())
2306
+ assert ((isVerbatimNullableTypeInC (M, func->getResultType ())
2291
2307
|| func->getResultType ()->hasArchetype ())
2292
2308
&& " func's result type is not nullable?!" );
2293
2309
return func->hasClangNode ();
@@ -2296,7 +2312,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2296
2312
// Computed properties of non-optional reference type that were imported from
2297
2313
// Objective-C.
2298
2314
if (auto var = dyn_cast<VarDecl>(decl)) {
2299
- assert ((isNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
2315
+ assert ((isVerbatimNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
2300
2316
|| var->getType ()->getReferenceStorageReferent ()->hasArchetype ())
2301
2317
&& " property's result type is not nullable?!" );
2302
2318
return var->hasClangNode ();
@@ -2305,7 +2321,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2305
2321
// Subscripts of non-optional reference type that were imported from
2306
2322
// Objective-C.
2307
2323
if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
2308
- assert ((isNullableTypeInC (M, subscript->getElementType ())
2324
+ assert ((isVerbatimNullableTypeInC (M, subscript->getElementType ())
2309
2325
|| subscript->getElementType ()->hasArchetype ())
2310
2326
&& " subscript's result type is not nullable?!" );
2311
2327
return subscript->hasClangNode ();
@@ -2329,7 +2345,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
2329
2345
// get the function we're calling.
2330
2346
if (auto apply = dyn_cast<ApplyExpr>(expr)) {
2331
2347
// The result has to be a nullable type.
2332
- if (!isNullableTypeInC (M, apply->getType ()))
2348
+ if (!isVerbatimNullableTypeInC (M, apply->getType ()))
2333
2349
return false ;
2334
2350
2335
2351
auto getFuncDeclFromDynamicMemberLookup = [&](Expr *expr) -> FuncDecl * {
@@ -2382,25 +2398,25 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
2382
2398
2383
2399
// A reference to a member property.
2384
2400
if (auto member = dyn_cast<MemberRefExpr>(expr)) {
2385
- return isNullableTypeInC (M, member->getType ()) &&
2401
+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
2386
2402
mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
2387
2403
}
2388
2404
2389
2405
// A reference to a subscript.
2390
2406
if (auto subscript = dyn_cast<SubscriptExpr>(expr)) {
2391
- return isNullableTypeInC (M, subscript->getType ()) &&
2407
+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
2392
2408
mayLieAboutNonOptionalReturn (M, subscript->getDecl ().getDecl ());
2393
2409
}
2394
2410
2395
2411
// A reference to a member property found via dynamic lookup.
2396
2412
if (auto member = dyn_cast<DynamicMemberRefExpr>(expr)) {
2397
- return isNullableTypeInC (M, member->getType ()) &&
2413
+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
2398
2414
mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
2399
2415
}
2400
2416
2401
2417
// A reference to a subscript found via dynamic lookup.
2402
2418
if (auto subscript = dyn_cast<DynamicSubscriptExpr>(expr)) {
2403
- return isNullableTypeInC (M, subscript->getType ()) &&
2419
+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
2404
2420
mayLieAboutNonOptionalReturn (M, subscript->getMember ().getDecl ());
2405
2421
}
2406
2422
0 commit comments