Skip to content

Commit 7fed21a

Browse files
committed
SILGen: Handle emitting borrowed lvalues from value bindings.
Replace the "must be an address" assertion with an implementation that emits and borrows the base value. Fixes #71598.
1 parent 0365c6a commit 7fed21a

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,9 +1193,11 @@ namespace {
11931193

11941194
ManagedValue project(SILGenFunction &SGF, SILLocation loc,
11951195
ManagedValue base) && override {
1196-
assert(base
1197-
&& base.getType().isAddress()
1198-
&& "should have an address base to borrow from");
1196+
// If the base is already loaded, we just need to borrow it.
1197+
if (!base.getType().isAddress()) {
1198+
return base.formalAccessBorrow(SGF, loc);
1199+
}
1200+
11991201
// If the base value is address-only then we can borrow from the
12001202
// address in-place.
12011203
if (!base.getType().isLoadable(SGF.F)) {
@@ -3384,9 +3386,15 @@ void LValue::addNonMemberVarComponent(
33843386
"local var should not be actor isolated!");
33853387
}
33863388

3387-
assert(address.isLValue() &&
3388-
"Must have a physical copyable lvalue decl ref that "
3389-
"evaluates to an address");
3389+
if (!address.isLValue()) {
3390+
assert((AccessKind == SGFAccessKind::BorrowedObjectRead
3391+
|| AccessKind == SGFAccessKind::BorrowedAddressRead)
3392+
&& "non-borrow component requires an address base");
3393+
LV.add<ValueComponent>(address, std::nullopt, typeData,
3394+
/*rvalue*/ true);
3395+
LV.add<BorrowValueComponent>(typeData);
3396+
return;
3397+
}
33903398

33913399
llvm::Optional<SILAccessEnforcement> enforcement;
33923400
if (!Storage->isLet()) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
func foo(x: borrowing String) {}
4+
5+
var last:String
6+
{
7+
// CHECK-LABEL: sil{{.*}} @{{.*}}4lastSSvr :
8+
_read
9+
{
10+
// CHECK: [[X:%.*]] = move_value
11+
let x:String = ""
12+
// CHECK: [[BORROW1:%.*]] = begin_borrow [[X]]
13+
// CHECK: apply {{.*}}([[BORROW1]])
14+
// CHECK: end_borrow [[BORROW1]]
15+
foo(x: x)
16+
// CHECK: [[BORROW2:%.*]] = begin_borrow [[X]]
17+
// CHECK: yield [[BORROW2]] : {{.*}}, resume [[RESUME:bb[0-9]+]],
18+
// CHECK: [[RESUME]]:
19+
// CHECK: end_borrow [[BORROW2]]
20+
yield x
21+
}
22+
23+
_modify {
24+
var x: String = ""
25+
yield &x
26+
}
27+
}

0 commit comments

Comments
 (0)