2323#include " swift/AST/GenericParamList.h"
2424#include " swift/AST/Initializer.h"
2525#include " swift/AST/LazyResolver.h"
26+ #include " swift/AST/LifetimeDependence.h"
2627#include " swift/AST/Module.h"
2728#include " swift/AST/ParameterList.h"
2829#include " swift/AST/ParseRequests.h"
@@ -4909,6 +4910,104 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes,
49094910 return makeParserSuccess ();
49104911}
49114912
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+
49125011ParserStatus Parser::parseDeclAttributeList (
49135012 DeclAttributes &Attributes, bool ifConfigsAreDeclAttrs,
49145013 PatternBindingInitializer *initContext) {
@@ -5128,6 +5227,7 @@ ParserStatus Parser::parseDeclModifierList(DeclAttributes &Attributes,
51285227// / '@' attribute attribute-list-clause
51295228// / \endverbatim
51305229ParserStatus Parser::ParsedTypeAttributeList::slowParse (Parser &P) {
5230+ ParserStatus status;
51315231 PatternBindingInitializer *initContext = nullptr ;
51325232 auto &Tok = P.Tok ;
51335233 while (Tok.is (tok::kw_inout) ||
@@ -5139,7 +5239,8 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
51395239 Tok.isContextualKeyword (" borrowing" ) ||
51405240 Tok.isContextualKeyword (" transferring" ) ||
51415241 Tok.isContextualKeyword (" _const" ) ||
5142- Tok.isContextualKeyword (" _resultDependsOn" )))) {
5242+ Tok.isContextualKeyword (" _resultDependsOn" ) ||
5243+ Tok.isLifetimeDependenceToken ()))) {
51435244
51445245 if (Tok.isContextualKeyword (" isolated" )) {
51455246 if (IsolatedLoc.isValid ()) {
@@ -5169,11 +5270,22 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
51695270 // the actual parsing logic below.
51705271 if (Tok.isContextualKeyword (" transferring" )) {
51715272 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 () ,
51735274 false , getFeatureName (Feature::TransferringArgsAndResults));
51745275 }
51755276 }
51765277
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+
51775289 if (SpecifierLoc.isValid ()) {
51785290 P.diagnose (Tok, diag::parameter_specifier_repeated)
51795291 .fixItRemove (SpecifierLoc);
@@ -5198,7 +5310,6 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
51985310 SpecifierLoc = P.consumeToken ();
51995311 }
52005312
5201- ParserStatus status;
52025313 while (Tok.is (tok::at_sign)) {
52035314 // Ignore @substituted in SIL mode and leave it for the type parser.
52045315 if (P.isInSILMode () && P.peekToken ().getText () == " substituted" )
0 commit comments