mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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))
This commit is contained in:
@@ -2147,7 +2147,7 @@ ERROR(expected_lparen_after_lifetime_dependence, PointsToFirstBadToken,
|
|||||||
|
|
||||||
ERROR(expected_identifier_or_index_or_self_after_lifetime_dependence,
|
ERROR(expected_identifier_or_index_or_self_after_lifetime_dependence,
|
||||||
PointsToFirstBadToken,
|
PointsToFirstBadToken,
|
||||||
"expected identifier, index or self in lifetime dependence specifier",
|
"expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier",
|
||||||
())
|
())
|
||||||
|
|
||||||
ERROR(expected_rparen_after_lifetime_dependence, PointsToFirstBadToken,
|
ERROR(expected_rparen_after_lifetime_dependence, PointsToFirstBadToken,
|
||||||
|
|||||||
@@ -5014,6 +5014,7 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
|
|||||||
SmallVector<LifetimeDescriptor> sources;
|
SmallVector<LifetimeDescriptor> sources;
|
||||||
SourceLoc rParenLoc;
|
SourceLoc rParenLoc;
|
||||||
bool foundParamId = false;
|
bool foundParamId = false;
|
||||||
|
bool invalidSourceDescriptor = false;
|
||||||
status = parseList(
|
status = parseList(
|
||||||
tok::r_paren, lParenLoc, rParenLoc, /*AllowSepAfterLast=*/false,
|
tok::r_paren, lParenLoc, rParenLoc, /*AllowSepAfterLast=*/false,
|
||||||
diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
|
diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
|
||||||
@@ -5030,6 +5031,7 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
|
|||||||
auto sourceDescriptor =
|
auto sourceDescriptor =
|
||||||
parseLifetimeDescriptor(*this, lifetimeDependenceKind);
|
parseLifetimeDescriptor(*this, lifetimeDependenceKind);
|
||||||
if (!sourceDescriptor) {
|
if (!sourceDescriptor) {
|
||||||
|
invalidSourceDescriptor = true;
|
||||||
listStatus.setIsParseError();
|
listStatus.setIsParseError();
|
||||||
return listStatus;
|
return listStatus;
|
||||||
}
|
}
|
||||||
@@ -5037,6 +5039,10 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
|
|||||||
return listStatus;
|
return listStatus;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (invalidSourceDescriptor) {
|
||||||
|
status.setIsParseError();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
if (!foundParamId) {
|
if (!foundParamId) {
|
||||||
diagnose(
|
diagnose(
|
||||||
Tok,
|
Tok,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func testMissingLParenError(_ ne: NE) -> NE { // expected-error{{cannot infer th
|
|||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@_lifetime() // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
|
@_lifetime() // expected-error{{expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier}}
|
||||||
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)'}}
|
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)'}}
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -588,3 +588,8 @@ struct NonEscapableMutableSelf: ~Escapable {
|
|||||||
//
|
//
|
||||||
func f_inout_no_infer(a: inout MutNE, b: NE) {} // expected-error{{a function with a ~Escapable 'inout' parameter requires '@_lifetime(a: ...)'}}
|
func f_inout_no_infer(a: inout MutNE, b: NE) {} // expected-error{{a function with a ~Escapable 'inout' parameter requires '@_lifetime(a: ...)'}}
|
||||||
// expected-note @-1{{use '@_lifetime(a: copy a) to forward the inout dependency}}
|
// expected-note @-1{{use '@_lifetime(a: copy a) to forward the inout dependency}}
|
||||||
|
|
||||||
|
// Invalid keyword for the dependence kind.
|
||||||
|
//
|
||||||
|
@_lifetime(a: inout a) // expected-error{{expected 'copy', 'borrow', or '&' followed by an identifier, index or 'self' in lifetime dependence specifier}}
|
||||||
|
func f_inout_bad_keyword(a: inout MutableRawSpan) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user