|
15 | 15 | #include "DIMemoryUseCollector.h" |
16 | 16 | #include "swift/AST/DiagnosticEngine.h" |
17 | 17 | #include "swift/AST/DiagnosticsSIL.h" |
| 18 | +#include "swift/AST/DistributedDecl.h" |
18 | 19 | #include "swift/AST/Expr.h" |
19 | 20 | #include "swift/AST/Stmt.h" |
20 | 21 | #include "swift/ClangImporter/ClangModule.h" |
@@ -491,6 +492,7 @@ namespace { |
491 | 492 | void handleTypeOfSelfUse(DIMemoryUse &Use); |
492 | 493 | void handleInOutUse(const DIMemoryUse &Use); |
493 | 494 | void handleEscapeUse(const DIMemoryUse &Use); |
| 495 | + void handleFlowSensitiveActorIsolationUse(const DIMemoryUse &Use); |
494 | 496 |
|
495 | 497 | bool diagnoseReturnWithoutInitializingStoredProperties( |
496 | 498 | const SILInstruction *Inst, SILLocation loc, const DIMemoryUse &Use); |
@@ -565,6 +567,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory, |
565 | 567 | case DIUseKind::LoadForTypeOfSelf: |
566 | 568 | case DIUseKind::TypeOfSelf: |
567 | 569 | case DIUseKind::Escape: |
| 570 | + case DIUseKind::FlowSensitiveSelfIsolation: |
568 | 571 | continue; |
569 | 572 | case DIUseKind::Assign: |
570 | 573 | case DIUseKind::Set: |
@@ -1160,6 +1163,10 @@ void LifetimeChecker::doIt() { |
1160 | 1163 | case DIUseKind::BadExplicitStore: |
1161 | 1164 | diagnoseBadExplicitStore(Inst); |
1162 | 1165 | break; |
| 1166 | + |
| 1167 | + case DIUseKind::FlowSensitiveSelfIsolation: |
| 1168 | + handleFlowSensitiveActorIsolationUse(Use); |
| 1169 | + break; |
1163 | 1170 | } |
1164 | 1171 | } |
1165 | 1172 |
|
@@ -1344,6 +1351,73 @@ void LifetimeChecker::handleTypeOfSelfUse(DIMemoryUse &Use) { |
1344 | 1351 | } |
1345 | 1352 | } |
1346 | 1353 |
|
| 1354 | +void LifetimeChecker::handleFlowSensitiveActorIsolationUse( |
| 1355 | + const DIMemoryUse &Use) { |
| 1356 | + bool IsSuperInitComplete, FailedSelfUse; |
| 1357 | + |
| 1358 | + ASTContext &ctx = F.getASTContext(); |
| 1359 | + auto builtinInst = cast<BuiltinInst>(Use.Inst); |
| 1360 | + SILBuilderWithScope B(builtinInst); |
| 1361 | + SILValue replacement; |
| 1362 | + SILType optExistentialType = builtinInst->getType(); |
| 1363 | + SILLocation loc = builtinInst->getLoc(); |
| 1364 | + if (isInitializedAtUse(Use, &IsSuperInitComplete, &FailedSelfUse)) { |
| 1365 | + // 'self' is initialized, so replace this builtin with the appropriate |
| 1366 | + // operation to produce `any Actor. |
| 1367 | + |
| 1368 | + SILValue anyActorValue; |
| 1369 | + auto conformance = builtinInst->getSubstitutions().getConformances()[0]; |
| 1370 | + if (builtinInst->getBuiltinKind() == BuiltinValueKind::FlowSensitiveSelfIsolation) { |
| 1371 | + // Create a copy of the actor argument, which we intentionally did not |
| 1372 | + // copy in SILGen. |
| 1373 | + SILValue actor = B.createCopyValue(loc, builtinInst->getArguments()[0]); |
| 1374 | + |
| 1375 | + // Inject 'self' into 'any Actor'. |
| 1376 | + ProtocolConformanceRef conformances[1] = { conformance }; |
| 1377 | + SILType existentialType = optExistentialType.getOptionalObjectType(); |
| 1378 | + anyActorValue = B.createInitExistentialRef( |
| 1379 | + loc, existentialType, actor->getType().getASTType(), actor, |
| 1380 | + ctx.AllocateCopy(conformances)); |
| 1381 | + } else { |
| 1382 | + // Borrow the actor argument, which we need to form the appropriate |
| 1383 | + // call to the asLocalActor getter. |
| 1384 | + SILValue actor = B.createBeginBorrow(loc, builtinInst->getArguments()[0]); |
| 1385 | + |
| 1386 | + // Dig out the getter for asLocalActor. |
| 1387 | + auto asLocalActorDecl = getDistributedActorAsLocalActorComputedProperty( |
| 1388 | + F.getDeclContext()->getParentModule()); |
| 1389 | + auto asLocalActorGetter = asLocalActorDecl->getAccessor(AccessorKind::Get); |
| 1390 | + SILDeclRef asLocalActorRef = SILDeclRef( |
| 1391 | + asLocalActorGetter, SILDeclRef::Kind::Func); |
| 1392 | + SILFunction *asLocalActorFunc = F.getModule() |
| 1393 | + .lookUpFunction(asLocalActorRef); |
| 1394 | + SILValue asLocalActorValue = B.createFunctionRef(loc, asLocalActorFunc); |
| 1395 | + |
| 1396 | + // Call asLocalActor. It produces an 'any Actor'. |
| 1397 | + anyActorValue = B.createApply( |
| 1398 | + loc, |
| 1399 | + asLocalActorValue, |
| 1400 | + SubstitutionMap::get(asLocalActorGetter->getGenericSignature(), |
| 1401 | + { actor->getType().getASTType() }, |
| 1402 | + { conformance }), |
| 1403 | + { actor }); |
| 1404 | + B.createEndBorrow(loc, actor); |
| 1405 | + } |
| 1406 | + |
| 1407 | + // Then, wrap it in an optional. |
| 1408 | + replacement = B.createEnum( |
| 1409 | + loc, anyActorValue, ctx.getOptionalSomeDecl(), optExistentialType); |
| 1410 | + } else { |
| 1411 | + // 'self' is not initialized yet, so use 'nil'. |
| 1412 | + replacement = B.createEnum( |
| 1413 | + loc, SILValue(), ctx.getOptionalNoneDecl(), optExistentialType); |
| 1414 | + } |
| 1415 | + |
| 1416 | + // Introduce the replacement. |
| 1417 | + InstModCallbacks callbacks; |
| 1418 | + replaceAllUsesAndErase(builtinInst, replacement, callbacks); |
| 1419 | +} |
| 1420 | + |
1347 | 1421 | void LifetimeChecker::emitSelfConsumedDiagnostic(SILInstruction *Inst) { |
1348 | 1422 | if (!shouldEmitError(Inst)) |
1349 | 1423 | return; |
|
0 commit comments