Skip to content

Commit 102e5ec

Browse files
committed
Fix a compiler crash with '@'_lifetime(inout x), add diagnostic
This is a common mistake made more common be suggestions of existing diagnostic that tell users not to use a 'copy' dependency. Report a diagnostic error rather than crashing the compiler. Fix the diagnostic output to make sense relative to the source location. Fixes rdar://154136015 ([nonescapable] compiler assertion with @_lifetime(x: inout x)) (cherry picked from commit 080b682)
1 parent fcbcc8c commit 102e5ec

File tree

4 files changed

+13
-2
lines changed

4 files changed

+13
-2
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2140,7 +2140,7 @@ ERROR(expected_lparen_after_lifetime_dependence, PointsToFirstBadToken,
21402140

21412141
ERROR(expected_identifier_or_index_or_self_after_lifetime_dependence,
21422142
PointsToFirstBadToken,
2143-
"expected identifier, index or self in lifetime dependence specifier",
2143+
"expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier",
21442144
())
21452145

21462146
ERROR(expected_rparen_after_lifetime_dependence, PointsToFirstBadToken,

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4989,6 +4989,7 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
49894989
SmallVector<LifetimeDescriptor> sources;
49904990
SourceLoc rParenLoc;
49914991
bool foundParamId = false;
4992+
bool invalidSourceDescriptor = false;
49924993
status = parseList(
49934994
tok::r_paren, lParenLoc, rParenLoc, /*AllowSepAfterLast=*/false,
49944995
diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
@@ -5005,13 +5006,18 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
50055006
auto sourceDescriptor =
50065007
parseLifetimeDescriptor(*this, lifetimeDependenceKind);
50075008
if (!sourceDescriptor) {
5009+
invalidSourceDescriptor = true;
50085010
listStatus.setIsParseError();
50095011
return listStatus;
50105012
}
50115013
sources.push_back(*sourceDescriptor);
50125014
return listStatus;
50135015
});
50145016

5017+
if (invalidSourceDescriptor) {
5018+
status.setIsParseError();
5019+
return status;
5020+
}
50155021
if (!foundParamId) {
50165022
diagnose(
50175023
Tok,

test/Parse/lifetime_attr.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func testMissingLParenError(_ ne: NE) -> NE { // expected-error{{cannot infer th
2424
ne
2525
}
2626

27-
@_lifetime() // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
27+
@_lifetime() // expected-error{{expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier}}
2828
func testMissingDependence(_ ne: NE) -> NE { // expected-error{{cannot infer the lifetime dependence scope on a function with a ~Escapable parameter, specify '@_lifetime(borrow ne)' or '@_lifetime(copy ne)'}}
2929
ne
3030
}

test/Sema/lifetime_depend_infer.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,3 +625,8 @@ struct NE_NE_C: ~Escapable { // expected-error{{cannot infer implicit initializa
625625
func f_inout_no_infer(a: inout MutNE, b: NE) {} // expected-error{{a function with a ~Escapable 'inout' parameter requires '@_lifetime(a: ...)'}}
626626
// expected-note @-1{{use '@_lifetime(a: copy a) to forward the inout dependency}}
627627
628+
// Invalid keyword for the dependence kind.
629+
//
630+
@_lifetime(a: inout a) // expected-error{{expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier}}
631+
func f_inout_bad_keyword(a: inout MutableRawSpan) {}
632+

0 commit comments

Comments
 (0)