Revert "Promote missing_fragment_specifier to hard error"
This reverts commit 02eae432e7
.
This commit is contained in:
parent
9414f0b833
commit
f1eb88b28a
14 changed files with 90 additions and 32 deletions
|
@ -84,7 +84,7 @@ enum TokenTree {
|
|||
/// e.g., `$var`
|
||||
MetaVar(Span, Ident),
|
||||
/// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
|
||||
MetaVarDecl(Span, Ident /* name to bind */, NonterminalKind),
|
||||
MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
|
||||
}
|
||||
|
||||
impl TokenTree {
|
||||
|
|
|
@ -378,6 +378,11 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
|
|||
n_rec(sess, next_m, res.by_ref(), ret_val)?;
|
||||
}
|
||||
}
|
||||
TokenTree::MetaVarDecl(span, _, None) => {
|
||||
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
|
||||
return Err((span, "missing fragment specifier".to_string()));
|
||||
}
|
||||
}
|
||||
TokenTree::MetaVarDecl(sp, bind_name, _) => match ret_val
|
||||
.entry(MacroRulesNormalizedIdent::new(bind_name))
|
||||
{
|
||||
|
@ -446,6 +451,7 @@ fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode {
|
|||
///
|
||||
/// A `ParseResult`. Note that matches are kept track of through the items generated.
|
||||
fn inner_parse_loop<'root, 'tt>(
|
||||
sess: &ParseSess,
|
||||
cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
|
||||
next_items: &mut Vec<MatcherPosHandle<'root, 'tt>>,
|
||||
eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
|
||||
|
@ -563,9 +569,16 @@ fn inner_parse_loop<'root, 'tt>(
|
|||
})));
|
||||
}
|
||||
|
||||
// We need to match a metavar (but the identifier is invalid)... this is an error
|
||||
TokenTree::MetaVarDecl(span, _, None) => {
|
||||
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
|
||||
return Error(span, "missing fragment specifier".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// We need to match a metavar with a valid ident... call out to the black-box
|
||||
// parser by adding an item to `bb_items`.
|
||||
TokenTree::MetaVarDecl(span, _, kind) => {
|
||||
TokenTree::MetaVarDecl(span, _, Some(kind)) => {
|
||||
// Built-in nonterminals never start with these tokens, so we can eliminate
|
||||
// them from consideration.
|
||||
//
|
||||
|
@ -640,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
|||
// parsing from the black-box parser done. The result is that `next_items` will contain a
|
||||
// bunch of possible next matcher positions in `next_items`.
|
||||
match inner_parse_loop(
|
||||
parser.sess,
|
||||
&mut cur_items,
|
||||
&mut next_items,
|
||||
&mut eof_items,
|
||||
|
@ -701,7 +715,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
|||
let nts = bb_items
|
||||
.iter()
|
||||
.map(|item| match item.top_elts.get_tt(item.idx) {
|
||||
TokenTree::MetaVarDecl(_, bind, kind) => format!("{} ('{}')", kind, bind),
|
||||
TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
|
||||
_ => panic!(),
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
|
@ -731,7 +745,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
|||
assert_eq!(bb_items.len(), 1);
|
||||
|
||||
let mut item = bb_items.pop().unwrap();
|
||||
if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) {
|
||||
if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
|
||||
let match_cur = item.match_cur;
|
||||
// We use the span of the metavariable declaration to determine any
|
||||
// edition-specific matching behavior for non-terminals.
|
||||
|
|
|
@ -401,7 +401,7 @@ pub fn compile_declarative_macro(
|
|||
let diag = &sess.parse_sess.span_diagnostic;
|
||||
let lhs_nm = Ident::new(sym::lhs, def.span);
|
||||
let rhs_nm = Ident::new(sym::rhs, def.span);
|
||||
let tt_spec = NonterminalKind::TT;
|
||||
let tt_spec = Some(NonterminalKind::TT);
|
||||
|
||||
// Parse the macro_rules! invocation
|
||||
let (macro_rules, body) = match &def.kind {
|
||||
|
@ -578,7 +578,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
|
|||
TokenTree::Sequence(span, ref seq) => {
|
||||
if seq.separator.is_none()
|
||||
&& seq.tts.iter().all(|seq_tt| match *seq_tt {
|
||||
TokenTree::MetaVarDecl(_, _, NonterminalKind::Vis) => true,
|
||||
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
|
||||
TokenTree::Sequence(_, ref sub_seq) => {
|
||||
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|
||||
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
|
||||
|
@ -961,7 +961,7 @@ fn check_matcher_core(
|
|||
// Now `last` holds the complete set of NT tokens that could
|
||||
// end the sequence before SUFFIX. Check that every one works with `suffix`.
|
||||
for token in &last.tokens {
|
||||
if let TokenTree::MetaVarDecl(_, name, kind) = *token {
|
||||
if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token {
|
||||
for next_token in &suffix_first.tokens {
|
||||
match is_in_follow(next_token, kind) {
|
||||
IsInFollow::Yes => {}
|
||||
|
@ -1019,7 +1019,7 @@ fn check_matcher_core(
|
|||
}
|
||||
|
||||
fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
|
||||
if let mbe::TokenTree::MetaVarDecl(_, _, kind) = *tok {
|
||||
if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok {
|
||||
frag_can_be_followed_by_any(kind)
|
||||
} else {
|
||||
// (Non NT's can always be followed by anything in matchers.)
|
||||
|
@ -1123,7 +1123,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
}
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
},
|
||||
TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes,
|
||||
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
|
@ -1158,7 +1158,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
TokenTree::MetaVarDecl(
|
||||
_,
|
||||
_,
|
||||
NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path,
|
||||
Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
|
||||
) => IsInFollow::Yes,
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
|
@ -1171,7 +1171,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
|
|||
match *tt {
|
||||
mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token),
|
||||
mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
"unexpected mbe::TokenTree::{Sequence or Delimited} \
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree
|
|||
|
||||
use rustc_ast::token::{self, Token};
|
||||
use rustc_ast::tokenstream;
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
|
@ -73,7 +73,7 @@ pub(super) fn parse(
|
|||
.emit();
|
||||
token::NonterminalKind::Ident
|
||||
});
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, kind));
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
|
||||
continue;
|
||||
}
|
||||
_ => token.span,
|
||||
|
@ -83,8 +83,11 @@ pub(super) fn parse(
|
|||
}
|
||||
tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp),
|
||||
};
|
||||
sess.span_diagnostic.struct_span_err(span, "missing fragment specifier").emit();
|
||||
continue;
|
||||
if node_id != DUMMY_NODE_ID {
|
||||
// Macros loaded from other crates have dummy node ids.
|
||||
sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id);
|
||||
}
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, None));
|
||||
}
|
||||
|
||||
// Not a metavar or no matchers allowed, so just return the tree
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue