[sending] Begin parsing 'sending' while still accepting 'transferring'.

A few things:

1. Internally except for in the parser and the clang importer, we only represent
'sending'. This means that it will be easy to remove 'transferring' once enough
time has passed.

2. I included a warning that suggested to the user to change 'transferring' ->
'sending'.

3. I duplicated the parsing diagnostics for 'sending' so both will still get
different sets of diagnostics for parsing issues... but anywhere below parsing,
I have just changed 'transferring' to 'sending' since transferring isn't
represented at those lower levels.

4. Since SendingArgsAndResults is always enabled when TransferringArgsAndResults
is enabled (NOTE not vis-a-versa), we know that we can always parse sending. So
we import "transferring" as "sending". This means that even if one marks a
function with "transferring", the compiler will guard it behind a
SendingArgsAndResults -D flag and in the imported header print out sending.

rdar://128216574
This commit is contained in:
Michael Gottesman
2024-05-16 14:28:40 -07:00
parent 71e95b9527
commit b780ff6696
58 changed files with 946 additions and 236 deletions

View File

@@ -126,6 +126,8 @@ bool Parser::startsParameterName(bool isClosure) {
!Tok.isContextualKeyword("borrowing") &&
(!Context.LangOpts.hasFeature(Feature::TransferringArgsAndResults) ||
!Tok.isContextualKeyword("transferring")) &&
(!Context.LangOpts.hasFeature(Feature::SendingArgsAndResults) ||
!Tok.isContextualKeyword("sending")) &&
!Tok.isContextualKeyword("consuming") && !Tok.is(tok::kw_repeat) &&
(!Context.LangOpts.hasFeature(Feature::NonescapableTypes) ||
!Tok.isContextualKeyword("_resultDependsOn")))
@@ -272,10 +274,43 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
continue;
}
diagnose(Tok, diag::transferring_is_now_sendable)
.fixItReplace(Tok.getLoc(), "sending");
if (param.SendingLoc.isValid()) {
diagnose(Tok, diag::sending_and_transferring_used_together)
.fixItRemove(Tok.getLoc());
consumeToken();
continue;
}
param.TransferringLoc = consumeToken();
continue;
}
if (Context.LangOpts.hasFeature(Feature::SendingArgsAndResults) &&
Tok.isContextualKeyword("sending")) {
diagnose(Tok, diag::parameter_specifier_as_attr_disallowed,
Tok.getText())
.warnUntilSwiftVersion(6);
if (param.SendingLoc.isValid()) {
diagnose(Tok, diag::parameter_specifier_repeated)
.fixItRemove(Tok.getLoc());
consumeToken();
continue;
}
if (param.TransferringLoc.isValid()) {
diagnose(Tok, diag::sending_and_transferring_used_together)
.fixItRemove(param.TransferringLoc);
consumeToken();
continue;
}
param.SendingLoc = consumeToken();
continue;
}
if (!hasSpecifier) {
// These cases are handled later when mapping to ParamDecls for
// better fixits.
@@ -296,6 +331,11 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
param.SpecifierLoc = consumeToken();
}
if (param.SendingLoc.isValid()) {
diagnose(Tok, diag::sending_before_parameter_specifier,
getNameForParamSpecifier(param.SpecifierKind));
}
hasSpecifier = true;
} else {
// Redundant specifiers are fairly common, recognize, reject, and
@@ -584,6 +624,11 @@ mapParsedParameters(Parser &parser,
param->setSending();
}
if (paramInfo.SendingLoc.isValid()) {
type = new (parser.Context) SendingTypeRepr(type, paramInfo.SendingLoc);
param->setSending();
}
param->setTypeRepr(type);
// Dig through the type to find any attributes or modifiers that are
@@ -613,6 +658,8 @@ mapParsedParameters(Parser &parser,
param->setResultDependsOn(true);
else if (isa<TransferringTypeRepr>(STR))
param->setSending(true);
else if (isa<SendingTypeRepr>(STR))
param->setSending(true);
unwrappedType = STR->getBase();
continue;
}