Skip to content

Commit ae9eeb0

Browse files
authored
Merge pull request swiftlang#72936 from slavapestov/requestify-compute-captures
Request-ify TypeChecker::computeCaptures()
2 parents 2a58d61 + e342a38 commit ae9eeb0

19 files changed

+249
-95
lines changed

include/swift/AST/CaptureInfo.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -185,24 +185,19 @@ class CaptureInfo {
185185
}
186186

187187
bool isTrivial() const {
188+
assert(hasBeenComputed());
188189
return getCaptures().empty() && !hasGenericParamCaptures() &&
189190
!hasDynamicSelfCapture() && !hasOpaqueValueCapture();
190191
}
191192

192193
ArrayRef<CapturedValue> getCaptures() const {
193-
// FIXME: Ideally, everywhere that synthesizes a function should include
194-
// its capture info.
195-
if (!hasBeenComputed())
196-
return std::nullopt;
194+
assert(hasBeenComputed());
197195
return StorageAndFlags.getPointer()->getCaptures();
198196
}
199197

200198
/// \returns true if the function captures any generic type parameters.
201199
bool hasGenericParamCaptures() const {
202-
// FIXME: Ideally, everywhere that synthesizes a function should include
203-
// its capture info.
204-
if (!hasBeenComputed())
205-
return false;
200+
assert(hasBeenComputed());
206201
return StorageAndFlags.getInt().contains(Flags::HasGenericParamCaptures);
207202
}
208203

@@ -213,22 +208,17 @@ class CaptureInfo {
213208

214209
/// \returns the captured dynamic Self type, if any.
215210
DynamicSelfType *getDynamicSelfType() const {
216-
// FIXME: Ideally, everywhere that synthesizes a function should include
217-
// its capture info.
218-
if (!hasBeenComputed())
219-
return nullptr;
211+
assert(hasBeenComputed());
220212
return StorageAndFlags.getPointer()->getDynamicSelfType();
221213
}
222214

223215
bool hasOpaqueValueCapture() const {
216+
assert(hasBeenComputed());
224217
return getOpaqueValue() != nullptr;
225218
}
226219

227220
OpaqueValueExpr *getOpaqueValue() const {
228-
// FIXME: Ideally, everywhere that synthesizes a function should include
229-
// its capture info.
230-
if (!hasBeenComputed())
231-
return nullptr;
221+
assert(hasBeenComputed());
232222
return StorageAndFlags.getPointer()->getOpaqueValue();
233223
}
234224

include/swift/AST/Decl.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6814,9 +6814,14 @@ class ParamDecl : public VarDecl {
68146814

68156815
void setDefaultArgumentInitContext(Initializer *initContext);
68166816

6817-
CaptureInfo getDefaultArgumentCaptureInfo() const {
6817+
CaptureInfo getDefaultArgumentCaptureInfo() const;
6818+
6819+
std::optional<CaptureInfo> getCachedDefaultArgumentCaptureInfo() const {
68186820
assert(DefaultValueAndFlags.getPointer());
6819-
return DefaultValueAndFlags.getPointer()->Captures;
6821+
const auto &captures = DefaultValueAndFlags.getPointer()->Captures;
6822+
if (!captures.hasBeenComputed())
6823+
return std::nullopt;
6824+
return captures;
68206825
}
68216826

68226827
void setDefaultArgumentCaptureInfo(CaptureInfo captures);
@@ -7754,8 +7759,18 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
77547759
/// Retrieve the source range of the function declaration name + patterns.
77557760
SourceRange getSignatureSourceRange() const;
77567761

7757-
CaptureInfo getCaptureInfo() const { return Captures; }
7758-
void setCaptureInfo(CaptureInfo captures) { Captures = captures; }
7762+
CaptureInfo getCaptureInfo() const;
7763+
7764+
std::optional<CaptureInfo> getCachedCaptureInfo() const {
7765+
if (!Captures.hasBeenComputed())
7766+
return std::nullopt;
7767+
return Captures;
7768+
}
7769+
7770+
void setCaptureInfo(CaptureInfo captures) {
7771+
assert(captures.hasBeenComputed());
7772+
Captures = captures;
7773+
}
77597774

77607775
/// Retrieve the Objective-C selector that names this method.
77617776
ObjCSelector getObjCSelector(DeclName preferredName = DeclName(),

include/swift/AST/Expr.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,8 +3912,21 @@ class AbstractClosureExpr : public DeclContext, public Expr {
39123912
std::tuple<CapturedValue, unsigned, ApplyIsolationCrossing>>
39133913
&foundIsolationCrossings);
39143914

3915-
CaptureInfo getCaptureInfo() const { return Captures; }
3916-
void setCaptureInfo(CaptureInfo captures) { Captures = captures; }
3915+
CaptureInfo getCaptureInfo() const {
3916+
assert(Captures.hasBeenComputed());
3917+
return Captures;
3918+
}
3919+
3920+
std::optional<CaptureInfo> getCachedCaptureInfo() const {
3921+
if (!Captures.hasBeenComputed())
3922+
return std::nullopt;
3923+
return Captures;
3924+
}
3925+
3926+
void setCaptureInfo(CaptureInfo captures) {
3927+
assert(captures.hasBeenComputed());
3928+
Captures = captures;
3929+
}
39173930

39183931
/// Retrieve the parameters of this closure.
39193932
ParameterList *getParameters() { return parameterList; }

include/swift/AST/TypeCheckRequests.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4949,6 +4949,47 @@ class LifetimeDependenceInfoRequest
49494949
public:
49504950
// Caching.
49514951
bool isCached() const { return true; }
4952+
4953+
};
4954+
4955+
class CaptureInfoRequest :
4956+
public SimpleRequest<CaptureInfoRequest,
4957+
CaptureInfo(AbstractFunctionDecl *),
4958+
RequestFlags::SeparatelyCached> {
4959+
public:
4960+
using SimpleRequest::SimpleRequest;
4961+
4962+
private:
4963+
friend SimpleRequest;
4964+
4965+
// Evaluation.
4966+
CaptureInfo evaluate(Evaluator &evaluator, AbstractFunctionDecl *func) const;
4967+
4968+
public:
4969+
// Separate caching.
4970+
bool isCached() const { return true; }
4971+
std::optional<CaptureInfo> getCachedResult() const;
4972+
void cacheResult(CaptureInfo value) const;
4973+
};
4974+
4975+
class ParamCaptureInfoRequest :
4976+
public SimpleRequest<ParamCaptureInfoRequest,
4977+
CaptureInfo(ParamDecl *),
4978+
RequestFlags::SeparatelyCached> {
4979+
public:
4980+
using SimpleRequest::SimpleRequest;
4981+
4982+
private:
4983+
friend SimpleRequest;
4984+
4985+
// Evaluation.
4986+
CaptureInfo evaluate(Evaluator &evaluator, ParamDecl *param) const;
4987+
4988+
public:
4989+
// Separate caching.
4990+
bool isCached() const { return true; }
4991+
std::optional<CaptureInfo> getCachedResult() const;
4992+
void cacheResult(CaptureInfo value) const;
49524993
};
49534994

49544995
class SuppressesConformanceRequest

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,10 @@ SWIFT_REQUEST(TypeChecker, LifetimeDependenceInfoRequest,
571571
SWIFT_REQUEST(TypeChecker, SuppressesConformanceRequest,
572572
bool(NominalTypeDecl *decl, KnownProtocolKind kp),
573573
SeparatelyCached, NoLocationInfo)
574+
575+
SWIFT_REQUEST(TypeChecker, CaptureInfoRequest,
576+
CaptureInfo(AbstractFunctionDecl *),
577+
SeparatelyCached, NoLocationInfo)
578+
SWIFT_REQUEST(TypeChecker, ParamCaptureInfoRequest,
579+
CaptureInfo(ParamDecl *),
580+
SeparatelyCached, NoLocationInfo)

lib/AST/ASTDumper.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,10 +1402,10 @@ namespace {
14021402
printField(PD->getDefaultArgumentKind(), "default_arg");
14031403
}
14041404
if (PD->hasDefaultExpr() &&
1405-
PD->getDefaultArgumentCaptureInfo().hasBeenComputed() &&
1406-
!PD->getDefaultArgumentCaptureInfo().isTrivial()) {
1405+
PD->getCachedDefaultArgumentCaptureInfo() &&
1406+
!PD->getCachedDefaultArgumentCaptureInfo()->isTrivial()) {
14071407
printFieldRaw([&](raw_ostream &OS) {
1408-
PD->getDefaultArgumentCaptureInfo().print(OS);
1408+
PD->getCachedDefaultArgumentCaptureInfo()->print(OS);
14091409
}, "", CapturesColor);
14101410
}
14111411

@@ -1489,11 +1489,12 @@ namespace {
14891489

14901490
void printCommonAFD(AbstractFunctionDecl *D, const char *Type, StringRef Label) {
14911491
printCommon(D, Type, Label, FuncColor);
1492-
if (D->getCaptureInfo().hasBeenComputed() &&
1493-
!D->getCaptureInfo().isTrivial()) {
1494-
printFlagRaw([&](raw_ostream &OS) {
1495-
D->getCaptureInfo().print(OS);
1496-
});
1492+
if (auto captureInfo = D->getCachedCaptureInfo()) {
1493+
if (!captureInfo->isTrivial()) {
1494+
printFlagRaw([&](raw_ostream &OS) {
1495+
captureInfo->print(OS);
1496+
});
1497+
}
14971498
}
14981499

14991500
if (auto *attr = D->getAttrs().getAttribute<NonisolatedAttr>()) {
@@ -2828,11 +2829,12 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
28282829
break;
28292830
}
28302831

2831-
if (E->getCaptureInfo().hasBeenComputed() &&
2832-
!E->getCaptureInfo().isTrivial()) {
2833-
printFieldRaw([&](raw_ostream &OS) {
2834-
E->getCaptureInfo().print(OS);
2835-
}, "", CapturesColor);
2832+
if (auto captureInfo = E->getCachedCaptureInfo()) {
2833+
if (!captureInfo->isTrivial()) {
2834+
printFieldRaw([&](raw_ostream &OS) {
2835+
captureInfo->print(OS);
2836+
}, "", CapturesColor);
2837+
}
28362838
}
28372839
// Printing a function type doesn't indicate whether it's escaping because it doesn't
28382840
// matter in 99% of contexts. AbstractClosureExpr nodes are one of the only exceptions.

lib/AST/Decl.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8716,8 +8716,19 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
87168716
defaultInfo->InitContextAndIsTypeChecked.setPointer(initContext);
87178717
}
87188718

8719+
CaptureInfo ParamDecl::getDefaultArgumentCaptureInfo() const {
8720+
if (!DefaultValueAndFlags.getPointer())
8721+
return CaptureInfo::empty();
8722+
8723+
auto &ctx = getASTContext();
8724+
return evaluateOrDefault(ctx.evaluator,
8725+
ParamCaptureInfoRequest{const_cast<ParamDecl *>(this)},
8726+
CaptureInfo::empty());
8727+
}
8728+
87198729
void ParamDecl::setDefaultArgumentCaptureInfo(CaptureInfo captures) {
87208730
assert(DefaultValueAndFlags.getPointer());
8731+
assert(captures.hasBeenComputed());
87218732
DefaultValueAndFlags.getPointer()->Captures = captures;
87228733
}
87238734

@@ -9170,6 +9181,13 @@ const ParamDecl *swift::getParameterAt(const DeclContext *source,
91709181
return nullptr;
91719182
}
91729183

9184+
CaptureInfo AbstractFunctionDecl::getCaptureInfo() const {
9185+
auto &ctx = getASTContext();
9186+
return evaluateOrDefault(ctx.evaluator,
9187+
CaptureInfoRequest{const_cast<AbstractFunctionDecl *>(this)},
9188+
CaptureInfo::empty());
9189+
}
9190+
91739191
Type AbstractFunctionDecl::getMethodInterfaceType() const {
91749192
assert(getDeclContext()->isTypeContext());
91759193
auto Ty = getInterfaceType();

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,6 +3468,7 @@ void SourceFile::typeCheckDelayedFunctions() {
34683468
auto *AFD = DelayedFunctions[i];
34693469
assert(!AFD->getDeclContext()->isLocalContext());
34703470
AFD->getTypecheckedBody();
3471+
(void) AFD->getCaptureInfo();
34713472
}
34723473

34733474
DelayedFunctions.clear();

lib/AST/TypeCheckRequests.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,3 +2258,25 @@ void ExpandBodyMacroRequest::noteCycleStep(DiagnosticEngine &diags) const {
22582258
"body",
22592259
decl->getName());
22602260
}
2261+
2262+
std::optional<CaptureInfo>
2263+
CaptureInfoRequest::getCachedResult() const {
2264+
auto *func = std::get<0>(getStorage());
2265+
return func->getCachedCaptureInfo();
2266+
}
2267+
2268+
void CaptureInfoRequest::cacheResult(CaptureInfo info) const {
2269+
auto *func = std::get<0>(getStorage());
2270+
return func->setCaptureInfo(info);
2271+
}
2272+
2273+
std::optional<CaptureInfo>
2274+
ParamCaptureInfoRequest::getCachedResult() const {
2275+
auto *param = std::get<0>(getStorage());
2276+
return param->getCachedDefaultArgumentCaptureInfo();
2277+
}
2278+
2279+
void ParamCaptureInfoRequest::cacheResult(CaptureInfo info) const {
2280+
auto *param = std::get<0>(getStorage());
2281+
param->setDefaultArgumentCaptureInfo(info);
2282+
}

lib/SIL/IR/TypeLowering.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4169,8 +4169,6 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
41694169
};
41704170

41714171
collectCaptures = [&](CaptureInfo captureInfo) {
4172-
assert(captureInfo.hasBeenComputed());
4173-
41744172
if (captureInfo.hasGenericParamCaptures())
41754173
capturesGenericParams = true;
41764174
if (captureInfo.hasDynamicSelfCapture())

0 commit comments

Comments
 (0)