@@ -2263,12 +2263,41 @@ SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl,
22632263 Cleanups.pushCleanup <DeallocateLocalVariableAddressableBuffer>(decl, destroyCleanup);
22642264}
22652265
2266+ static bool isFullyAbstractedLowering (SILGenFunction &SGF,
2267+ Type formalType, SILType loweredType) {
2268+ return SGF.getLoweredType (AbstractionPattern::getOpaque (), formalType)
2269+ .getASTType ()
2270+ == loweredType.getASTType ();
2271+ }
2272+
2273+ static bool isNaturallyFullyAbstractedType (SILGenFunction &SGF,
2274+ Type formalType) {
2275+ return isFullyAbstractedLowering (SGF, formalType, SGF.getLoweredType (formalType));
2276+ }
2277+
22662278SILValue
2267- SILGenFunction::getLocalVariableAddressableBuffer (VarDecl *decl,
2268- SILLocation curLoc,
2269- ValueOwnership ownership) {
2279+ SILGenFunction::getVariableAddressableBuffer (VarDecl *decl,
2280+ SILLocation curLoc,
2281+ ValueOwnership ownership) {
2282+ // For locals, we might be able to retroactively produce a local addressable
2283+ // representation.
22702284 auto foundVarLoc = VarLocs.find (decl);
22712285 if (foundVarLoc == VarLocs.end ()) {
2286+ // If it's not local, is it at least a global stored variable?
2287+ if (decl->isGlobalStorage ()) {
2288+ // Is the global immutable?
2289+ if (!decl->isLet ()) {
2290+ return SILValue ();
2291+ }
2292+
2293+ // Does the storage naturally have a fully abstracted representation?
2294+ if (!isNaturallyFullyAbstractedType (*this , decl->getTypeInContext ())) {
2295+ return SILValue ();
2296+ }
2297+
2298+ // We can get the stable address via the addressor.
2299+ return emitGlobalVariableRef (curLoc, decl, std::nullopt ).getUnmanagedValue ();
2300+ }
22722301 return SILValue ();
22732302 }
22742303
@@ -2282,7 +2311,8 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22822311 // Check whether the bound value is inherently suitable for addressability.
22832312 // It must already be in memory and fully abstracted.
22842313 if (value->getType ().isAddress ()
2285- && fullyAbstractedTy.getASTType () == value->getType ().getASTType ()) {
2314+ && isFullyAbstractedLowering (*this , decl->getTypeInContext ()->getRValueType (),
2315+ value->getType ())) {
22862316 SILValue address = value;
22872317 // Begin an access if the address is mutable.
22882318 if (access != SILAccessEnforcement::Unknown) {
0 commit comments