23
23
#include " swift/AST/GenericParamList.h"
24
24
#include " swift/AST/Initializer.h"
25
25
#include " swift/AST/LazyResolver.h"
26
+ #include " swift/AST/LifetimeDependence.h"
26
27
#include " swift/AST/Module.h"
27
28
#include " swift/AST/ParameterList.h"
28
29
#include " swift/AST/ParseRequests.h"
@@ -4909,6 +4910,104 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes,
4909
4910
return makeParserSuccess ();
4910
4911
}
4911
4912
4913
+ static llvm::Optional<LifetimeDependenceKind>
4914
+ getLifetimeDependenceKind (const Token &T) {
4915
+ if (T.isContextualKeyword (" _copy" )) {
4916
+ return LifetimeDependenceKind::Copy;
4917
+ }
4918
+ if (T.isContextualKeyword (" _consume" )) {
4919
+ return LifetimeDependenceKind::Consume;
4920
+ }
4921
+ if (T.isContextualKeyword (" _borrow" )) {
4922
+ return LifetimeDependenceKind::Borrow;
4923
+ }
4924
+ if (T.isContextualKeyword (" _mutate" )) {
4925
+ return LifetimeDependenceKind::Mutate;
4926
+ }
4927
+ return llvm::None;
4928
+ }
4929
+
4930
+ ParserStatus Parser::parseLifetimeDependenceSpecifiers (
4931
+ SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList) {
4932
+ ParserStatus status;
4933
+ // TODO: Add fixits for diagnostics in this function.
4934
+ do {
4935
+ auto lifetimeDependenceKind = getLifetimeDependenceKind (Tok);
4936
+ if (!lifetimeDependenceKind.has_value ()) {
4937
+ break ;
4938
+ }
4939
+ // consume the lifetime dependence kind
4940
+ consumeToken ();
4941
+
4942
+ if (!Tok.isFollowingLParen ()) {
4943
+ diagnose (Tok, diag::expected_lparen_after_lifetime_dependence);
4944
+ status.setIsParseError ();
4945
+ continue ;
4946
+ }
4947
+ // consume the l_paren
4948
+ auto lParenLoc = consumeToken ();
4949
+ SourceLoc rParenLoc;
4950
+ bool foundParamId = false ;
4951
+ status = parseList (
4952
+ tok::r_paren, lParenLoc, rParenLoc, /* AllowSepAfterLast*/ false ,
4953
+ diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
4954
+ ParserStatus listStatus;
4955
+ foundParamId = true ;
4956
+ switch (Tok.getKind ()) {
4957
+ case tok::identifier: {
4958
+ Identifier paramName;
4959
+ auto paramLoc =
4960
+ consumeIdentifier (paramName, /* diagnoseDollarPrefix=*/ false );
4961
+ specifierList.push_back (
4962
+ LifetimeDependenceSpecifier::
4963
+ getNamedLifetimeDependenceSpecifier (
4964
+ paramLoc, *lifetimeDependenceKind, paramName));
4965
+ break ;
4966
+ }
4967
+ case tok::integer_literal: {
4968
+ SourceLoc paramLoc;
4969
+ unsigned paramNum;
4970
+ if (parseUnsignedInteger (
4971
+ paramNum, paramLoc,
4972
+ diag::expected_param_index_lifetime_dependence)) {
4973
+ skipUntil (tok::r_paren);
4974
+ listStatus.setIsParseError ();
4975
+ return listStatus;
4976
+ }
4977
+ specifierList.push_back (
4978
+ LifetimeDependenceSpecifier::
4979
+ getOrderedLifetimeDependenceSpecifier (
4980
+ paramLoc, *lifetimeDependenceKind, paramNum));
4981
+ break ;
4982
+ }
4983
+ case tok::kw_self: {
4984
+ auto paramLoc = consumeToken (tok::kw_self);
4985
+ specifierList.push_back (
4986
+ LifetimeDependenceSpecifier::getSelfLifetimeDependenceSpecifier (
4987
+ paramLoc, *lifetimeDependenceKind));
4988
+ break ;
4989
+ }
4990
+ default :
4991
+ diagnose (
4992
+ Tok,
4993
+ diag::
4994
+ expected_identifier_or_index_or_self_after_lifetime_dependence);
4995
+ skipUntil (tok::r_paren);
4996
+ listStatus.setIsParseError ();
4997
+ return listStatus;
4998
+ }
4999
+ return listStatus;
5000
+ });
5001
+
5002
+ if (!foundParamId) {
5003
+ diagnose (Tok, diag::expected_identifier_or_index_or_self_after_lifetime_dependence);
5004
+ status.setIsParseError ();
5005
+ }
5006
+ } while (true );
5007
+
5008
+ return status;
5009
+ }
5010
+
4912
5011
ParserStatus Parser::parseDeclAttributeList (
4913
5012
DeclAttributes &Attributes, bool ifConfigsAreDeclAttrs,
4914
5013
PatternBindingInitializer *initContext) {
@@ -5128,6 +5227,7 @@ ParserStatus Parser::parseDeclModifierList(DeclAttributes &Attributes,
5128
5227
// / '@' attribute attribute-list-clause
5129
5228
// / \endverbatim
5130
5229
ParserStatus Parser::ParsedTypeAttributeList::slowParse (Parser &P) {
5230
+ ParserStatus status;
5131
5231
PatternBindingInitializer *initContext = nullptr ;
5132
5232
auto &Tok = P.Tok ;
5133
5233
while (Tok.is (tok::kw_inout) ||
@@ -5139,7 +5239,8 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
5139
5239
Tok.isContextualKeyword (" borrowing" ) ||
5140
5240
Tok.isContextualKeyword (" transferring" ) ||
5141
5241
Tok.isContextualKeyword (" _const" ) ||
5142
- Tok.isContextualKeyword (" _resultDependsOn" )))) {
5242
+ Tok.isContextualKeyword (" _resultDependsOn" ) ||
5243
+ Tok.isLifetimeDependenceToken ()))) {
5143
5244
5144
5245
if (Tok.isContextualKeyword (" isolated" )) {
5145
5246
if (IsolatedLoc.isValid ()) {
@@ -5169,11 +5270,22 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
5169
5270
// the actual parsing logic below.
5170
5271
if (Tok.isContextualKeyword (" transferring" )) {
5171
5272
if (!P.Context .LangOpts .hasFeature (Feature::TransferringArgsAndResults)) {
5172
- P.diagnose (Tok, diag::requires_experimental_feature, " transferring " ,
5273
+ P.diagnose (Tok, diag::requires_experimental_feature, Tok. getRawText () ,
5173
5274
false , getFeatureName (Feature::TransferringArgsAndResults));
5174
5275
}
5175
5276
}
5176
5277
5278
+ if (Tok.isLifetimeDependenceToken ()) {
5279
+ if (!P.Context .LangOpts .hasFeature (Feature::NonescapableTypes)) {
5280
+ P.diagnose (Tok, diag::requires_experimental_feature,
5281
+ " lifetime dependence specifier" , false ,
5282
+ getFeatureName (Feature::NonescapableTypes));
5283
+ }
5284
+ status |=
5285
+ P.parseLifetimeDependenceSpecifiers (lifetimeDependenceSpecifiers);
5286
+ continue ;
5287
+ }
5288
+
5177
5289
if (SpecifierLoc.isValid ()) {
5178
5290
P.diagnose (Tok, diag::parameter_specifier_repeated)
5179
5291
.fixItRemove (SpecifierLoc);
@@ -5198,7 +5310,6 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
5198
5310
SpecifierLoc = P.consumeToken ();
5199
5311
}
5200
5312
5201
- ParserStatus status;
5202
5313
while (Tok.is (tok::at_sign)) {
5203
5314
// Ignore @substituted in SIL mode and leave it for the type parser.
5204
5315
if (P.isInSILMode () && P.peekToken ().getText () == " substituted" )
0 commit comments