Skip to content

Remove Parser::missing_fragment_specifier. #95747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ use rustc_ast::token::{DelimToken, Token, TokenKind};
use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::MultiSpan;
use rustc_session::lint::builtin::META_VARIABLE_MISUSE;
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
use rustc_session::parse::ParseSess;
use rustc_span::symbol::kw;
use rustc_span::{symbol::MacroRulesNormalizedIdent, Span};
Expand Down Expand Up @@ -261,7 +261,16 @@ fn check_binders(
}
}
// Similarly, this can only happen when checking a toplevel macro.
TokenTree::MetaVarDecl(span, name, _kind) => {
TokenTree::MetaVarDecl(span, name, kind) => {
if kind.is_none() {
sess.buffer_lint(
MISSING_FRAGMENT_SPECIFIER,
span,
node_id,
&format!("missing fragment specifier"),
);
*valid = false;
}
if !macros.is_empty() {
sess.span_diagnostic.span_bug(span, "unexpected MetaVarDecl in nested lhs");
}
Expand Down
52 changes: 15 additions & 37 deletions compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub(super) enum MatcherLoc {
MetaVarDecl {
span: Span,
bind: Ident,
kind: Option<NonterminalKind>,
kind: NonterminalKind,
next_metavar: usize,
seq_depth: usize,
},
Expand Down Expand Up @@ -189,7 +189,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match
locs.push(MatcherLoc::MetaVarDecl {
span,
bind,
kind,
kind: kind.unwrap(), // presence was checked for earlier
next_metavar: *next_metavar,
seq_depth,
});
Expand Down Expand Up @@ -409,7 +409,6 @@ impl TtParser {
/// track of through the mps generated.
fn parse_tt_inner(
&mut self,
sess: &ParseSess,
matcher: &[MatcherLoc],
token: &Token,
) -> Option<NamedParseResult> {
Expand Down Expand Up @@ -508,20 +507,12 @@ impl TtParser {
mp.idx = idx_first;
self.cur_mps.push(mp);
}
&MatcherLoc::MetaVarDecl { span, kind, .. } => {
&MatcherLoc::MetaVarDecl { kind, .. } => {
// Built-in nonterminals never start with these tokens, so we can eliminate
// them from consideration. We use the span of the metavariable declaration
// to determine any edition-specific matching behavior for non-terminals.
if let Some(kind) = kind {
if Parser::nonterminal_may_begin_with(kind, token) {
self.bb_mps.push(mp);
}
} else {
// Both this check and the one in `nameize` are necessary, surprisingly.
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
// E.g. `$e` instead of `$e:expr`.
return Some(Error(span, "missing fragment specifier".to_string()));
}
if Parser::nonterminal_may_begin_with(kind, token) {
self.bb_mps.push(mp);
}
}
MatcherLoc::Eof => {
Expand All @@ -547,7 +538,7 @@ impl TtParser {
// Need to take ownership of the matches from within the `Lrc`.
Lrc::make_mut(&mut eof_mp.matches);
let matches = Lrc::try_unwrap(eof_mp.matches).unwrap().into_iter();
self.nameize(sess, matcher, matches)
self.nameize(matcher, matches)
}
EofMatcherPositions::Multiple => {
Error(token.span, "ambiguity: multiple successful parses".to_string())
Expand Down Expand Up @@ -585,7 +576,7 @@ impl TtParser {

// Process `cur_mps` until either we have finished the input or we need to get some
// parsing from the black-box parser done.
if let Some(res) = self.parse_tt_inner(&parser.sess, matcher, &parser.token) {
if let Some(res) = self.parse_tt_inner(matcher, &parser.token) {
return res;
}

Expand Down Expand Up @@ -615,11 +606,7 @@ impl TtParser {
let mut mp = self.bb_mps.pop().unwrap();
let loc = &matcher[mp.idx];
if let &MatcherLoc::MetaVarDecl {
span,
kind: Some(kind),
next_metavar,
seq_depth,
..
span, kind, next_metavar, seq_depth, ..
} = loc
{
// We use the span of the metavariable declaration to determine any
Expand Down Expand Up @@ -668,7 +655,7 @@ impl TtParser {
.bb_mps
.iter()
.map(|mp| match &matcher[mp.idx] {
MatcherLoc::MetaVarDecl { bind, kind: Some(kind), .. } => {
MatcherLoc::MetaVarDecl { bind, kind, .. } => {
format!("{} ('{}')", kind, bind)
}
_ => unreachable!(),
Expand All @@ -692,29 +679,20 @@ impl TtParser {

fn nameize<I: Iterator<Item = NamedMatch>>(
&self,
sess: &ParseSess,
matcher: &[MatcherLoc],
mut res: I,
) -> NamedParseResult {
// Make that each metavar has _exactly one_ binding. If so, insert the binding into the
// `NamedParseResult`. Otherwise, it's an error.
let mut ret_val = FxHashMap::default();
for loc in matcher {
if let &MatcherLoc::MetaVarDecl { span, bind, kind, .. } = loc {
if kind.is_some() {
match ret_val.entry(MacroRulesNormalizedIdent::new(bind)) {
Vacant(spot) => spot.insert(res.next().unwrap()),
Occupied(..) => {
return Error(span, format!("duplicated bind name: {}", bind));
}
};
} else {
// Both this check and the one in `parse_tt_inner` are necessary, surprisingly.
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
// E.g. `$e` instead of `$e:expr`.
return Error(span, "missing fragment specifier".to_string());
if let &MatcherLoc::MetaVarDecl { span, bind, .. } = loc {
match ret_val.entry(MacroRulesNormalizedIdent::new(bind)) {
Vacant(spot) => spot.insert(res.next().unwrap()),
Occupied(..) => {
return Error(span, format!("duplicated bind name: {}", bind));
}
}
};
}
}
Success(ret_val)
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_expand/src/mbe/quoted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetiti

use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream;
use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast::NodeId;
use rustc_ast_pretty::pprust;
use rustc_feature::Features;
use rustc_session::parse::{feature_err, ParseSess};
Expand Down Expand Up @@ -102,10 +102,6 @@ pub(super) fn parse(
}
tree => tree.as_ref().map_or(start_sp, tokenstream::TokenTree::span),
};
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));
}

Expand Down
16 changes: 0 additions & 16 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use rustc_resolve::{Resolver, ResolverArenas};
use rustc_serialize::json;
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn};
use rustc_session::lint;
use rustc_session::output::{filename_for_input, filename_for_metadata};
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
Expand Down Expand Up @@ -349,23 +348,8 @@ pub fn configure_and_expand(
ecx.check_unused_macros();
});

let mut missing_fragment_specifiers: Vec<_> = ecx
.sess
.parse_sess
.missing_fragment_specifiers
.borrow()
.iter()
.map(|(span, node_id)| (*span, *node_id))
.collect();
missing_fragment_specifiers.sort_unstable_by_key(|(span, _)| *span);

let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();

for (span, node_id) in missing_fragment_specifiers {
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
let msg = "missing fragment specifier";
resolver.lint_buffer().buffer_lint(lint, node_id, span, msg);
}
if cfg!(windows) {
env::set_var("PATH", &old_path);
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ pub struct ParseSess {
pub config: CrateConfig,
pub check_config: CrateCheckConfig,
pub edition: Edition,
pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
/// Places where raw identifiers were used. This is used to avoid complaining about idents
/// clashing with keywords in new editions.
pub raw_identifier_spans: Lock<Vec<Span>>,
Expand Down Expand Up @@ -195,7 +194,6 @@ impl ParseSess {
config: FxHashSet::default(),
check_config: CrateCheckConfig::default(),
edition: ExpnId::root().expn_data().edition,
missing_fragment_specifiers: Default::default(),
raw_identifier_spans: Lock::new(Vec::new()),
bad_unicode_identifiers: Lock::new(Default::default()),
source_map,
Expand Down