Skip to content

Commit 7f6d600

Browse files
gregomnijckarter
authored andcommitted
Move merging of CapturedValue flags into the class itself so that it'll be more clear that dealing with this will be required if more flags are added in the future. And mergeFlags correctly on the dynamic self capture.
1 parent ed6baaa commit 7f6d600

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

include/swift/AST/CaptureInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ class CapturedValue {
6464

6565
bool isDynamicSelfMetadata() const { return !Value.getPointer(); }
6666

67+
CapturedValue mergeFlags(CapturedValue cv) {
68+
assert(Value.getPointer() == cv.Value.getPointer() &&
69+
"merging flags on two different value decls");
70+
return CapturedValue(Value.getPointer(), getFlags() & cv.getFlags());
71+
}
72+
6773
ValueDecl *getDecl() const {
6874
assert(Value.getPointer() && "dynamic Self metadata capture does not "
6975
"have a value");

lib/SIL/TypeLowering.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,16 +2144,36 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
21442144
goto capture_value;
21452145
}
21462146
}
2147+
2148+
if (!capturedVar->hasStorage())
2149+
continue;
2150+
2151+
// We can always capture the storage in these cases.
2152+
Type captureType = capturedVar->getType();
2153+
if (auto *metatypeType = captureType->getAs<MetatypeType>())
2154+
captureType = metatypeType->getInstanceType();
2155+
2156+
if (auto *selfType = captureType->getAs<DynamicSelfType>()) {
2157+
captureType = selfType->getSelfType();
2158+
2159+
// We're capturing a 'self' value with dynamic 'Self' type;
2160+
// handle it specially.
2161+
if (captureType->getClassOrBoundGenericClass()) {
2162+
if (selfCapture)
2163+
selfCapture = selfCapture->mergeFlags(capture);
2164+
else
2165+
selfCapture = capture;
2166+
continue;
2167+
}
2168+
}
21472169
}
21482170
capture_value:
21492171
// Collect non-function captures.
21502172
ValueDecl *value = capture.getDecl();
21512173
if (capturedValues.count(value)) {
21522174
for (auto it = captures.begin(); it != captures.end(); ++it) {
21532175
if (it->getDecl() == value) {
2154-
// The value is already in the list, it needs to have the logical
2155-
// AND of each flag of all uses.
2156-
*it = CapturedValue(value, it->getFlags() & capture.getFlags());
2176+
*it = it->mergeFlags(capture);
21572177
break;
21582178
}
21592179
}

0 commit comments

Comments
 (0)