Skip to content

Commit 62b05c8

Browse files
committed
Reenable BorrowToDestructureTransform during the MoveOnlyAddressChecker.
The comment stated that this was used to turn switches into consumes (which is no longer relevant), but it looks like it is also necessary for the move-only address checker to be able to properly understand partial consumes of fields in some code patterns. Now that we surround borrowing switches in plenty of opaque accesses to protect them from being pried apart by the move checker, it should be safe to reenable this.
1 parent 755f260 commit 62b05c8

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,25 +2194,23 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
21942194
unsigned numDiagnostics =
21952195
moveChecker.diagnosticEmitter.getDiagnosticCount();
21962196

2197-
// Before we do anything, run the borrow to destructure transform in case
2198-
// we have a switch_enum user.
2199-
if (!getASTContext().LangOpts.hasFeature(Feature::BorrowingSwitch)) {
2200-
BorrowToDestructureTransform borrowToDestructure(
2201-
moveChecker.allocator, markedValue, li, moveChecker.diagnosticEmitter,
2202-
moveChecker.poa);
2203-
if (!borrowToDestructure.transform()) {
2204-
assert(moveChecker.diagnosticEmitter
2205-
.didEmitCheckerDoesntUnderstandDiagnostic());
2206-
LLVM_DEBUG(llvm::dbgs()
2207-
<< "Failed to perform borrow to destructure transform!\n");
2208-
return false;
2209-
}
2210-
// If we emitted an error diagnostic, do not transform further and instead
2211-
// mark that we emitted an early diagnostic and return true.
2212-
if (numDiagnostics != moveChecker.diagnosticEmitter.getDiagnosticCount()) {
2213-
LLVM_DEBUG(llvm::dbgs() << "Emitting borrow to destructure error!\n");
2214-
return true;
2215-
}
2197+
// Before we do anything, run the borrow to destructure transform to reduce
2198+
// copies through borrows.
2199+
BorrowToDestructureTransform borrowToDestructure(
2200+
moveChecker.allocator, markedValue, li, moveChecker.diagnosticEmitter,
2201+
moveChecker.poa);
2202+
if (!borrowToDestructure.transform()) {
2203+
assert(moveChecker.diagnosticEmitter
2204+
.didEmitCheckerDoesntUnderstandDiagnostic());
2205+
LLVM_DEBUG(llvm::dbgs()
2206+
<< "Failed to perform borrow to destructure transform!\n");
2207+
return false;
2208+
}
2209+
// If we emitted an error diagnostic, do not transform further and instead
2210+
// mark that we emitted an early diagnostic and return true.
2211+
if (numDiagnostics != moveChecker.diagnosticEmitter.getDiagnosticCount()) {
2212+
LLVM_DEBUG(llvm::dbgs() << "Emitting borrow to destructure error!\n");
2213+
return true;
22162214
}
22172215

22182216
// Now, validate that what we will transform into a take isn't a take that
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify -enable-experimental-feature BorrowingSwitch -enable-experimental-feature MoveOnlyPartialConsumption -parse-as-library %s
2+
3+
func foo() {
4+
let node = Node()
5+
bar(node.next)
6+
}
7+
8+
struct Node: ~Copyable {
9+
var next: Link
10+
11+
init() { fatalError() }
12+
}
13+
14+
struct Link: ~Copyable {}
15+
16+
func bar(_: consuming Link) {}
17+
18+

0 commit comments

Comments
 (0)