Skip to content

Commit 409a7d5

Browse files
committed
[silgen] Change argument emission to emit @_noImplicitCopy arguments in such a form that move checking works on it.
This means that one can pass around let moveOnly values using @_noImplicitCopy.
1 parent 6e8f83c commit 409a7d5

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

lib/SILGen/SILGenProlog.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,17 @@ struct ArgumentInitHelper {
275275
if (!argrv.getType().isAddress()) {
276276
if (SGF.getASTContext().SILOpts.EnableExperimentalLexicalLifetimes &&
277277
value->getOwnershipKind() == OwnershipKind::Owned) {
278+
bool isNoImplicitCopy = false;
279+
if (auto *arg = dyn_cast<SILFunctionArgument>(value))
280+
isNoImplicitCopy = arg->isNoImplicitCopy();
278281
value =
279282
SILValue(SGF.B.createBeginBorrow(loc, value, /*isLexical*/ true));
280283
SGF.Cleanups.pushCleanup<EndBorrowCleanup>(value);
284+
if (isNoImplicitCopy) {
285+
value = SGF.B.emitCopyValueOperation(loc, value);
286+
value = SGF.B.createMoveValue(loc, value);
287+
SGF.enterDestroyCleanup(value);
288+
}
281289
}
282290
SGF.B.createDebugValue(loc, value, varinfo);
283291
} else {

test/SILGen/noimplicitcopy_attr.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,5 @@ public class Klass {}
88
// CHECK-SIL: bb0(%0 : @noImplicitCopy $Klass):
99

1010
public func arguments(@_noImplicitCopy _ x: Klass) -> Klass {
11-
let y = x
12-
let z = x
1311
return x
1412
}

test/SILOptimizer/move_only_checker.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,17 @@ public func aggGenericStructAccessField<T>(_ x: AggGenericStruct<T>) {
357357
print(x2.lhs)
358358
}
359359
}
360+
361+
/////////////////////////////////
362+
// No Implicit Copy Attributes //
363+
/////////////////////////////////
364+
365+
public func klassNoImplicitCopyArgument(@_noImplicitCopy _ x: Klass) -> Klass {
366+
return x
367+
}
368+
369+
public func klassNoImplicitCopyArgumentError(@_noImplicitCopy _ x: Klass) -> Klass { // expected-error {{'x' consumed more than once}}
370+
let y = x // expected-note {{consuming use}}
371+
print(y)
372+
return x // expected-note {{consuming use}}
373+
}

0 commit comments

Comments
 (0)