From 5f0dd44b3b1b142582d3dc8264cb2b8dd8f7c7f0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 12 Jun 2025 00:02:12 +0800 Subject: avoid `&mut P` in `visit_expr` etc methods --- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/pat.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 93489aa8ee9..93c76c47f06 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -4087,7 +4087,7 @@ impl<'a> CondChecker<'a> { } impl MutVisitor for CondChecker<'_> { - fn visit_expr(&mut self, e: &mut P) { + fn visit_expr(&mut self, e: &mut Expr) { self.depth += 1; use ForbiddenLetReason::*; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 7a226136e23..64653ee2a04 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1094,7 +1094,7 @@ impl<'a> Parser<'a> { fn make_all_value_bindings_mutable(pat: &mut P) -> bool { struct AddMut(bool); impl MutVisitor for AddMut { - fn visit_pat(&mut self, pat: &mut P) { + fn visit_pat(&mut self, pat: &mut Pat) { if let PatKind::Ident(BindingMode(ByRef::No, m @ Mutability::Not), ..) = &mut pat.kind { -- cgit 1.4.1-3-g733a5 From b131b6f630843d34a14f250e3b46733253f3465b Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 10 Jun 2025 19:18:31 +0200 Subject: Rework how the disallowed qualifier lints are generated Signed-off-by: Jonathan Brouwer --- compiler/rustc_parse/messages.ftl | 2 + compiler/rustc_parse/src/errors.rs | 8 +- compiler/rustc_parse/src/parser/item.rs | 81 ++++++++++- compiler/rustc_parse/src/parser/ty.rs | 65 ++------- tests/ui/parser/bad-fn-ptr-qualifier.fixed | 8 + tests/ui/parser/bad-fn-ptr-qualifier.rs | 3 - tests/ui/parser/bad-fn-ptr-qualifier.stderr | 160 +++++++------------- .../parser/recover/recover-const-async-fn-ptr.rs | 3 - .../recover/recover-const-async-fn-ptr.stderr | 162 +++++++-------------- 9 files changed, 208 insertions(+), 284 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 1f221b4bf78..f6e0b08b140 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -299,10 +299,12 @@ parse_float_literal_unsupported_base = {$base} float literal is not supported parse_fn_pointer_cannot_be_async = an `fn` pointer type cannot be `async` .label = `async` because of this .suggestion = remove the `async` qualifier + .note = allowed qualifiers are: `unsafe` and `extern` parse_fn_pointer_cannot_be_const = an `fn` pointer type cannot be `const` .label = `const` because of this .suggestion = remove the `const` qualifier + .note = allowed qualifiers are: `unsafe` and `extern` parse_fn_ptr_with_generics = function pointer types may not have generic parameters .suggestion = consider moving the lifetime {$arity -> diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 2dba568a258..0f0c5434800 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2938,22 +2938,22 @@ pub(crate) struct DynAfterMut { #[derive(Diagnostic)] #[diag(parse_fn_pointer_cannot_be_const)] +#[note] pub(crate) struct FnPointerCannotBeConst { #[primary_span] - pub span: Span, #[label] - pub qualifier: Span, + pub span: Span, #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] pub suggestion: Span, } #[derive(Diagnostic)] #[diag(parse_fn_pointer_cannot_be_async)] +#[note] pub(crate) struct FnPointerCannotBeAsync { #[primary_span] - pub span: Span, #[label] - pub qualifier: Span, + pub span: Span, #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] pub suggestion: Span, } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index a325c2a57ab..658ed4bd41c 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -23,7 +23,7 @@ use super::{ AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect, Parser, PathStyle, Recovered, Trailing, UsePreAttrPos, }; -use crate::errors::{self, MacroExpandsToAdtField}; +use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField}; use crate::{exp, fluent_generated as fluent}; impl<'a> Parser<'a> { @@ -2402,7 +2402,7 @@ impl<'a> Parser<'a> { case: Case, ) -> PResult<'a, (Ident, FnSig, Generics, Option>, Option>)> { let fn_span = self.token.span; - let header = self.parse_fn_front_matter(vis, case)?; // `const ... fn` + let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn` let ident = self.parse_ident()?; // `foo` let mut generics = self.parse_generics()?; // `<'a, T, ...>` let decl = match self.parse_fn_decl( @@ -2658,16 +2658,37 @@ impl<'a> Parser<'a> { /// /// `vis` represents the visibility that was already parsed, if any. Use /// `Visibility::Inherited` when no visibility is known. + /// + /// If `parsing_mode` is `FrontMatterParsingMode::FunctionPtrType`, we error on `const` and `async` qualifiers, + /// which are not allowed in function pointer types. pub(super) fn parse_fn_front_matter( &mut self, orig_vis: &Visibility, case: Case, + parsing_mode: FrontMatterParsingMode, ) -> PResult<'a, FnHeader> { let sp_start = self.token.span; let constness = self.parse_constness(case); + if parsing_mode == FrontMatterParsingMode::FunctionPtrType + && let Const::Yes(const_span) = constness + { + self.dcx().emit_err(FnPointerCannotBeConst { + span: const_span, + suggestion: const_span.until(self.token.span), + }); + } let async_start_sp = self.token.span; let coroutine_kind = self.parse_coroutine_kind(case); + if parsing_mode == FrontMatterParsingMode::FunctionPtrType + && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind + { + self.dcx().emit_err(FnPointerCannotBeAsync { + span: async_span, + suggestion: async_span.until(self.token.span), + }); + } + // FIXME(gen_blocks): emit a similar error for `gen fn()` let unsafe_start_sp = self.token.span; let safety = self.parse_safety(case); @@ -2703,6 +2724,11 @@ impl<'a> Parser<'a> { enum WrongKw { Duplicated(Span), Misplaced(Span), + /// `MisplacedDisallowedQualifier` is only used instead of `Misplaced`, + /// when the misplaced keyword is disallowed by the current `FrontMatterParsingMode`. + /// In this case, we avoid generating the suggestion to swap around the keywords, + /// as we already generated a suggestion to remove the keyword earlier. + MisplacedDisallowedQualifier, } // We may be able to recover @@ -2716,7 +2742,21 @@ impl<'a> Parser<'a> { Const::Yes(sp) => Some(WrongKw::Duplicated(sp)), Const::No => { recover_constness = Const::Yes(self.token.span); - Some(WrongKw::Misplaced(async_start_sp)) + match parsing_mode { + FrontMatterParsingMode::Function => { + Some(WrongKw::Misplaced(async_start_sp)) + } + FrontMatterParsingMode::FunctionPtrType => { + self.dcx().emit_err(FnPointerCannotBeConst { + span: self.token.span, + suggestion: self + .token + .span + .with_lo(self.prev_token.span.hi()), + }); + Some(WrongKw::MisplacedDisallowedQualifier) + } + } } } } else if self.check_keyword(exp!(Async)) { @@ -2742,7 +2782,21 @@ impl<'a> Parser<'a> { closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID, }); - Some(WrongKw::Misplaced(unsafe_start_sp)) + match parsing_mode { + FrontMatterParsingMode::Function => { + Some(WrongKw::Misplaced(async_start_sp)) + } + FrontMatterParsingMode::FunctionPtrType => { + self.dcx().emit_err(FnPointerCannotBeAsync { + span: self.token.span, + suggestion: self + .token + .span + .with_lo(self.prev_token.span.hi()), + }); + Some(WrongKw::MisplacedDisallowedQualifier) + } + } } } } else if self.check_keyword(exp!(Unsafe)) { @@ -2840,14 +2894,20 @@ impl<'a> Parser<'a> { // FIXME(gen_blocks): add keyword recovery logic for genness - if wrong_kw.is_some() + if let Some(wrong_kw) = wrong_kw && self.may_recover() && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case)) { // Advance past the misplaced keyword and `fn` self.bump(); self.bump(); - err.emit(); + // When we recover from a `MisplacedDisallowedQualifier`, we already emitted an error for the disallowed qualifier + // So we don't emit another error that the qualifier is unexpected. + if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) { + err.cancel(); + } else { + err.emit(); + } return Ok(FnHeader { constness: recover_constness, safety: recover_safety, @@ -3194,3 +3254,12 @@ enum IsMacroRulesItem { Yes { has_bang: bool }, No, } + +#[derive(Copy, Clone, PartialEq, Eq)] +pub(super) enum FrontMatterParsingMode { + /// Parse the front matter of a function declaration + Function, + /// Parse the front matter of a function pointet type. + /// For function pointer types, the `const` and `async` keywords are not permitted. + FunctionPtrType, +} diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 9ddfc179e9b..620a34044d1 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -15,10 +15,11 @@ use thin_vec::{ThinVec, thin_vec}; use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::errors::{ self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, - FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg, - HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, - NestedCVariadicType, ReturnTypesUseThinArrow, + FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword, + LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, + ReturnTypesUseThinArrow, }; +use crate::parser::item::FrontMatterParsingMode; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; /// Signals whether parsing a type should allow `+`. @@ -669,62 +670,16 @@ impl<'a> Parser<'a> { tokens: None, }; let span_start = self.token.span; - let ast::FnHeader { ext, safety, constness, coroutine_kind } = - self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?; - let fn_start_lo = self.prev_token.span.lo(); + let ast::FnHeader { ext, safety, .. } = self.parse_fn_front_matter( + &inherited_vis, + Case::Sensitive, + FrontMatterParsingMode::FunctionPtrType, + )?; if self.may_recover() && self.token == TokenKind::Lt { self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?; } let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?; - let whole_span = lo.to(self.prev_token.span); - - // Order/parsing of "front matter" follows: - // ` fn()` - // ^ ^ ^ ^ ^ - // | | | | fn_start_lo - // | | | ext_sp.lo - // | | safety_sp.lo - // | coroutine_sp.lo - // const_sp.lo - if let ast::Const::Yes(const_span) = constness { - let next_token_lo = if let Some( - ast::CoroutineKind::Async { span, .. } - | ast::CoroutineKind::Gen { span, .. } - | ast::CoroutineKind::AsyncGen { span, .. }, - ) = coroutine_kind - { - span.lo() - } else if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety { - span.lo() - } else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext { - span.lo() - } else { - fn_start_lo - }; - let sugg_span = const_span.with_hi(next_token_lo); - self.dcx().emit_err(FnPointerCannotBeConst { - span: whole_span, - qualifier: const_span, - suggestion: sugg_span, - }); - } - if let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind { - let next_token_lo = if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety - { - span.lo() - } else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext { - span.lo() - } else { - fn_start_lo - }; - let sugg_span = async_span.with_hi(next_token_lo); - self.dcx().emit_err(FnPointerCannotBeAsync { - span: whole_span, - qualifier: async_span, - suggestion: sugg_span, - }); - } - // FIXME(gen_blocks): emit a similar error for `gen fn()` + let decl_span = span_start.to(self.prev_token.span); Ok(TyKind::BareFn(P(BareFnTy { ext, safety, generic_params: params, decl, decl_span }))) } diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.fixed b/tests/ui/parser/bad-fn-ptr-qualifier.fixed index 8a97a2f09cc..e9b87a72aab 100644 --- a/tests/ui/parser/bad-fn-ptr-qualifier.fixed +++ b/tests/ui/parser/bad-fn-ptr-qualifier.fixed @@ -23,4 +23,12 @@ pub type FTT6 = for<'a> unsafe extern "C" fn(); //~^ ERROR an `fn` pointer type cannot be `const` //~| ERROR an `fn` pointer type cannot be `async` +// Tests with qualifiers in the wrong order +pub type W1 = unsafe fn(); +//~^ ERROR an `fn` pointer type cannot be `const` +pub type W2 = unsafe fn(); +//~^ ERROR an `fn` pointer type cannot be `async` +pub type W3 = for<'a> unsafe fn(); +//~^ ERROR an `fn` pointer type cannot be `const` + fn main() {} diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.rs b/tests/ui/parser/bad-fn-ptr-qualifier.rs index 748852a76e1..f110375509c 100644 --- a/tests/ui/parser/bad-fn-ptr-qualifier.rs +++ b/tests/ui/parser/bad-fn-ptr-qualifier.rs @@ -26,12 +26,9 @@ pub type FTT6 = for<'a> const async unsafe extern "C" fn(); // Tests with qualifiers in the wrong order pub type W1 = unsafe const fn(); //~^ ERROR an `fn` pointer type cannot be `const` -//~| ERROR expected one of `extern` or `fn`, found keyword `const` pub type W2 = unsafe async fn(); //~^ ERROR an `fn` pointer type cannot be `async` -//~| ERROR expected one of `extern` or `fn`, found keyword `async` pub type W3 = for<'a> unsafe const fn(); //~^ ERROR an `fn` pointer type cannot be `const` -//~| ERROR expected one of `extern` or `fn`, found keyword `const` fn main() {} diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.stderr b/tests/ui/parser/bad-fn-ptr-qualifier.stderr index a0bd3f974ab..f3fbbf67159 100644 --- a/tests/ui/parser/bad-fn-ptr-qualifier.stderr +++ b/tests/ui/parser/bad-fn-ptr-qualifier.stderr @@ -2,10 +2,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/bad-fn-ptr-qualifier.rs:5:15 | LL | pub type T0 = const fn(); - | -----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type T0 = const fn(); @@ -16,10 +15,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/bad-fn-ptr-qualifier.rs:6:15 | LL | pub type T1 = const extern "C" fn(); - | -----^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type T1 = const extern "C" fn(); @@ -30,10 +28,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/bad-fn-ptr-qualifier.rs:7:15 | LL | pub type T2 = const unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type T2 = const unsafe extern "C" fn(); @@ -44,10 +41,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/bad-fn-ptr-qualifier.rs:8:15 | LL | pub type T3 = async fn(); - | -----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type T3 = async fn(); @@ -58,10 +54,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/bad-fn-ptr-qualifier.rs:9:15 | LL | pub type T4 = async extern "C" fn(); - | -----^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type T4 = async extern "C" fn(); @@ -72,10 +67,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/bad-fn-ptr-qualifier.rs:10:15 | LL | pub type T5 = async unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type T5 = async unsafe extern "C" fn(); @@ -86,10 +80,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/bad-fn-ptr-qualifier.rs:11:15 | LL | pub type T6 = const async unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type T6 = const async unsafe extern "C" fn(); @@ -97,13 +90,12 @@ LL + pub type T6 = async unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:11:15 + --> $DIR/bad-fn-ptr-qualifier.rs:11:21 | LL | pub type T6 = const async unsafe extern "C" fn(); - | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type T6 = const async unsafe extern "C" fn(); @@ -111,13 +103,12 @@ LL + pub type T6 = const unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:15:17 + --> $DIR/bad-fn-ptr-qualifier.rs:15:25 | LL | pub type FTT0 = for<'a> const fn(); - | ^^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type FTT0 = for<'a> const fn(); @@ -125,13 +116,12 @@ LL + pub type FTT0 = for<'a> fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:16:17 + --> $DIR/bad-fn-ptr-qualifier.rs:16:25 | LL | pub type FTT1 = for<'a> const extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type FTT1 = for<'a> const extern "C" fn(); @@ -139,13 +129,12 @@ LL + pub type FTT1 = for<'a> extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:17:17 + --> $DIR/bad-fn-ptr-qualifier.rs:17:25 | LL | pub type FTT2 = for<'a> const unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type FTT2 = for<'a> const unsafe extern "C" fn(); @@ -153,13 +142,12 @@ LL + pub type FTT2 = for<'a> unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:18:17 + --> $DIR/bad-fn-ptr-qualifier.rs:18:25 | LL | pub type FTT3 = for<'a> async fn(); - | ^^^^^^^^-----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type FTT3 = for<'a> async fn(); @@ -167,13 +155,12 @@ LL + pub type FTT3 = for<'a> fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:19:17 + --> $DIR/bad-fn-ptr-qualifier.rs:19:25 | LL | pub type FTT4 = for<'a> async extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type FTT4 = for<'a> async extern "C" fn(); @@ -181,13 +168,12 @@ LL + pub type FTT4 = for<'a> extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:20:17 + --> $DIR/bad-fn-ptr-qualifier.rs:20:25 | LL | pub type FTT5 = for<'a> async unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type FTT5 = for<'a> async unsafe extern "C" fn(); @@ -195,13 +181,12 @@ LL + pub type FTT5 = for<'a> unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:22:17 + --> $DIR/bad-fn-ptr-qualifier.rs:22:25 | LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn(); @@ -209,93 +194,56 @@ LL + pub type FTT6 = for<'a> async unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:22:17 + --> $DIR/bad-fn-ptr-qualifier.rs:22:31 | LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn(); - | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn(); LL + pub type FTT6 = for<'a> const unsafe extern "C" fn(); | -error: expected one of `extern` or `fn`, found keyword `const` - --> $DIR/bad-fn-ptr-qualifier.rs:27:22 - | -LL | pub type W1 = unsafe const fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` - | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` - error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:27:15 + --> $DIR/bad-fn-ptr-qualifier.rs:27:22 | LL | pub type W1 = unsafe const fn(); - | ^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type W1 = unsafe const fn(); -LL + pub type W1 = const fn(); +LL + pub type W1 = unsafe fn(); | -error: expected one of `extern` or `fn`, found keyword `async` - --> $DIR/bad-fn-ptr-qualifier.rs:30:22 - | -LL | pub type W2 = unsafe async fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` - | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` - error: an `fn` pointer type cannot be `async` - --> $DIR/bad-fn-ptr-qualifier.rs:30:15 + --> $DIR/bad-fn-ptr-qualifier.rs:29:22 | LL | pub type W2 = unsafe async fn(); - | ^^^^^^^-----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - pub type W2 = unsafe async fn(); -LL + pub type W2 = async fn(); - | - -error: expected one of `extern` or `fn`, found keyword `const` - --> $DIR/bad-fn-ptr-qualifier.rs:33:30 - | -LL | pub type W3 = for<'a> unsafe const fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` +LL + pub type W2 = unsafe fn(); | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` error: an `fn` pointer type cannot be `const` - --> $DIR/bad-fn-ptr-qualifier.rs:33:15 + --> $DIR/bad-fn-ptr-qualifier.rs:31:30 | LL | pub type W3 = for<'a> unsafe const fn(); - | ^^^^^^^^^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - pub type W3 = for<'a> unsafe const fn(); -LL + pub type W3 = for<'a> const fn(); +LL + pub type W3 = for<'a> unsafe fn(); | -error: aborting due to 22 previous errors +error: aborting due to 19 previous errors diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.rs b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs index 8e4c6e92412..a74b618c282 100644 --- a/tests/ui/parser/recover/recover-const-async-fn-ptr.rs +++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs @@ -23,13 +23,10 @@ type FT6 = for<'a> const async unsafe extern "C" fn(); // Tests with qualifiers in the wrong order type W1 = unsafe const fn(); //~^ ERROR an `fn` pointer type cannot be `const` -//~| ERROR expected one of `extern` or `fn`, found keyword `const` type W2 = unsafe async fn(); //~^ ERROR an `fn` pointer type cannot be `async` -//~| ERROR expected one of `extern` or `fn`, found keyword `async` type W3 = for<'a> unsafe const fn(); //~^ ERROR an `fn` pointer type cannot be `const` -//~| ERROR expected one of `extern` or `fn`, found keyword `const` fn main() { let _recovery_witness: () = 0; //~ ERROR mismatched types diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr index 82b9162cfdc..3700bee6e15 100644 --- a/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr +++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr @@ -2,10 +2,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/recover-const-async-fn-ptr.rs:3:11 | LL | type T0 = const fn(); - | -----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type T0 = const fn(); @@ -16,10 +15,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/recover-const-async-fn-ptr.rs:4:11 | LL | type T1 = const extern "C" fn(); - | -----^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type T1 = const extern "C" fn(); @@ -30,10 +28,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/recover-const-async-fn-ptr.rs:5:11 | LL | type T2 = const unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type T2 = const unsafe extern "C" fn(); @@ -44,10 +41,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/recover-const-async-fn-ptr.rs:6:11 | LL | type T3 = async fn(); - | -----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type T3 = async fn(); @@ -58,10 +54,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/recover-const-async-fn-ptr.rs:7:11 | LL | type T4 = async extern "C" fn(); - | -----^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type T4 = async extern "C" fn(); @@ -72,10 +67,9 @@ error: an `fn` pointer type cannot be `async` --> $DIR/recover-const-async-fn-ptr.rs:8:11 | LL | type T5 = async unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type T5 = async unsafe extern "C" fn(); @@ -86,10 +80,9 @@ error: an `fn` pointer type cannot be `const` --> $DIR/recover-const-async-fn-ptr.rs:9:11 | LL | type T6 = const async unsafe extern "C" fn(); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type T6 = const async unsafe extern "C" fn(); @@ -97,13 +90,12 @@ LL + type T6 = async unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:9:11 + --> $DIR/recover-const-async-fn-ptr.rs:9:17 | LL | type T6 = const async unsafe extern "C" fn(); - | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type T6 = const async unsafe extern "C" fn(); @@ -111,13 +103,12 @@ LL + type T6 = const unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:13:12 + --> $DIR/recover-const-async-fn-ptr.rs:13:20 | LL | type FT0 = for<'a> const fn(); - | ^^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type FT0 = for<'a> const fn(); @@ -125,13 +116,12 @@ LL + type FT0 = for<'a> fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:14:12 + --> $DIR/recover-const-async-fn-ptr.rs:14:20 | LL | type FT1 = for<'a> const extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type FT1 = for<'a> const extern "C" fn(); @@ -139,13 +129,12 @@ LL + type FT1 = for<'a> extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:15:12 + --> $DIR/recover-const-async-fn-ptr.rs:15:20 | LL | type FT2 = for<'a> const unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type FT2 = for<'a> const unsafe extern "C" fn(); @@ -153,13 +142,12 @@ LL + type FT2 = for<'a> unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:16:12 + --> $DIR/recover-const-async-fn-ptr.rs:16:20 | LL | type FT3 = for<'a> async fn(); - | ^^^^^^^^-----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type FT3 = for<'a> async fn(); @@ -167,13 +155,12 @@ LL + type FT3 = for<'a> fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:17:12 + --> $DIR/recover-const-async-fn-ptr.rs:17:20 | LL | type FT4 = for<'a> async extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type FT4 = for<'a> async extern "C" fn(); @@ -181,13 +168,12 @@ LL + type FT4 = for<'a> extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:18:12 + --> $DIR/recover-const-async-fn-ptr.rs:18:20 | LL | type FT5 = for<'a> async unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type FT5 = for<'a> async unsafe extern "C" fn(); @@ -195,13 +181,12 @@ LL + type FT5 = for<'a> unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:19:12 + --> $DIR/recover-const-async-fn-ptr.rs:19:20 | LL | type FT6 = for<'a> const async unsafe extern "C" fn(); - | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type FT6 = for<'a> const async unsafe extern "C" fn(); @@ -209,102 +194,65 @@ LL + type FT6 = for<'a> async unsafe extern "C" fn(); | error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:19:12 + --> $DIR/recover-const-async-fn-ptr.rs:19:26 | LL | type FT6 = for<'a> const async unsafe extern "C" fn(); - | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type FT6 = for<'a> const async unsafe extern "C" fn(); LL + type FT6 = for<'a> const unsafe extern "C" fn(); | -error: expected one of `extern` or `fn`, found keyword `const` - --> $DIR/recover-const-async-fn-ptr.rs:24:18 - | -LL | type W1 = unsafe const fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` - | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` - error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:24:11 + --> $DIR/recover-const-async-fn-ptr.rs:24:18 | LL | type W1 = unsafe const fn(); - | ^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type W1 = unsafe const fn(); -LL + type W1 = const fn(); +LL + type W1 = unsafe fn(); | -error: expected one of `extern` or `fn`, found keyword `async` - --> $DIR/recover-const-async-fn-ptr.rs:27:18 - | -LL | type W2 = unsafe async fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` - | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` - error: an `fn` pointer type cannot be `async` - --> $DIR/recover-const-async-fn-ptr.rs:27:11 + --> $DIR/recover-const-async-fn-ptr.rs:26:18 | LL | type W2 = unsafe async fn(); - | ^^^^^^^-----^^^^^ - | | - | `async` because of this + | ^^^^^ `async` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `async` qualifier | LL - type W2 = unsafe async fn(); -LL + type W2 = async fn(); - | - -error: expected one of `extern` or `fn`, found keyword `const` - --> $DIR/recover-const-async-fn-ptr.rs:30:26 - | -LL | type W3 = for<'a> unsafe const fn(); - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` +LL + type W2 = unsafe fn(); | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` error: an `fn` pointer type cannot be `const` - --> $DIR/recover-const-async-fn-ptr.rs:30:11 + --> $DIR/recover-const-async-fn-ptr.rs:28:26 | LL | type W3 = for<'a> unsafe const fn(); - | ^^^^^^^^^^^^^^^-----^^^^^ - | | - | `const` because of this + | ^^^^^ `const` because of this | + = note: allowed qualifiers are: `unsafe` and `extern` help: remove the `const` qualifier | LL - type W3 = for<'a> unsafe const fn(); -LL + type W3 = for<'a> const fn(); +LL + type W3 = for<'a> unsafe fn(); | error[E0308]: mismatched types - --> $DIR/recover-const-async-fn-ptr.rs:35:33 + --> $DIR/recover-const-async-fn-ptr.rs:32:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer | | | expected due to this -error: aborting due to 23 previous errors +error: aborting due to 20 previous errors For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 96fd9fc2dd8aa45ab19c2e07ed172b50566215ac Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 15 Jun 2025 14:59:05 +0800 Subject: use `if let` guards where possible --- compiler/rustc_builtin_macros/src/test.rs | 5 +---- compiler/rustc_parse/src/parser/diagnostics.rs | 27 +++++++++++--------------- 2 files changed, 12 insertions(+), 20 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index b439fa34f5b..b067578794b 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -118,10 +118,7 @@ pub(crate) fn expand_test_or_bench( let (item, is_stmt) = match item { Annotatable::Item(i) => (i, false), - Annotatable::Stmt(stmt) if matches!(stmt.kind, ast::StmtKind::Item(_)) => { - // FIXME: Use an 'if let' guard once they are implemented - if let ast::StmtKind::Item(i) = stmt.kind { (i, true) } else { unreachable!() } - } + Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true), other => { not_testable_error(cx, attr_sp, None); return vec![other]; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b49a13ce584..215202c4bd5 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2273,23 +2273,18 @@ impl<'a> Parser<'a> { ), // Also catches `fn foo(&a)`. PatKind::Ref(ref inner_pat, mutab) - if matches!(inner_pat.clone().kind, PatKind::Ident(..)) => + if let PatKind::Ident(_, ident, _) = inner_pat.clone().kind => { - match inner_pat.clone().kind { - PatKind::Ident(_, ident, _) => { - let mutab = mutab.prefix_str(); - ( - ident, - "self: ", - format!("{ident}: &{mutab}TypeName"), - "_: ", - pat.span.shrink_to_lo(), - pat.span, - pat.span.shrink_to_lo(), - ) - } - _ => unreachable!(), - } + let mutab = mutab.prefix_str(); + ( + ident, + "self: ", + format!("{ident}: &{mutab}TypeName"), + "_: ", + pat.span.shrink_to_lo(), + pat.span, + pat.span.shrink_to_lo(), + ) } _ => { // Otherwise, try to get a type and emit a suggestion. -- cgit 1.4.1-3-g733a5 From c63665cd73dda46c63aaa17c51d1cd83750fe2e1 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 11 Jun 2025 15:06:50 +0800 Subject: Dont suggest converting `///` to regular comment when it appears after missing `,` in list Signed-off-by: xizheyin --- compiler/rustc_parse/src/parser/diagnostics.rs | 45 ++++++++++++++-------- ...doc-comment-after-missing-comma-issue-142311.rs | 34 ++++++++++++++++ ...comment-after-missing-comma-issue-142311.stderr | 43 +++++++++++++++++++++ 3 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 tests/ui/parser/doc-comment-after-missing-comma-issue-142311.rs create mode 100644 tests/ui/parser/doc-comment-after-missing-comma-issue-142311.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b49a13ce584..26b5548df17 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -686,23 +686,34 @@ impl<'a> Parser<'a> { } if let token::DocComment(kind, style, _) = self.token.kind { - // We have something like `expr //!val` where the user likely meant `expr // !val` - let pos = self.token.span.lo() + BytePos(2); - let span = self.token.span.with_lo(pos).with_hi(pos); - err.span_suggestion_verbose( - span, - format!( - "add a space before {} to write a regular comment", - match (kind, style) { - (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`", - (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`", - (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`", - (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`", - }, - ), - " ".to_string(), - Applicability::MachineApplicable, - ); + // This is to avoid suggesting converting a doc comment to a regular comment + // when missing a comma before the doc comment in lists (#142311): + // + // ``` + // enum Foo{ + // A /// xxxxxxx + // B, + // } + // ``` + if !expected.contains(&TokenType::Comma) { + // We have something like `expr //!val` where the user likely meant `expr // !val` + let pos = self.token.span.lo() + BytePos(2); + let span = self.token.span.with_lo(pos).with_hi(pos); + err.span_suggestion_verbose( + span, + format!( + "add a space before {} to write a regular comment", + match (kind, style) { + (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`", + (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`", + (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`", + (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`", + }, + ), + " ".to_string(), + Applicability::MaybeIncorrect, + ); + } } let sp = if self.token == token::Eof { diff --git a/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.rs b/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.rs new file mode 100644 index 00000000000..7ac6fa127f4 --- /dev/null +++ b/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.rs @@ -0,0 +1,34 @@ +//! Check that if the parser suggests converting `///` to a regular comment +//! when it appears after a missing comma in an list (e.g. `enum` variants). +//! +//! Related issue +//! - https://github.com/rust-lang/rust/issues/142311 + +enum Foo { + /// Like the noise a sheep makes + Bar + /// Like where people drink + //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `/// Like where people drink` + Baa///xxxxxx + //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx` + Baz///xxxxxx + //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx` +} + +fn foo() { + let a = [ + 1///xxxxxx + //~^ ERROR expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found doc comment `///xxxxxx` + 2 + ]; +} + +fn bar() { + let a = [ + 1, + 2///xxxxxx + //~^ ERROR expected one of `,`, `.`, `?`, `]`, or an operator, found doc comment `///xxxxxx` + ]; +} + +fn main() {} diff --git a/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.stderr b/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.stderr new file mode 100644 index 00000000000..d95cecfc560 --- /dev/null +++ b/tests/ui/parser/doc-comment-after-missing-comma-issue-142311.stderr @@ -0,0 +1,43 @@ +error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `/// Like where people drink` + --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:10:5 + | +LL | Bar + | - + | | + | expected one of `(`, `,`, `=`, `{`, or `}` + | help: missing `,` +LL | /// Like where people drink + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token + +error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx` + --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:12:8 + | +LL | Baa///xxxxxx + | -^^^^^^^^ + | | + | expected one of `(`, `,`, `=`, `{`, or `}` + | help: missing `,` + +error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx` + --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:14:8 + | +LL | Baz///xxxxxx + | ^^^^^^^^^ expected one of `(`, `,`, `=`, `{`, or `}` + | + = help: doc comments must come before what they document, if a comment was intended use `//` + = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found doc comment `///xxxxxx` + --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:20:10 + | +LL | 1///xxxxxx + | ^^^^^^^^^ expected one of `,`, `.`, `;`, `?`, `]`, or an operator + +error: expected one of `,`, `.`, `?`, `]`, or an operator, found doc comment `///xxxxxx` + --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:29:10 + | +LL | 2///xxxxxx + | ^^^^^^^^^ expected one of `,`, `.`, `?`, `]`, or an operator + +error: aborting due to 5 previous errors + -- cgit 1.4.1-3-g733a5