about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/visit.rs4
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs52
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs3
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs65
-rw-r--r--tests/ui/parser/anon-enums-are-ambiguous.rs26
-rw-r--r--tests/ui/parser/anon-enums.rs17
-rw-r--r--tests/ui/parser/anon-enums.stderr68
-rw-r--r--tests/ui/parser/fake-anon-enums-in-macros.rs20
-rw-r--r--tests/ui/parser/issues/issue-87086-colon-path-sep.rs1
-rw-r--r--tests/ui/parser/issues/issue-87086-colon-path-sep.stderr81
10 files changed, 72 insertions, 265 deletions
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index e7b2e4b1cb4..bdb1879ec20 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -403,8 +403,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(tys) => {
-            walk_list!(visitor, visit_ty, tys);
+        TyKind::Tup(tuple_element_types) => {
+            walk_list!(visitor, visit_ty, tuple_element_types);
         }
         TyKind::BareFn(function_declaration) => {
             walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 26274822ed8..16d5edfd303 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2394,7 +2394,7 @@ impl<'a> Parser<'a> {
 
     /// 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_or_anon_enum(
+    pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
         &mut self,
         mut first_pat: P<Pat>,
         expected: Option<Expected>,
@@ -2405,41 +2405,26 @@ impl<'a> Parser<'a> {
         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 colon_span = self.token.span;
+        let span = self.token.span;
         // We only emit "unexpected `:`" error here if we can successfully parse the
         // whole pattern correctly in that case.
-        let mut snapshot_pat = self.create_snapshot_for_diagnostic();
-        let mut snapshot_type = self.create_snapshot_for_diagnostic();
+        let snapshot = self.create_snapshot_for_diagnostic();
 
         // Create error for "unexpected `:`".
         match self.expected_one_of_not_found(&[], &[]) {
             Err(mut err) => {
-                snapshot_pat.bump(); // Skip the `:`.
-                snapshot_type.bump(); // Skip the `:`.
-                match snapshot_pat.parse_pat_no_top_alt(expected) {
+                self.bump(); // Skip the `:`.
+                match self.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.
@@ -2503,8 +2488,8 @@ impl<'a> Parser<'a> {
                             _ => {}
                         }
                         if show_sugg {
-                            err.span_suggestion_verbose(
-                                colon_span.until(self.look_ahead(1, |t| t.span)),
+                            err.span_suggestion(
+                                span,
                                 "maybe write a path separator here",
                                 "::",
                                 Applicability::MaybeIncorrect,
@@ -2512,24 +2497,13 @@ impl<'a> Parser<'a> {
                         } else {
                             first_pat = self.mk_pat(new_span, PatKind::Wild);
                         }
-                        self.restore_snapshot(snapshot_pat);
+                        err.emit();
                     }
                 }
-                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);
-                        let new_span = first_pat.span.to(ty.span);
-                        first_pat = self.mk_pat(new_span, PatKind::Wild);
-                    }
-                }
-                err.emit();
             }
             _ => {
                 // Carry on as if we had not done anything. This should be unreachable.
+                self.restore_snapshot(snapshot);
             }
         };
         first_pat
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 88c75fd81e7..e75554ba124 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -148,8 +148,7 @@ impl<'a> Parser<'a> {
 
             // 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_or_anon_enum(first_pat, expected);
+                first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
             }
 
             if let Some(leading_vert_span) = leading_vert_span {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 306cbcff149..646e2f45e64 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -17,7 +17,6 @@ use rustc_ast::{
     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::{Applicability, PResult};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, sym, Ident};
@@ -50,24 +49,17 @@ pub(super) enum AllowPlus {
     No,
 }
 
-#[derive(PartialEq, Clone, Copy)]
+#[derive(PartialEq)]
 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:
@@ -100,7 +92,7 @@ impl RecoverReturnSign {
 }
 
 // Is `...` (`CVarArgs`) legal at this level of type parsing?
-#[derive(PartialEq, Clone, Copy)]
+#[derive(PartialEq)]
 enum AllowCVariadic {
     Yes,
     No,
@@ -125,7 +117,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -140,7 +131,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             Some(ty_params),
             RecoverQuestionMark::Yes,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -155,7 +145,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
-            RecoverAnonEnum::Yes,
         )
     }
 
@@ -173,7 +162,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::Yes,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -187,7 +175,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::No,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -199,7 +186,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::Yes,
             None,
             RecoverQuestionMark::No,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -212,7 +198,6 @@ impl<'a> Parser<'a> {
             RecoverReturnSign::OnlyFatArrow,
             None,
             RecoverQuestionMark::Yes,
-            RecoverAnonEnum::No,
         )
     }
 
@@ -232,7 +217,6 @@ impl<'a> Parser<'a> {
                 recover_return_sign,
                 None,
                 RecoverQuestionMark::Yes,
-                RecoverAnonEnum::Yes,
             )?;
             FnRetTy::Ty(ty)
         } else if recover_return_sign.can_recover(&self.token.kind) {
@@ -247,7 +231,6 @@ impl<'a> Parser<'a> {
                 recover_return_sign,
                 None,
                 RecoverQuestionMark::Yes,
-                RecoverAnonEnum::Yes,
             )?;
             FnRetTy::Ty(ty)
         } else {
@@ -263,7 +246,6 @@ impl<'a> Parser<'a> {
         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);
@@ -347,50 +329,9 @@ impl<'a> Parser<'a> {
             AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
             AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
         }
-        if RecoverQuestionMark::Yes == recover_question_mark {
+        if let 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::Err));
-        }
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
diff --git a/tests/ui/parser/anon-enums-are-ambiguous.rs b/tests/ui/parser/anon-enums-are-ambiguous.rs
new file mode 100644
index 00000000000..b0173cf98e0
--- /dev/null
+++ b/tests/ui/parser/anon-enums-are-ambiguous.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+macro_rules! test_expr {
+    ($expr:expr) => {};
+}
+
+macro_rules! test_ty {
+    ($a:ty | $b:ty) => {};
+}
+
+fn main() {
+    test_expr!(a as fn() -> B | C);
+    // Do not break the `|` operator.
+
+    test_expr!(|_: fn() -> B| C | D);
+    // Do not break `-> Ret` in closure args.
+
+    test_ty!(A | B);
+    // We can't support anon enums in arbitrary positions.
+
+    test_ty!(fn() -> A | B);
+    // Don't break fn ptrs.
+
+    test_ty!(impl Fn() -> A | B);
+    // Don't break parenthesized generics.
+}
diff --git a/tests/ui/parser/anon-enums.rs b/tests/ui/parser/anon-enums.rs
deleted file mode 100644
index 56b8a3d43be..00000000000
--- a/tests/ui/parser/anon-enums.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-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
-        true => 42.,
-        false => 0.333,
-    }
-}
-
-fn main() {
-    match foo(true) {
-        42: i32 => (), //~ ERROR expected
-        _: f64 => (), //~ ERROR expected
-        x: i32 => (), //~ ERROR expected
-    }
-}
diff --git a/tests/ui/parser/anon-enums.stderr b/tests/ui/parser/anon-enums.stderr
deleted file mode 100644
index 84158225660..00000000000
--- a/tests/ui/parser/anon-enums.stderr
+++ /dev/null
@@ -1,68 +0,0 @@
-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:13:11
-   |
-LL |         42: i32 => (),
-   |           ^ --- specifying the type of a pattern isn't supported
-   |           |
-   |           expected one of `...`, `..=`, `..`, or `|`
-
-error: expected `|`, found `:`
-  --> $DIR/anon-enums.rs:14:10
-   |
-LL |         _: f64 => (),
-   |          ^ --- specifying the type of a pattern isn't supported
-   |          |
-   |          expected `|`
-
-error: expected one of `@` or `|`, found `:`
-  --> $DIR/anon-enums.rs:15: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: aborting due to 6 previous errors
-
diff --git a/tests/ui/parser/fake-anon-enums-in-macros.rs b/tests/ui/parser/fake-anon-enums-in-macros.rs
deleted file mode 100644
index 38fe8dee238..00000000000
--- a/tests/ui/parser/fake-anon-enums-in-macros.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// build-pass
-macro_rules! check_ty {
-    ($Z:ty) => { compile_error!("triggered"); };
-    ($X:ty | $Y:ty) => { $X };
-}
-
-macro_rules! check {
-    ($Z:ty) => { compile_error!("triggered"); };
-    ($X:ty | $Y:ty) => { };
-}
-
-check! { i32 | u8 }
-
-fn foo(x: check_ty! { i32 | u8 }) -> check_ty! { i32 | u8 } {
-    x
-}
-fn main() {
-    let x: check_ty! { i32 | u8 } = 42;
-    let _: check_ty! { i32 | u8 } = foo(x);
-}
diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
index e1ea38f2795..0b7b67496d6 100644
--- a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
+++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
@@ -68,6 +68,7 @@ fn main() {
         Foo:Bar::Baz => {}
         //~^ ERROR: expected one of
         //~| HELP: maybe write a path separator here
+        //~| ERROR: failed to resolve: `Bar` is a variant, not a module
     }
     match myfoo {
         Foo::Bar => {}
diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
index 63b072ac4cd..2050a16beb3 100644
--- a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
+++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
@@ -2,118 +2,89 @@ 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
-   |
-LL |         Foo::Bar => {}
-   |            ~~
+   |            help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         qux::Foo::Bar => {}
-   |                 ~~
+   |                 help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         qux::Foo::Baz => {}
-   |            ~~
+   |            help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         qux::Foo::Baz if true => {}
-   |            ~~
+   |            help: maybe write a path separator here: `::`
 
 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
-   |
-LL |     if let Foo::Bar = f() {
-   |               ~~
+   |               help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         ref qux::Foo::Baz => {}
-   |                ~~
+   |                help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         mut qux::Foo::Baz => {}
-   |                ~~
+   |                help: maybe write a path separator here: `::`
 
 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
-   |
-LL |         Foo::Bar::Baz => {}
-   |            ~~
+   |            help: maybe write a path separator here: `::`
 
 error: expected one of `@` or `|`, found `:`
-  --> $DIR/issue-87086-colon-path-sep.rs:74:12
+  --> $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: `::`
+
+error[E0433]: failed to resolve: `Bar` is a variant, not a module
+  --> $DIR/issue-87086-colon-path-sep.rs:68:13
    |
-help: maybe write a path separator here
-   |
-LL |         Foo::Bar => {}
-   |            ~~
+LL |         Foo:Bar::Baz => {}
+   |             ^^^ `Bar` is a variant, not a module
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
+For more information about this error, try `rustc --explain E0433`.