Skip to content

Commit 875e67a

Browse files
committed
[MoveOnly] Fix consumption of opened existentials.
Enable walking into `TypeOffsetSizePair`s from an existential into an archetype. And set the access kind on `open_existential_addr` instructions which are the sources of rewritten `copy_addr`s to mutable. rdar://141279635
1 parent f201cee commit 875e67a

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3431,6 +3431,10 @@ void MoveOnlyAddressCheckerPImpl::rewriteUses(
34313431
auto accessPath = AccessPathWithBase::computeInScope(copy->getSrc());
34323432
if (auto *access = dyn_cast_or_null<BeginAccessInst>(accessPath.base))
34333433
access->setAccessKind(SILAccessKind::Modify);
3434+
if (auto *oeai =
3435+
dyn_cast_or_null<OpenExistentialAddrInst>(copy->getSrc())) {
3436+
oeai->setAccessKind(OpenedExistentialAccess::Mutable);
3437+
}
34343438
copy->setIsTakeOfSrc(IsTake);
34353439
continue;
34363440
}

lib/SILOptimizer/Mandatory/MoveOnlyTypeUtils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ TypeOffsetSizePair::walkOneLevelTowardsChild(
127127
llvm_unreachable("Not a child of this enum?!");
128128
}
129129

130+
if (ancestorType.isExistentialType()) {
131+
assert(childType);
132+
auto childArchetypeType =
133+
childType.getASTType()->getAs<ExistentialArchetypeType>();
134+
assert(childArchetypeType);
135+
assert(childArchetypeType->getExistentialType()->getCanonicalType() ==
136+
ancestorType.getASTType());
137+
return {{ancestorOffsetSize, childType}};
138+
}
139+
130140
llvm_unreachable("Hit a leaf type?! Should have handled it earlier");
131141
}
132142

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-build-swift %s
2+
3+
protocol P: ~Copyable {
4+
var property: Bool { get }
5+
consuming func function()
6+
}
7+
8+
struct S: P, ~Copyable {
9+
var property: Bool { false }
10+
consuming func function() {}
11+
}
12+
13+
func g(s: consuming any P & ~Copyable) {
14+
let s = s
15+
s.function()
16+
}
17+
18+
func f() {
19+
let s = S()
20+
g(s: s)
21+
}

0 commit comments

Comments
 (0)