@@ -412,6 +412,7 @@ void SILGenFunction::emitExprInto(Expr *E, Initialization *I,
412
412
return ;
413
413
}
414
414
415
+ FormalEvaluationScope writeback (*this );
415
416
RValue result = emitRValue (E, SGFContext (I));
416
417
if (result.isInContext ())
417
418
return ;
@@ -2792,6 +2793,20 @@ RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
2792
2793
// Any writebacks for this access are tightly scoped.
2793
2794
FormalEvaluationScope scope (SGF);
2794
2795
2796
+ // For a noncopyable resulting expression, try to borrow instead.
2797
+ if (E->getType ()->isNoncopyable ()) {
2798
+ LValue lv = SGF.emitLValue (E, SGFAccessKind::BorrowedObjectRead);
2799
+ ManagedValue mv = SGF.emitRawProjectedLValue (E, std::move (lv));
2800
+
2801
+ // If we got back a borrow (aka +0) because of a coroutine read
2802
+ // accessor, defer the end_apply to the outer evaluation scope.
2803
+ // Otherwise, we can end any other formal accesses now.
2804
+ if (mv.isPlusZero ())
2805
+ std::move (scope).deferPop ();
2806
+
2807
+ return RValue (SGF, E, mv);
2808
+ }
2809
+
2795
2810
LValue lv = SGF.emitLValue (E, SGFAccessKind::OwnedObjectRead);
2796
2811
// We can't load at +0 without further analysis, since the formal access into
2797
2812
// the lvalue will end immediately.
@@ -6143,6 +6158,8 @@ RValue RValueEmitter::visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
6143
6158
SmallVector<ManagedValue, 1 > results;
6144
6159
SGF.emitOptionalEvaluation (E, E->getType (), results, C,
6145
6160
[&](SmallVectorImpl<ManagedValue> &results, SGFContext primaryC) {
6161
+ // Generate each result in its own evaluation scope.
6162
+ FormalEvaluationScope evalScope (SGF);
6146
6163
ManagedValue result;
6147
6164
if (!emitOptimizedOptionalEvaluation (SGF, E, result, primaryC)) {
6148
6165
result = SGF.emitRValueAsSingleValue (E->getSubExpr (), primaryC);
@@ -6476,7 +6493,7 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
6476
6493
void SILGenFunction::emitOpenExistentialExprImpl (
6477
6494
OpenExistentialExpr *E,
6478
6495
llvm::function_ref<void (Expr *)> emitSubExpr) {
6479
- assert (isInFormalEvaluationScope ());
6496
+ ASSERT (isInFormalEvaluationScope ());
6480
6497
6481
6498
// Emit the existential value.
6482
6499
if (E->getExistentialValue ()->getType ()->is <LValueType>()) {
@@ -6511,7 +6528,14 @@ RValue RValueEmitter::visitOpenExistentialExpr(OpenExistentialExpr *E,
6511
6528
return RValue (SGF, E, *result);
6512
6529
}
6513
6530
6514
- FormalEvaluationScope writebackScope (SGF);
6531
+ // Introduce a fresh, nested evaluation scope for Copyable types.
6532
+ // This is a bit of a hack, as it should always be up to our caller
6533
+ // to establish the right level of formal access scope, in case we
6534
+ // formally borrow the opened existential instead of copying it.
6535
+ std::optional<FormalEvaluationScope> scope;
6536
+ if (!E->getType ()->isNoncopyable ())
6537
+ scope.emplace (SGF);
6538
+
6515
6539
return SGF.emitOpenExistentialExpr <RValue>(E,
6516
6540
[&](Expr *subExpr) -> RValue {
6517
6541
return visit (subExpr, C);
@@ -7496,17 +7520,17 @@ void SILGenFunction::emitIgnoredExpr(Expr *E) {
7496
7520
// arguments.
7497
7521
7498
7522
FullExpr scope (Cleanups, CleanupLocation (E));
7523
+ FormalEvaluationScope evalScope (*this );
7524
+
7499
7525
if (E->getType ()->hasLValueType ()) {
7500
7526
// Emit the l-value, but don't perform an access.
7501
- FormalEvaluationScope scope (*this );
7502
7527
emitLValue (E, SGFAccessKind::IgnoredRead);
7503
7528
return ;
7504
7529
}
7505
7530
7506
7531
// If this is a load expression, we try hard not to actually do the load
7507
7532
// (which could materialize a potentially expensive value with cleanups).
7508
7533
if (auto *LE = dyn_cast<LoadExpr>(E)) {
7509
- FormalEvaluationScope scope (*this );
7510
7534
LValue lv = emitLValue (LE->getSubExpr (), SGFAccessKind::IgnoredRead);
7511
7535
7512
7536
// If loading from the lvalue is guaranteed to have no side effects, we
@@ -7541,7 +7565,6 @@ void SILGenFunction::emitIgnoredExpr(Expr *E) {
7541
7565
// emit the precondition(s) without having to load the value.
7542
7566
SmallVector<ForceValueExpr *, 4 > forceValueExprs;
7543
7567
if (auto *LE = findLoadThroughForceValueExprs (E, forceValueExprs)) {
7544
- FormalEvaluationScope scope (*this );
7545
7568
LValue lv = emitLValue (LE->getSubExpr (), SGFAccessKind::IgnoredRead);
7546
7569
7547
7570
ManagedValue value;
0 commit comments