Skip to content

Commit fb0b3fa

Browse files
authored
Merge pull request #77149 from Azoy/swift-syntax-integer-types
[ASTGen/Parse] Implement ASTGen changes for integer generics from Swift Syntax and restrict parsing integer types in certain contexts
2 parents 058c14c + 13406e3 commit fb0b3fa

File tree

23 files changed

+262
-53
lines changed

23 files changed

+262
-53
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,6 +1938,12 @@ BridgedVarargTypeRepr_createParsed(BridgedASTContext cContext,
19381938
BridgedTypeRepr base,
19391939
BridgedSourceLoc cEllipsisLoc);
19401940

1941+
SWIFT_NAME(
1942+
"BridgedIntegerTypeRepr.createParsed(_:string:loc:minusLoc:)")
1943+
BridgedIntegerTypeRepr BridgedIntegerTypeRepr_createParsed(
1944+
BridgedASTContext cContext, BridgedStringRef cString, BridgedSourceLoc cLoc,
1945+
BridgedSourceLoc cMinusLoc);
1946+
19411947
SWIFT_NAME("BridgedTypeRepr.dump(self:)")
19421948
void BridgedTypeRepr_dump(BridgedTypeRepr type);
19431949

include/swift/Parse/Parser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,11 @@ class Parser {
14111411
ParserResult<TypeRepr> parseTypeSimple(
14121412
Diag<> MessageID, ParseTypeReason reason);
14131413

1414+
ParserResult<TypeRepr> parseTypeOrValue();
1415+
ParserResult<TypeRepr> parseTypeOrValue(Diag<> MessageID,
1416+
ParseTypeReason reason = ParseTypeReason::Unspecified,
1417+
bool fromASTGen = false);
1418+
14141419
/// Parse layout constraint.
14151420
LayoutConstraint parseLayoutConstraint(Identifier LayoutConstraintID);
14161421

lib/AST/Bridging/TypeReprBridging.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,13 @@ BridgedExistentialTypeRepr_createParsed(BridgedASTContext cContext,
298298
return new (context)
299299
ExistentialTypeRepr(cAnyLoc.unbridged(), baseTy.unbridged());
300300
}
301+
302+
BridgedIntegerTypeRepr
303+
BridgedIntegerTypeRepr_createParsed(BridgedASTContext cContext,
304+
BridgedStringRef cString,
305+
BridgedSourceLoc cLoc,
306+
BridgedSourceLoc cMinusLoc) {
307+
ASTContext &context = cContext.unbridged();
308+
return new (context) IntegerTypeRepr(cString.unbridged(), cLoc.unbridged(),
309+
cMinusLoc.unbridged());
310+
}

lib/ASTGen/Sources/ASTGen/Exprs.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ extension ASTGenVisitor {
659659
if let generics = node.genericArgumentClause {
660660
leftAngleLoc = self.generateSourceLoc(generics.leftAngle)
661661
genericArgs = generics.arguments.map {
662-
self.generate(type: $0.argument)
662+
self.generate(genericArgument: $0.argument)
663663
}
664664
rightAngleLoc = self.generateSourceLoc(generics.rightAngle)
665665
} else {
@@ -760,7 +760,7 @@ extension ASTGenVisitor {
760760
let generics = node.genericArgumentClause
761761
let lAngleLoc = self.generateSourceLoc(generics.leftAngle)
762762
let genericArguments = generics.arguments.lazy.map {
763-
self.generate(type: $0.argument)
763+
self.generate(genericArgument: $0.argument)
764764
}
765765
let rAngleLoc = self.generateSourceLoc(generics.rightAngle)
766766
return .createParsed(

lib/ASTGen/Sources/ASTGen/Generics.swift

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import ASTBridging
14+
15+
@_spi(ExperimentalLanguageFeatures)
16+
@_spi(RawSyntax)
1417
import SwiftSyntax
1518

1619
extension ASTGenVisitor {
@@ -72,8 +75,8 @@ extension ASTGenVisitor {
7275
return BridgedRequirementRepr(
7376
SeparatorLoc: self.generateSourceLoc(sameType.equal),
7477
Kind: .sameType,
75-
FirstType: self.generate(type: sameType.leftType),
76-
SecondType: self.generate(type: sameType.rightType)
78+
FirstType: self.generate(sameTypeLeftType: sameType.leftType),
79+
SecondType: self.generate(sameTypeRightType: sameType.rightType)
7780
)
7881
case .layoutRequirement(_):
7982
// FIXME: Implement layout requirement translation.
@@ -87,4 +90,71 @@ extension ASTGenVisitor {
8790
requirements: requirements.bridgedArray(in: self)
8891
)
8992
}
93+
94+
func generate(sameTypeLeftType node: SameTypeRequirementSyntax.LeftType) -> BridgedTypeRepr {
95+
switch node {
96+
case .type(let type):
97+
return self.generate(type: type)
98+
99+
case .expr(let expr):
100+
return self.generateIntegerType(expr: expr).asTypeRepr
101+
}
102+
}
103+
104+
func generate(sameTypeRightType node: SameTypeRequirementSyntax.RightType) -> BridgedTypeRepr {
105+
switch node {
106+
case .type(let type):
107+
return self.generate(type: type)
108+
109+
case .expr(let expr):
110+
return self.generateIntegerType(expr: expr).asTypeRepr
111+
}
112+
}
113+
114+
func generate(genericArgument node: GenericArgumentSyntax.Argument) -> BridgedTypeRepr {
115+
switch node {
116+
case .type(let type):
117+
return self.generate(type: type)
118+
119+
case .expr(let expr):
120+
return self.generateIntegerType(expr: expr).asTypeRepr
121+
}
122+
}
123+
124+
func generateIntegerType(expr node: ExprSyntax) -> BridgedIntegerTypeRepr {
125+
var minusLoc = BridgedSourceLoc()
126+
let literalExpr: IntegerLiteralExprSyntax
127+
128+
// The only expressions generic argument types support right now are
129+
// integer literals, '123', and prefix operators for negative integer
130+
// literals, '-123'.
131+
switch node.as(ExprSyntaxEnum.self) {
132+
case .integerLiteralExpr(let node):
133+
literalExpr = node
134+
135+
case .prefixOperatorExpr(let node):
136+
let op = node.operator
137+
138+
guard op.text == "-" else {
139+
fatalError("Unknown prefix operator for generic argument type")
140+
}
141+
142+
guard let node = node.expression.as(IntegerLiteralExprSyntax.self) else {
143+
fatalError("Unknown expression kind for generic argument type")
144+
}
145+
146+
minusLoc = self.generateSourceLoc(op)
147+
literalExpr = node
148+
149+
default:
150+
fatalError("Unknown expression kind for generic argument type")
151+
}
152+
153+
return .createParsed(
154+
self.ctx,
155+
string: self.copyAndStripUnderscores(text: literalExpr.literal.rawText),
156+
loc: self.generateSourceLoc(literalExpr),
157+
minusLoc: minusLoc
158+
)
159+
}
90160
}

lib/ASTGen/Sources/ASTGen/SourceFile.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ extension Parser.ExperimentalFeatures {
7575
mapFeature(.NonescapableTypes, to: .nonescapableTypes)
7676
mapFeature(.TrailingComma, to: .trailingComma)
7777
mapFeature(.CoroutineAccessors, to: .coroutineAccessors)
78+
mapFeature(.ValueGenerics, to: .valueGenerics)
7879
}
7980
}
8081

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ extension ASTGenVisitor {
120120
}
121121

122122
let genericArguments = generics.arguments.lazy.map {
123-
self.generate(type: $0.argument)
123+
self.generate(genericArgument: $0.argument)
124124
}
125125

126126
return BridgedUnqualifiedIdentTypeRepr.createParsed(
@@ -140,7 +140,7 @@ extension ASTGenVisitor {
140140
let angleRange: BridgedSourceRange
141141
if let generics = node.genericArgumentClause {
142142
genericArguments = generics.arguments.lazy.map {
143-
self.generate(type: $0.argument)
143+
self.generate(genericArgument: $0.argument)
144144
}.bridgedArray(in: self)
145145

146146
angleRange = self.generateSourceRange(start: generics.leftAngle, end: generics.rightAngle)

lib/Macros/Sources/SwiftMacros/DistributedResolvableMacro.swift

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12+
@_spi(ExperimentalLanguageFeatures)
1213
import SwiftSyntax
1314
import SwiftSyntaxMacros
1415
import SwiftDiagnostics
@@ -141,10 +142,25 @@ extension DistributedResolvableMacro {
141142
specificActorSystemRequirement = conformanceReq.rightType.trimmed
142143
isGenericStub = true
143144

144-
case .sameTypeRequirement(let sameTypeReq)
145-
where sameTypeReq.leftType.isActorSystem:
146-
specificActorSystemRequirement = sameTypeReq.rightType.trimmed
147-
isGenericStub = false
145+
case .sameTypeRequirement(let sameTypeReq):
146+
switch sameTypeReq.leftType {
147+
case .type(let type) where type.isActorSystem:
148+
switch sameTypeReq.rightType.trimmed {
149+
case .type(let rightType):
150+
specificActorSystemRequirement = rightType
151+
isGenericStub = false
152+
153+
case .expr:
154+
throw DiagnosticsError(
155+
syntax: sameTypeReq.rightType,
156+
message: "Expression type not supported for distributed actor",
157+
id: .invalidGenericArgument
158+
)
159+
}
160+
161+
default:
162+
continue
163+
}
148164

149165
default:
150166
continue
@@ -265,6 +281,7 @@ struct DistributedResolvableMacroDiagnostic: DiagnosticMessage {
265281
enum ID: String {
266282
case invalidApplication = "invalid type"
267283
case missingInitializer = "missing initializer"
284+
case invalidGenericArgument = "invalid generic argument"
268285
}
269286

270287
var message: String

lib/Macros/Sources/SwiftMacros/OptionSetMacro.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public struct OptionSetMacro {
7272
of attribute: AttributeSyntax,
7373
attachedTo decl: Decl,
7474
in context: Context
75-
) -> (StructDeclSyntax, EnumDeclSyntax, TypeSyntax)? {
75+
) -> (StructDeclSyntax, EnumDeclSyntax, GenericArgumentSyntax.Argument)? {
7676
// Determine the name of the options enum.
7777
let optionsEnumName: String
7878
if case let .argumentList(arguments) = attribute.arguments,

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3963,7 +3963,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
39633963
return makeParserSuccess();
39643964
}
39653965

3966-
auto countType = parseType(diag::expected_type);
3966+
auto countType = parseTypeOrValue(diag::expected_type);
39673967
if (countType.isNull()) {
39683968
return makeParserSuccess();
39693969
}

lib/Parse/ParseGeneric.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@ ParserStatus Parser::parseGenericWhereClause(
317317

318318
// Parse the leading type. It doesn't necessarily have to be just a type
319319
// identifier if we're dealing with a same-type constraint.
320-
ParserResult<TypeRepr> FirstType = parseType();
320+
//
321+
// Note: This can be a value type, e.g. '123 == N' or 'N == 123'.
322+
ParserResult<TypeRepr> FirstType = parseTypeOrValue();
321323

322324
if (FirstType.hasCodeCompletion()) {
323325
Status.setHasCodeCompletionAndIsError();
@@ -377,7 +379,9 @@ ParserStatus Parser::parseGenericWhereClause(
377379
SourceLoc EqualLoc = consumeToken();
378380

379381
// Parse the second type.
380-
ParserResult<TypeRepr> SecondType = parseType();
382+
//
383+
// Note: This can be a value type, e.g. '123 == N' or 'N == 123'.
384+
ParserResult<TypeRepr> SecondType = parseTypeOrValue();
381385
Status |= SecondType;
382386
if (SecondType.isNull())
383387
SecondType = makeParserResult(ErrorTypeRepr::create(Context, PreviousLoc));

lib/Parse/ParseType.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,6 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
175175
tildeLoc = consumeToken();
176176
}
177177

178-
// Eat any '-' preceding integer literals.
179-
SourceLoc minusLoc;
180-
if (Tok.isMinus() && peekToken().is(tok::integer_literal)) {
181-
minusLoc = consumeToken();
182-
}
183-
184178
switch (Tok.getKind()) {
185179
case tok::kw_Self:
186180
case tok::identifier:
@@ -237,12 +231,6 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
237231
}
238232
return makeParserCodeCompletionResult<TypeRepr>(
239233
ErrorTypeRepr::create(Context, consumeToken(tok::code_complete)));
240-
case tok::integer_literal: {
241-
auto text = copyAndStripUnderscores(Tok.getText());
242-
auto loc = consumeToken(tok::integer_literal);
243-
ty = makeParserResult(new (Context) IntegerTypeRepr(text, loc, minusLoc));
244-
break;
245-
}
246234
case tok::l_square: {
247235
ty = parseTypeCollection();
248236
break;
@@ -739,7 +727,8 @@ ParserStatus Parser::parseGenericArguments(SmallVectorImpl<TypeRepr *> &Args,
739727
// variadic generic types.
740728
if (!startsWithGreater(Tok)) {
741729
while (true) {
742-
ParserResult<TypeRepr> Ty = parseType(diag::expected_type);
730+
// Note: This can be a value type, e.g. 'Vector<3, Int>'.
731+
ParserResult<TypeRepr> Ty = parseTypeOrValue(diag::expected_type);
743732
if (Ty.isNull() || Ty.hasCodeCompletion()) {
744733
// Skip until we hit the '>'.
745734
RAngleLoc = skipUntilGreaterInTypeList();
@@ -1481,6 +1470,31 @@ Parser::parseTypeImplicitlyUnwrappedOptional(ParserResult<TypeRepr> base) {
14811470
return makeParserResult(ParserStatus(base), TyR);
14821471
}
14831472

1473+
ParserResult<TypeRepr> Parser::parseTypeOrValue() {
1474+
return parseTypeOrValue(diag::expected_type);
1475+
}
1476+
1477+
ParserResult<TypeRepr> Parser::parseTypeOrValue(Diag<> MessageID,
1478+
ParseTypeReason reason,
1479+
bool fromASTGen) {
1480+
// Eat any '-' preceding integer literals.
1481+
SourceLoc minusLoc;
1482+
if (Tok.isMinus() && peekToken().is(tok::integer_literal)) {
1483+
minusLoc = consumeToken();
1484+
}
1485+
1486+
// Attempt to parse values first. Right now the only value that can be parsed
1487+
// as a type are integers.
1488+
if (Tok.is(tok::integer_literal)) {
1489+
auto text = copyAndStripUnderscores(Tok.getText());
1490+
auto loc = consumeToken(tok::integer_literal);
1491+
return makeParserResult(new (Context) IntegerTypeRepr(text, loc, minusLoc));
1492+
}
1493+
1494+
// Otherwise, attempt to parse a regular type.
1495+
return parseType(MessageID, reason, fromASTGen);
1496+
}
1497+
14841498
//===----------------------------------------------------------------------===//
14851499
// Speculative type list parsing
14861500
//===----------------------------------------------------------------------===//

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,42 @@ bool SILParser::parseASTType(CanType &result,
10671067
return false;
10681068
}
10691069

1070+
bool SILParser::parseASTTypeOrValue(CanType &result,
1071+
GenericSignature genericSig,
1072+
GenericParamList *genericParams,
1073+
bool forceContextualType) {
1074+
auto parsedType = P.parseTypeOrValue();
1075+
if (parsedType.isNull()) return true;
1076+
1077+
// If we weren't given a specific generic context to resolve the type
1078+
// within, use the contextual generic parameters and always produce
1079+
// a contextual type. Otherwise, produce a contextual type only if
1080+
// we were asked for one.
1081+
bool wantContextualType = forceContextualType;
1082+
if (!genericSig) {
1083+
genericSig = ContextGenericSig;
1084+
wantContextualType = true;
1085+
}
1086+
if (genericParams == nullptr)
1087+
genericParams = ContextGenericParams;
1088+
1089+
bindSILGenericParams(parsedType.get());
1090+
1091+
auto resolvedType = performTypeResolution(
1092+
parsedType.get(), /*isSILType=*/false, genericSig, genericParams);
1093+
if (wantContextualType && genericSig) {
1094+
resolvedType = genericSig.getGenericEnvironment()
1095+
->mapTypeIntoContext(resolvedType);
1096+
}
1097+
1098+
if (resolvedType->hasError())
1099+
return true;
1100+
1101+
result = resolvedType->getCanonicalType();
1102+
1103+
return false;
1104+
}
1105+
10701106
void SILParser::bindSILGenericParams(TypeRepr *TyR) {
10711107
// Resolve the generic environments for parsed generic function and box types.
10721108
class HandleSILGenericParamsWalker : public ASTWalker {
@@ -3122,7 +3158,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
31223158
CanType paramType;
31233159
if (parseSILType(Ty) ||
31243160
parseVerbatim("for") ||
3125-
parseASTType(paramType))
3161+
parseASTTypeOrValue(paramType))
31263162
return true;
31273163

31283164
ResultVal = B.createTypeValue(InstLoc, Ty, paramType);

lib/SIL/Parser/SILParser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ class SILParser {
235235
return false;
236236
}
237237

238+
bool parseASTTypeOrValue(CanType &result,
239+
GenericSignature genericSig = GenericSignature(),
240+
GenericParamList *genericParams = nullptr,
241+
bool forceContextualType = false);
242+
238243
std::optional<StringRef>
239244
parseOptionalAttribute(ArrayRef<StringRef> expected) {
240245
// We parse here @ <identifier>.

0 commit comments

Comments
 (0)