Skip to content

Commit ed14202

Browse files
committed
Add flag to forbid recovery in the parser
1 parent 85d089b commit ed14202

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ fn expand_macro<'cx>(
250250
// hacky, but speeds up the `html5ever` benchmark significantly. (Issue
251251
// 68836 suggests a more comprehensive but more complex change to deal with
252252
// this situation.)
253+
// FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
253254
let parser = parser_from_cx(sess, arg.clone());
254255

255256
// Try each arm's matchers.

compiler/rustc_parse/src/parser/expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,8 @@ impl<'a> Parser<'a> {
21122112
// HACK: This is needed so we can detect whether we're inside a macro,
21132113
// where regular assumptions about what tokens can follow other tokens
21142114
// don't necessarily apply.
2115+
&& self.may_recover()
2116+
// FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
21152117
&& self.subparser_name.is_none()
21162118
{
21172119
// It is likely that the closure body is a block but where the

compiler/rustc_parse/src/parser/mod.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
115115
};
116116
}
117117

118+
#[derive(Clone, Copy)]
119+
pub enum Recovery {
120+
Allowed,
121+
Forbidden,
122+
}
123+
118124
#[derive(Clone)]
119125
pub struct Parser<'a> {
120126
pub sess: &'a ParseSess,
@@ -152,12 +158,15 @@ pub struct Parser<'a> {
152158
/// This allows us to recover when the user forget to add braces around
153159
/// multiple statements in the closure body.
154160
pub current_closure: Option<ClosureSpans>,
161+
/// Whether the parser is allowed to recover and parse invalid code successfully (and emit a diagnostic as a side effect).
162+
/// This is disabled when parsing macro arguments, see #103534
163+
pub recovery: Recovery,
155164
}
156165

157-
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
166+
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
158167
// it doesn't unintentionally get bigger.
159168
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
160-
rustc_data_structures::static_assert_size!(Parser<'_>, 328);
169+
rustc_data_structures::static_assert_size!(Parser<'_>, 336);
161170

162171
/// Stores span information about a closure.
163172
#[derive(Clone)]
@@ -483,6 +492,7 @@ impl<'a> Parser<'a> {
483492
inner_attr_ranges: Default::default(),
484493
},
485494
current_closure: None,
495+
recovery: Recovery::Allowed,
486496
};
487497

488498
// Make parser point to the first token.
@@ -491,6 +501,15 @@ impl<'a> Parser<'a> {
491501
parser
492502
}
493503

504+
pub fn forbid_recovery(mut self) -> Self {
505+
self.recovery = Recovery::Forbidden;
506+
self
507+
}
508+
509+
fn may_recover(&self) -> bool {
510+
matches!(self.recovery, Recovery::Allowed)
511+
}
512+
494513
pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
495514
match self.expect_one_of(&[], &[]) {
496515
Err(e) => Err(e),

0 commit comments

Comments
 (0)