]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #107813 - compiler-errors:bad-impl-trait-in-macro-is-ok, r=estebank
authorMichael Goulet <michael@errs.io>
Thu, 9 Feb 2023 04:01:26 +0000 (20:01 -0800)
committerGitHub <noreply@github.com>
Thu, 9 Feb 2023 04:01:26 +0000 (20:01 -0800)
Do not eagerly recover for bad `impl Trait` types in macros

Fixes #107796

cc #106712, ```@estebank``` and ```@Ezrashaw``` please make sure to use [`Parser::may_recover`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.may_recover) for all eager-token-consuming parser recoveries.

This also fixes a separate regression from #99915, that was introduced before we added `may_recover` though.

compiler/rustc_parse/src/parser/ty.rs
tests/ui/parser/bad-recover-kw-after-impl.rs [new file with mode: 0644]
tests/ui/parser/bad-recover-ty-after-impl.rs [new file with mode: 0644]

index a19ea04fa5e75e47128fa769952be3b6083a68c6..5b92563fc358b68b1bbf824feacef2d9542e4a09 100644 (file)
@@ -694,8 +694,9 @@ fn parse_generic_bounds_common(
         // `where`, so stop if it's it.
         // We also continue if we find types (not traits), again for error recovery.
         while self.can_begin_bound()
-            || self.token.can_begin_type()
-            || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
+            || (self.may_recover()
+                && (self.token.can_begin_type()
+                    || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
         {
             if self.token.is_keyword(kw::Dyn) {
                 // Account for `&dyn Trait + dyn Other`.
diff --git a/tests/ui/parser/bad-recover-kw-after-impl.rs b/tests/ui/parser/bad-recover-kw-after-impl.rs
new file mode 100644 (file)
index 0000000..218cd76
--- /dev/null
@@ -0,0 +1,15 @@
+// check-pass
+
+// edition:2021
+// for the `impl` + keyword test
+
+macro_rules! impl_primitive {
+    ($ty:ty) => {
+        compile_error!("whoops");
+    };
+    (impl async) => {};
+}
+
+impl_primitive!(impl async);
+
+fn main() {}
diff --git a/tests/ui/parser/bad-recover-ty-after-impl.rs b/tests/ui/parser/bad-recover-ty-after-impl.rs
new file mode 100644 (file)
index 0000000..510e08b
--- /dev/null
@@ -0,0 +1,17 @@
+// check-pass
+
+macro_rules! impl_primitive {
+    ($ty:ty) => { impl_primitive!(impl $ty); };
+    (impl $ty:ty) => { fn a(_: $ty) {} }
+}
+
+impl_primitive! { u8 }
+
+macro_rules! test {
+    ($ty:ty) => { compile_error!("oh no"); };
+    (impl &) => {};
+}
+
+test!(impl &);
+
+fn main() {}