Skip to content

Commit 4786bed

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 6669b24 commit 4786bed

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
@@ -3430,6 +3430,10 @@ void MoveOnlyAddressCheckerPImpl::rewriteUses(
34303430
auto accessPath = AccessPathWithBase::computeInScope(copy->getSrc());
34313431
if (auto *access = dyn_cast_or_null<BeginAccessInst>(accessPath.base))
34323432
access->setAccessKind(SILAccessKind::Modify);
3433+
if (auto *oeai =
3434+
dyn_cast_or_null<OpenExistentialAddrInst>(copy->getSrc())) {
3435+
oeai->setAccessKind(OpenedExistentialAccess::Mutable);
3436+
}
34333437
copy->setIsTakeOfSrc(IsTake);
34343438
continue;
34353439
}

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)