Skip to content

Commit 8283724

Browse files
Merge #1052
1052: Add hints for valid follow tokens r=CohenArthur a=CohenArthur This PR adds hints about the allowed tokens after a certain fragment, and fixes tests to uphold the new error message Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2 parents ff5f300 + 3e50906 commit 8283724

File tree

7 files changed

+23
-18
lines changed

7 files changed

+23
-18
lines changed

gcc/rust/parse/rust-parse.cc

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
172172
}}};
173173

174174
Location error_locus = match.get_match_locus ();
175+
std::string kind_str = "fragment";
176+
auto &allowed_toks = follow_set[last_match.get_frag_spec ().get_kind ()];
175177

176178
// There are two behaviors to handle here: If the follow-up match is a token,
177179
// we want to check if it is allowed.
@@ -183,16 +185,12 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
183185
{
184186
case AST::MacroMatch::Tok: {
185187
auto tok = static_cast<AST::Token *> (&match);
186-
auto &allowed_toks
187-
= follow_set[last_match.get_frag_spec ().get_kind ()];
188-
auto is_valid = contains (allowed_toks, tok->get_id ());
189-
if (!is_valid)
190-
// FIXME: Add hint about allowed fragments
191-
rust_error_at (tok->get_match_locus (),
192-
"token %<%s%> is not allowed after %<%s%> fragment",
193-
tok->get_str ().c_str (),
194-
last_match.get_frag_spec ().as_string ().c_str ());
195-
return is_valid;
188+
if (contains (allowed_toks, tok->get_id ()))
189+
return true;
190+
kind_str = "token `"
191+
+ std::string (get_token_description (tok->get_id ())) + "`";
192+
error_locus = tok->get_match_locus ();
193+
break;
196194
}
197195
break;
198196
case AST::MacroMatch::Repetition: {
@@ -219,9 +217,16 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
219217
break;
220218
}
221219

222-
// FIXME: Improve error message
223-
rust_error_at (error_locus, "fragment not allowed after %<%s%> fragment",
220+
rust_error_at (error_locus, "%s is not allowed after %<%s%> fragment",
221+
kind_str.c_str (),
224222
last_match.get_frag_spec ().as_string ().c_str ());
223+
auto allowed_toks_str
224+
= "`" + std::string (get_token_description (allowed_toks[0])) + "`";
225+
for (size_t i = 1; i < allowed_toks.size (); i++)
226+
allowed_toks_str
227+
+= ", `" + std::string (get_token_description (allowed_toks[i])) + "`";
228+
229+
rust_inform (error_locus, "allowed tokens are %s", allowed_toks_str.c_str ());
225230

226231
return false;
227232
}

gcc/testsuite/rust/compile/macro27.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! m {
22
($a:expr tok) => {
3-
// { dg-error "token .tok. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
3+
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
44
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
55
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
66
$a

gcc/testsuite/rust/compile/macro28.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! m {
22
($a:expr $(tok $es:expr)*) => {
3-
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
3+
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
44
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
55
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
66
$a

gcc/testsuite/rust/compile/macro29.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! m {
22
($($es:expr)* tok) => {
3-
// { dg-error "token .tok. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
3+
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
44
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
55
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
66
$a

gcc/testsuite/rust/compile/macro30.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! m {
22
($e:expr $f:expr) => {
3-
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
3+
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
44
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
55
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
66
$e

gcc/testsuite/rust/compile/macro31.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! m {
22
($($e:expr)* $($f:expr)*) => {
3-
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
3+
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
44
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
55
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
66
$e

gcc/testsuite/rust/compile/macro35.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! inside_matcher {
2-
(($e:expr tok) tok) => {{}}; // { dg-error "token .tok. is not allowed after .expr. fragment" }
2+
(($e:expr tok) tok) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
33
// { dg-error "failed to parse macro matcher" "" { target *-*-* } .-1 }
44
// { dg-error "failed to parse macro match" "" { target *-*-* } .-2 }
55
// { dg-error "required first macro rule" "" { target *-*-* } .-3 }

0 commit comments

Comments
 (0)