Skip to content

Commit 1ef80b8

Browse files
authored
Merge pull request #13261 from nkcsgexi/lib-syntax-req-where
2 parents ec807a8 + ad70fb0 commit 1ef80b8

File tree

5 files changed

+22
-2
lines changed

5 files changed

+22
-2
lines changed

include/swift/Syntax/SyntaxParsingContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ enum class SyntaxContextKind {
3333
Expr,
3434
Type,
3535
Pattern,
36+
Syntax,
3637
};
3738

3839
/// Indicates what action should be performed on the destruction of

lib/Parse/ParseGeneric.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/Syntax/SyntaxNodes.h"
2323
#include "swift/Syntax/SyntaxParsingContext.h"
2424
using namespace swift;
25+
using namespace swift::syntax;
2526

2627
/// parseGenericParameters - Parse a sequence of generic parameters, e.g.,
2728
/// < T : Comparable, U : Container> along with an optional requires clause.
@@ -245,11 +246,17 @@ ParserStatus Parser::parseGenericWhereClause(
245246
SmallVectorImpl<RequirementRepr> &Requirements,
246247
bool &FirstTypeInComplete,
247248
bool AllowLayoutConstraints) {
249+
SyntaxParsingContext ClauseContext(SyntaxContext,
250+
SyntaxKind::GenericWhereClause);
248251
ParserStatus Status;
249252
// Parse the 'where'.
250253
WhereLoc = consumeToken(tok::kw_where);
251254
FirstTypeInComplete = false;
255+
SyntaxParsingContext ReqListContext(SyntaxContext,
256+
SyntaxKind::GenericRequirementList);
257+
bool HasNextReq;
252258
do {
259+
SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
253260
// Parse the leading type-identifier.
254261
auto FirstTypeResult = parseTypeIdentifier();
255262
if (FirstTypeResult.hasSyntax())
@@ -269,7 +276,7 @@ ParserStatus Parser::parseGenericWhereClause(
269276
if (Tok.is(tok::colon)) {
270277
// A conformance-requirement.
271278
SourceLoc ColonLoc = consumeToken();
272-
279+
ReqContext.setCreateSyntax(SyntaxKind::ConformanceRequirement);
273280
if (Tok.is(tok::identifier) &&
274281
getLayoutConstraint(Context.getIdentifier(Tok.getText()), Context)
275282
->isKnownLayout()) {
@@ -309,6 +316,7 @@ ParserStatus Parser::parseGenericWhereClause(
309316
}
310317
} else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
311318
Tok.is(tok::equal)) {
319+
ReqContext.setCreateSyntax(SyntaxKind::SameTypeRequirement);
312320
// A same-type-requirement
313321
if (Tok.is(tok::equal)) {
314322
diagnose(Tok, diag::requires_single_equal)
@@ -334,8 +342,9 @@ ParserStatus Parser::parseGenericWhereClause(
334342
Status.setIsParseError();
335343
break;
336344
}
345+
HasNextReq = consumeIf(tok::comma);
337346
// If there's a comma, keep parsing the list.
338-
} while (consumeIf(tok::comma));
347+
} while (HasNextReq);
339348

340349
if (Requirements.empty())
341350
WhereLoc = SourceLoc();

lib/Syntax/SyntaxParsingContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ RC<RawSyntax> bridgeAs(SyntaxContextKind Kind, ArrayRef<RC<RawSyntax>> Parts) {
158158
if (!RawNode->isPattern())
159159
return makeUnknownSyntax(SyntaxKind::UnknownPattern, Parts);
160160
break;
161+
case SyntaxContextKind::Syntax:
162+
// We don't need to coerce in this case.
163+
break;
161164
}
162165
return RawNode;
163166
} else {
@@ -178,6 +181,9 @@ RC<RawSyntax> bridgeAs(SyntaxContextKind Kind, ArrayRef<RC<RawSyntax>> Parts) {
178181
case SyntaxContextKind::Pattern:
179182
UnknownKind = SyntaxKind::UnknownPattern;
180183
break;
184+
case SyntaxContextKind::Syntax:
185+
UnknownKind = SyntaxKind::Unknown;
186+
break;
181187
}
182188
return makeUnknownSyntax(UnknownKind, Parts);
183189
}

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,5 @@ struct foo <MemberDeclBlock>{<Attribute>
8484
private </DeclModifier><DeclModifier>static </DeclModifier>func foo() <CodeBlock>{}</CodeBlock>
8585
}
8686
}</MemberDeclBlock>
87+
88+
struct S<A, B, C, D> <GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>A</SimpleTypeIdentifier>:<SimpleTypeIdentifier>B</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><SimpleTypeIdentifier>B</SimpleTypeIdentifier>==<SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>A </SimpleTypeIdentifier>: <SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>B</SimpleTypeIdentifier>.C </MemberTypeIdentifier>== <MemberTypeIdentifier><SimpleTypeIdentifier>D</SimpleTypeIdentifier>.A</MemberTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>A</SimpleTypeIdentifier>.B</MemberTypeIdentifier>: <MemberTypeIdentifier><SimpleTypeIdentifier>C</SimpleTypeIdentifier>.D </MemberTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,5 @@ struct foo {
8484
private static func foo() {}
8585
}
8686
}
87+
88+
struct S<A, B, C, D> where A:B, B==C, A : C, B.C == D.A, A.B: C.D {}

0 commit comments

Comments
 (0)