macros: Add hints for follow-set restrictions
Adds a new call to `rust_inform()` in order to let the user know about the tokens allowed after the previous match. Since this changes the error message, tests also need to be adjusted.
This commit is contained in:
parent
ff5f3005d0
commit
3e5090608d
|
@ -172,6 +172,8 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
|
|||
}}};
|
||||
|
||||
Location error_locus = match.get_match_locus ();
|
||||
std::string kind_str = "fragment";
|
||||
auto &allowed_toks = follow_set[last_match.get_frag_spec ().get_kind ()];
|
||||
|
||||
// There are two behaviors to handle here: If the follow-up match is a token,
|
||||
// we want to check if it is allowed.
|
||||
|
@ -183,16 +185,12 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
|
|||
{
|
||||
case AST::MacroMatch::Tok: {
|
||||
auto tok = static_cast<AST::Token *> (&match);
|
||||
auto &allowed_toks
|
||||
= follow_set[last_match.get_frag_spec ().get_kind ()];
|
||||
auto is_valid = contains (allowed_toks, tok->get_id ());
|
||||
if (!is_valid)
|
||||
// FIXME: Add hint about allowed fragments
|
||||
rust_error_at (tok->get_match_locus (),
|
||||
"token %<%s%> is not allowed after %<%s%> fragment",
|
||||
tok->get_str ().c_str (),
|
||||
last_match.get_frag_spec ().as_string ().c_str ());
|
||||
return is_valid;
|
||||
if (contains (allowed_toks, tok->get_id ()))
|
||||
return true;
|
||||
kind_str = "token `"
|
||||
+ std::string (get_token_description (tok->get_id ())) + "`";
|
||||
error_locus = tok->get_match_locus ();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AST::MacroMatch::Repetition: {
|
||||
|
@ -219,9 +217,16 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match,
|
|||
break;
|
||||
}
|
||||
|
||||
// FIXME: Improve error message
|
||||
rust_error_at (error_locus, "fragment not allowed after %<%s%> fragment",
|
||||
rust_error_at (error_locus, "%s is not allowed after %<%s%> fragment",
|
||||
kind_str.c_str (),
|
||||
last_match.get_frag_spec ().as_string ().c_str ());
|
||||
auto allowed_toks_str
|
||||
= "`" + std::string (get_token_description (allowed_toks[0])) + "`";
|
||||
for (size_t i = 1; i < allowed_toks.size (); i++)
|
||||
allowed_toks_str
|
||||
+= ", `" + std::string (get_token_description (allowed_toks[i])) + "`";
|
||||
|
||||
rust_inform (error_locus, "allowed tokens are %s", allowed_toks_str.c_str ());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
macro_rules! m {
|
||||
($a:expr tok) => {
|
||||
// { dg-error "token .tok. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
|
||||
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
|
||||
$a
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
macro_rules! m {
|
||||
($a:expr $(tok $es:expr)*) => {
|
||||
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
|
||||
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
|
||||
$a
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
macro_rules! m {
|
||||
($($es:expr)* tok) => {
|
||||
// { dg-error "token .tok. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
|
||||
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
|
||||
$a
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
macro_rules! m {
|
||||
($e:expr $f:expr) => {
|
||||
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
|
||||
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
|
||||
$e
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
macro_rules! m {
|
||||
($($e:expr)* $($f:expr)*) => {
|
||||
// { dg-error "fragment not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
|
||||
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
|
||||
// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
|
||||
$e
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
macro_rules! inside_matcher {
|
||||
(($e:expr tok) tok) => {{}}; // { dg-error "token .tok. is not allowed after .expr. fragment" }
|
||||
(($e:expr tok) tok) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
|
||||
// { dg-error "failed to parse macro matcher" "" { target *-*-* } .-1 }
|
||||
// { dg-error "failed to parse macro match" "" { target *-*-* } .-2 }
|
||||
// { dg-error "required first macro rule" "" { target *-*-* } .-3 }
|
||||
|
|
Loading…
Reference in New Issue