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 | |
| 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``
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 17 | ||||
| -rw-r--r-- | tests/crashes/137874.rs | 4 | ||||
| -rw-r--r-- | tests/ui/associated-consts/issue-93835.rs | 3 | ||||
| -rw-r--r-- | tests/ui/associated-consts/issue-93835.stderr | 32 | ||||
| -rw-r--r-- | tests/ui/macros/failed-to-reparse-issue-137874.rs | 12 | ||||
| -rw-r--r-- | tests/ui/macros/failed-to-reparse-issue-137874.stderr | 10 |
7 files changed, 48 insertions, 33 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 28f596ac092..958a6917dff 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -676,12 +676,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); let safety = self.lower_safety(*safety, hir::Safety::Unsafe); - - // njn: where for this? if define_opaque.is_some() { self.dcx().span_err(i.span, "foreign statics cannot define opaque types"); } - (ident, hir::ForeignItemKind::Static(ty, *mutability, safety)) } ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => { 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) diff --git a/tests/crashes/137874.rs b/tests/crashes/137874.rs deleted file mode 100644 index 44718809024..00000000000 --- a/tests/crashes/137874.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #137874 -fn a() { - match b { deref !(0c) }; -} diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs index 048681f0477..d6c2acaa9ed 100644 --- a/tests/ui/associated-consts/issue-93835.rs +++ b/tests/ui/associated-consts/issue-93835.rs @@ -3,11 +3,10 @@ fn e() { type_ascribe!(p, a<p:p<e=6>>); //~^ ERROR cannot find type `a` in this scope - //~| ERROR path separator must be a double colon //~| ERROR cannot find value //~| ERROR associated const equality + //~| ERROR cannot find trait `p` in this scope //~| ERROR associated const equality - //~| ERROR failed to resolve: use of unresolved module or unlinked crate `p` } fn main() {} diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr index e154ae25de2..551b50d0eb6 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/associated-consts/issue-93835.stderr @@ -1,15 +1,3 @@ -error: path separator must be a double colon - --> $DIR/issue-93835.rs:4:25 - | -LL | type_ascribe!(p, a<p:p<e=6>>); - | ^ - | - = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728> -help: use a double colon instead - | -LL | type_ascribe!(p, a<p::p<e=6>>); - | + - error[E0425]: cannot find value `p` in this scope --> $DIR/issue-93835.rs:4:19 | @@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope LL | type_ascribe!(p, a<p:p<e=6>>); | ^ not found in this scope +error[E0405]: cannot find trait `p` in this scope + --> $DIR/issue-93835.rs:4:26 + | +LL | type_ascribe!(p, a<p:p<e=6>>); + | ^ not found in this scope + error[E0658]: associated const equality is incomplete --> $DIR/issue-93835.rs:4:28 | @@ -43,15 +37,7 @@ LL | type_ascribe!(p, a<p:p<e=6>>); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p` - --> $DIR/issue-93835.rs:4:24 - | -LL | type_ascribe!(p, a<p:p<e=6>>); - | ^ use of unresolved module or unlinked crate `p` - | - = help: you might be missing a crate named `p` - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0412, E0425, E0433, E0658. -For more information about an error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0405, E0412, E0425, E0658. +For more information about an error, try `rustc --explain E0405`. diff --git a/tests/ui/macros/failed-to-reparse-issue-137874.rs b/tests/ui/macros/failed-to-reparse-issue-137874.rs new file mode 100644 index 00000000000..3e55ac376fe --- /dev/null +++ b/tests/ui/macros/failed-to-reparse-issue-137874.rs @@ -0,0 +1,12 @@ +// This originally crashed because `Recovery::Forbidden` wasn't being applied +// when fragments pasted by declarative macros were reparsed. + +macro_rules! m { + ($p:pat) => { + if let $p = 0 {} + } +} + +fn main() { + m!(0X0); //~ ERROR invalid base prefix for number literal +} diff --git a/tests/ui/macros/failed-to-reparse-issue-137874.stderr b/tests/ui/macros/failed-to-reparse-issue-137874.stderr new file mode 100644 index 00000000000..5bbb8b7f9e2 --- /dev/null +++ b/tests/ui/macros/failed-to-reparse-issue-137874.stderr @@ -0,0 +1,10 @@ +error: invalid base prefix for number literal + --> $DIR/failed-to-reparse-issue-137874.rs:11:8 + | +LL | m!(0X0); + | ^^^ help: try making the prefix lowercase (notice the capitalization): `0x0` + | + = note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + +error: aborting due to 1 previous error + |
