@@ -2266,12 +2266,41 @@ SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl,
22662266 Cleanups.pushCleanup <DeallocateLocalVariableAddressableBuffer>(decl, destroyCleanup);
22672267}
22682268
2269+ static bool isFullyAbstractedLowering (SILGenFunction &SGF,
2270+ Type formalType, SILType loweredType) {
2271+ return SGF.getLoweredType (AbstractionPattern::getOpaque (), formalType)
2272+ .getASTType ()
2273+ == loweredType.getASTType ();
2274+ }
2275+
2276+ static bool isNaturallyFullyAbstractedType (SILGenFunction &SGF,
2277+ Type formalType) {
2278+ return isFullyAbstractedLowering (SGF, formalType, SGF.getLoweredType (formalType));
2279+ }
2280+
22692281SILValue
2270- SILGenFunction::getLocalVariableAddressableBuffer (VarDecl *decl,
2271- SILLocation curLoc,
2272- ValueOwnership ownership) {
2282+ SILGenFunction::getVariableAddressableBuffer (VarDecl *decl,
2283+ SILLocation curLoc,
2284+ ValueOwnership ownership) {
2285+ // For locals, we might be able to retroactively produce a local addressable
2286+ // representation.
22732287 auto foundVarLoc = VarLocs.find (decl);
22742288 if (foundVarLoc == VarLocs.end ()) {
2289+ // If it's not local, is it at least a global stored variable?
2290+ if (decl->isGlobalStorage ()) {
2291+ // Is the global immutable?
2292+ if (!decl->isLet ()) {
2293+ return SILValue ();
2294+ }
2295+
2296+ // Does the storage naturally have a fully abstracted representation?
2297+ if (!isNaturallyFullyAbstractedType (*this , decl->getTypeInContext ())) {
2298+ return SILValue ();
2299+ }
2300+
2301+ // We can get the stable address via the addressor.
2302+ return emitGlobalVariableRef (curLoc, decl, std::nullopt ).getUnmanagedValue ();
2303+ }
22752304 return SILValue ();
22762305 }
22772306
@@ -2285,7 +2314,8 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22852314 // Check whether the bound value is inherently suitable for addressability.
22862315 // It must already be in memory and fully abstracted.
22872316 if (value->getType ().isAddress ()
2288- && fullyAbstractedTy.getASTType () == value->getType ().getASTType ()) {
2317+ && isFullyAbstractedLowering (*this , decl->getTypeInContext ()->getRValueType (),
2318+ value->getType ())) {
22892319 SILValue address = value;
22902320 // Begin an access if the address is mutable.
22912321 if (access != SILAccessEnforcement::Unknown) {
0 commit comments