Skip to content

Commit 5b02713

Browse files
Merge pull request #73857 from nate-chandler/rdar125864434
[MoveOnly] Call borrowing methods on existentials.
2 parents 3bf21c7 + 8aec896 commit 5b02713

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ SubElementOffset::computeForAddress(SILValue projectionDerivedFromRoot,
158158
continue;
159159
}
160160

161+
if (auto *oea =
162+
dyn_cast<OpenExistentialAddrInst>(projectionDerivedFromRoot)) {
163+
projectionDerivedFromRoot = oea->getOperand();
164+
continue;
165+
}
166+
161167
if (auto *teai =
162168
dyn_cast<TupleElementAddrInst>(projectionDerivedFromRoot)) {
163169
SILType tupleType = teai->getOperand()->getType();

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,14 @@ bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
190190
if (paramInfo.isIndirectMutating())
191191
continue;
192192

193+
// The ExistentialSpecializerCloner copies the incoming generic argument
194+
// into an existential if it is non-consuming (if it's consuming, it's
195+
// moved into the existential via `copy_addr [take]`). Introducing a copy
196+
// of a move-only value isn't legal.
197+
if (!paramInfo.isConsumed() &&
198+
paramInfo.getSILStorageInterfaceType().isMoveOnly())
199+
continue;
200+
193201
ETAD.AccessType = paramInfo.isConsumed()
194202
? OpenedExistentialAccess::Mutable
195203
: OpenedExistentialAccess::Immutable;

test/Interpreter/rdar125864434.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -o %t/bin
3+
// RUN: %target-codesign %t/bin
4+
// RUN: %target-run %t/bin | %FileCheck %s
5+
6+
// REQUIRES: executable_test
7+
8+
protocol Boopable: ~Copyable {
9+
func boop()
10+
}
11+
12+
struct S: ~Copyable, Boopable {
13+
func boop() { print("boop") }
14+
}
15+
16+
func check(_ b: borrowing any Boopable & ~Copyable) {
17+
b.boop()
18+
}
19+
20+
// CHECK: boop
21+
check(S())

0 commit comments

Comments
 (0)