2626#include " SILGen.h"
2727#include " SILGenFunction.h"
2828#include " Scope.h"
29+ #include " swift/AST/Decl.h"
2930#include " swift/AST/DiagnosticsCommon.h"
3031#include " swift/AST/DiagnosticsSIL.h"
3132#include " swift/AST/GenericEnvironment.h"
@@ -3072,15 +3073,16 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30723073
30733074 static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e,
30743075 LValueOptions options) {
3075- if (auto *m = dyn_cast<MemberRefExpr>(e)) {
3076+ if (LookupExpr *le;
3077+ (le = dyn_cast<MemberRefExpr>(e)) || (le = dyn_cast<SubscriptExpr>(e))) {
30763078 // If our m is a pure noncopyable type or our base is, we need to perform
30773079 // a noncopyable base borrow.
30783080 //
30793081 // DISCUSSION: We can have a noncopyable member_ref_expr with a copyable
30803082 // base if the noncopyable member_ref_expr is from a computed method. In
30813083 // such a case, we want to ensure that we wrap things the right way.
3082- if (m ->getType ()->isNoncopyable () ||
3083- m ->getBase ()->getType ()->isNoncopyable ()) {
3084+ if (le ->getType ()->isNoncopyable () ||
3085+ le ->getBase ()->getType ()->isNoncopyable ()) {
30843086 return true ;
30853087 }
30863088
@@ -3140,18 +3142,17 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31403142 return SGL.visitRec (e, accessKind, options, Orig);
31413143 }
31423144
3143- LValue visitMemberRefExpr (MemberRefExpr *e, SGFAccessKind accessKind ,
3144- LValueOptions options) {
3145- // If we have a member_ref_expr, we create a component that will when we
3146- // evaluate the lvalue,
3147- VarDecl *var = cast<VarDecl >(e->getMember ().getDecl ());
3148-
3145+ LValue getLookupExprBaseLValue (LookupExpr *e, AccessSemantics accessSemantics ,
3146+ SGFAccessKind accessKind,
3147+ LValueOptions options,
3148+ AccessStrategy &strategy) {
3149+ auto storage = cast<AbstractStorageDecl >(e->getMember ().getDecl ());
3150+
31493151 assert (!e->getType ()->is <LValueType>());
31503152
31513153 auto pair = std::make_pair<>(e->getSourceRange (), SGF.FunctionDC );
31523154
3153- auto accessSemantics = e->getAccessSemantics ();
3154- AccessStrategy strategy = var->getAccessStrategy (
3155+ strategy = storage->getAccessStrategy (
31553156 accessSemantics, getFormalAccessKind (accessKind),
31563157 SGF.SGM .M .getSwiftModule (), SGF.F .getResilienceExpansion (), pair,
31573158 /* useOldABI=*/ false );
@@ -3168,21 +3169,54 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31683169 orig = AbstractionPattern::getOpaque ();
31693170 }
31703171
3171- LValue lv = visit (
3172+ return visit (
31723173 e->getBase (),
3173- getBaseAccessKind (SGF.SGM , var , accessKind, strategy, baseFormalType,
3174+ getBaseAccessKind (SGF.SGM , storage , accessKind, strategy, baseFormalType,
31743175 /* for borrow*/ true ),
31753176 getBaseOptions (options, strategy, addressable));
3177+ }
3178+
3179+ LValue visitSubscriptExpr (SubscriptExpr *e, SGFAccessKind accessKind,
3180+ LValueOptions options) {
3181+ AccessStrategy strategy = AccessStrategy::getStorage ();
3182+ LValue lv = getLookupExprBaseLValue (e, e->getAccessSemantics (),
3183+ accessKind, options,
3184+ strategy);
3185+ auto subs = e->getMember ().getSubstitutions ();
3186+
3187+ auto subscript = cast<SubscriptDecl>(e->getMember ().getDecl ());
3188+
3189+ auto storageCanType = SGF.prepareStorageType (subscript, subs);
3190+ auto indices = SGF.prepareIndices (e, storageCanType, strategy, e->getArgs ());
3191+
3192+ lv.addMemberSubscriptComponent (SGF, e, subscript, subs,
3193+ options, e->isSuper (), accessKind, strategy,
3194+ getSubstFormalRValueType (e),
3195+ std::move (indices),
3196+ e->getArgs ());
3197+ return lv;
3198+ }
3199+
3200+ LValue visitMemberRefExpr (MemberRefExpr *e, SGFAccessKind accessKind,
3201+ LValueOptions options) {
3202+ AccessStrategy strategy = AccessStrategy::getStorage ();
3203+ LValue lv = getLookupExprBaseLValue (e, e->getAccessSemantics (),
3204+ accessKind, options,
3205+ strategy);
3206+
3207+ auto var = cast<VarDecl>(e->getMember ().getDecl ());
3208+
31763209 std::optional<ActorIsolation> actorIso;
31773210 if (e->isImplicitlyAsync ())
31783211 actorIso = getActorIsolation (var);
3179- lv.addMemberVarComponent (SGF, e, var, e->getMember ().getSubstitutions (),
3212+
3213+ lv.addMemberVarComponent (SGF, e, var,
3214+ e->getMember ().getSubstitutions (),
31803215 options, e->isSuper (), accessKind, strategy,
3181- formalRValueType ,
3216+ getSubstFormalRValueType (e) ,
31823217 false /* is on self parameter*/ , actorIso);
31833218
31843219 SGF.SGM .noteMemberRefExpr (e);
3185-
31863220 return lv;
31873221 }
31883222
0 commit comments