about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2022-10-25 21:24:01 +0200
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2022-10-25 22:06:53 +0200
commited142028641079918b95b539f0570e92469687fe (patch)
tree6e084cde0588b24bb9c1d3e410843828fcfd8e77 /compiler/rustc_parse/src/parser
parent85d089b41e2a0c0f07ab34f6c5a7c451389f25e6 (diff)
downloadrust-ed142028641079918b95b539f0570e92469687fe.tar.gz
rust-ed142028641079918b95b539f0570e92469687fe.zip
Add flag to forbid recovery in the parser
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs23
2 files changed, 23 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ca216b1cd10..a781748efc5 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2112,6 +2112,8 @@ impl<'a> Parser<'a> {
             // HACK: This is needed so we can detect whether we're inside a macro,
             // where regular assumptions about what tokens can follow other tokens
             // don't necessarily apply.
+            && self.may_recover()
+            // FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
             && self.subparser_name.is_none()
         {
             // It is likely that the closure body is a block but where the
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 89c24920f85..89f7ab930b1 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -115,6 +115,12 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
     };
 }
 
+#[derive(Clone, Copy)]
+pub enum Recovery {
+    Allowed,
+    Forbidden,
+}
+
 #[derive(Clone)]
 pub struct Parser<'a> {
     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
     /// multiple statements in the closure body.
     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.
 #[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.
 #[derive(Clone)]
@@ -483,6 +492,7 @@ impl<'a> Parser<'a> {
                 inner_attr_ranges: Default::default(),
             },
             current_closure: None,
+            recovery: Recovery::Allowed,
         };
 
         // Make parser point to the first token.
@@ -491,6 +501,15 @@ impl<'a> Parser<'a> {
         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> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => Err(e),