X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=compiler%2Frustc_parse%2Fsrc%2Fparser%2Fty.rs;h=82d9138c7a331948c16e4c50bf711f558a845d33;hb=e19ae977ec4c8eaccd92c8e16da4ca4d6ca318d5;hp=1766b0293de52a33c2eceb3254ecfe0b44e7f0af;hpb=0c53b215de0c57833756300e81ac9c5f84a541a3;p=rust.git diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 1766b0293de..82d9138c7a3 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -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> { 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> { RecoverReturnSign::Yes, None, RecoverQuestionMark::Yes, + RecoverAnonEnum::Yes, ) } @@ -156,6 +167,7 @@ pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P> { RecoverReturnSign::Yes, None, RecoverQuestionMark::Yes, + RecoverAnonEnum::No, ) } @@ -169,6 +181,7 @@ pub(super) fn parse_as_cast_ty(&mut self) -> PResult<'a, P> { RecoverReturnSign::Yes, None, RecoverQuestionMark::No, + RecoverAnonEnum::No, ) } @@ -180,6 +193,7 @@ pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P> { RecoverReturnSign::Yes, None, RecoverQuestionMark::No, + RecoverAnonEnum::No, ) } @@ -192,6 +206,7 @@ pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { 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> { 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::>() + .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",