Skip to content

Commit ae09d4d

Browse files
committed
SILGen: Emit copy x on a trivial value as a trivial copy.
Avoids an assertion failure emitting an `explicit_copy_value` on the trivial value, which is unsupported. This allows `copy x` to compile, albeit with no effect (which is not ideal, but also not a regression, since no-implicit-copy controls still don't fully work on trivial values). Fixes #80573 and rdar://148712387.
1 parent c8609c7 commit ae09d4d

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

lib/SILGen/SILGenExpr.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -7179,6 +7179,14 @@ RValue RValueEmitter::visitCopyExpr(CopyExpr *E, SGFContext C) {
71797179
auto address = SGF.emitAddressOfLValue(subExpr, std::move(lv));
71807180

71817181
if (subType.isLoadable(SGF.F)) {
7182+
// Trivial types don't undergo any lifetime analysis, so simply load
7183+
// the value.
7184+
if (subType.isTrivial(SGF.F)
7185+
&& !address.getType().isMoveOnlyWrapped()) {
7186+
return RValue(SGF, {SGF.B.createLoadCopy(E, address)},
7187+
subType.getASTType());
7188+
}
7189+
71827190
// Use a formal access load borrow so this closes in the writeback scope
71837191
// above.
71847192
ManagedValue value = SGF.B.createFormalAccessLoadBorrow(E, address);

test/SILGen/copy_expr.swift

+6
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,9 @@ func testCallMethodOnAddressOnlyInOutCopy<T : P>(_ x: inout T) {
439439
_ = (copy x).computedK
440440
_ = (copy x).consumingComputedK
441441
}
442+
443+
struct Trivial: BitwiseCopyable { var x: Int }
444+
445+
func copyTrivial(x: inout Trivial) -> Trivial {
446+
return copy x
447+
}

0 commit comments

Comments
 (0)