diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-04-05 13:18:17 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-05 13:18:17 +1100 |
| commit | 66ccc4fe28785e4e7d6f3b59eadbffd5296f8ad7 (patch) | |
| tree | ab8653e1f67995ce243188f582e73f9a4dce06cf /compiler/rustc_parse/src | |
| parent | 6907e011e452751b687b17dfd7178e02b62f5707 (diff) | |
| parent | b9e13cb539c23a320e3856eba82711cd6360407e (diff) | |
| download | rust-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.rs | 17 |
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) |
