Skip to content

Commit e159040

Browse files
authored
Merge pull request #62705 from DougGregor/closure-discriminators-request
2 parents 3693029 + c951497 commit e159040

15 files changed

+231
-80
lines changed

include/swift/AST/Expr.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3791,11 +3791,11 @@ class AbstractClosureExpr : public DeclContext, public Expr {
37913791

37923792
public:
37933793
AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit,
3794-
unsigned Discriminator, DeclContext *Parent)
3794+
DeclContext *Parent)
37953795
: DeclContext(DeclContextKind::AbstractClosureExpr, Parent),
37963796
Expr(Kind, Implicit, FnType),
37973797
parameterList(nullptr) {
3798-
Bits.AbstractClosureExpr.Discriminator = Discriminator;
3798+
Bits.AbstractClosureExpr.Discriminator = InvalidDiscriminator;
37993799
}
38003800

38013801
CaptureInfo getCaptureInfo() const { return Captures; }
@@ -3824,11 +3824,18 @@ class AbstractClosureExpr : public DeclContext, public Expr {
38243824
/// optimization and therefore make it into e.g. stack traces.
38253825
/// Having their symbol names be stable across minor code changes is
38263826
/// therefore pretty useful for debugging.)
3827-
unsigned getDiscriminator() const {
3827+
unsigned getDiscriminator() const;
3828+
3829+
/// Retrieve the raw discriminator, which may not have been computed yet.
3830+
///
3831+
/// Only use this for queries that are checking for (e.g.) reentrancy or
3832+
/// intentionally do not want to initiate verification.
3833+
unsigned getRawDiscriminator() const {
38283834
return Bits.AbstractClosureExpr.Discriminator;
38293835
}
3836+
38303837
void setDiscriminator(unsigned discriminator) {
3831-
assert(getDiscriminator() == InvalidDiscriminator);
3838+
assert(getRawDiscriminator() == InvalidDiscriminator);
38323839
assert(discriminator != InvalidDiscriminator);
38333840
Bits.AbstractClosureExpr.Discriminator = discriminator;
38343841
}
@@ -3987,9 +3994,9 @@ class ClosureExpr : public AbstractClosureExpr {
39873994
SourceRange bracketRange, VarDecl *capturedSelfDecl,
39883995
ParameterList *params, SourceLoc asyncLoc, SourceLoc throwsLoc,
39893996
SourceLoc arrowLoc, SourceLoc inLoc, TypeExpr *explicitResultType,
3990-
unsigned discriminator, DeclContext *parent)
3997+
DeclContext *parent)
39913998
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
3992-
discriminator, parent),
3999+
parent),
39934000
Attributes(attributes), BracketRange(bracketRange),
39944001
CapturedSelfDecl(capturedSelfDecl),
39954002
AsyncLoc(asyncLoc), ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc),
@@ -4185,10 +4192,9 @@ class AutoClosureExpr : public AbstractClosureExpr {
41854192
AsyncLet = 3,
41864193
};
41874194

4188-
AutoClosureExpr(Expr *Body, Type ResultTy, unsigned Discriminator,
4189-
DeclContext *Parent)
4195+
AutoClosureExpr(Expr *Body, Type ResultTy, DeclContext *Parent)
41904196
: AbstractClosureExpr(ExprKind::AutoClosure, ResultTy, /*Implicit=*/true,
4191-
Discriminator, Parent) {
4197+
Parent) {
41924198
if (Body != nullptr)
41934199
setBody(Body);
41944200

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,6 +3792,26 @@ class MacroDefinitionRequest
37923792
bool isCached() const { return true; }
37933793
};
37943794

3795+
/// Compute the local discriminators for the given declaration context.
3796+
///
3797+
/// This is a state-changing operation for closures within the context, which
3798+
/// produces the number of assigned discriminators.
3799+
class LocalDiscriminatorsRequest
3800+
: public SimpleRequest<LocalDiscriminatorsRequest,
3801+
unsigned(DeclContext *),
3802+
RequestFlags::Cached> {
3803+
public:
3804+
using SimpleRequest::SimpleRequest;
3805+
3806+
private:
3807+
friend SimpleRequest;
3808+
3809+
unsigned evaluate(Evaluator &evaluator, DeclContext *dc) const;
3810+
3811+
public:
3812+
bool isCached() const { return true; }
3813+
};
3814+
37953815
void simple_display(llvm::raw_ostream &out, ASTNode node);
37963816
void simple_display(llvm::raw_ostream &out, Type value);
37973817
void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,6 @@ SWIFT_REQUEST(TypeChecker, UsesTypeWrapperFeature,
449449
SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
450450
MacroDefinition(MacroDecl *),
451451
Cached, NoLocationInfo)
452+
SWIFT_REQUEST(TypeChecker, LocalDiscriminatorsRequest,
453+
unsigned(DeclContext *),
454+
Cached, NoLocationInfo)

include/swift/Parse/LocalContext.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ class LocalContext {
3131
/// various identifiers.
3232
llvm::DenseMap<Identifier, unsigned> LocalDiscriminators;
3333

34-
/// The next discriminator for an explicit closure expression.
35-
unsigned NextClosureDiscriminator = 0;
36-
3734
LocalContext(const LocalContext &) = delete;
3835
LocalContext &operator=(const LocalContext &) = delete;
3936

@@ -48,22 +45,6 @@ class LocalContext {
4845
"maybe the name hasn't been set yet?");
4946
return LocalDiscriminators[name]++;
5047
}
51-
52-
/// Return a number that'll be unique in this context across all
53-
/// explicit anonymous closure expressions.
54-
unsigned claimNextClosureDiscriminator() {
55-
return NextClosureDiscriminator++;
56-
}
57-
58-
/// True if we saw any anonymous closures. This is useful when
59-
/// parsing an initializer context, because such contexts only
60-
/// need to exist if the initializer contains closures.
61-
bool hasClosures() const { return NextClosureDiscriminator != 0; }
62-
63-
/// Override the next closure discriminator value.
64-
void overrideNextClosureDiscriminator(unsigned discriminator) {
65-
NextClosureDiscriminator = discriminator;
66-
}
6748
};
6849

6950
/// Information associated with parsing the top-level context.

lib/AST/ASTDumper.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,13 @@ void swift::printContext(raw_ostream &os, DeclContext *dc) {
13881388
PrintWithColorRAII(os, DiscriminatorColor)
13891389
<< "autoclosure discriminator=";
13901390
}
1391-
PrintWithColorRAII(os, DiscriminatorColor) << ACE->getDiscriminator();
1391+
1392+
// If we aren't printing to standard error or the debugger output stream,
1393+
// this client expects to see the computed discriminator. Compute it now.
1394+
if (&os != &llvm::errs() && &os != &llvm::dbgs())
1395+
(void)ACE->getDiscriminator();
1396+
1397+
PrintWithColorRAII(os, DiscriminatorColor) << ACE->getRawDiscriminator();
13921398
break;
13931399
}
13941400

@@ -2554,8 +2560,14 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25542560

25552561
llvm::raw_ostream &printClosure(AbstractClosureExpr *E, char const *name) {
25562562
printCommon(E, name);
2563+
2564+
// If we aren't printing to standard error or the debugger output stream,
2565+
// this client expects to see the computed discriminator. Compute it now.
2566+
if (&OS != &llvm::errs() && &OS != &llvm::dbgs())
2567+
(void)E->getDiscriminator();
2568+
25572569
PrintWithColorRAII(OS, DiscriminatorColor)
2558-
<< " discriminator=" << E->getDiscriminator();
2570+
<< " discriminator=" << E->getRawDiscriminator();
25592571

25602572
switch (auto isolation = E->getActorIsolation()) {
25612573
case ClosureActorIsolation::Independent:

lib/AST/CASTBridging.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ void *ClosureExpr_create(void *ctx, void *body, void *dc) {
385385

386386
auto *out = new (Context)
387387
ClosureExpr(attributes, bracketRange, nullptr, nullptr, asyncLoc,
388-
throwsLoc, arrowLoc, inLoc, nullptr, 0, (DeclContext *)dc);
388+
throwsLoc, arrowLoc, inLoc, nullptr, (DeclContext *)dc);
389389
out->setBody((BraceStmt *)body, true);
390390
out->setParameterList(params);
391391
return (Expr *)out;

lib/AST/Expr.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,27 @@ ActorIsolation ClosureActorIsolation::getActorIsolation() const {
18571857
}
18581858
}
18591859

1860+
unsigned AbstractClosureExpr::getDiscriminator() const {
1861+
auto raw = getRawDiscriminator();
1862+
if (raw != InvalidDiscriminator)
1863+
return raw;
1864+
1865+
evaluateOrDefault(
1866+
getASTContext().evaluator, LocalDiscriminatorsRequest{getParent()}, 0);
1867+
1868+
// Ill-formed code might not be able to assign discriminators, so assign
1869+
// a new one now.
1870+
if (getRawDiscriminator() == InvalidDiscriminator &&
1871+
getASTContext().Diags.hadAnyError()) {
1872+
const_cast<AbstractClosureExpr *>(this)->
1873+
Bits.AbstractClosureExpr.Discriminator =
1874+
getASTContext().NextAutoClosureDiscriminator++;
1875+
}
1876+
1877+
assert(getRawDiscriminator() != InvalidDiscriminator);
1878+
return getRawDiscriminator();
1879+
}
1880+
18601881
void AbstractClosureExpr::setParameterList(ParameterList *P) {
18611882
parameterList = P;
18621883
// Change the DeclContext of any parameters to be this closure.

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,12 +2789,10 @@ ParserResult<Expr> Parser::parseExprClosure() {
27892789
return makeParserError();
27902790
}
27912791

2792-
unsigned discriminator = CurLocalContext->claimNextClosureDiscriminator();
2793-
27942792
// Create the closure expression and enter its context.
27952793
auto *closure = new (Context) ClosureExpr(
27962794
attributes, bracketRange, capturedSelfDecl, params, asyncLoc, throwsLoc,
2797-
arrowLoc, inLoc, explicitResultType, discriminator, CurDeclContext);
2795+
arrowLoc, inLoc, explicitResultType, CurDeclContext);
27982796
ParseFunctionBody cc(*this, closure);
27992797

28002798
// Handle parameters.

lib/Parse/Parser.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,6 @@ bool IDEInspectionSecondPassRequest::evaluate(
119119
// Decrement the closure discriminator index by one so a top-level closure
120120
// gets the same discriminator as before when being re-parsed in the second
121121
// pass.
122-
parserState->getTopLevelContext().overrideNextClosureDiscriminator(
123-
parserState->getTopLevelContext().claimNextClosureDiscriminator() - 1);
124122
auto state = parserState->takeIDEInspectionDelayedDeclState();
125123
auto &Ctx = SF->getASTContext();
126124

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,8 +1187,7 @@ namespace {
11871187
}
11881188

11891189
auto *const thunk =
1190-
new (ctx) AutoClosureExpr(/*set body later*/ nullptr, thunkTy,
1191-
AutoClosureExpr::InvalidDiscriminator, dc);
1190+
new (ctx) AutoClosureExpr(/*set body later*/ nullptr, thunkTy, dc);
11921191
thunk->setParameterList(thunkParamList);
11931192
thunk->setThunkKind(AutoClosureExpr::Kind::SingleCurryThunk);
11941193
cs.cacheType(thunk);
@@ -1427,8 +1426,7 @@ namespace {
14271426

14281427
// Finally, construct the outer thunk.
14291428
auto *outerThunk =
1430-
new (ctx) AutoClosureExpr(outerThunkBody, outerThunkTy,
1431-
AutoClosureExpr::InvalidDiscriminator, dc);
1429+
new (ctx) AutoClosureExpr(outerThunkBody, outerThunkTy, dc);
14321430
outerThunk->setThunkKind(AutoClosureExpr::Kind::DoubleCurryThunk);
14331431
outerThunk->setParameterList(
14341432
ParameterList::create(ctx, SourceLoc(), selfParamDecl, SourceLoc()));
@@ -5153,14 +5151,12 @@ namespace {
51535151
// return "{ [$kp$ = \(E)] in $0[keyPath: $kp$] }"
51545152

51555153
auto &ctx = cs.getASTContext();
5156-
auto discriminator = AutoClosureExpr::InvalidDiscriminator;
51575154

51585155
FunctionType::ExtInfo closureInfo;
51595156
auto closureTy =
51605157
FunctionType::get({FunctionType::Param(baseTy)}, leafTy, closureInfo);
51615158
auto closure = new (ctx)
5162-
AutoClosureExpr(/*set body later*/nullptr, leafTy,
5163-
discriminator, dc);
5159+
AutoClosureExpr(/*set body later*/nullptr, leafTy, dc);
51645160

51655161
auto param = new (ctx) ParamDecl(
51665162
SourceLoc(),

0 commit comments

Comments
 (0)