@@ -3304,23 +3304,61 @@ Expr *SILGenFunction::findStorageReferenceExprForMoveOnly(Expr *argExpr,
3304
3304
// referenced is a move-only type.
3305
3305
3306
3306
AbstractStorageDecl *storage = nullptr ;
3307
+ AccessSemantics accessSemantics;
3307
3308
Type type;
3308
3309
if (auto dre = dyn_cast<DeclRefExpr>(result.getStorageRef ())) {
3309
3310
storage = dyn_cast<AbstractStorageDecl>(dre->getDecl ());
3310
3311
type = dre->getType ();
3312
+ accessSemantics = dre->getAccessSemantics ();
3311
3313
} else if (auto mre = dyn_cast<MemberRefExpr>(result.getStorageRef ())) {
3312
3314
storage = dyn_cast<AbstractStorageDecl>(mre->getDecl ().getDecl ());
3313
3315
type = mre->getType ();
3316
+ accessSemantics = mre->getAccessSemantics ();
3314
3317
} else if (auto se = dyn_cast<SubscriptExpr>(result.getStorageRef ())) {
3315
3318
storage = dyn_cast<AbstractStorageDecl>(se->getDecl ().getDecl ());
3316
3319
type = se->getType ();
3320
+ accessSemantics = se->getAccessSemantics ();
3317
3321
}
3318
3322
3319
3323
if (!storage)
3320
3324
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:
3324
3362
return nullptr ;
3325
3363
}
3326
3364
0 commit comments