SILGen: Properly set up addressability scopes for case pattern bindings.

In order to accommodate case bodies with multiple case labels, the AST
represents the bindings in each pattern as a distinct declaration from
the matching binding in the case body, and SILGen shares the variable
representation between the two declarations. That means that the two
declarations also need to be able to share an addressable representation.
Add an "alias" state to the addressable buffer data structures so that
we can refer back to the original case label var decl when the case body
var decl is brought into scope, so that accesses through either decl
properly force the addressable representation.

Fixes rdar://154543619.
This commit is contained in:
Joe Groff
2025-07-07 14:37:27 -07:00
parent 47bb174683
commit 5e021bc55a
5 changed files with 126 additions and 31 deletions

View File

@@ -24,7 +24,6 @@
#include "swift/AST/SILOptions.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/AST/Types.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/ProfileCounter.h"
#include "swift/Basic/STLExtras.h"
@@ -241,7 +240,7 @@ static bool isWildcardPattern(const Pattern *p) {
/// Check to see if the given pattern is a specializing pattern,
/// and return a semantic pattern for it.
Pattern *getSpecializingPattern(Pattern *p) {
static Pattern *getSpecializingPattern(Pattern *p) {
// Empty entries are basically AnyPatterns.
if (!p) return nullptr;
@@ -975,9 +974,8 @@ private:
if (IsFinalUse) {
ArgForwarderBase::forwardIntoIrrefutable(value);
return value;
} else {
return ArgForwarderBase::forward(value, loc);
}
return ArgForwarderBase::forward(value, loc);
}
};
@@ -3175,6 +3173,9 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
expectedLoc = SILGenFunction::VarLoc(vdLoc->second.value,
vdLoc->second.access,
vdLoc->second.box);
expectedLoc.addressableBuffer = vd;
// Alias the addressable buffer for the two variables.
SGF.AddressableBuffers[expected] = vd;
// Emit a debug description for the variable, nested within a scope
// for the pattern match.