Skip to content

Commit 3decd81

Browse files
authored
Merge pull request #71630 from jckarter/emit-value-as-borrow
SILGen: Handle emitting borrowed lvalues from value bindings.
2 parents 0308b16 + 7fed21a commit 3decd81

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
@@ -1195,9 +1195,11 @@ namespace {
11951195

11961196
ManagedValue project(SILGenFunction &SGF, SILLocation loc,
11971197
ManagedValue base) && override {
1198-
assert(base
1199-
&& base.getType().isAddress()
1200-
&& "should have an address base to borrow from");
1198+
// If the base is already loaded, we just need to borrow it.
1199+
if (!base.getType().isAddress()) {
1200+
return base.formalAccessBorrow(SGF, loc);
1201+
}
1202+
12011203
// If the base value is address-only then we can borrow from the
12021204
// address in-place.
12031205
if (!base.getType().isLoadable(SGF.F)) {
@@ -3380,9 +3382,15 @@ void LValue::addNonMemberVarComponent(
33803382
"local var should not be actor isolated!");
33813383
}
33823384

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

33873395
llvm::Optional<SILAccessEnforcement> enforcement;
33883396
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)