about summary refs log tree commit diff
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
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``
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs3
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs17
-rw-r--r--tests/crashes/137874.rs4
-rw-r--r--tests/ui/associated-consts/issue-93835.rs3
-rw-r--r--tests/ui/associated-consts/issue-93835.stderr32
-rw-r--r--tests/ui/macros/failed-to-reparse-issue-137874.rs12
-rw-r--r--tests/ui/macros/failed-to-reparse-issue-137874.stderr10
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
+