Skip to content

Commit c46eb22

Browse files
committed
AST: Don't attach trailing where clause requirements to the GenericParamList
Previously we had two representations for the 'where' clause of a parsed declaration; if the declaration had generic parameters of its own, we would store them in the GenericParamList, otherwise we would store them separately in a TrailingWhereClause instance. Since the latter is more general and also used for protocols and extensions, let's just use it for everything and simplify GenericParamList in the process.
1 parent daf65ce commit c46eb22

14 files changed

+84
-170
lines changed

include/swift/AST/Decl.h

+1-38
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,6 @@ class GenericParamList final :
11901190

11911191
GenericParamList *OuterParameters;
11921192

1193-
SourceLoc TrailingWhereLoc;
1194-
unsigned FirstTrailingWhereArg;
1195-
11961193
GenericParamList(SourceLoc LAngleLoc,
11971194
ArrayRef<GenericTypeParamDecl *> Params,
11981195
SourceLoc WhereLoc,
@@ -1272,31 +1269,6 @@ class GenericParamList final :
12721269
/// implicitly-generated requirements, and may be non-empty even if no
12731270
/// 'where' keyword is present.
12741271
ArrayRef<RequirementRepr> getRequirements() const { return Requirements; }
1275-
1276-
/// Retrieve only those requirements that are written within the brackets,
1277-
/// which does not include any requirements written in a trailing where
1278-
/// clause.
1279-
ArrayRef<RequirementRepr> getNonTrailingRequirements() const {
1280-
return Requirements.slice(0, FirstTrailingWhereArg);
1281-
}
1282-
1283-
/// Retrieve only those requirements written in a trailing where
1284-
/// clause.
1285-
ArrayRef<RequirementRepr> getTrailingRequirements() const {
1286-
return Requirements.slice(FirstTrailingWhereArg);
1287-
}
1288-
1289-
/// Determine whether the generic parameters have a trailing where clause.
1290-
bool hasTrailingWhereClause() const {
1291-
return FirstTrailingWhereArg < Requirements.size();
1292-
}
1293-
1294-
/// Add a trailing 'where' clause to the list of requirements.
1295-
///
1296-
/// Trailing where clauses are written outside the angle brackets, after the
1297-
/// main part of a declaration's signature.
1298-
void addTrailingWhereClause(ASTContext &ctx, SourceLoc trailingWhereLoc,
1299-
ArrayRef<RequirementRepr> trailingRequirements);
13001272

13011273
/// Retrieve the outer generic parameter list.
13021274
///
@@ -1321,19 +1293,10 @@ class GenericParamList final :
13211293
if (WhereLoc.isInvalid())
13221294
return SourceRange();
13231295

1324-
auto endLoc = Requirements[FirstTrailingWhereArg-1].getSourceRange().End;
1296+
auto endLoc = Requirements.back().getSourceRange().End;
13251297
return SourceRange(WhereLoc, endLoc);
13261298
}
13271299

1328-
/// Retrieve the source range covering the trailing where clause.
1329-
SourceRange getTrailingWhereClauseSourceRange() const {
1330-
if (!hasTrailingWhereClause())
1331-
return SourceRange();
1332-
1333-
return SourceRange(TrailingWhereLoc,
1334-
Requirements.back().getSourceRange().End);
1335-
}
1336-
13371300
/// Configure the depth of the generic parameters in this list.
13381301
void setDepth(unsigned depth);
13391302

include/swift/AST/TypeCheckRequests.h

+3
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ struct WhereClauseOwner {
396396
WhereClauseOwner(DeclContext *dc, GenericParamList *genericParams)
397397
: dc(dc), source(genericParams) {}
398398

399+
WhereClauseOwner(DeclContext *dc, TrailingWhereClause *where)
400+
: dc(dc), source(where) {}
401+
399402
WhereClauseOwner(DeclContext *dc, SpecializeAttr *attr)
400403
: dc(dc), source(attr) {}
401404

include/swift/Parse/Parser.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -1647,9 +1647,7 @@ class Parser {
16471647
diagnoseWhereClauseInGenericParamList(const GenericParamList *GenericParams);
16481648

16491649
ParserStatus
1650-
parseFreestandingGenericWhereClause(GenericContext *genCtx,
1651-
GenericParamList *&GPList,
1652-
ParseDeclOptions flags);
1650+
parseFreestandingGenericWhereClause(GenericContext *genCtx);
16531651

16541652
ParserStatus parseGenericWhereClause(
16551653
SourceLoc &WhereLoc, SmallVectorImpl<RequirementRepr> &Requirements,

lib/AST/ASTDumper.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,7 @@ namespace {
561561
};
562562

563563
if (const auto GC = Owner.dyn_cast<const GenericContext *>()) {
564-
if (GC->getParsedGenericParams() == nullptr)
565-
printWhere(GC->getTrailingWhereClause());
564+
printWhere(GC->getTrailingWhereClause());
566565
} else {
567566
const auto ATD = Owner.get<const AssociatedTypeDecl *>();
568567
printWhere(ATD->getTrailingWhereClause());

lib/AST/ASTWalker.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
142142
for (auto &Req: Where->getRequirements())
143143
if (doIt(Req))
144144
return true;
145-
} else if (const auto GP = GC->getParsedGenericParams()) {
146-
for (auto Req: GP->getTrailingRequirements())
147-
if (doIt(Req))
148-
return true;
149145
}
150146
return false;
151147
}
@@ -445,7 +441,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
445441
}
446442

447443
// Visit param conformance
448-
for (auto Req : GPL->getNonTrailingRequirements()) {
444+
for (auto Req : GPL->getRequirements()) {
449445
if (doIt(Req))
450446
return true;
451447
}

lib/AST/Decl.cpp

+2-26
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,7 @@ GenericParamList::GenericParamList(SourceLoc LAngleLoc,
888888
SourceLoc RAngleLoc)
889889
: Brackets(LAngleLoc, RAngleLoc), NumParams(Params.size()),
890890
WhereLoc(WhereLoc), Requirements(Requirements),
891-
OuterParameters(nullptr),
892-
FirstTrailingWhereArg(Requirements.size())
891+
OuterParameters(nullptr)
893892
{
894893
std::uninitialized_copy(Params.begin(), Params.end(),
895894
getTrailingObjects<GenericTypeParamDecl *>());
@@ -938,27 +937,6 @@ GenericParamList::clone(DeclContext *dc) const {
938937
return GenericParamList::create(ctx, SourceLoc(), params, SourceLoc());
939938
}
940939

941-
void GenericParamList::addTrailingWhereClause(
942-
ASTContext &ctx,
943-
SourceLoc trailingWhereLoc,
944-
ArrayRef<RequirementRepr> trailingRequirements) {
945-
assert(TrailingWhereLoc.isInvalid() &&
946-
"Already have a trailing where clause?");
947-
TrailingWhereLoc = trailingWhereLoc;
948-
FirstTrailingWhereArg = Requirements.size();
949-
950-
// Create a unified set of requirements.
951-
auto newRequirements = ctx.AllocateUninitialized<RequirementRepr>(
952-
Requirements.size() + trailingRequirements.size());
953-
std::memcpy(newRequirements.data(), Requirements.data(),
954-
Requirements.size() * sizeof(RequirementRepr));
955-
std::memcpy(newRequirements.data() + Requirements.size(),
956-
trailingRequirements.data(),
957-
trailingRequirements.size() * sizeof(RequirementRepr));
958-
959-
Requirements = newRequirements;
960-
}
961-
962940
void GenericParamList::setDepth(unsigned depth) {
963941
for (auto param : *this)
964942
param->setDepth(depth);
@@ -1054,9 +1032,7 @@ void GenericContext::setGenericSignature(GenericSignature genericSig) {
10541032
}
10551033

10561034
SourceRange GenericContext::getGenericTrailingWhereClauseSourceRange() const {
1057-
if (auto *params = getParsedGenericParams())
1058-
return params->getTrailingWhereClauseSourceRange();
1059-
else if (const auto *where = getTrailingWhereClause())
1035+
if (const auto *where = getTrailingWhereClause())
10601036
return where->getSourceRange();
10611037

10621038
return SourceRange();

lib/AST/GenericSignatureBuilder.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -7591,17 +7591,17 @@ InferredGenericSignatureRequest::evaluate(
75917591
.visitRequirements(TypeResolutionStage::Structural,
75927592
visitRequirement);
75937593
}
7594-
} else {
7595-
// The declaration has a where clause, but no generic parameters of its own.
7596-
const auto ctx = paramSource.get<GenericContext *>();
7597-
7598-
assert(ctx->getTrailingWhereClause() && "No params or where clause");
7594+
}
75997595

7600-
// Determine where and how to perform name lookup.
7601-
lookupDC = ctx;
7596+
if (auto *ctx = paramSource.dyn_cast<GenericContext *>()) {
7597+
// The declaration might have a trailing where clause.
7598+
if (auto *where = ctx->getTrailingWhereClause()) {
7599+
// Determine where and how to perform name lookup.
7600+
lookupDC = ctx;
76027601

7603-
WhereClauseOwner(ctx).visitRequirements(
7604-
TypeResolutionStage::Structural, visitRequirement);
7602+
WhereClauseOwner(lookupDC, where).visitRequirements(
7603+
TypeResolutionStage::Structural, visitRequirement);
7604+
}
76057605
}
76067606

76077607
/// Perform any remaining requirement inference.

lib/AST/NameLookup.cpp

+16-30
Original file line numberDiff line numberDiff line change
@@ -898,21 +898,24 @@ TypeDeclsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
898898
auto decls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext);
899899
result.insert(result.end(), decls.begin(), decls.end());
900900
};
901-
for (const auto &req : ext->getGenericParams()->getTrailingRequirements()) {
902-
switch (req.getKind()) {
903-
case RequirementReprKind::TypeConstraint:
904-
resolve(req.getSubjectRepr());
905-
resolve(req.getConstraintRepr());
906-
break;
907901

908-
case RequirementReprKind::SameType:
909-
resolve(req.getFirstTypeRepr());
910-
resolve(req.getSecondTypeRepr());
911-
break;
902+
if (auto *whereClause = ext->getTrailingWhereClause()) {
903+
for (const auto &req : whereClause->getRequirements()) {
904+
switch (req.getKind()) {
905+
case RequirementReprKind::TypeConstraint:
906+
resolve(req.getSubjectRepr());
907+
resolve(req.getConstraintRepr());
908+
break;
912909

913-
case RequirementReprKind::LayoutConstraint:
914-
resolve(req.getSubjectRepr());
915-
break;
910+
case RequirementReprKind::SameType:
911+
resolve(req.getFirstTypeRepr());
912+
resolve(req.getSecondTypeRepr());
913+
break;
914+
915+
case RequirementReprKind::LayoutConstraint:
916+
resolve(req.getSubjectRepr());
917+
break;
918+
}
916919
}
917920
}
918921

@@ -2333,23 +2336,6 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
23332336
outerParams = outerParams->getOuterParameters())
23342337
outerParams->setDepth(depth--);
23352338

2336-
// If we have a trailing where clause, deal with it now.
2337-
// For now, trailing where clauses are only permitted on protocol extensions.
2338-
if (auto trailingWhereClause = ext->getTrailingWhereClause()) {
2339-
if (genericParams) {
2340-
// Merge the trailing where clause into the generic parameter list.
2341-
// FIXME: Long-term, we'd like clients to deal with the trailing where
2342-
// clause explicitly, but for now it's far more direct to represent
2343-
// the trailing where clause as part of the requirements.
2344-
genericParams->addTrailingWhereClause(
2345-
ext->getASTContext(),
2346-
trailingWhereClause->getWhereLoc(),
2347-
trailingWhereClause->getRequirements());
2348-
}
2349-
2350-
// If there's no generic parameter list, the where clause is diagnosed
2351-
// in typeCheckDecl().
2352-
}
23532339
return genericParams;
23542340
} else if (auto *proto = dyn_cast<ProtocolDecl>(value)) {
23552341
// The generic parameter 'Self'.

lib/IDE/Formatting.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,8 @@ class FormatWalker : public ASTWalker {
15851585
return Ctx;
15861586
if (auto Ctx = getIndentContextFrom(AFD->getParsedGenericParams(), ContextLoc, D))
15871587
return Ctx;
1588+
if (auto Ctx = getIndentContextFrom(AFD->getTrailingWhereClause(), ContextLoc, D))
1589+
return Ctx;
15881590

15891591
if (TrailingTarget)
15901592
return None;
@@ -1658,6 +1660,8 @@ class FormatWalker : public ASTWalker {
16581660
return Ctx;
16591661
if (auto Ctx = getIndentContextFrom(SD->getParsedGenericParams(), ContextLoc, D))
16601662
return Ctx;
1663+
if (auto Ctx = getIndentContextFrom(SD->getTrailingWhereClause(), ContextLoc, D))
1664+
return Ctx;
16611665

16621666
if (TrailingTarget)
16631667
return None;
@@ -1756,6 +1760,10 @@ class FormatWalker : public ASTWalker {
17561760
D)) {
17571761
return Ctx;
17581762
}
1763+
if (auto Ctx = getIndentContextFrom(TAD->getTrailingWhereClause(), ContextLoc,
1764+
D)) {
1765+
return Ctx;
1766+
}
17591767

17601768
return IndentContext {ContextLoc, !OutdentChecker::hasOutdent(SM, D)};
17611769
}
@@ -1874,11 +1882,6 @@ class FormatWalker : public ASTWalker {
18741882
return Ctx;
18751883
}
18761884

1877-
SourceRange TrailingRange = GP->getTrailingWhereClauseSourceRange();
1878-
if (auto Ctx = getIndentContextFromWhereClause(GP->getRequirements(),
1879-
TrailingRange, ContextLoc,
1880-
WalkableParent))
1881-
return Ctx;
18821885
return None;
18831886
}
18841887

lib/Parse/ParseDecl.cpp

+14-18
Original file line numberDiff line numberDiff line change
@@ -5052,10 +5052,10 @@ parseDeclTypeAlias(Parser::ParseDeclOptions Flags, DeclAttributes &Attributes) {
50525052
TAD->setUnderlyingTypeRepr(UnderlyingTy.getPtrOrNull());
50535053
TAD->getAttrs() = Attributes;
50545054

5055-
// Parse a 'where' clause if present, adding it to our GenericParamList.
5055+
// Parse a 'where' clause if present.
50565056
if (Tok.is(tok::kw_where)) {
50575057
ContextChange CC(*this, TAD);
5058-
Status |= parseFreestandingGenericWhereClause(TAD, genericParams, Flags);
5058+
Status |= parseFreestandingGenericWhereClause(TAD);
50595059
}
50605060

50615061
if (UnderlyingTy.isNull()) {
@@ -6393,11 +6393,11 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
63936393
}
63946394
}
63956395

6396-
// Parse a 'where' clause if present, adding it to our GenericParamList.
6396+
// Parse a 'where' clause if present.
63976397
if (Tok.is(tok::kw_where)) {
63986398
ContextChange CC(*this, FD);
63996399

6400-
Status |= parseFreestandingGenericWhereClause(FD, GenericParams, Flags);
6400+
Status |= parseFreestandingGenericWhereClause(FD);
64016401
if (Status.hasCodeCompletion() && !CodeCompletion) {
64026402
// Trigger delayed parsing, no need to continue.
64036403
return Status;
@@ -6650,10 +6650,9 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
66506650

66516651
diagnoseWhereClauseInGenericParamList(GenericParams);
66526652

6653-
// Parse a 'where' clause if present, adding it to our GenericParamList.
6653+
// Parse a 'where' clause if present.
66546654
if (Tok.is(tok::kw_where)) {
6655-
auto whereStatus =
6656-
parseFreestandingGenericWhereClause(ED, GenericParams, Flags);
6655+
auto whereStatus = parseFreestandingGenericWhereClause(ED);
66576656
if (whereStatus.hasCodeCompletion() && !CodeCompletion) {
66586657
// Trigger delayed parsing, no need to continue.
66596658
return whereStatus;
@@ -6931,10 +6930,9 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
69316930

69326931
diagnoseWhereClauseInGenericParamList(GenericParams);
69336932

6934-
// Parse a 'where' clause if present, adding it to our GenericParamList.
6933+
// Parse a 'where' clause if present.
69356934
if (Tok.is(tok::kw_where)) {
6936-
auto whereStatus =
6937-
parseFreestandingGenericWhereClause(SD, GenericParams, Flags);
6935+
auto whereStatus = parseFreestandingGenericWhereClause(SD);
69386936
if (whereStatus.hasCodeCompletion() && !CodeCompletion) {
69396937
// Trigger delayed parsing, no need to continue.
69406938
return whereStatus;
@@ -7044,10 +7042,9 @@ ParserResult<ClassDecl> Parser::parseDeclClass(ParseDeclOptions Flags,
70447042

70457043
diagnoseWhereClauseInGenericParamList(GenericParams);
70467044

7047-
// Parse a 'where' clause if present, adding it to our GenericParamList.
7045+
// Parse a 'where' clause if present.
70487046
if (Tok.is(tok::kw_where)) {
7049-
auto whereStatus =
7050-
parseFreestandingGenericWhereClause(CD, GenericParams, Flags);
7047+
auto whereStatus = parseFreestandingGenericWhereClause(CD);
70517048
if (whereStatus.hasCodeCompletion() && !CodeCompletion) {
70527049
// Trigger delayed parsing, no need to continue.
70537050
return whereStatus;
@@ -7287,12 +7284,11 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
72877284

72887285
DefaultArgs.setFunctionContext(Subscript, Subscript->getIndices());
72897286

7290-
// Parse a 'where' clause if present, adding it to our GenericParamList.
7287+
// Parse a 'where' clause if present.
72917288
if (Tok.is(tok::kw_where)) {
72927289
ContextChange CC(*this, Subscript);
72937290

7294-
Status |= parseFreestandingGenericWhereClause(Subscript, GenericParams,
7295-
Flags);
7291+
Status |= parseFreestandingGenericWhereClause(Subscript);
72967292
if (Status.hasCodeCompletion() && !CodeCompletion) {
72977293
// Trigger delayed parsing, no need to continue.
72987294
return Status;
@@ -7430,11 +7426,11 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
74307426
CD->setImplicitlyUnwrappedOptional(IUO);
74317427
CD->getAttrs() = Attributes;
74327428

7433-
// Parse a 'where' clause if present, adding it to our GenericParamList.
7429+
// Parse a 'where' clause if present.
74347430
if (Tok.is(tok::kw_where)) {
74357431
ContextChange(*this, CD);
74367432

7437-
Status |= parseFreestandingGenericWhereClause(CD, GenericParams, Flags);
7433+
Status |= parseFreestandingGenericWhereClause(CD);
74387434
if (Status.hasCodeCompletion() && !CodeCompletion) {
74397435
// Trigger delayed parsing, no need to continue.
74407436
return Status;

0 commit comments

Comments
 (0)