@@ -2274,12 +2274,28 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
2274
2274
return SGF.emitEmptyTupleRValue (E, C);
2275
2275
}
2276
2276
2277
- static bool isNullableTypeInC (SILModule &M, Type ty) {
2277
+ static bool isVerbatimNullableTypeInC (SILModule &M, Type ty) {
2278
2278
ty = ty->getLValueOrInOutObjectType ()->getReferenceStorageReferent ();
2279
2279
2280
- // Functions, class instances, and @objc existentials are all nullable.
2281
- if (ty->hasReferenceSemantics ())
2280
+ // Class instances, and @objc existentials are all nullable.
2281
+ if (ty->hasReferenceSemantics ()) {
2282
+ // So are blocks, but we usually bridge them to Swift closures before we get
2283
+ // a chance to check for optional promotion, so we're already screwed if
2284
+ // an API lies about nullability.
2285
+ if (auto fnTy = ty->getAs <AnyFunctionType>()) {
2286
+ switch (fnTy->getRepresentation ()) {
2287
+ // Carried verbatim from C.
2288
+ case FunctionTypeRepresentation::Block:
2289
+ case FunctionTypeRepresentation::CFunctionPointer:
2290
+ return true ;
2291
+ // Was already bridged.
2292
+ case FunctionTypeRepresentation::Swift:
2293
+ case FunctionTypeRepresentation::Thin:
2294
+ return false ;
2295
+ }
2296
+ }
2282
2297
return true ;
2298
+ }
2283
2299
2284
2300
// Other types like UnsafePointer can also be nullable.
2285
2301
const DeclContext *DC = M.getAssociatedContext ();
@@ -2310,7 +2326,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2310
2326
// Functions that return non-optional reference type and were imported from
2311
2327
// Objective-C.
2312
2328
if (auto func = dyn_cast<FuncDecl>(decl)) {
2313
- assert ((isNullableTypeInC (M, func->getResultType ())
2329
+ assert ((isVerbatimNullableTypeInC (M, func->getResultType ())
2314
2330
|| func->getResultType ()->hasArchetype ())
2315
2331
&& " func's result type is not nullable?!" );
2316
2332
return func->hasClangNode ();
@@ -2319,7 +2335,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2319
2335
// Computed properties of non-optional reference type that were imported from
2320
2336
// Objective-C.
2321
2337
if (auto var = dyn_cast<VarDecl>(decl)) {
2322
- assert ((isNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
2338
+ assert ((isVerbatimNullableTypeInC (M, var->getType ()->getReferenceStorageReferent ())
2323
2339
|| var->getType ()->getReferenceStorageReferent ()->hasArchetype ())
2324
2340
&& " property's result type is not nullable?!" );
2325
2341
return var->hasClangNode ();
@@ -2328,7 +2344,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M,
2328
2344
// Subscripts of non-optional reference type that were imported from
2329
2345
// Objective-C.
2330
2346
if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
2331
- assert ((isNullableTypeInC (M, subscript->getElementType ())
2347
+ assert ((isVerbatimNullableTypeInC (M, subscript->getElementType ())
2332
2348
|| subscript->getElementType ()->hasArchetype ())
2333
2349
&& " subscript's result type is not nullable?!" );
2334
2350
return subscript->hasClangNode ();
@@ -2352,7 +2368,7 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
2352
2368
// get the function we're calling.
2353
2369
if (auto apply = dyn_cast<ApplyExpr>(expr)) {
2354
2370
// The result has to be a nullable type.
2355
- if (!isNullableTypeInC (M, apply->getType ()))
2371
+ if (!isVerbatimNullableTypeInC (M, apply->getType ()))
2356
2372
return false ;
2357
2373
2358
2374
auto getFuncDeclFromDynamicMemberLookup = [&](Expr *expr) -> FuncDecl * {
@@ -2405,25 +2421,25 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
2405
2421
2406
2422
// A reference to a member property.
2407
2423
if (auto member = dyn_cast<MemberRefExpr>(expr)) {
2408
- return isNullableTypeInC (M, member->getType ()) &&
2424
+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
2409
2425
mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
2410
2426
}
2411
2427
2412
2428
// A reference to a subscript.
2413
2429
if (auto subscript = dyn_cast<SubscriptExpr>(expr)) {
2414
- return isNullableTypeInC (M, subscript->getType ()) &&
2430
+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
2415
2431
mayLieAboutNonOptionalReturn (M, subscript->getDecl ().getDecl ());
2416
2432
}
2417
2433
2418
2434
// A reference to a member property found via dynamic lookup.
2419
2435
if (auto member = dyn_cast<DynamicMemberRefExpr>(expr)) {
2420
- return isNullableTypeInC (M, member->getType ()) &&
2436
+ return isVerbatimNullableTypeInC (M, member->getType ()) &&
2421
2437
mayLieAboutNonOptionalReturn (M, member->getMember ().getDecl ());
2422
2438
}
2423
2439
2424
2440
// A reference to a subscript found via dynamic lookup.
2425
2441
if (auto subscript = dyn_cast<DynamicSubscriptExpr>(expr)) {
2426
- return isNullableTypeInC (M, subscript->getType ()) &&
2442
+ return isVerbatimNullableTypeInC (M, subscript->getType ()) &&
2427
2443
mayLieAboutNonOptionalReturn (M, subscript->getMember ().getDecl ());
2428
2444
}
2429
2445
0 commit comments