@@ -3304,23 +3304,61 @@ Expr *SILGenFunction::findStorageReferenceExprForMoveOnly(Expr *argExpr,
33043304 // referenced is a move-only type.
33053305
33063306 AbstractStorageDecl *storage = nullptr ;
3307+ AccessSemantics accessSemantics;
33073308 Type type;
33083309 if (auto dre = dyn_cast<DeclRefExpr>(result.getStorageRef ())) {
33093310 storage = dyn_cast<AbstractStorageDecl>(dre->getDecl ());
33103311 type = dre->getType ();
3312+ accessSemantics = dre->getAccessSemantics ();
33113313 } else if (auto mre = dyn_cast<MemberRefExpr>(result.getStorageRef ())) {
33123314 storage = dyn_cast<AbstractStorageDecl>(mre->getDecl ().getDecl ());
33133315 type = mre->getType ();
3316+ accessSemantics = mre->getAccessSemantics ();
33143317 } else if (auto se = dyn_cast<SubscriptExpr>(result.getStorageRef ())) {
33153318 storage = dyn_cast<AbstractStorageDecl>(se->getDecl ().getDecl ());
33163319 type = se->getType ();
3320+ accessSemantics = se->getAccessSemantics ();
33173321 }
33183322
33193323 if (!storage)
33203324 return nullptr ;
3321- if (!storage->hasStorage () && storage->getReadImpl () != ReadImplKind::Read &&
3322- storage->getReadImpl () != ReadImplKind::Read2 &&
3323- storage->getReadImpl () != ReadImplKind::Address) {
3325+ // This should match the strategy computation used in
3326+ // SILGenLValue::visit{DeclRef,Member}RefExpr.
3327+ auto strategy = storage->getAccessStrategy (accessSemantics,
3328+ AccessKind::Read, SGM.M .getSwiftModule (), F.getResilienceExpansion (),
3329+ /* old abi*/ false );
3330+
3331+ switch (strategy.getKind ()) {
3332+ case AccessStrategy::Storage:
3333+ // Storage can benefit from direct borrowing/consumption.
3334+ break ;
3335+ case AccessStrategy::DirectToAccessor:
3336+ case AccessStrategy::DispatchToAccessor:
3337+ // If the accessor naturally produces a borrow, then we benefit from
3338+ // directly borrowing it.
3339+ switch (strategy.getAccessor ()) {
3340+ case AccessorKind::Address:
3341+ case AccessorKind::MutableAddress:
3342+ case AccessorKind::Read:
3343+ case AccessorKind::Read2:
3344+ case AccessorKind::Modify:
3345+ case AccessorKind::Modify2:
3346+ // Accessors that produce a borrow/inout value can be borrowed.
3347+ break ;
3348+
3349+ case AccessorKind::Get:
3350+ case AccessorKind::Set:
3351+ case AccessorKind::DistributedGet:
3352+ case AccessorKind::Init:
3353+ case AccessorKind::WillSet:
3354+ case AccessorKind::DidSet:
3355+ // Other accessors can't.
3356+ return nullptr ;
3357+ }
3358+ break ;
3359+
3360+ case AccessStrategy::MaterializeToTemporary:
3361+ case AccessStrategy::DispatchToDistributedThunk:
33243362 return nullptr ;
33253363 }
33263364
0 commit comments