]> git.lizzy.rs Git - rust.git/commitdiff
Teach parser to understand fake anonymous enum syntax
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 15 Jan 2023 22:36:46 +0000 (22:36 +0000)
committerEsteban Küber <esteban@kuber.com.ar>
Tue, 17 Jan 2023 01:58:32 +0000 (01:58 +0000)
Parse `-> Ty | OtherTy`.
Parse type ascription in top level patterns.

13 files changed:
compiler/rustc_ast/src/ast.rs
compiler/rustc_ast/src/mut_visit.rs
compiler/rustc_ast/src/visit.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_pretty/src/pprust/state.rs
compiler/rustc_parse/src/parser/diagnostics.rs
compiler/rustc_parse/src/parser/pat.rs
compiler/rustc_parse/src/parser/ty.rs
compiler/rustc_passes/src/hir_stats.rs
src/tools/rustfmt/src/types.rs
tests/ui/parser/anon-enums.rs [new file with mode: 0644]
tests/ui/parser/anon-enums.stderr [new file with mode: 0644]
tests/ui/parser/issues/issue-87086-colon-path-sep.stderr

index 7de594719ddc44568872ea3ee2516da728a96ada..3aad51325dcd6c98a9ca4d736eb29d1debe5ceed 100644 (file)
@@ -2096,6 +2096,9 @@ pub enum TyKind {
     Err,
     /// Placeholder for a `va_list`.
     CVarArgs,
+    /// Placeholder for "anonymous enums", which don't exist, but keeping their
+    /// information around lets us produce better diagnostics.
+    AnonEnum(Vec<P<Ty>>),
 }
 
 impl TyKind {
index 77f342d1eb322efe2a35deb211006e6408a243b5..894885cf0fea7cd2fe23bbc192c22de101e242ed 100644 (file)
@@ -470,7 +470,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             vis.visit_fn_decl(decl);
             vis.visit_span(decl_span);
         }
-        TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
+        TyKind::AnonEnum(tys) | TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
         TyKind::Paren(ty) => vis.visit_ty(ty),
         TyKind::Path(qself, path) => {
             vis.visit_qself(qself);
index e8823eff83afe1bab63061dd862a7ed40af53575..1ab70f0309c0142e2ef9c41b5745906e24c817e1 100644 (file)
@@ -400,8 +400,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
             visitor.visit_ty(&mutable_type.ty)
         }
-        TyKind::Tup(tuple_element_types) => {
-            walk_list!(visitor, visit_ty, tuple_element_types);
+        TyKind::AnonEnum(tys) | TyKind::Tup(tys) => {
+            walk_list!(visitor, visit_ty, tys);
         }
         TyKind::BareFn(function_declaration) => {
             walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
index 41d4a5679f1a0b2822396af1256c20e5497350a0..a60d02002da33d6648a6ce81cf920401afd53096 100644 (file)
@@ -1235,6 +1235,7 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir>
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => hir::TyKind::Err,
+            TyKind::AnonEnum(_) => hir::TyKind::Err,
             TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Ref(region, mt) => {
index 6a8064b0e874e84fc7731af56d705b41457d861d..3f9b96a6158a16fb62b38d029068225a3ca8e138 100644 (file)
@@ -1041,6 +1041,9 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
                 }
                 self.pclose();
             }
+            ast::TyKind::AnonEnum(elts) => {
+                self.strsep("|", false, Inconsistent, elts, |s, ty| s.print_type(ty));
+            }
             ast::TyKind::Paren(typ) => {
                 self.popen();
                 self.print_type(typ);
index 4c918c6702ed9b19f3a2ed08af51506c50e17666..07bd76dc39ba9fee87694b885a0ed2ea207c785b 100644 (file)
@@ -2372,7 +2372,7 @@ pub fn dummy_const_arg_needs_braces(
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
+    pub(crate) fn maybe_recover_colon_colon_in_pat_typo_or_anon_enum(
         &mut self,
         mut first_pat: P<Pat>,
         expected: Expected,
@@ -2383,26 +2383,41 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
         if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
             || !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
         {
+            let mut snapshot_type = self.create_snapshot_for_diagnostic();
+            snapshot_type.bump(); // `:`
+            match snapshot_type.parse_ty() {
+                Err(inner_err) => {
+                    inner_err.cancel();
+                }
+                Ok(ty) => {
+                    let Err(mut err) = self.expected_one_of_not_found(&[], &[]) else {
+                        return first_pat;
+                    };
+                    err.span_label(ty.span, "specifying the type of a pattern isn't supported");
+                    self.restore_snapshot(snapshot_type);
+                    let span = first_pat.span.to(ty.span);
+                    first_pat = self.mk_pat(span, PatKind::Wild);
+                    err.emit();
+                }
+            }
             return first_pat;
         }
         // The pattern looks like it might be a path with a `::` -> `:` typo:
         // `match foo { bar:baz => {} }`
-        let span = self.token.span;
+        let colon_span = self.token.span;
         // We only emit "unexpected `:`" error here if we can successfully parse the
         // whole pattern correctly in that case.
-        let snapshot = self.create_snapshot_for_diagnostic();
+        let mut snapshot_pat = self.create_snapshot_for_diagnostic();
+        let mut snapshot_type = self.create_snapshot_for_diagnostic();
 
         // Create error for "unexpected `:`".
         match self.expected_one_of_not_found(&[], &[]) {
             Err(mut err) => {
-                self.bump(); // Skip the `:`.
-                match self.parse_pat_no_top_alt(expected) {
+                snapshot_pat.bump(); // Skip the `:`.
+                snapshot_type.bump(); // Skip the `:`.
+                match snapshot_pat.parse_pat_no_top_alt(expected) {
                     Err(inner_err) => {
-                        // Carry on as if we had not done anything, callers will emit a
-                        // reasonable error.
                         inner_err.cancel();
-                        err.cancel();
-                        self.restore_snapshot(snapshot);
                     }
                     Ok(mut pat) => {
                         // We've parsed the rest of the pattern.
@@ -2466,8 +2481,8 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
                             _ => {}
                         }
                         if show_sugg {
-                            err.span_suggestion(
-                                span,
+                            err.span_suggestion_verbose(
+                                colon_span.until(self.look_ahead(1, |t| t.span)),
                                 "maybe write a path separator here",
                                 "::",
                                 Applicability::MaybeIncorrect,
@@ -2475,13 +2490,22 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
                         } else {
                             first_pat = self.mk_pat(new_span, PatKind::Wild);
                         }
-                        err.emit();
+                        self.restore_snapshot(snapshot_pat);
                     }
                 }
+                match snapshot_type.parse_ty() {
+                    Err(inner_err) => {
+                        inner_err.cancel();
+                    }
+                    Ok(ty) => {
+                        err.span_label(ty.span, "specifying the type of a pattern isn't supported");
+                        self.restore_snapshot(snapshot_type);
+                    }
+                }
+                err.emit();
             }
             _ => {
                 // Carry on as if we had not done anything. This should be unreachable.
-                self.restore_snapshot(snapshot);
             }
         };
         first_pat
index e73a17ced7deb2598f52a013189ee3392e379547..e5411538eea220ce5ff179026be98d677b08dc67 100644 (file)
@@ -116,7 +116,8 @@ fn parse_pat_allow_top_alt_inner(
 
             // Check if the user wrote `foo:bar` instead of `foo::bar`.
             if ra == RecoverColon::Yes {
-                first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
+                first_pat =
+                    self.maybe_recover_colon_colon_in_pat_typo_or_anon_enum(first_pat, expected);
             }
 
             if let Some(leading_vert_span) = leading_vert_span {
index a6f702e5428694aa4077eeae5363c905674c030e..72994df6f9f46fc69ef488bc232eafe360340192 100644 (file)
@@ -11,6 +11,7 @@
     self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime,
     MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
 };
+use rustc_ast_pretty::pprust;
 use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, sym, Ident};
@@ -43,17 +44,24 @@ pub(super) enum AllowPlus {
     No,
 }
 
-#[derive(PartialEq)]
+#[derive(PartialEq, Clone, Copy)]
 pub(super) enum RecoverQPath {
     Yes,
     No,
 }
 
+#[derive(PartialEq, Clone, Copy)]
 pub(super) enum RecoverQuestionMark {
     Yes,
     No,
 }
 
+#[derive(PartialEq, Clone, Copy)]
+pub(super) enum RecoverAnonEnum {
+    Yes,
+    No,
+}
+
 /// Signals whether parsing a type should recover `->`.
 ///
 /// More specifically, when parsing a function like:
@@ -86,7 +94,7 @@ fn can_recover(self, token: &TokenKind) -> bool {
 }
 
 // Is `...` (`CVarArgs`) legal at this level of type parsing?
-#[derive(PartialEq)]
+#[derive(PartialEq, Clone, Copy)]
 enum AllowCVariadic {
     Yes,
     No,
@@ -111,6 +119,7 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -125,6 +134,7 @@ pub(super) fn parse_ty_with_generics_recovery(
             RecoverReturnSign::Yes,
             Some(ty_params),
             RecoverQuestionMark::Yes,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -139,6 +149,7 @@ pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
+            RecoverAnonEnum::Yes,
         )
     }
 
@@ -156,6 +167,7 @@ pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -169,6 +181,7 @@ pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::No,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -180,6 +193,7 @@ pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::No,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -192,6 +206,7 @@ pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
             RecoverReturnSign::OnlyFatArrow,
             None,
             RecoverQuestionMark::Yes,
+            RecoverAnonEnum::No,
         )
     }
 
@@ -211,6 +226,7 @@ pub(super) fn parse_ret_ty(
                 recover_return_sign,
                 None,
                 RecoverQuestionMark::Yes,
+                RecoverAnonEnum::Yes,
             )?;
             FnRetTy::Ty(ty)
         } else if recover_return_sign.can_recover(&self.token.kind) {
@@ -232,6 +248,7 @@ pub(super) fn parse_ret_ty(
                 recover_return_sign,
                 None,
                 RecoverQuestionMark::Yes,
+                RecoverAnonEnum::Yes,
             )?;
             FnRetTy::Ty(ty)
         } else {
@@ -247,6 +264,7 @@ fn parse_ty_common(
         recover_return_sign: RecoverReturnSign,
         ty_generics: Option<&Generics>,
         recover_question_mark: RecoverQuestionMark,
+        recover_anon_enum: RecoverAnonEnum,
     ) -> PResult<'a, P<Ty>> {
         let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
@@ -325,14 +343,55 @@ fn parse_ty_common(
         let mut ty = self.mk_ty(span, kind);
 
         // Try to recover from use of `+` with incorrect priority.
-        if matches!(allow_plus, AllowPlus::Yes) {
+        if allow_plus == AllowPlus::Yes {
             self.maybe_recover_from_bad_type_plus(&ty)?;
         } else {
             self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty);
         }
-        if let RecoverQuestionMark::Yes = recover_question_mark {
+        if RecoverQuestionMark::Yes == recover_question_mark {
             ty = self.maybe_recover_from_question_mark(ty);
         }
+        if recover_anon_enum == RecoverAnonEnum::Yes
+            && self.check_noexpect(&token::BinOp(token::Or))
+            && self.look_ahead(1, |t| t.can_begin_type())
+        {
+            let mut pipes = vec![self.token.span];
+            let mut types = vec![ty];
+            loop {
+                if !self.eat(&token::BinOp(token::Or)) {
+                    break;
+                }
+                pipes.push(self.prev_token.span);
+                types.push(self.parse_ty_common(
+                    allow_plus,
+                    allow_c_variadic,
+                    recover_qpath,
+                    recover_return_sign,
+                    ty_generics,
+                    recover_question_mark,
+                    RecoverAnonEnum::No,
+                )?);
+            }
+            let mut err = self.struct_span_err(pipes, "anonymous enums are not supported");
+            for ty in &types {
+                err.span_label(ty.span, "");
+            }
+            err.help(&format!(
+                "create a named `enum` and use it here instead:\nenum Name {{\n{}\n}}",
+                types
+                    .iter()
+                    .enumerate()
+                    .map(|(i, t)| format!(
+                        "    Variant{}({}),",
+                        i + 1, // Lets not confuse people with zero-indexing :)
+                        pprust::to_string(|s| s.print_type(&t)),
+                    ))
+                    .collect::<Vec<_>>()
+                    .join("\n"),
+            ));
+            err.emit();
+            return Ok(self.mk_ty(lo.to(self.prev_token.span), TyKind::AnonEnum(types)));
+        }
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
index b86d2316820cec75ab3fa744079775fa22151d6c..312bd8839e0d0ed9a5b82dd19ec935c97b278f5b 100644 (file)
@@ -579,6 +579,7 @@ fn visit_ty(&mut self, t: &'v ast::Ty) {
             [
                 Slice,
                 Array,
+                AnonEnum,
                 Ptr,
                 Ref,
                 BareFn,
index c1991e8d2c80800ef354d7ccc5554928349450be..f065ec680d724bd68ce0d9010721c3a232f19b13 100644 (file)
@@ -839,7 +839,9 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
                 })
             }
             ast::TyKind::CVarArgs => Some("...".to_owned()),
-            ast::TyKind::Err => Some(context.snippet(self.span).to_owned()),
+            ast::TyKind::AnonEnum(_) | ast::TyKind::Err => {
+                Some(context.snippet(self.span).to_owned())
+            }
             ast::TyKind::Typeof(ref anon_const) => rewrite_call(
                 context,
                 "typeof",
diff --git a/tests/ui/parser/anon-enums.rs b/tests/ui/parser/anon-enums.rs
new file mode 100644 (file)
index 0000000..a8b5e83
--- /dev/null
@@ -0,0 +1,19 @@
+fn foo(x: bool | i32) -> i32 | f64 {
+//~^ ERROR anonymous enums are not supported
+//~| ERROR anonymous enums are not supported
+    match x {
+        x: i32 => x, //~ ERROR expected
+        //~^ ERROR failed to resolve
+        true => 42.,
+        false => 0.333,
+    }
+}
+
+fn main() {
+    match foo(true) {
+        42: i32 => (), //~ ERROR expected
+        _: f64 => (), //~ ERROR expected
+        x: i32 => (), //~ ERROR expected
+        //~^ ERROR failed to resolve
+    }
+}
diff --git a/tests/ui/parser/anon-enums.stderr b/tests/ui/parser/anon-enums.stderr
new file mode 100644 (file)
index 0000000..4febf2d
--- /dev/null
@@ -0,0 +1,81 @@
+error: anonymous enums are not supported
+  --> $DIR/anon-enums.rs:1:16
+   |
+LL | fn foo(x: bool | i32) -> i32 | f64 {
+   |           ---- ^ ---
+   |
+   = help: create a named `enum` and use it here instead:
+           enum Name {
+               Variant1(bool),
+               Variant2(i32),
+           }
+
+error: anonymous enums are not supported
+  --> $DIR/anon-enums.rs:1:30
+   |
+LL | fn foo(x: bool | i32) -> i32 | f64 {
+   |                          --- ^ ---
+   |
+   = help: create a named `enum` and use it here instead:
+           enum Name {
+               Variant1(i32),
+               Variant2(f64),
+           }
+
+error: expected one of `@` or `|`, found `:`
+  --> $DIR/anon-enums.rs:5:10
+   |
+LL |         x: i32 => x,
+   |          ^ --- specifying the type of a pattern isn't supported
+   |          |
+   |          expected one of `@` or `|`
+   |
+help: maybe write a path separator here
+   |
+LL |         x::i32 => x,
+   |          ~~
+
+error: expected one of `...`, `..=`, `..`, or `|`, found `:`
+  --> $DIR/anon-enums.rs:14:11
+   |
+LL |         42: i32 => (),
+   |           ^ --- specifying the type of a pattern isn't supported
+   |           |
+   |           expected one of `...`, `..=`, `..`, or `|`
+
+error: expected `|`, found `:`
+  --> $DIR/anon-enums.rs:15:10
+   |
+LL |         _: f64 => (),
+   |          ^ --- specifying the type of a pattern isn't supported
+   |          |
+   |          expected `|`
+
+error: expected one of `@` or `|`, found `:`
+  --> $DIR/anon-enums.rs:16:10
+   |
+LL |         x: i32 => (),
+   |          ^ --- specifying the type of a pattern isn't supported
+   |          |
+   |          expected one of `@` or `|`
+   |
+help: maybe write a path separator here
+   |
+LL |         x::i32 => (),
+   |          ~~
+
+error[E0433]: failed to resolve: use of undeclared crate or module `x`
+  --> $DIR/anon-enums.rs:5:9
+   |
+LL |         x: i32 => x,
+   |         ^ use of undeclared crate or module `x`
+
+error[E0433]: failed to resolve: use of undeclared crate or module `x`
+  --> $DIR/anon-enums.rs:16:9
+   |
+LL |         x: i32 => (),
+   |         ^ use of undeclared crate or module `x`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
index 2050a16beb34983c63e96f847a82c1d23f3f16d5..ed05bfe8b0a32cc804dc51b59d056405dcc9e7c6 100644 (file)
@@ -2,82 +2,118 @@ error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:17:12
    |
 LL |         Foo:Bar => {}
-   |            ^
+   |            ^--- specifying the type of a pattern isn't supported
    |            |
    |            expected one of `@` or `|`
-   |            help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         Foo::Bar => {}
+   |            ~~
 
 error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:23:17
    |
 LL |         qux::Foo:Bar => {}
-   |                 ^
+   |                 ^--- specifying the type of a pattern isn't supported
    |                 |
    |                 expected one of 8 possible tokens
-   |                 help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         qux::Foo::Bar => {}
+   |                 ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:29:12
    |
 LL |         qux:Foo::Baz => {}
-   |            ^
+   |            ^-------- specifying the type of a pattern isn't supported
    |            |
    |            expected one of `@` or `|`
-   |            help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         qux::Foo::Baz => {}
+   |            ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:35:12
    |
 LL |         qux: Foo::Baz if true => {}
-   |            ^
+   |            ^ -------- specifying the type of a pattern isn't supported
    |            |
    |            expected one of `@` or `|`
-   |            help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         qux::Foo::Baz if true => {}
+   |            ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:40:15
    |
 LL |     if let Foo:Bar = f() {
-   |               ^
+   |               ^--- specifying the type of a pattern isn't supported
    |               |
    |               expected one of `@` or `|`
-   |               help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |     if let Foo::Bar = f() {
+   |               ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:48:16
    |
 LL |         ref qux: Foo::Baz => {}
-   |                ^
+   |                ^ -------- specifying the type of a pattern isn't supported
    |                |
    |                expected one of `@` or `|`
-   |                help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         ref qux::Foo::Baz => {}
+   |                ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:57:16
    |
 LL |         mut qux: Foo::Baz => {}
-   |                ^
+   |                ^ -------- specifying the type of a pattern isn't supported
    |                |
    |                expected one of `@` or `|`
-   |                help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         mut qux::Foo::Baz => {}
+   |                ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:68:12
    |
 LL |         Foo:Bar::Baz => {}
-   |            ^
+   |            ^-------- specifying the type of a pattern isn't supported
    |            |
    |            expected one of `@` or `|`
-   |            help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         Foo::Bar::Baz => {}
+   |            ~~
 
 error: expected one of `@` or `|`, found `:`
   --> $DIR/issue-87086-colon-path-sep.rs:75:12
    |
 LL |         Foo:Bar => {}
-   |            ^
+   |            ^--- specifying the type of a pattern isn't supported
    |            |
    |            expected one of `@` or `|`
-   |            help: maybe write a path separator here: `::`
+   |
+help: maybe write a path separator here
+   |
+LL |         Foo::Bar => {}
+   |            ~~
 
 error[E0433]: failed to resolve: `Bar` is a variant, not a module
   --> $DIR/issue-87086-colon-path-sep.rs:68:13