diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 0144aabb24413..5ed40094c03f2 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -758,8 +758,6 @@ impl Token { OpenInvisible(InvisibleOrigin::MetaVar(MetaVarKind::Ty { .. } | MetaVarKind::Path)) => { true } - // For anonymous structs or unions, which only appear in specific positions - // (type of struct fields or union fields), we don't consider them as regular types _ => false, } } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 4333559afb1c0..53d7044521e5a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -4,7 +4,7 @@ use rustc_ast::{AttrStyle, NodeId, token}; use rustc_attr_ir::target::Target; use rustc_attr_ir::{AttrPath, CfgEntry}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{Diagnostic, MultiSpan}; +use rustc_errors::Diagnostic; use rustc_feature::Features; use rustc_lint_defs::builtin::UNREACHABLE_CFG_SELECT_PREDICATES; use rustc_parse::exp; @@ -87,10 +87,9 @@ pub fn parse_cfg_select( lint_node_id: NodeId, ) -> Result { let mut branches = CfgSelectBranches::default(); - let mut branch_attr_error: Option = None; while p.token != token::Eof { - reject_branch_outer_attrs(p, &mut branch_attr_error)?; + p.recover_from_outer_attributes("`cfg_select` branches").map_err(|e| e.emit())?; if p.eat_keyword(exp!(Underscore)) { let underscore = p.prev_token; @@ -145,10 +144,6 @@ pub fn parse_cfg_select( } } - if let Some(guar) = branch_attr_error { - return Err(guar); - } - let it = branches .reachable .iter() @@ -161,27 +156,6 @@ pub fn parse_cfg_select( Ok(branches) } -fn reject_branch_outer_attrs( - p: &mut Parser<'_>, - branch_attr_error: &mut Option, -) -> Result<(), ErrorGuaranteed> { - let Some(spans) = p.parse_cfg_select_branch_outer_attrs().map_err(|e| e.emit())? else { - return Ok(()); - }; - - for (spans, msg) in [ - (spans.doc_comments, "doc comments are not allowed on `cfg_select` branches"), - (spans.attrs, "attributes are not allowed on `cfg_select` branches"), - ] { - if !spans.is_empty() { - branch_attr_error - .get_or_insert(p.dcx().struct_span_err(MultiSpan::from_spans(spans), msg).emit()); - } - } - - Ok(()) -} - fn lint_unreachable( p: &mut Parser<'_>, predicates: impl Iterator, diff --git a/compiler/rustc_parse/src/diagnostics.rs b/compiler/rustc_parse/src/diagnostics.rs index a09b2a38593ed..1dc2d625fe0e0 100644 --- a/compiler/rustc_parse/src/diagnostics.rs +++ b/compiler/rustc_parse/src/diagnostics.rs @@ -1826,60 +1826,6 @@ pub(crate) struct ParenthesesInMatchPatSugg { pub right: Span, } -#[derive(Diagnostic)] -#[diag("documentation comments cannot be applied to a function parameter's type")] -pub(crate) struct DocCommentOnParamType { - #[primary_span] - #[label("doc comments are not allowed here")] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag("attributes cannot be applied to a function parameter's type")] -pub(crate) struct AttributeOnParamType { - #[primary_span] - #[label("attributes are not allowed here")] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag("attributes cannot be applied to types")] -pub(crate) struct AttributeOnType { - #[primary_span] - #[label("attributes are not allowed here")] - pub span: Span, - #[suggestion( - "remove attribute from here", - code = "", - applicability = "machine-applicable", - style = "tool-only" - )] - pub fix_span: Span, -} - -#[derive(Diagnostic)] -#[diag("attributes cannot be applied to generic arguments")] -pub(crate) struct AttributeOnGenericArg { - #[primary_span] - #[label("attributes are not allowed here")] - pub span: Span, - #[suggestion( - "remove attribute from here", - code = "", - applicability = "machine-applicable", - style = "tool-only" - )] - pub fix_span: Span, -} - -#[derive(Diagnostic)] -#[diag("attributes cannot be applied here")] -pub(crate) struct AttributeOnEmptyType { - #[primary_span] - #[label("attributes are not allowed here")] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("patterns aren't allowed in {$target}", code = E0642)] pub(crate) struct PatternMethodParamWithoutBody { diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index b2ad898311cc3..4d6255aa08f8f 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -507,4 +507,42 @@ impl<'a> Parser<'a> { Err(self.dcx().create_err(err)) } + + /// Recover from outer attributes in places where none were expected. + pub fn recover_from_outer_attributes(&mut self, target: &str) -> PResult<'a, ()> { + // We check the token ourselves first to prevent `#` + // from getting added to the set of expected tokens. + if !self.may_recover() || !matches!(self.token.kind, token::Pound | token::DocComment(..)) { + return Ok(()); + } + + let attrs = self.parse_outer_attributes()?; + if attrs.is_empty() { + return Ok(()); + } + + let attrs = attrs.take_for_recovery(self.psess); + let span = attrs.first().unwrap().span.to(attrs.last().unwrap().span); + + let subject = if attrs.iter().all(|attr| matches!(attr.kind, ast::AttrKind::DocComment(..))) + { + "doc comments" + } else { + "attributes" + }; + + self.dcx() + .struct_span_err(span, format!("{subject} cannot be applied to {target}")) + .with_span_label(span, format!("{subject} are not allowed here")) + .with_span_suggestion_with_style( + span.until(self.token.span), + format!("remove these {subject}"), + String::new(), + rustc_errors::Applicability::MachineApplicable, + rustc_errors::SuggestionStyle::CompletelyHidden, + ) + .emit(); + + Ok(()) + } } diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs index 3d89cabbbc655..cf1ef62e56d5a 100644 --- a/compiler/rustc_parse/src/parser/cfg_select.rs +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -1,6 +1,6 @@ +use rustc_ast::token; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; -use rustc_ast::{AttrKind, token}; use rustc_errors::PResult; use rustc_span::Span; @@ -48,34 +48,4 @@ impl<'a> Parser<'a> { } Ok(TokenStream::from_ast(&expr)) } - - /// Parses outer attributes before a `cfg_select!` branch for recovery. - pub fn parse_cfg_select_branch_outer_attrs( - &mut self, - ) -> PResult<'a, Option> { - let attrs = self.parse_outer_attributes()?; - if attrs.is_empty() { - return Ok(None); - } - - let mut spans = CfgSelectBranchAttrSpans::default(); - for attr in attrs.take_for_recovery(self.psess) { - match attr.kind { - AttrKind::Normal(..) => spans.attrs.push(attr.span), - AttrKind::Synthetic(..) => unreachable!(), - // `parse_outer_attributes` already emitted E0753 for inner doc comments before - // recovering them as outer doc-comment attributes. - AttrKind::DocComment(comment_kind, _) - if self.span_to_snippet(attr.span).ok().is_some_and( - |snippet| match comment_kind { - token::CommentKind::Line => snippet.starts_with("//!"), - token::CommentKind::Block => snippet.starts_with("/*!"), - }, - ) => {} - AttrKind::DocComment(..) => spans.doc_comments.push(attr.span), - } - } - - Ok(Some(spans)) - } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 0b91828639d36..6d4a0215eb7b3 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -26,10 +26,9 @@ use super::{ SeqSep, TokenType, }; use crate::diagnostics::{ - AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AsyncUseBlockIn2015, AttributeOnParamType, - AwaitSuggestion, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, - ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg, - DocCommentDoesNotDocumentAnything, DocCommentOnParamType, DoubleColonInBound, + AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AsyncUseBlockIn2015, AwaitSuggestion, + BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained, + ComparisonOperatorsCannotBeChainedSugg, DocCommentDoesNotDocumentAnything, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, ExprParenthesesNeeded, FoundPathInGenerics, GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait, @@ -2216,22 +2215,6 @@ impl<'a> Parser<'a> { } } - pub(super) fn eat_incorrect_doc_comment_for_param_type(&mut self) { - if let token::DocComment(..) = self.token.kind { - self.dcx().emit_err(DocCommentOnParamType { span: self.token.span }); - self.bump(); - } else if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { - let lo = self.token.span; - // Skip every token until next possible arg. - while self.token != token::CloseBracket { - self.bump(); - } - let sp = lo.to(self.token.span); - self.bump(); - self.dcx().emit_err(AttributeOnParamType { span: sp }); - } - } - pub(super) fn parameter_without_type( &mut self, err: &mut Diag<'_>, diff --git a/compiler/rustc_parse/src/parser/function.rs b/compiler/rustc_parse/src/parser/function.rs index 72b8507ccef0f..57fe19226066c 100644 --- a/compiler/rustc_parse/src/parser/function.rs +++ b/compiler/rustc_parse/src/parser/function.rs @@ -778,12 +778,10 @@ impl<'a> Parser<'a> { }; } - this.eat_incorrect_doc_comment_for_param_type(); (pat, this.parse_ty_for_param()?) } else { debug!("parse_param_general ident_to_pat"); let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic(); - this.eat_incorrect_doc_comment_for_param_type(); let mut ty = this.parse_ty_for_param(); if let Ok(t) = &ty { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 664c089e3f153..cbd0891c7fe9a 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -16,14 +16,11 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::ast::{PatKind, TyKind}; use crate::diagnostics::{ - self, AttributeOnEmptyType, AttributeOnGenericArg, ConstGenericWithoutBraces, - ConstGenericWithoutBracesSugg, PathFoundAttributeInParams, PathFoundCVariadicParams, - PathSingleColon, PathTripleColon, + self, ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, PathFoundAttributeInParams, + PathFoundCVariadicParams, PathSingleColon, PathTripleColon, }; use crate::exp; -use crate::parser::{ - CommaRecoveryMode, Expr, ExprKind, FnContext, FnParseMode, RecoverColon, RecoverComma, -}; +use crate::parser::{CommaRecoveryMode, Expr, FnContext, FnParseMode, RecoverColon, RecoverComma}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -914,12 +911,8 @@ impl<'a> Parser<'a> { &mut self, ty_generics: Option<&Generics>, ) -> PResult<'a, Option> { - let mut attr_span: Option = None; - if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { - let attrs_wrapper = self.parse_outer_attributes()?; - let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); - attr_span = Some(raw_attrs[0].span.to(raw_attrs.last().unwrap().span)); - } + self.recover_from_outer_attributes("generic arguments")?; + let start = self.token.span; let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. @@ -939,33 +932,9 @@ impl<'a> Parser<'a> { } match self.parse_ty() { - Ok(ty) => { - // Since the type parser recovers from some malformed slice and array types and - // successfully returns a type, we need to look for `TyKind::Err`s in the - // type to determine if error recovery has occurred and if the input is not a - // syntactically valid type after all. - if let ast::TyKind::Slice(inner_ty) | ast::TyKind::Array(inner_ty, _) = &ty.kind - && let ast::TyKind::Err(_) = inner_ty.kind - && let Some(snapshot) = snapshot - && let Some(expr) = - self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) - { - return Ok(Some( - self.dummy_const_arg_needs_braces( - self.dcx() - .struct_span_err(expr.span, "invalid const generic expression"), - expr.span, - ), - )); - } - - GenericArg::Type(ty) - } + Ok(ty) => GenericArg::Type(ty), Err(err) => { - let stopped_at_doc_comment = matches!(self.token.kind, token::DocComment(..)); - - if !stopped_at_doc_comment - && let Some(snapshot) = snapshot + if let Some(snapshot) = snapshot && let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) { @@ -977,9 +946,6 @@ impl<'a> Parser<'a> { } } else if self.token.is_keyword(kw::Const) { return self.recover_const_param_declaration(ty_generics); - } else if let Some(attr_span) = attr_span { - let diag = self.dcx().create_err(AttributeOnEmptyType { span: attr_span }); - return Err(diag); } else { // Fall back by trying to parse a const-expr expression. If we successfully do so, // then we should report an error that it needs to be wrapped in braces. @@ -999,21 +965,6 @@ impl<'a> Parser<'a> { } }; - if let Some(attr_span) = attr_span { - let guar = self.dcx().emit_err(AttributeOnGenericArg { - span: attr_span, - fix_span: attr_span.until(arg.span()), - }); - return Ok(Some(match arg { - GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), - GenericArg::Const(_) => { - let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); - GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) - } - GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), - })); - } - Ok(Some(arg)) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 31732882f7e86..f62f8f1765652 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -12,10 +12,10 @@ use thin_vec::{ThinVec, thin_vec}; use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::diagnostics::{ - self, AttributeOnEmptyType, AttributeOnType, DynAfterMut, ExpectedFnPathFoundFnKeyword, - ExpectedMutOrConstInRawPointerType, FnPtrWithGenerics, FnPtrWithGenericsSugg, - HelpUseLatestEdition, InvalidCVariadicType, InvalidDynKeyword, LifetimeAfterMut, - NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow, + self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, + FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidCVariadicType, + InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, + ReturnTypesUseThinArrow, }; use crate::parser::{FnContext, FnParseMode, FrontMatterParsingMode}; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; @@ -279,27 +279,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Box> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); - if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { - let attrs_wrapper = self.parse_outer_attributes()?; - let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); - let attr_span = raw_attrs[0].span.to(raw_attrs.last().unwrap().span); - let (full_span, guar) = match self.parse_ty() { - Ok(ty) => { - let full_span = attr_span.until(ty.span); - let guar = self - .dcx() - .emit_err(AttributeOnType { span: attr_span, fix_span: full_span }); - (attr_span, guar) - } - Err(err) => { - err.cancel(); - let guar = self.dcx().emit_err(AttributeOnEmptyType { span: attr_span }); - (attr_span, guar) - } - }; - return Ok(self.mk_ty(full_span, TyKind::Err(guar))); - } if let Some(ty) = self.eat_metavar_seq_with_matcher( |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }), |this| this.parse_ty_no_question_mark_recover(), @@ -307,10 +287,12 @@ impl<'a> Parser<'a> { return Ok(ty); } + self.recover_from_outer_attributes("types")?; + let lo = self.token.span; let mut impl_dyn_multi = false; let kind = if self.check(exp!(OpenParen)) { - self.parse_ty_tuple_or_parens(lo, allow_plus)? + self.parse_paren_start_ty(lo, allow_plus)? } else if self.eat(exp!(Bang)) { // Never type `!` TyKind::Never @@ -352,15 +334,18 @@ impl<'a> Parser<'a> { let kw = self.prev_token.ident().unwrap().0; let removal_span = kw.span.with_hi(self.token.span.lo()); let path = self.parse_path(PathStyle::Type)?; - let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); - let kind = self.parse_remaining_bounds_path( + let mut bounds = thin_vec![GenericBound::Trait(PolyTraitRef::new( bound_vars, path, - lo, - parse_plus, + TraitBoundModifiers::NONE, + lo.to(self.prev_token.span), ast::Parens::No, - )?; - let err = self.dcx().create_err(diagnostics::TransposeDynOrImpl { + ))]; + if allow_plus == AllowPlus::Yes && self.check_plus() { + self.eat_plus(); + bounds.append(&mut self.parse_generic_bounds()?); + } + self.dcx().emit_err(diagnostics::TransposeDynOrImpl { span: kw.span, kw: kw.name.as_str(), sugg: diagnostics::TransposeDynOrImplSugg { @@ -369,24 +354,15 @@ impl<'a> Parser<'a> { kw: kw.name.as_str(), }, }); - - // Take the parsed bare trait object and turn it either - // into a `dyn` object or an `impl Trait`. - let kind = match (kind, kw.name) { - (TyKind::TraitObject(bounds, _), kw::Dyn) => { - TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) - } - (TyKind::TraitObject(bounds, _), kw::Impl) => { - TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) - } - _ => return Err(err), - }; - err.emit(); - kind + match kw.name { + kw::Dyn => TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn), + kw::Impl => TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds), + _ => unreachable!(), + } } else { let path = self.parse_path(PathStyle::Type)?; let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); - self.parse_remaining_bounds_path( + self.finish_parsing_bare_trait_object_ty( bound_vars, path, lo, @@ -410,7 +386,7 @@ impl<'a> Parser<'a> { } else if self.check_path() { self.parse_path_start_ty(lo, allow_plus, ty_generics)? } else if self.can_begin_bound() { - self.parse_bare_trait_object(lo, allow_plus)? + self.parse_bare_trait_object_ty(lo, allow_plus)? } else if self.eat(exp!(DotDotDot)) { match allow_c_variadic { AllowCVariadic::Yes => TyKind::CVarArgs, @@ -460,10 +436,14 @@ impl<'a> Parser<'a> { Ok(TyKind::UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, inner_ty }))) } - /// Parses either: - /// - `(TYPE)`, a parenthesized type. - /// - `(TYPE,)`, a tuple with a single field of type TYPE. - fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { + /// Parse a type that begins with an opening parenthesis `(`. + /// + /// More specifically, it parses one of the following: + /// + /// 1. parenthesized type + /// 2. tuple type + /// 3. bare trait object type where the first trait bound is parenthesized + fn parse_paren_start_ty(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { let mut trailing_plus = false; let (ts, trailing) = self.parse_paren_comma_seq(|p| { let ty = p.parse_ty()?; @@ -473,25 +453,41 @@ impl<'a> Parser<'a> { if ts.len() == 1 && matches!(trailing, Trailing::No) { let ty = ts.into_iter().next().unwrap(); + + // Let's check if we actually have a bare trait object type where the first trait bound + // is parenthesized. That's the case if the parentheses are followed by a `+` and if + // what's contained between the parentheses resembles a *BareTraitBound*. + // + // For context, looking at bounds in general (see *Bound*), only trait bounds are + // allowed to be wrapped in parentheses, not however lifetime and use bounds. let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus(); match ty.kind { - // `"(" BareTraitBound ")" "+" Bound "+" ...`. - TyKind::Path(None, path) if maybe_bounds => self.parse_remaining_bounds_path( - ThinVec::new(), - path, - lo, - true, - ast::Parens::Yes, - ), - // For `('a) + …`, we know that `'a` in type position already lead to an error being - // emitted. To reduce output, let's indirectly suppress E0178 (bad `+` in type) and - // other irrelevant consequential errors. - TyKind::TraitObject(bounds, TraitObjectSyntax::None) + // `"(" TypePath ")" "+"` + TyKind::Path(None, path) if maybe_bounds => self + .finish_parsing_bare_trait_object_ty( + ThinVec::new(), + path, + lo, + true, + ast::Parens::Yes, + ), + // `"(" BareTraitBound\TypePath | UseBound ")" "+"` + // + // * FIXME: As alluded to above, only trait bounds are meant to allow parens. + // Arguably, it's an accident that we're permitting *UseBound*s and thus types + // like `(use<>)+`. Might need a T-lang FCP to change this. + // * We're checking `!trailing_plus` to prevent us from accepting code like + // `(T+)+` or `('a+)+`. + // * While we could be looking at `('a)+` which we don't want to accept, we + // know that the `parse_ty` above has already emitted an error since the + // lifetime isn't immediately followed by a `+`. + TyKind::TraitObject(mut bounds, TraitObjectSyntax::None) if maybe_bounds && bounds.len() == 1 && !trailing_plus => { - self.parse_remaining_bounds(bounds, true) + self.eat_plus(); + bounds.append(&mut self.parse_generic_bounds()?); + Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } - // `(TYPE)` _ => Ok(TyKind::Paren(ty)), } } else { @@ -499,7 +495,11 @@ impl<'a> Parser<'a> { } } - fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { + fn parse_bare_trait_object_ty( + &mut self, + lo: Span, + allow_plus: AllowPlus, + ) -> PResult<'a, TyKind> { // A lifetime only begins a bare trait object type if it is followed by `+`! if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) { // In Rust 2021 and beyond, we assume that the user didn't intend to write a bare trait @@ -556,7 +556,7 @@ impl<'a> Parser<'a> { } } - fn parse_remaining_bounds_path( + fn finish_parsing_bare_trait_object_ty( &mut self, generic_params: ThinVec, path: ast::Path, @@ -564,25 +564,15 @@ impl<'a> Parser<'a> { parse_plus: bool, parens: ast::Parens, ) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new( + let mut bounds = thin_vec![GenericBound::Trait(PolyTraitRef::new( generic_params, path, TraitBoundModifiers::NONE, lo.to(self.prev_token.span), parens, - ); - let bounds = thin_vec![GenericBound::Trait(poly_trait_ref)]; - self.parse_remaining_bounds(bounds, parse_plus) - } - - /// Parse the remainder of a bare trait object type given an already parsed list. - fn parse_remaining_bounds( - &mut self, - mut bounds: GenericBounds, - plus: bool, - ) -> PResult<'a, TyKind> { - if plus { - self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded + ))]; + if parse_plus { + self.eat_plus(); bounds.append(&mut self.parse_generic_bounds()?); } Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) @@ -640,19 +630,7 @@ impl<'a> Parser<'a> { /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type. /// The opening `[` bracket is already eaten. fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> { - let elt_ty = match self.parse_ty() { - Ok(ty) => ty, - Err(err) - if self.look_ahead(1, |t| *t == token::CloseBracket) - | self.look_ahead(1, |t| *t == token::Semi) => - { - // Recover from `[LIT; EXPR]` and `[LIT]` - self.bump(); - let guar = err.emit(); - self.mk_ty(self.prev_token.span, TyKind::Err(guar)) - } - Err(err) => return Err(err), - }; + let elt_ty = self.parse_ty()?; let ty = if self.eat(exp!(Semi)) { let mut length = self.parse_expr_anon_const()?; @@ -1020,11 +998,11 @@ impl<'a> Parser<'a> { Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)) } - /// Parses a type starting with a path. + /// Parse a type that begins with a path. /// /// This can be: /// 1. a type macro, `mac!(...)`, - /// 2. a bare trait object, `B0 + ... + Bn`, + /// 2. a bare trait object type, `B0 + ... + Bn`, /// 3. or a path, `path::to::MyType`. fn parse_path_start_ty( &mut self, @@ -1039,7 +1017,13 @@ impl<'a> Parser<'a> { Ok(TyKind::MacCall(Box::new(MacCall { path, args: self.parse_delim_args()? }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { // `Trait1 + Trait2 + 'a` - self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true, ast::Parens::No) + self.finish_parsing_bare_trait_object_ty( + ThinVec::new(), + path, + lo, + true, + ast::Parens::No, + ) } else { // Just a type path. Ok(TyKind::Path(None, path)) @@ -1415,9 +1399,10 @@ impl<'a> Parser<'a> { // Someone has written something like `&dyn (Trait + Other)`. The correct code // would be `&(dyn Trait + Other)` if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) { - let bounds = thin_vec![]; - self.parse_remaining_bounds(bounds, true)?; + self.eat_plus(); + self.parse_generic_bounds()?; self.expect(exp!(CloseParen))?; + self.dcx().emit_err(diagnostics::IncorrectParensTraitBounds { span: vec![lo, self.prev_token.span], sugg: diagnostics::IncorrectParensTraitBoundsSugg { diff --git a/tests/ui/const-generics/bad-const-generic-exprs.rs b/tests/ui/const-generics/bad-const-generic-exprs.rs index 423752ca25eba..3c2aaa56dcc26 100644 --- a/tests/ui/const-generics/bad-const-generic-exprs.rs +++ b/tests/ui/const-generics/bad-const-generic-exprs.rs @@ -18,14 +18,12 @@ fn main() { //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[12]>; //~^ ERROR expected type - //~| ERROR invalid const generic expression //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[0, 1, 3]>; //~^ ERROR expected type //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[0xff; 8]>; //~^ ERROR expected type - //~| ERROR invalid const generic expression //~| HELP expressions must be enclosed in braces to be used as const generic arguments let _: Wow<[1, 2]>; // Regression test for issue #81698. //~^ ERROR expected type diff --git a/tests/ui/const-generics/bad-const-generic-exprs.stderr b/tests/ui/const-generics/bad-const-generic-exprs.stderr index 6d308bdc90708..294221a4134ef 100644 --- a/tests/ui/const-generics/bad-const-generic-exprs.stderr +++ b/tests/ui/const-generics/bad-const-generic-exprs.stderr @@ -58,12 +58,6 @@ error: expected type, found `12` | LL | let _: Wow<[12]>; | ^^ expected type - -error: invalid const generic expression - --> $DIR/bad-const-generic-exprs.rs:19:16 - | -LL | let _: Wow<[12]>; - | ^^^^ | help: expressions must be enclosed in braces to be used as const generic arguments | @@ -71,7 +65,7 @@ LL | let _: Wow<{ [12] }>; | + + error: expected type, found `0` - --> $DIR/bad-const-generic-exprs.rs:23:17 + --> $DIR/bad-const-generic-exprs.rs:22:17 | LL | let _: Wow<[0, 1, 3]>; | ^ expected type @@ -82,16 +76,10 @@ LL | let _: Wow<{ [0, 1, 3] }>; | + + error: expected type, found `0xff` - --> $DIR/bad-const-generic-exprs.rs:26:17 + --> $DIR/bad-const-generic-exprs.rs:25:17 | LL | let _: Wow<[0xff; 8]>; | ^^^^ expected type - -error: invalid const generic expression - --> $DIR/bad-const-generic-exprs.rs:26:16 - | -LL | let _: Wow<[0xff; 8]>; - | ^^^^^^^^^ | help: expressions must be enclosed in braces to be used as const generic arguments | @@ -99,7 +87,7 @@ LL | let _: Wow<{ [0xff; 8] }>; | + + error: expected type, found `1` - --> $DIR/bad-const-generic-exprs.rs:30:17 + --> $DIR/bad-const-generic-exprs.rs:28:17 | LL | let _: Wow<[1, 2]>; // Regression test for issue #81698. | ^ expected type @@ -110,7 +98,7 @@ LL | let _: Wow<{ [1, 2] }>; // Regression test for issue #81698. | + + error: expected type, found `0` - --> $DIR/bad-const-generic-exprs.rs:33:17 + --> $DIR/bad-const-generic-exprs.rs:31:17 | LL | let _: Wow<&0>; | ^ expected type @@ -121,7 +109,7 @@ LL | let _: Wow<{ &0 }>; | + + error: expected type, found `""` - --> $DIR/bad-const-generic-exprs.rs:36:17 + --> $DIR/bad-const-generic-exprs.rs:34:17 | LL | let _: Wow<("", 0)>; | ^^ expected type @@ -132,7 +120,7 @@ LL | let _: Wow<{ ("", 0) }>; | + + error: expected type, found `1` - --> $DIR/bad-const-generic-exprs.rs:39:17 + --> $DIR/bad-const-generic-exprs.rs:37:17 | LL | let _: Wow<(1 + 2) * 3>; | ^ expected type @@ -143,7 +131,7 @@ LL | let _: Wow<{ (1 + 2) * 3 }>; | + + error: expected one of `,` or `>`, found `0` - --> $DIR/bad-const-generic-exprs.rs:43:17 + --> $DIR/bad-const-generic-exprs.rs:41:17 | LL | let _: Wow; | - ^ expected one of `,` or `>` @@ -155,5 +143,5 @@ help: you might have meant to end the type parameters here LL | let _: Wow0>; | + -error: aborting due to 15 previous errors +error: aborting due to 13 previous errors diff --git a/tests/ui/lifetimes/raw/multiple-prefixes.rs b/tests/ui/lifetimes/raw/multiple-prefixes.rs index f335373d8a7e7..d629ff76c8bbc 100644 --- a/tests/ui/lifetimes/raw/multiple-prefixes.rs +++ b/tests/ui/lifetimes/raw/multiple-prefixes.rs @@ -1,6 +1,6 @@ //@ edition: 2021 fn test(x: &'r#r#r ()) {} -//~^ ERROR expected type, found `#` +//~^ ERROR expected one of fn main() {} diff --git a/tests/ui/lifetimes/raw/multiple-prefixes.stderr b/tests/ui/lifetimes/raw/multiple-prefixes.stderr index 8d5479e0a4fc5..dacb1e8027859 100644 --- a/tests/ui/lifetimes/raw/multiple-prefixes.stderr +++ b/tests/ui/lifetimes/raw/multiple-prefixes.stderr @@ -1,8 +1,8 @@ -error: expected type, found `#` - --> $DIR/multiple-prefixes.rs:3:17 +error: expected one of `!` or `[`, found `r` + --> $DIR/multiple-prefixes.rs:3:18 | LL | fn test(x: &'r#r#r ()) {} - | ^ expected type + | ^ expected one of `!` or `[` error: aborting due to 1 previous error diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 0d5fcec971550..10d6355b11c03 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -207,16 +207,16 @@ cfg_select! { // Regression test for https://github.com/rust-lang/rust/issues/155701. cfg_select! { /// doc comment - //~^ ERROR doc comments are not allowed on `cfg_select` branches + //~^ ERROR doc comments cannot be applied to `cfg_select` branches debug_assertions => {} /// doc comment - //~^ ERROR doc comments are not allowed on `cfg_select` branches + //~^ ERROR doc comments cannot be applied to `cfg_select` branches _ => {} } cfg_select! { #[cfg(false)] - //~^ ERROR attributes are not allowed on `cfg_select` branches + //~^ ERROR attributes cannot be applied to `cfg_select` branches debug_assertions => {} _ => {} } @@ -231,6 +231,7 @@ cfg_select! { cfg_select! { //! inner doc comment //~^ ERROR expected outer doc comment + //~| ERROR doc comments cannot be applied to `cfg_select` branches debug_assertions => {} _ => {} } @@ -238,7 +239,7 @@ cfg_select! { cfg_select! { debug_assertions => {} /// line1 - //~^ ERROR doc comments are not allowed on `cfg_select` branches + //~^ ERROR doc comments cannot be applied to `cfg_select` branches // line2 /// line3 _ => {} @@ -246,7 +247,7 @@ cfg_select! { cfg_select! { /// outer doc comment - //~^ ERROR doc comments are not allowed on `cfg_select` branches + //~^ ERROR doc comments cannot be applied to `cfg_select` branches //! inner doc comment //~^ ERROR expected outer doc comment debug_assertions => {} diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 9af74456367f2..7c963785db289 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -55,23 +55,23 @@ error: expected one of `(`, `::`, `=>`, or `=`, found `!` LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` -error: doc comments are not allowed on `cfg_select` branches +error: doc comments cannot be applied to `cfg_select` branches --> $DIR/cfg_select.rs:209:5 | LL | /// doc comment - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ doc comments are not allowed here -error: doc comments are not allowed on `cfg_select` branches +error: doc comments cannot be applied to `cfg_select` branches --> $DIR/cfg_select.rs:212:5 | LL | /// doc comment - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ doc comments are not allowed here -error: attributes are not allowed on `cfg_select` branches +error: attributes cannot be applied to `cfg_select` branches --> $DIR/cfg_select.rs:218:5 | LL | #[cfg(false)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ attributes are not allowed here error: an inner attribute is not permitted in this context --> $DIR/cfg_select.rs:225:5 @@ -95,17 +95,22 @@ LL - //! inner doc comment LL + // inner doc comment | -error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:240:5 +error: doc comments cannot be applied to `cfg_select` branches + --> $DIR/cfg_select.rs:232:5 + | +LL | //! inner doc comment + | ^^^^^^^^^^^^^^^^^^^^^ doc comments are not allowed here + +error: doc comments cannot be applied to `cfg_select` branches + --> $DIR/cfg_select.rs:241:5 | -LL | /// line1 - | ^^^^^^^^^ -... -LL | /// line3 - | ^^^^^^^^^ +LL | / /// line1 +... | +LL | | /// line3 + | |_____________^ doc comments are not allowed here error[E0753]: expected outer doc comment - --> $DIR/cfg_select.rs:250:5 + --> $DIR/cfg_select.rs:251:5 | LL | //! inner doc comment | ^^^^^^^^^^^^^^^^^^^^^ @@ -117,20 +122,22 @@ LL - //! inner doc comment LL + // inner doc comment | -error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:248:5 +error: doc comments cannot be applied to `cfg_select` branches + --> $DIR/cfg_select.rs:249:5 | -LL | /// outer doc comment - | ^^^^^^^^^^^^^^^^^^^^^ +LL | / /// outer doc comment +LL | | +LL | | //! inner doc comment + | |_________________________^ doc comments are not allowed here error[E0425]: cannot find type `Thing1` in this scope - --> $DIR/cfg_select.rs:278:13 + --> $DIR/cfg_select.rs:279:13 | LL | let t1: Thing1; | ^^^^^^ not found in this scope | note: found an item that was configured out - --> $DIR/cfg_select.rs:258:16 + --> $DIR/cfg_select.rs:259:16 | LL | all(true, false) => { | ----- the item is gated here @@ -138,20 +145,20 @@ LL | struct Thing1; | ^^^^^^ error[E0425]: cannot find type `Thing2` in this scope - --> $DIR/cfg_select.rs:280:13 + --> $DIR/cfg_select.rs:281:13 | LL | let t2: Thing2; | ^^^^^^ not found in this scope | note: found an item that was configured out - --> $DIR/cfg_select.rs:265:16 + --> $DIR/cfg_select.rs:266:16 | LL | feature = "meow" => { | ---------------- the item is gated behind the `meow` feature LL | struct Thing2; | ^^^^^^ note: found an item that was configured out - --> $DIR/cfg_select.rs:272:16 + --> $DIR/cfg_select.rs:273:16 | LL | all(true, feature = "meow") => { | ---------------- the item is gated behind the `meow` feature @@ -218,7 +225,7 @@ LL | cfg!() => {} = help: to expect this configuration use `--check-cfg=cfg(cfg)` = note: see for more information about checking conditional configuration -error: aborting due to 19 previous errors; 7 warnings emitted +error: aborting due to 20 previous errors; 7 warnings emitted Some errors have detailed explanations: E0425, E0539, E0565, E0753. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/attribute-on-empty.rs b/tests/ui/parser/attribute-on-empty.rs index 0177e6c1b59d4..135929a9fa397 100644 --- a/tests/ui/parser/attribute-on-empty.rs +++ b/tests/ui/parser/attribute-on-empty.rs @@ -1,29 +1,36 @@ -//! Regression test for: -//! +// Exercise outer attributes being applied to "nothing" in invalid contexts. struct Baz(i32); -fn main() { +fn f() { let _: Baz<#[cfg(false)]> = todo!(); - //~^ ERROR attributes cannot be applied here + //~^ ERROR attributes cannot be applied to generic arguments } -fn f(_param: #[attr]) {} -//~^ ERROR attributes cannot be applied to a function parameter's type +fn g(_param: #[attr]) {} +//~^ ERROR attributes cannot be applied to types //~| ERROR expected type, found `)` -fn g() -> #[attr] { 0 } -//~^ ERROR attributes cannot be applied here +fn barrier0() { + fn f() -> #[attr] { 0 } + //~^ ERROR attributes cannot be applied to types + //~| ERROR expected type, found `{` +} struct S { field: #[attr], - //~^ ERROR attributes cannot be applied here - field1: (#[attr], i32), - //~^ ERROR attributes cannot be applied here + //~^ ERROR attributes cannot be applied to types + //~| ERROR expected type, found `,` } -type Tuple = (#[attr], String); -//~^ ERROR attributes cannot be applied here +fn barrier1() { + type Tuple = (#[attr], String); + //~^ ERROR attributes cannot be applied to types + //~| ERROR expected type, found `,` +} impl #[attr] {} -//~^ ERROR attributes cannot be applied here +//~^ ERROR attributes cannot be applied to types +//~| ERROR expected type, found `{` + +fn main() {} diff --git a/tests/ui/parser/attribute-on-empty.stderr b/tests/ui/parser/attribute-on-empty.stderr index 6bcbf1ceb8d1f..5376e3e472cdd 100644 --- a/tests/ui/parser/attribute-on-empty.stderr +++ b/tests/ui/parser/attribute-on-empty.stderr @@ -1,52 +1,70 @@ -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:7:16 +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-empty.rs:6:16 | LL | let _: Baz<#[cfg(false)]> = todo!(); - | - ^^^^^^^^^^^^^ attributes are not allowed here - | | - | while parsing the type for `_` + | ^^^^^^^^^^^^^ attributes are not allowed here -error: attributes cannot be applied to a function parameter's type - --> $DIR/attribute-on-empty.rs:11:14 +error: attributes cannot be applied to types + --> $DIR/attribute-on-empty.rs:10:14 | -LL | fn f(_param: #[attr]) {} +LL | fn g(_param: #[attr]) {} | ^^^^^^^ attributes are not allowed here error: expected type, found `)` - --> $DIR/attribute-on-empty.rs:11:21 + --> $DIR/attribute-on-empty.rs:10:21 | -LL | fn f(_param: #[attr]) {} +LL | fn g(_param: #[attr]) {} | ^ expected type -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:15:11 +error: attributes cannot be applied to types + --> $DIR/attribute-on-empty.rs:15:15 | -LL | fn g() -> #[attr] { 0 } - | ^^^^^^^ attributes are not allowed here +LL | fn f() -> #[attr] { 0 } + | ^^^^^^^ attributes are not allowed here + +error: expected type, found `{` + --> $DIR/attribute-on-empty.rs:15:23 + | +LL | fn f() -> #[attr] { 0 } + | ^ expected type -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:19:12 +error: attributes cannot be applied to types + --> $DIR/attribute-on-empty.rs:21:12 | LL | field: #[attr], | ^^^^^^^ attributes are not allowed here -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:21:14 +error: expected type, found `,` + --> $DIR/attribute-on-empty.rs:21:19 | -LL | field1: (#[attr], i32), - | ^^^^^^^ attributes are not allowed here +LL | struct S { + | - while parsing this struct +LL | field: #[attr], + | ^ expected type -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:25:15 +error: attributes cannot be applied to types + --> $DIR/attribute-on-empty.rs:27:19 | -LL | type Tuple = (#[attr], String); - | ^^^^^^^ attributes are not allowed here +LL | type Tuple = (#[attr], String); + | ^^^^^^^ attributes are not allowed here -error: attributes cannot be applied here - --> $DIR/attribute-on-empty.rs:28:6 +error: expected type, found `,` + --> $DIR/attribute-on-empty.rs:27:26 + | +LL | type Tuple = (#[attr], String); + | ^ expected type + +error: attributes cannot be applied to types + --> $DIR/attribute-on-empty.rs:32:6 | LL | impl #[attr] {} | ^^^^^^^ attributes are not allowed here -error: aborting due to 8 previous errors +error: expected type, found `{` + --> $DIR/attribute-on-empty.rs:32:14 + | +LL | impl #[attr] {} + | ^ expected type + +error: aborting due to 11 previous errors diff --git a/tests/ui/parser/attribute-on-type.fixed b/tests/ui/parser/attribute-on-type-or-gen-arg.fixed similarity index 100% rename from tests/ui/parser/attribute-on-type.fixed rename to tests/ui/parser/attribute-on-type-or-gen-arg.fixed diff --git a/tests/ui/parser/attribute-on-type.rs b/tests/ui/parser/attribute-on-type-or-gen-arg.rs similarity index 100% rename from tests/ui/parser/attribute-on-type.rs rename to tests/ui/parser/attribute-on-type-or-gen-arg.rs diff --git a/tests/ui/parser/attribute-on-type.stderr b/tests/ui/parser/attribute-on-type-or-gen-arg.stderr similarity index 78% rename from tests/ui/parser/attribute-on-type.stderr rename to tests/ui/parser/attribute-on-type-or-gen-arg.stderr index 316620325c04c..f565b0b81ac90 100644 --- a/tests/ui/parser/attribute-on-type.stderr +++ b/tests/ui/parser/attribute-on-type-or-gen-arg.stderr @@ -1,89 +1,89 @@ error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:13:18 + --> $DIR/attribute-on-type-or-gen-arg.rs:13:18 | LL | let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:16:12 + --> $DIR/attribute-on-type-or-gen-arg.rs:16:12 | LL | let _: #[attr] &'static str = "123"; | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:19:16 + --> $DIR/attribute-on-type-or-gen-arg.rs:19:16 | LL | let _: Bar<#[cfg(false)] 'static> = Bar(&123); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:22:16 + --> $DIR/attribute-on-type-or-gen-arg.rs:22:16 | LL | let _: Baz<#[cfg(false)] 42> = Baz(42); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:25:16 + --> $DIR/attribute-on-type-or-gen-arg.rs:25:16 | LL | let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:28:16 + --> $DIR/attribute-on-type-or-gen-arg.rs:28:16 | LL | let _: Bar<#[cfg(false)] 'static> = Bar(&456); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:31:23 + --> $DIR/attribute-on-type-or-gen-arg.rs:31:23 | LL | let _generic: Box<#[attr] i32> = Box::new(1); | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:34:22 + --> $DIR/attribute-on-type-or-gen-arg.rs:34:22 | LL | let _assignment: #[attr] i32 = *Box::new(1); | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:37:23 + --> $DIR/attribute-on-type-or-gen-arg.rs:37:23 | LL | let _complex: Vec<#[derive(Debug)] String> = vec![]; | ^^^^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments - --> $DIR/attribute-on-type.rs:40:26 + --> $DIR/attribute-on-type-or-gen-arg.rs:40:26 | LL | let _nested: Box> = Box::new(vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:44:11 + --> $DIR/attribute-on-type-or-gen-arg.rs:44:11 | LL | fn g() -> #[attr] i32 { 0 } | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:48:12 + --> $DIR/attribute-on-type-or-gen-arg.rs:48:12 | LL | field: #[attr] i32, | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:50:14 + --> $DIR/attribute-on-type-or-gen-arg.rs:50:14 | LL | field1: (#[attr] i32, i32), | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:54:15 + --> $DIR/attribute-on-type-or-gen-arg.rs:54:15 | LL | type Tuple = (#[attr] i32, String); | ^^^^^^^ attributes are not allowed here error: attributes cannot be applied to types - --> $DIR/attribute-on-type.rs:57:6 + --> $DIR/attribute-on-type-or-gen-arg.rs:57:6 | LL | impl #[attr] S {} | ^^^^^^^ attributes are not allowed here diff --git a/tests/ui/parser/doc-comment-in-generic-tuple-type.rs b/tests/ui/parser/doc-comment-in-generic-tuple-type.rs index 929777db6e4c0..d62a5698c3a96 100644 --- a/tests/ui/parser/doc-comment-in-generic-tuple-type.rs +++ b/tests/ui/parser/doc-comment-in-generic-tuple-type.rs @@ -2,7 +2,7 @@ struct Foo { a: Vec<( /// Docstring - //~^ ERROR expected type, found doc comment + //~^ ERROR doc comments cannot be applied to types f32, f32, )>, diff --git a/tests/ui/parser/doc-comment-in-generic-tuple-type.stderr b/tests/ui/parser/doc-comment-in-generic-tuple-type.stderr index fc718dae8e511..c432bb95cc0bb 100644 --- a/tests/ui/parser/doc-comment-in-generic-tuple-type.stderr +++ b/tests/ui/parser/doc-comment-in-generic-tuple-type.stderr @@ -1,11 +1,8 @@ -error: expected type, found doc comment `/// Docstring` +error: doc comments cannot be applied to types --> $DIR/doc-comment-in-generic-tuple-type.rs:4:9 | -LL | struct Foo { - | --- while parsing this struct -LL | a: Vec<( LL | /// Docstring - | ^^^^^^^^^^^^^ expected type + | ^^^^^^^^^^^^^ doc comments are not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/parser/fn-arg-doc-comment.rs b/tests/ui/parser/fn-arg-doc-comment.rs index 57a4d15fa2564..962c5fb6dddc1 100644 --- a/tests/ui/parser/fn-arg-doc-comment.rs +++ b/tests/ui/parser/fn-arg-doc-comment.rs @@ -10,7 +10,7 @@ pub fn f( //~ NOTE function defined here ) {} fn bar(id: #[allow(dead_code)] i32) {} -//~^ ERROR attributes cannot be applied to a function parameter's type +//~^ ERROR attributes cannot be applied to types //~| NOTE attributes are not allowed here //~| NOTE function defined here diff --git a/tests/ui/parser/fn-arg-doc-comment.stderr b/tests/ui/parser/fn-arg-doc-comment.stderr index 84c8bb3c2d094..62ce856009490 100644 --- a/tests/ui/parser/fn-arg-doc-comment.stderr +++ b/tests/ui/parser/fn-arg-doc-comment.stderr @@ -1,4 +1,4 @@ -error: attributes cannot be applied to a function parameter's type +error: attributes cannot be applied to types --> $DIR/fn-arg-doc-comment.rs:12:12 | LL | fn bar(id: #[allow(dead_code)] i32) {} diff --git a/tests/ui/parser/issues/issue-103143.rs b/tests/ui/parser/issues/issue-103143.rs index 90f10fc1a089c..a1cb73df798fe 100644 --- a/tests/ui/parser/issues/issue-103143.rs +++ b/tests/ui/parser/issues/issue-103143.rs @@ -2,4 +2,6 @@ fn main() { x::<#[a]y::> //~^ ERROR attributes cannot be applied to generic arguments //~| ERROR cannot find value `x` in this scope + //~| ERROR cannot find type `y` in this scope + //~| ERROR cannot find type `z` in this scope } diff --git a/tests/ui/parser/issues/issue-103143.stderr b/tests/ui/parser/issues/issue-103143.stderr index 168a2077396c7..6272ecc8526a9 100644 --- a/tests/ui/parser/issues/issue-103143.stderr +++ b/tests/ui/parser/issues/issue-103143.stderr @@ -10,6 +10,18 @@ error[E0425]: cannot find value `x` in this scope LL | x::<#[a]y::> | ^ not found in this scope -error: aborting due to 2 previous errors +error[E0425]: cannot find type `y` in this scope + --> $DIR/issue-103143.rs:2:13 + | +LL | x::<#[a]y::> + | ^ not found in this scope + +error[E0425]: cannot find type `z` in this scope + --> $DIR/issue-103143.rs:2:17 + | +LL | x::<#[a]y::> + | ^ not found in this scope + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0425`.