about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-04-05 13:18:17 +1100
committerGitHub <noreply@github.com>2025-04-05 13:18:17 +1100
commit66ccc4fe28785e4e7d6f3b59eadbffd5296f8ad7 (patch)
treeab8653e1f67995ce243188f582e73f9a4dce06cf /compiler/rustc_parse/src
parent6907e011e452751b687b17dfd7178e02b62f5707 (diff)
parentb9e13cb539c23a320e3856eba82711cd6360407e (diff)
downloadrust-66ccc4fe28785e4e7d6f3b59eadbffd5296f8ad7.tar.gz
rust-66ccc4fe28785e4e7d6f3b59eadbffd5296f8ad7.zip
Rollup merge of #139341 - nnethercote:fix-137874, r=petrochenkov
Apply `Recovery::Forbidden` when reparsing pasted macro fragments.

Fixes #137874.

The changes to the output of `tests/ui/associated-consts/issue-93835.rs`
partly undo the changes seen when `NtTy` was removed in #133436, which
is good.

r? ``@petrochenkov``
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 392a1c1057a..3b0861a9942 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -512,6 +512,14 @@ impl<'a> Parser<'a> {
         self
     }
 
+    #[inline]
+    fn with_recovery<T>(&mut self, recovery: Recovery, f: impl FnOnce(&mut Self) -> T) -> T {
+        let old = mem::replace(&mut self.recovery, recovery);
+        let res = f(self);
+        self.recovery = old;
+        res
+    }
+
     /// Whether the parser is allowed to recover from broken code.
     ///
     /// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
@@ -770,7 +778,14 @@ impl<'a> Parser<'a> {
             && match_mv_kind(mv_kind)
         {
             self.bump();
-            let res = f(self).expect("failed to reparse {mv_kind:?}");
+
+            // Recovery is disabled when parsing macro arguments, so it must
+            // also be disabled when reparsing pasted macro arguments,
+            // otherwise we get inconsistent results (e.g. #137874).
+            let res = self.with_recovery(Recovery::Forbidden, |this| {
+                f(this).expect("failed to reparse {mv_kind:?}")
+            });
+
             if let token::CloseDelim(delim) = self.token.kind
                 && let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim
                 && match_mv_kind(mv_kind)