Skip to content

Commit 1dd7983

Browse files
committed
[move-only] When we emit a noncopyable temporary allocation, always attach a mark_must_check [consumable_and_assignable].
Most of the time SILGen already emits these correctly without having extra copies, but in certain situations SILGen will emit copies that we need the move checker to eliminate (e.x.: when we generate a yield). An additional benefit is that this also will catch places where the frontend makes a mistake. This also removes a bunch of "copy of noncopyable" types error that showed up in the implicit compiler generated modify.
1 parent 46bb094 commit 1dd7983

File tree

3 files changed

+266
-187
lines changed

3 files changed

+266
-187
lines changed

lib/SILGen/SILGenDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,13 +1964,19 @@ InitializationPtr SILGenFunction::emitLocalVariableWithCleanup(
19641964
std::unique_ptr<TemporaryInitialization>
19651965
SILGenFunction::emitTemporary(SILLocation loc, const TypeLowering &tempTL) {
19661966
SILValue addr = emitTemporaryAllocation(loc, tempTL.getLoweredType());
1967+
if (addr->getType().isMoveOnly())
1968+
addr = B.createMarkMustCheckInst(
1969+
loc, addr, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
19671970
return useBufferAsTemporary(addr, tempTL);
19681971
}
19691972

19701973
std::unique_ptr<TemporaryInitialization>
19711974
SILGenFunction::emitFormalAccessTemporary(SILLocation loc,
19721975
const TypeLowering &tempTL) {
19731976
SILValue addr = emitTemporaryAllocation(loc, tempTL.getLoweredType());
1977+
if (addr->getType().isMoveOnly())
1978+
addr = B.createMarkMustCheckInst(
1979+
loc, addr, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
19741980
CleanupHandle cleanup =
19751981
enterDormantFormalAccessTemporaryCleanup(addr, loc, tempTL);
19761982
return std::unique_ptr<TemporaryInitialization>(

lib/SILGen/SILGenLValue.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ LogicalPathComponent::projectForRead(SILGenFunction &SGF, SILLocation loc,
366366
}
367367

368368
TemporaryInitializationPtr tempInit;
369+
ManagedValue result;
369370
RValue rvalue;
370371

371372
// If the RValue type has an openedExistential, then the RValue must be
@@ -377,9 +378,11 @@ LogicalPathComponent::projectForRead(SILGenFunction &SGF, SILLocation loc,
377378

378379
// Create a temporary, whose type may depend on the 'get'.
379380
tempInit = SGF.emitFormalAccessTemporary(loc, RValueTL);
381+
result = tempInit->getManagedAddress();
380382
} else {
381383
// Create a temporary for a static (non-dependent) RValue type.
382384
tempInit = SGF.emitFormalAccessTemporary(loc, RValueTL);
385+
result = tempInit->getManagedAddress();
383386

384387
// Emit a 'get' directly into the temporary.
385388
rvalue = std::move(*this).get(SGF, loc, base, SGFContext(tempInit.get()));
@@ -390,7 +393,8 @@ LogicalPathComponent::projectForRead(SILGenFunction &SGF, SILLocation loc,
390393
if (!rvalue.isInContext())
391394
std::move(rvalue).forwardInto(SGF, loc, tempInit.get());
392395

393-
return tempInit->getManagedAddress();
396+
assert(result);
397+
return result;
394398
}
395399

396400
ManagedValue LogicalPathComponent::project(SILGenFunction &SGF,

0 commit comments

Comments
 (0)