]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_parse/src/parser/ty.rs
Auto merge of #107443 - cjgillot:generator-less-query, r=compiler-errors
[rust.git] / compiler / rustc_parse / src / parser / ty.rs
index 1766b0293de52a33c2eceb3254ecfe0b44e7f0af..82d9138c7a331948c16e4c50bf711f558a845d33 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::Err));
+        }
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
@@ -989,7 +1048,7 @@ fn parse_generic_ty_bound(
                 self.parse_remaining_bounds(bounds, true)?;
                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
                 let sp = vec![lo, self.prev_token.span];
-                let sugg: Vec<_> = sp.iter().map(|sp| (*sp, String::new())).collect();
+                let sugg = vec![(lo, String::from(" ")), (self.prev_token.span, String::new())];
                 self.struct_span_err(sp, "incorrect braces around trait bounds")
                     .multipart_suggestion(
                         "remove the parentheses",