From 8dac2b156617bb21dcd732ac1939cb10e3abc53d Mon Sep 17 00:00:00 2001 From: Joe Groff <jgroff@apple.com> Date: Fri, 11 Apr 2025 12:21:54 -0700 Subject: [PATCH] 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. --- lib/SILGen/SILGenExpr.cpp | 8 ++++++++ test/SILGen/copy_expr.swift | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 4341c4d024efd..b1c1ac1e1a010 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -7178,6 +7178,14 @@ RValue RValueEmitter::visitCopyExpr(CopyExpr *E, SGFContext C) { auto address = SGF.emitAddressOfLValue(subExpr, std::move(lv)); if (subType.isLoadable(SGF.F)) { + // Trivial types don't undergo any lifetime analysis, so simply load + // the value. + if (subType.isTrivial(SGF.F) + && !address.getType().isMoveOnlyWrapped()) { + return RValue(SGF, {SGF.B.createLoadCopy(E, address)}, + subType.getASTType()); + } + // Use a formal access load borrow so this closes in the writeback scope // above. ManagedValue value = SGF.B.createFormalAccessLoadBorrow(E, address); diff --git a/test/SILGen/copy_expr.swift b/test/SILGen/copy_expr.swift index 1cb51175f879e..2469df79f25c5 100644 --- a/test/SILGen/copy_expr.swift +++ b/test/SILGen/copy_expr.swift @@ -439,3 +439,9 @@ func testCallMethodOnAddressOnlyInOutCopy<T : P>(_ x: inout T) { _ = (copy x).computedK _ = (copy x).consumingComputedK } + +struct Trivial: BitwiseCopyable { var x: Int } + +func copyTrivial(x: inout Trivial) -> Trivial { + return copy x +}