Skip to content

Commit 0a9a640

Browse files
committed
Parse: Create a trailing where clause even if it was incomplete
Also, store the end location of the where clause explicitly, so that we can recover it even if there are no requirements. This fixes one of the failing tests when parser lookup is disabled in swift-ide-test by ensuring that the source range of the function extends to the end of the 'where' clause, even though the 'where' clause has a code completion token in it.
1 parent 1a6f86b commit 0a9a640

File tree

5 files changed

+42
-45
lines changed

5 files changed

+42
-45
lines changed

include/swift/AST/GenericParamList.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ class GenericParamList final :
324324
if (WhereLoc.isInvalid())
325325
return SourceRange();
326326

327+
if (Requirements.empty())
328+
return WhereLoc;
329+
327330
auto endLoc = Requirements.back().getSourceRange().End;
328331
return SourceRange(WhereLoc, endLoc);
329332
}
@@ -352,16 +355,18 @@ class alignas(RequirementRepr) TrailingWhereClause final :
352355
friend TrailingObjects;
353356

354357
SourceLoc WhereLoc;
358+
SourceLoc EndLoc;
355359

356360
/// The number of requirements. The actual requirements are tail-allocated.
357361
unsigned NumRequirements;
358362

359-
TrailingWhereClause(SourceLoc whereLoc,
363+
TrailingWhereClause(SourceLoc whereLoc, SourceLoc endLoc,
360364
ArrayRef<RequirementRepr> requirements);
361365

362366
public:
363367
/// Create a new trailing where clause with the given set of requirements.
364-
static TrailingWhereClause *create(ASTContext &ctx, SourceLoc whereLoc,
368+
static TrailingWhereClause *create(ASTContext &ctx,
369+
SourceLoc whereLoc, SourceLoc endLoc,
365370
ArrayRef<RequirementRepr> requirements);
366371

367372
/// Retrieve the location of the 'where' keyword.
@@ -379,8 +384,7 @@ class alignas(RequirementRepr) TrailingWhereClause final :
379384

380385
/// Compute the source range containing this trailing where clause.
381386
SourceRange getSourceRange() const {
382-
return SourceRange(WhereLoc,
383-
getRequirements().back().getSourceRange().End);
387+
return SourceRange(WhereLoc, EndLoc);
384388
}
385389

386390
void print(llvm::raw_ostream &OS, bool printWhereKeyword) const;

include/swift/Parse/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,8 +1689,9 @@ class Parser {
16891689
parseFreestandingGenericWhereClause(GenericContext *genCtx);
16901690

16911691
ParserStatus parseGenericWhereClause(
1692-
SourceLoc &WhereLoc, SmallVectorImpl<RequirementRepr> &Requirements,
1693-
bool &FirstTypeInComplete, bool AllowLayoutConstraints = false);
1692+
SourceLoc &WhereLoc, SourceLoc &EndLoc,
1693+
SmallVectorImpl<RequirementRepr> &Requirements,
1694+
bool AllowLayoutConstraints = false);
16941695

16951696
ParserStatus
16961697
parseProtocolOrAssociatedTypeWhereClause(TrailingWhereClause *&trailingWhere,

lib/AST/GenericParamList.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ GenericTypeParamDecl *GenericParamList::lookUpGenericParam(
110110
}
111111

112112
TrailingWhereClause::TrailingWhereClause(
113-
SourceLoc whereLoc,
113+
SourceLoc whereLoc, SourceLoc endLoc,
114114
ArrayRef<RequirementRepr> requirements)
115-
: WhereLoc(whereLoc),
115+
: WhereLoc(whereLoc), EndLoc(endLoc),
116116
NumRequirements(requirements.size())
117117
{
118118
std::uninitialized_copy(requirements.begin(), requirements.end(),
@@ -122,8 +122,9 @@ TrailingWhereClause::TrailingWhereClause(
122122
TrailingWhereClause *TrailingWhereClause::create(
123123
ASTContext &ctx,
124124
SourceLoc whereLoc,
125+
SourceLoc endLoc,
125126
ArrayRef<RequirementRepr> requirements) {
126127
unsigned size = totalSizeToAlloc<RequirementRepr>(requirements.size());
127128
void *mem = ctx.Allocate(size, alignof(TrailingWhereClause));
128-
return new (mem) TrailingWhereClause(whereLoc, requirements);
129+
return new (mem) TrailingWhereClause(whereLoc, endLoc, requirements);
129130
}

lib/Parse/ParseDecl.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -717,13 +717,12 @@ bool Parser::parseSpecializeAttributeArguments(
717717

718718
// Parse the where clause.
719719
if (Tok.is(tok::kw_where)) {
720-
SourceLoc whereLoc;
720+
SourceLoc whereLoc, endLoc;
721721
SmallVector<RequirementRepr, 4> requirements;
722-
bool firstTypeInComplete;
723-
parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete,
722+
parseGenericWhereClause(whereLoc, endLoc, requirements,
724723
/* AllowLayoutConstraints */ true);
725724
TrailingWhereClause =
726-
TrailingWhereClause::create(Context, whereLoc, requirements);
725+
TrailingWhereClause::create(Context, whereLoc, endLoc, requirements);
727726
}
728727
return true;
729728
}
@@ -1053,12 +1052,12 @@ bool Parser::parseDifferentiableAttributeArguments(
10531052

10541053
// Parse a trailing 'where' clause if any.
10551054
if (Tok.is(tok::kw_where)) {
1056-
SourceLoc whereLoc;
1055+
SourceLoc whereLoc, endLoc;
10571056
SmallVector<RequirementRepr, 4> requirements;
1058-
bool firstTypeInComplete;
1059-
parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete,
1057+
parseGenericWhereClause(whereLoc, endLoc, requirements,
10601058
/*AllowLayoutConstraints*/ true);
1061-
whereClause = TrailingWhereClause::create(Context, whereLoc, requirements);
1059+
whereClause =
1060+
TrailingWhereClause::create(Context, whereLoc, endLoc, requirements);
10621061
}
10631062
return false;
10641063
}
@@ -4878,19 +4877,17 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
48784877
TrailingWhereClause *trailingWhereClause = nullptr;
48794878
bool trailingWhereHadCodeCompletion = false;
48804879
if (Tok.is(tok::kw_where)) {
4881-
SourceLoc whereLoc;
4880+
SourceLoc whereLoc, endLoc;
48824881
SmallVector<RequirementRepr, 4> requirements;
4883-
bool firstTypeInComplete;
4884-
auto whereStatus = parseGenericWhereClause(whereLoc, requirements,
4885-
firstTypeInComplete);
4882+
auto whereStatus = parseGenericWhereClause(whereLoc, endLoc, requirements);
48864883
if (whereStatus.hasCodeCompletion()) {
48874884
if (isCodeCompletionFirstPass())
48884885
return whereStatus;
48894886
trailingWhereHadCodeCompletion = true;
48904887
}
48914888
if (!requirements.empty()) {
4892-
trailingWhereClause = TrailingWhereClause::create(Context, whereLoc,
4893-
requirements);
4889+
trailingWhereClause =
4890+
TrailingWhereClause::create(Context, whereLoc, endLoc, requirements);
48944891
}
48954892
status |= whereStatus;
48964893
}

lib/Parse/ParseGeneric.cpp

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ Parser::parseGenericParameters(SourceLoc LAngleLoc) {
140140

141141
// Parse the optional where-clause.
142142
SourceLoc WhereLoc;
143+
SourceLoc EndLoc;
143144
SmallVector<RequirementRepr, 4> Requirements;
144-
bool FirstTypeInComplete;
145145
if (Tok.is(tok::kw_where) &&
146-
parseGenericWhereClause(WhereLoc, Requirements,
147-
FirstTypeInComplete).isErrorOrHasCompletion()) {
146+
parseGenericWhereClause(WhereLoc, EndLoc, Requirements)
147+
.isErrorOrHasCompletion()) {
148148
Invalid = true;
149149
}
150150

@@ -261,16 +261,14 @@ Parser::diagnoseWhereClauseInGenericParamList(const GenericParamList *
261261
/// same-type-requirement:
262262
/// type-identifier '==' type
263263
ParserStatus Parser::parseGenericWhereClause(
264-
SourceLoc &WhereLoc,
264+
SourceLoc &WhereLoc, SourceLoc &EndLoc,
265265
SmallVectorImpl<RequirementRepr> &Requirements,
266-
bool &FirstTypeInComplete,
267266
bool AllowLayoutConstraints) {
268267
SyntaxParsingContext ClauseContext(SyntaxContext,
269268
SyntaxKind::GenericWhereClause);
270269
ParserStatus Status;
271270
// Parse the 'where'.
272271
WhereLoc = consumeToken(tok::kw_where);
273-
FirstTypeInComplete = false;
274272
SyntaxParsingContext ReqListContext(SyntaxContext,
275273
SyntaxKind::GenericRequirementList);
276274
bool HasNextReq;
@@ -283,7 +281,7 @@ ParserStatus Parser::parseGenericWhereClause(
283281
if (Tok.is(tok::code_complete)) {
284282
if (CodeCompletion)
285283
CodeCompletion->completeGenericRequirement();
286-
consumeToken(tok::code_complete);
284+
EndLoc = consumeToken(tok::code_complete);
287285
Status.setHasCodeCompletionAndIsError();
288286
break;
289287
}
@@ -295,7 +293,6 @@ ParserStatus Parser::parseGenericWhereClause(
295293
if (FirstType.hasCodeCompletion()) {
296294
BodyContext->setTransparent();
297295
Status.setHasCodeCompletionAndIsError();
298-
FirstTypeInComplete = true;
299296
}
300297

301298
if (FirstType.isNull()) {
@@ -383,8 +380,10 @@ ParserStatus Parser::parseGenericWhereClause(
383380
}
384381
} while (HasNextReq);
385382

386-
if (Requirements.empty())
387-
WhereLoc = SourceLoc();
383+
if (!Requirements.empty())
384+
EndLoc = Requirements.back().getSourceRange().End;
385+
else if (EndLoc.isInvalid())
386+
EndLoc = WhereLoc;
388387

389388
return Status;
390389
}
@@ -396,31 +395,26 @@ parseFreestandingGenericWhereClause(GenericContext *genCtx) {
396395
assert(Tok.is(tok::kw_where) && "Shouldn't call this without a where");
397396

398397
SmallVector<RequirementRepr, 4> Requirements;
399-
SourceLoc WhereLoc;
400-
bool FirstTypeInComplete;
401-
auto result = parseGenericWhereClause(WhereLoc, Requirements,
402-
FirstTypeInComplete);
403-
if (result.isErrorOrHasCompletion() || Requirements.empty())
404-
return result;
398+
SourceLoc WhereLoc, EndLoc;
399+
auto result = parseGenericWhereClause(WhereLoc, EndLoc, Requirements);
405400

406401
genCtx->setTrailingWhereClause(
407-
TrailingWhereClause::create(Context, WhereLoc, Requirements));
402+
TrailingWhereClause::create(Context, WhereLoc, EndLoc, Requirements));
408403

409-
return ParserStatus();
404+
return result;
410405
}
411406

412407
/// Parse a where clause after a protocol or associated type declaration.
413408
ParserStatus Parser::parseProtocolOrAssociatedTypeWhereClause(
414409
TrailingWhereClause *&trailingWhere, bool isProtocol) {
415410
assert(Tok.is(tok::kw_where) && "Shouldn't call this without a where");
416-
SourceLoc whereLoc;
411+
SourceLoc whereLoc, endLoc;
417412
SmallVector<RequirementRepr, 4> requirements;
418-
bool firstTypeInComplete;
419413
auto whereStatus =
420-
parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete);
414+
parseGenericWhereClause(whereLoc, endLoc, requirements);
421415
if (whereStatus.isSuccess() && !whereStatus.hasCodeCompletion()) {
422416
trailingWhere =
423-
TrailingWhereClause::create(Context, whereLoc, requirements);
417+
TrailingWhereClause::create(Context, whereLoc, endLoc, requirements);
424418
} else if (whereStatus.hasCodeCompletion()) {
425419
return whereStatus;
426420
}

0 commit comments

Comments
 (0)