Add flag to forbid recovery in the parser
This commit is contained in:
parent
85d089b41e
commit
ed14202864
3 changed files with 24 additions and 2 deletions
|
@ -250,6 +250,7 @@ fn expand_macro<'cx>(
|
||||||
// hacky, but speeds up the `html5ever` benchmark significantly. (Issue
|
// hacky, but speeds up the `html5ever` benchmark significantly. (Issue
|
||||||
// 68836 suggests a more comprehensive but more complex change to deal with
|
// 68836 suggests a more comprehensive but more complex change to deal with
|
||||||
// this situation.)
|
// this situation.)
|
||||||
|
// FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
|
||||||
let parser = parser_from_cx(sess, arg.clone());
|
let parser = parser_from_cx(sess, arg.clone());
|
||||||
|
|
||||||
// Try each arm's matchers.
|
// Try each arm's matchers.
|
||||||
|
|
|
@ -2112,6 +2112,8 @@ impl<'a> Parser<'a> {
|
||||||
// HACK: This is needed so we can detect whether we're inside a macro,
|
// HACK: This is needed so we can detect whether we're inside a macro,
|
||||||
// where regular assumptions about what tokens can follow other tokens
|
// where regular assumptions about what tokens can follow other tokens
|
||||||
// don't necessarily apply.
|
// don't necessarily apply.
|
||||||
|
&& self.may_recover()
|
||||||
|
// FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
|
||||||
&& self.subparser_name.is_none()
|
&& self.subparser_name.is_none()
|
||||||
{
|
{
|
||||||
// It is likely that the closure body is a block but where the
|
// It is likely that the closure body is a block but where the
|
||||||
|
|
|
@ -115,6 +115,12 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Recovery {
|
||||||
|
Allowed,
|
||||||
|
Forbidden,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
pub sess: &'a ParseSess,
|
pub sess: &'a ParseSess,
|
||||||
|
@ -152,12 +158,15 @@ pub struct Parser<'a> {
|
||||||
/// This allows us to recover when the user forget to add braces around
|
/// This allows us to recover when the user forget to add braces around
|
||||||
/// multiple statements in the closure body.
|
/// multiple statements in the closure body.
|
||||||
pub current_closure: Option<ClosureSpans>,
|
pub current_closure: Option<ClosureSpans>,
|
||||||
|
/// Whether the parser is allowed to recover and parse invalid code successfully (and emit a diagnostic as a side effect).
|
||||||
|
/// This is disabled when parsing macro arguments, see #103534
|
||||||
|
pub recovery: Recovery,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
|
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
|
||||||
// it doesn't unintentionally get bigger.
|
// it doesn't unintentionally get bigger.
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
rustc_data_structures::static_assert_size!(Parser<'_>, 328);
|
rustc_data_structures::static_assert_size!(Parser<'_>, 336);
|
||||||
|
|
||||||
/// Stores span information about a closure.
|
/// Stores span information about a closure.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -483,6 +492,7 @@ impl<'a> Parser<'a> {
|
||||||
inner_attr_ranges: Default::default(),
|
inner_attr_ranges: Default::default(),
|
||||||
},
|
},
|
||||||
current_closure: None,
|
current_closure: None,
|
||||||
|
recovery: Recovery::Allowed,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make parser point to the first token.
|
// Make parser point to the first token.
|
||||||
|
@ -491,6 +501,15 @@ impl<'a> Parser<'a> {
|
||||||
parser
|
parser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn forbid_recovery(mut self) -> Self {
|
||||||
|
self.recovery = Recovery::Forbidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn may_recover(&self) -> bool {
|
||||||
|
matches!(self.recovery, Recovery::Allowed)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
|
pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
|
||||||
match self.expect_one_of(&[], &[]) {
|
match self.expect_one_of(&[], &[]) {
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue