@@ -412,6 +412,7 @@ void SILGenFunction::emitExprInto(Expr *E, Initialization *I,
412412 return ;
413413 }
414414
415+ FormalEvaluationScope writeback (*this );
415416 RValue result = emitRValue (E, SGFContext (I));
416417 if (result.isInContext ())
417418 return ;
@@ -2792,6 +2793,20 @@ RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
27922793 // Any writebacks for this access are tightly scoped.
27932794 FormalEvaluationScope scope (SGF);
27942795
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+
27952810 LValue lv = SGF.emitLValue (E, SGFAccessKind::OwnedObjectRead);
27962811 // We can't load at +0 without further analysis, since the formal access into
27972812 // the lvalue will end immediately.
@@ -6143,6 +6158,8 @@ RValue RValueEmitter::visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
61436158 SmallVector<ManagedValue, 1 > results;
61446159 SGF.emitOptionalEvaluation (E, E->getType (), results, C,
61456160 [&](SmallVectorImpl<ManagedValue> &results, SGFContext primaryC) {
6161+ // Generate each result in its own evaluation scope.
6162+ FormalEvaluationScope evalScope (SGF);
61466163 ManagedValue result;
61476164 if (!emitOptimizedOptionalEvaluation (SGF, E, result, primaryC)) {
61486165 result = SGF.emitRValueAsSingleValue (E->getSubExpr (), primaryC);
@@ -6476,7 +6493,7 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
64766493void SILGenFunction::emitOpenExistentialExprImpl (
64776494 OpenExistentialExpr *E,
64786495 llvm::function_ref<void (Expr *)> emitSubExpr) {
6479- assert (isInFormalEvaluationScope ());
6496+ ASSERT (isInFormalEvaluationScope ());
64806497
64816498 // Emit the existential value.
64826499 if (E->getExistentialValue ()->getType ()->is <LValueType>()) {
@@ -6511,7 +6528,14 @@ RValue RValueEmitter::visitOpenExistentialExpr(OpenExistentialExpr *E,
65116528 return RValue (SGF, E, *result);
65126529 }
65136530
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+
65156539 return SGF.emitOpenExistentialExpr <RValue>(E,
65166540 [&](Expr *subExpr) -> RValue {
65176541 return visit (subExpr, C);
@@ -7496,17 +7520,17 @@ void SILGenFunction::emitIgnoredExpr(Expr *E) {
74967520 // arguments.
74977521
74987522 FullExpr scope (Cleanups, CleanupLocation (E));
7523+ FormalEvaluationScope evalScope (*this );
7524+
74997525 if (E->getType ()->hasLValueType ()) {
75007526 // Emit the l-value, but don't perform an access.
7501- FormalEvaluationScope scope (*this );
75027527 emitLValue (E, SGFAccessKind::IgnoredRead);
75037528 return ;
75047529 }
75057530
75067531 // If this is a load expression, we try hard not to actually do the load
75077532 // (which could materialize a potentially expensive value with cleanups).
75087533 if (auto *LE = dyn_cast<LoadExpr>(E)) {
7509- FormalEvaluationScope scope (*this );
75107534 LValue lv = emitLValue (LE->getSubExpr (), SGFAccessKind::IgnoredRead);
75117535
75127536 // If loading from the lvalue is guaranteed to have no side effects, we
@@ -7541,7 +7565,6 @@ void SILGenFunction::emitIgnoredExpr(Expr *E) {
75417565 // emit the precondition(s) without having to load the value.
75427566 SmallVector<ForceValueExpr *, 4 > forceValueExprs;
75437567 if (auto *LE = findLoadThroughForceValueExprs (E, forceValueExprs)) {
7544- FormalEvaluationScope scope (*this );
75457568 LValue lv = emitLValue (LE->getSubExpr (), SGFAccessKind::IgnoredRead);
75467569
75477570 ManagedValue value;
0 commit comments