Skip to content

Commit aa9085a

Browse files
committed
Handle attr parse failures
Adding nice error messages for when things go wrong.
1 parent 3a13721 commit aa9085a

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,8 @@ ERROR(attr_missing_label,PointsToFirstBadToken,
14321432
"missing label '%0:' in '@%1' attribute", (StringRef, StringRef))
14331433
ERROR(attr_expected_label,none,
14341434
"expected label '%0:' in '@%1' attribute", (StringRef, StringRef))
1435+
ERROR(attr_expected_colon_after_label,none,
1436+
"expected ':' after label '%0'", (StringRef))
14351437

14361438
ERROR(alignment_must_be_positive_integer,none,
14371439
"alignment value must be a positive integer literal", ())

lib/Parse/ParseDecl.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,7 +2751,6 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
27512751
}
27522752

27532753
case DAK_UnavailableFromAsync: {
2754-
27552754
StringRef message;
27562755
if (consumeIf(tok::l_paren)) {
27572756
if (!Tok.is(tok::identifier)) {
@@ -2761,27 +2760,36 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
27612760
StringRef flag = Tok.getText();
27622761

27632762
if (flag != "message") {
2764-
llvm_unreachable("Unknown unavailable argument");
2763+
diagnose(Tok.getLoc(), diag::attr_unknown_option, flag, AttrName);
2764+
return true;
27652765
}
27662766
consumeToken();
27672767
if (!consumeIf(tok::colon)) {
2768-
llvm_unreachable("Expected ':' following 'message'");
2768+
if (!Tok.is(tok::equal)) {
2769+
diagnose(Tok.getLoc(), diag::attr_expected_colon_after_label, flag);
2770+
return false;
2771+
}
2772+
diagnose(Tok.getLoc(), diag::replace_equal_with_colon_for_value)
2773+
.fixItReplace(Tok.getLoc(), ": ");
2774+
consumeToken();
27692775
}
27702776
if (!Tok.is(tok::string_literal)) {
2771-
llvm_unreachable("Expected string literal");
2777+
diagnose(Tok.getLoc(), diag::attr_expected_string_literal, AttrName);
2778+
return false;
27722779
}
27732780

27742781
Optional<StringRef> value = getStringLiteralIfNotInterpolated(
2775-
Loc, "' I don't know what goes here! '");
2782+
Tok.getLoc(), flag);
27762783
if (!value)
2777-
llvm_unreachable("Expected a message, homie");
2778-
2784+
return false;
2785+
Token stringTok = Tok;
27792786
consumeToken();
2780-
27812787
message = *value;
27822788

27832789
if (!consumeIf(tok::r_paren))
2784-
llvm_unreachable("Expected a closing r-paren");
2790+
diagnose(stringTok.getRange().getEnd(), diag::attr_expected_rparen,
2791+
AttrName, /*isModifiler*/false)
2792+
.fixItInsertAfter(stringTok.getLoc(), ")");
27852793
}
27862794

27872795
Attributes.add(new (Context) UnavailableFromAsyncAttr(

test/Concurrency/unavailable_from_async.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,33 @@ func asyncFunc() async { // expected-error{{asynchronous global function 'asyncF
128128
}
129129

130130
}
131+
132+
// Parsing tests
133+
134+
// expected-error@+2 {{expected declaration}}
135+
// expected-error@+1:24{{unknown option 'nope' for attribute '_unavailableFromAsync'}}
136+
@_unavailableFromAsync(nope: "almost right, but not quite")
137+
func blarp1() {}
138+
139+
// expected-error@+2 {{expected declaration}}
140+
// expected-error@+1 {{expected ':' after label 'message'}}
141+
@_unavailableFromAsync(message; "almost right, but not quite")
142+
func blarp2() {}
143+
144+
// expected-error@+1:31 {{'=' has been replaced with ':' in attribute arguments}}{{31-32=: }}
145+
@_unavailableFromAsync(message="almost right, but not quite")
146+
func blarp3() {}
147+
148+
// expected-error@+2 {{expected declaration}}
149+
// expected-error@+1 {{expected string literal in '_unavailableFromAsync' attribute}}
150+
@_unavailableFromAsync(message: 32)
151+
func blarp4() {}
152+
153+
// expected-error@+2 {{expected declaration}}
154+
// expected-error@+1 {{message cannot be an interpolated string}}
155+
@_unavailableFromAsync(message: "blarppy blarp \(31 + 10)")
156+
func blarp5() {}
157+
158+
// expected-error@+1:48 {{expected ')' in '_unavailableFromAsync' attribute}}{{48-48=)}}
159+
@_unavailableFromAsync(message: "blarppy blarp"
160+
func blarp6() {}

0 commit comments

Comments
 (0)