rustc_parse/parser/
item.rs

1use std::fmt::Write;
2use std::mem;
3
4use ast::token::IdentIsRaw;
5use rustc_ast::ast::*;
6use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
7use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
8use rustc_ast::util::case::Case;
9use rustc_ast::{
10    attr, {self as ast},
11};
12use rustc_ast_pretty::pprust;
13use rustc_errors::codes::*;
14use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
15use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN;
16use rustc_span::edit_distance::edit_distance;
17use rustc_span::edition::Edition;
18use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, source_map, sym};
19use thin_vec::{ThinVec, thin_vec};
20use tracing::debug;
21
22use super::diagnostics::{ConsumeClosingDelim, dummy_arg};
23use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
24use super::{
25    AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect, Parser, PathStyle,
26    Recovered, Trailing, UsePreAttrPos,
27};
28use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField};
29use crate::{exp, fluent_generated as fluent};
30
31impl<'a> Parser<'a> {
32    /// Parses a source module as a crate. This is the main entry point for the parser.
33    pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
34        let (attrs, items, spans) = self.parse_mod(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eof,
    token_type: crate::parser::token_type::TokenType::Eof,
}exp!(Eof))?;
35        Ok(ast::Crate { attrs, items, spans, id: DUMMY_NODE_ID, is_placeholder: false })
36    }
37
38    /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
39    fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
40        let safety = self.parse_safety(Case::Sensitive);
41        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Mod,
    token_type: crate::parser::token_type::TokenType::KwMod,
}exp!(Mod))?;
42        let ident = self.parse_ident()?;
43        let mod_kind = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
44            ModKind::Unloaded
45        } else {
46            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace))?;
47            let (inner_attrs, items, inner_span) = self.parse_mod(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace))?;
48            attrs.extend(inner_attrs);
49            ModKind::Loaded(items, Inline::Yes, inner_span)
50        };
51        Ok(ItemKind::Mod(safety, ident, mod_kind))
52    }
53
54    /// Parses the contents of a module (inner attributes followed by module items).
55    /// We exit once we hit `term` which can be either
56    /// - EOF (for files)
57    /// - `}` for mod items
58    pub fn parse_mod(
59        &mut self,
60        term: ExpTokenPair,
61    ) -> PResult<'a, (AttrVec, ThinVec<Box<Item>>, ModSpans)> {
62        let lo = self.token.span;
63        let attrs = self.parse_inner_attributes()?;
64
65        let post_attr_lo = self.token.span;
66        let mut items: ThinVec<Box<_>> = ThinVec::new();
67
68        // There shouldn't be any stray semicolons before or after items.
69        // `parse_item` consumes the appropriate semicolons so any leftover is an error.
70        loop {
71            while self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {} // Eat all bad semicolons
72            let Some(item) = self.parse_item(ForceCollect::No)? else {
73                break;
74            };
75            items.push(item);
76        }
77
78        if !self.eat(term) {
79            let token_str = super::token_descr(&self.token);
80            if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
81                let is_let = self.token.is_keyword(kw::Let);
82                let is_let_mut = is_let && self.look_ahead(1, |t| t.is_keyword(kw::Mut));
83                let let_has_ident = is_let && !is_let_mut && self.is_kw_followed_by_ident(kw::Let);
84
85                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected item, found {0}",
                token_str))
    })format!("expected item, found {token_str}");
86                let mut err = self.dcx().struct_span_err(self.token.span, msg);
87
88                let label = if is_let {
89                    "`let` cannot be used for global variables"
90                } else {
91                    "expected item"
92                };
93                err.span_label(self.token.span, label);
94
95                if is_let {
96                    if is_let_mut {
97                        err.help("consider using `static` and a `Mutex` instead of `let mut`");
98                    } else if let_has_ident {
99                        err.span_suggestion_short(
100                            self.token.span,
101                            "consider using `static` or `const` instead of `let`",
102                            "static",
103                            Applicability::MaybeIncorrect,
104                        );
105                    } else {
106                        err.help("consider using `static` or `const` instead of `let`");
107                    }
108                }
109                err.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
110                return Err(err);
111            }
112        }
113
114        let inject_use_span = post_attr_lo.data().with_hi(post_attr_lo.lo());
115        let mod_spans = ModSpans { inner_span: lo.to(self.prev_token.span), inject_use_span };
116        Ok((attrs, items, mod_spans))
117    }
118}
119
120enum ReuseKind {
121    Path,
122    Impl,
123}
124
125impl<'a> Parser<'a> {
126    pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Box<Item>>> {
127        let fn_parse_mode =
128            FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
129        self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new))
130    }
131
132    fn parse_item_(
133        &mut self,
134        fn_parse_mode: FnParseMode,
135        force_collect: ForceCollect,
136    ) -> PResult<'a, Option<Item>> {
137        self.recover_vcs_conflict_marker();
138        let attrs = self.parse_outer_attributes()?;
139        self.recover_vcs_conflict_marker();
140        self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect)
141    }
142
143    pub(super) fn parse_item_common(
144        &mut self,
145        attrs: AttrWrapper,
146        mac_allowed: bool,
147        attrs_allowed: bool,
148        fn_parse_mode: FnParseMode,
149        force_collect: ForceCollect,
150    ) -> PResult<'a, Option<Item>> {
151        if let Some(item) =
152            self.eat_metavar_seq(MetaVarKind::Item, |this| this.parse_item(ForceCollect::Yes))
153        {
154            let mut item = item.expect("an actual item");
155            attrs.prepend_to_nt_inner(&mut item.attrs);
156            return Ok(Some(*item));
157        }
158
159        self.collect_tokens(None, attrs, force_collect, |this, mut attrs| {
160            let lo = this.token.span;
161            let vis = this.parse_visibility(FollowedByType::No)?;
162            let mut def = this.parse_defaultness();
163            let kind = this.parse_item_kind(
164                &mut attrs,
165                mac_allowed,
166                lo,
167                &vis,
168                &mut def,
169                fn_parse_mode,
170                Case::Sensitive,
171            )?;
172            if let Some(kind) = kind {
173                this.error_on_unconsumed_default(def, &kind);
174                let span = lo.to(this.prev_token.span);
175                let id = DUMMY_NODE_ID;
176                let item = Item { attrs, id, kind, vis, span, tokens: None };
177                return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
178            }
179
180            // At this point, we have failed to parse an item.
181            if !#[allow(non_exhaustive_omitted_patterns)] match vis.kind {
    VisibilityKind::Inherited => true,
    _ => false,
}matches!(vis.kind, VisibilityKind::Inherited) {
182                this.dcx().emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis });
183            }
184
185            if let Defaultness::Default(span) = def {
186                this.dcx().emit_err(errors::DefaultNotFollowedByItem { span });
187            }
188
189            if !attrs_allowed {
190                this.recover_attrs_no_item(&attrs)?;
191            }
192            Ok((None, Trailing::No, UsePreAttrPos::No))
193        })
194    }
195
196    /// Error in-case `default` was parsed in an in-appropriate context.
197    fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
198        if let Defaultness::Default(span) = def {
199            self.dcx().emit_err(errors::InappropriateDefault {
200                span,
201                article: kind.article(),
202                descr: kind.descr(),
203            });
204        }
205    }
206
207    /// Parses one of the items allowed by the flags.
208    fn parse_item_kind(
209        &mut self,
210        attrs: &mut AttrVec,
211        macros_allowed: bool,
212        lo: Span,
213        vis: &Visibility,
214        def: &mut Defaultness,
215        fn_parse_mode: FnParseMode,
216        case: Case,
217    ) -> PResult<'a, Option<ItemKind>> {
218        let check_pub = def == &Defaultness::Final;
219        let mut def_ = || mem::replace(def, Defaultness::Final);
220
221        let info = if !self.is_use_closure() && self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Use,
    token_type: crate::parser::token_type::TokenType::KwUse,
}exp!(Use), case) {
222            self.parse_use_item()?
223        } else if self.check_fn_front_matter(check_pub, case) {
224            // FUNCTION ITEM
225            let (ident, sig, generics, contract, body) =
226                self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
227            ItemKind::Fn(Box::new(Fn {
228                defaultness: def_(),
229                ident,
230                sig,
231                generics,
232                contract,
233                body,
234                define_opaque: None,
235                eii_impls: ThinVec::new(),
236            }))
237        } else if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern), case) {
238            if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Crate,
    token_type: crate::parser::token_type::TokenType::KwCrate,
}exp!(Crate), case) {
239                // EXTERN CRATE
240                self.parse_item_extern_crate()?
241            } else {
242                // EXTERN BLOCK
243                self.parse_item_foreign_mod(attrs, Safety::Default)?
244            }
245        } else if self.is_unsafe_foreign_mod() {
246            // EXTERN BLOCK
247            let safety = self.parse_safety(Case::Sensitive);
248            self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern))?;
249            self.parse_item_foreign_mod(attrs, safety)?
250        } else if let Some(safety) = self.parse_global_static_front_matter(case) {
251            // STATIC ITEM
252            let mutability = self.parse_mutability();
253            self.parse_static_item(safety, mutability)?
254        } else if self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Trait,
    token_type: crate::parser::token_type::TokenType::KwTrait,
}exp!(Trait), case) || self.check_trait_front_matter() {
255            // TRAIT ITEM
256            self.parse_item_trait(attrs, lo)?
257        } else if self.check_impl_frontmatter(0) {
258            // IMPL ITEM
259            self.parse_item_impl(attrs, def_(), false)?
260        } else if let Const::Yes(const_span) = self.parse_constness(case) {
261            // CONST ITEM
262            self.recover_const_mut(const_span);
263            self.recover_missing_kw_before_item()?;
264            let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
265            ItemKind::Const(Box::new(ConstItem {
266                defaultness: def_(),
267                ident,
268                generics,
269                ty,
270                rhs,
271                define_opaque: None,
272            }))
273        } else if let Some(kind) = self.is_reuse_item() {
274            self.parse_item_delegation(attrs, def_(), kind)?
275        } else if self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Mod,
    token_type: crate::parser::token_type::TokenType::KwMod,
}exp!(Mod), case)
276            || self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe), case) && self.is_keyword_ahead(1, &[kw::Mod])
277        {
278            // MODULE ITEM
279            self.parse_item_mod(attrs)?
280        } else if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Type,
    token_type: crate::parser::token_type::TokenType::KwType,
}exp!(Type), case) {
281            // TYPE ITEM
282            self.parse_type_alias(def_())?
283        } else if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Enum,
    token_type: crate::parser::token_type::TokenType::KwEnum,
}exp!(Enum), case) {
284            // ENUM ITEM
285            self.parse_item_enum()?
286        } else if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Struct,
    token_type: crate::parser::token_type::TokenType::KwStruct,
}exp!(Struct), case) {
287            // STRUCT ITEM
288            self.parse_item_struct()?
289        } else if self.is_kw_followed_by_ident(kw::Union) {
290            // UNION ITEM
291            self.bump(); // `union`
292            self.parse_item_union()?
293        } else if self.is_builtin() {
294            // BUILTIN# ITEM
295            return self.parse_item_builtin();
296        } else if self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Macro,
    token_type: crate::parser::token_type::TokenType::KwMacro,
}exp!(Macro), case) {
297            // MACROS 2.0 ITEM
298            self.parse_item_decl_macro(lo)?
299        } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
300            // MACRO_RULES ITEM
301            self.parse_item_macro_rules(vis, has_bang)?
302        } else if self.isnt_macro_invocation()
303            && (self.token.is_ident_named(sym::import)
304                || self.token.is_ident_named(sym::using)
305                || self.token.is_ident_named(sym::include)
306                || self.token.is_ident_named(sym::require))
307        {
308            return self.recover_import_as_use();
309        } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
310            self.recover_missing_kw_before_item()?;
311            return Ok(None);
312        } else if self.isnt_macro_invocation() && case == Case::Sensitive {
313            _ = def_;
314
315            // Recover wrong cased keywords
316            return self.parse_item_kind(
317                attrs,
318                macros_allowed,
319                lo,
320                vis,
321                def,
322                fn_parse_mode,
323                Case::Insensitive,
324            );
325        } else if macros_allowed && self.check_path() {
326            if self.isnt_macro_invocation() {
327                self.recover_missing_kw_before_item()?;
328            }
329            // MACRO INVOCATION ITEM
330            ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
331        } else {
332            return Ok(None);
333        };
334        Ok(Some(info))
335    }
336
337    fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
338        let span = self.token.span;
339        let token_name = super::token_descr(&self.token);
340        let snapshot = self.create_snapshot_for_diagnostic();
341        self.bump();
342        match self.parse_use_item() {
343            Ok(u) => {
344                self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
345                Ok(Some(u))
346            }
347            Err(e) => {
348                e.cancel();
349                self.restore_snapshot(snapshot);
350                Ok(None)
351            }
352        }
353    }
354
355    fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
356        let tree = self.parse_use_tree()?;
357        if let Err(mut e) = self.expect_semi() {
358            match tree.kind {
359                UseTreeKind::Glob => {
360                    e.note("the wildcard token must be last on the path");
361                }
362                UseTreeKind::Nested { .. } => {
363                    e.note("glob-like brace syntax must be last on the path");
364                }
365                _ => (),
366            }
367            return Err(e);
368        }
369        Ok(ItemKind::Use(tree))
370    }
371
372    /// When parsing a statement, would the start of a path be an item?
373    pub(super) fn is_path_start_item(&mut self) -> bool {
374        self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }`
375        || self.is_reuse_item().is_some() // yes: `reuse impl Trait for Struct { self.0 }`, yes: `reuse some_path::foo;`
376        || self.check_trait_front_matter() // no: `auto::b`, yes: `auto trait X { .. }`
377        || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
378        || #[allow(non_exhaustive_omitted_patterns)] match self.is_macro_rules_item() {
    IsMacroRulesItem::Yes { .. } => true,
    _ => false,
}matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) // no: `macro_rules::b`, yes: `macro_rules! mac`
379    }
380
381    fn is_reuse_item(&mut self) -> Option<ReuseKind> {
382        if !self.token.is_keyword(kw::Reuse) {
383            return None;
384        }
385
386        // no: `reuse ::path` for compatibility reasons with macro invocations
387        if self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep) {
388            Some(ReuseKind::Path)
389        } else if self.check_impl_frontmatter(1) {
390            Some(ReuseKind::Impl)
391        } else {
392            None
393        }
394    }
395
396    /// Are we sure this could not possibly be a macro invocation?
397    fn isnt_macro_invocation(&mut self) -> bool {
398        self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
399    }
400
401    /// Recover on encountering a struct, enum, or method definition where the user
402    /// forgot to add the `struct`, `enum`, or `fn` keyword
403    fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
404        let is_pub = self.prev_token.is_keyword(kw::Pub);
405        let is_const = self.prev_token.is_keyword(kw::Const);
406        let ident_span = self.token.span;
407        let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
408        let insert_span = ident_span.shrink_to_lo();
409
410        let ident = if self.token.is_ident()
411            && self.token.is_non_reserved_ident()
412            && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
413            && self.look_ahead(1, |t| {
414                #[allow(non_exhaustive_omitted_patterns)] match t.kind {
    token::Lt | token::OpenBrace | token::OpenParen => true,
    _ => false,
}matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
415            }) {
416            self.parse_ident().unwrap()
417        } else {
418            return Ok(());
419        };
420
421        let mut found_generics = false;
422        if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Lt,
    token_type: crate::parser::token_type::TokenType::Lt,
}exp!(Lt)) {
423            found_generics = true;
424            self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Gt,
    token_type: crate::parser::token_type::TokenType::Gt,
}exp!(Gt)]);
425            self.bump(); // `>`
426        }
427
428        let err = if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
429            // possible struct or enum definition where `struct` or `enum` was forgotten
430            if self.look_ahead(1, |t| *t == token::CloseBrace) {
431                // `S {}` could be unit enum or struct
432                Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span })
433            } else if self.look_ahead(2, |t| *t == token::Colon)
434                || self.look_ahead(3, |t| *t == token::Colon)
435            {
436                // `S { f:` or `S { pub f:`
437                Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident })
438            } else {
439                Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident })
440            }
441        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
442            // possible function or tuple struct definition where `fn` or `struct` was forgotten
443            self.bump(); // `(`
444            let is_method = self.recover_self_param();
445
446            self.consume_block(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen), ConsumeClosingDelim::Yes);
447
448            let err = if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::RArrow,
    token_type: crate::parser::token_type::TokenType::RArrow,
}exp!(RArrow)) || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
449                self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)]);
450                self.bump(); // `{`
451                self.consume_block(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), ConsumeClosingDelim::Yes);
452                if is_method {
453                    errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident }
454                } else {
455                    errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident }
456                }
457            } else if is_pub && self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
458                errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
459            } else {
460                errors::MissingKeywordForItemDefinition::Ambiguous {
461                    span,
462                    subdiag: if found_generics {
463                        None
464                    } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
465                        Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
466                            span: ident_span,
467                            snippet,
468                        })
469                    } else {
470                        Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
471                    },
472                }
473            };
474            Some(err)
475        } else if found_generics {
476            Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
477        } else {
478            None
479        };
480
481        if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
482    }
483
484    fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
485        // To be expanded
486        Ok(None)
487    }
488
489    /// Parses an item macro, e.g., `item!();`.
490    fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
491        let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
492        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))?; // `!`
493        match self.parse_delim_args() {
494            // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
495            Ok(args) => {
496                self.eat_semi_for_macro_if_needed(&args);
497                self.complain_if_pub_macro(vis, false);
498                Ok(MacCall { path, args })
499            }
500
501            Err(mut err) => {
502                // Maybe the user misspelled `macro_rules` (issue #91227)
503                if self.token.is_ident()
504                    && let [segment] = path.segments.as_slice()
505                    && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
506                {
507                    err.span_suggestion(
508                        path.span,
509                        "perhaps you meant to define a macro",
510                        "macro_rules",
511                        Applicability::MachineApplicable,
512                    );
513                }
514                Err(err)
515            }
516        }
517    }
518
519    /// Recover if we parsed attributes and expected an item but there was none.
520    fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
521        let ([start @ end] | [start, .., end]) = attrs else {
522            return Ok(());
523        };
524        let msg = if end.is_doc_comment() {
525            "expected item after doc comment"
526        } else {
527            "expected item after attributes"
528        };
529        let mut err = self.dcx().struct_span_err(end.span, msg);
530        if end.is_doc_comment() {
531            err.span_label(end.span, "this doc comment doesn't document anything");
532        } else if self.token == TokenKind::Semi {
533            err.span_suggestion_verbose(
534                self.token.span,
535                "consider removing this semicolon",
536                "",
537                Applicability::MaybeIncorrect,
538            );
539        }
540        if let [.., penultimate, _] = attrs {
541            err.span_label(start.span.to(penultimate.span), "other attributes here");
542        }
543        Err(err)
544    }
545
546    fn is_async_fn(&self) -> bool {
547        self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
548    }
549
550    fn parse_polarity(&mut self) -> ast::ImplPolarity {
551        // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
552        if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
553            self.bump(); // `!`
554            ast::ImplPolarity::Negative(self.prev_token.span)
555        } else {
556            ast::ImplPolarity::Positive
557        }
558    }
559
560    /// Parses an implementation item.
561    ///
562    /// ```ignore (illustrative)
563    /// impl<'a, T> TYPE { /* impl items */ }
564    /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
565    /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
566    /// impl<'a, T> const TRAIT for TYPE { /* impl items */ }
567    /// ```
568    ///
569    /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
570    /// ```ebnf
571    /// "impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
572    /// "impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
573    /// ```
574    fn parse_item_impl(
575        &mut self,
576        attrs: &mut AttrVec,
577        defaultness: Defaultness,
578        is_reuse: bool,
579    ) -> PResult<'a, ItemKind> {
580        let mut constness = self.parse_constness(Case::Sensitive);
581        let safety = self.parse_safety(Case::Sensitive);
582        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Impl,
    token_type: crate::parser::token_type::TokenType::KwImpl,
}exp!(Impl))?;
583
584        // First, parse generic parameters if necessary.
585        let mut generics = if self.choose_generics_over_qpath(0) {
586            self.parse_generics()?
587        } else {
588            let mut generics = Generics::default();
589            // impl A for B {}
590            //    /\ this is where `generics.span` should point when there are no type params.
591            generics.span = self.prev_token.span.shrink_to_hi();
592            generics
593        };
594
595        if let Const::No = constness {
596            // FIXME(const_trait_impl): disallow `impl const Trait`
597            constness = self.parse_constness(Case::Sensitive);
598        }
599
600        if let Const::Yes(span) = constness {
601            self.psess.gated_spans.gate(sym::const_trait_impl, span);
602        }
603
604        // Parse stray `impl async Trait`
605        if (self.token_uninterpolated_span().at_least_rust_2018()
606            && self.token.is_keyword(kw::Async))
607            || self.is_kw_followed_by_ident(kw::Async)
608        {
609            self.bump();
610            self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
611        }
612
613        let polarity = self.parse_polarity();
614
615        // Parse both types and traits as a type, then reinterpret if necessary.
616        let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
617        {
618            let span = self.prev_token.span.between(self.token.span);
619            return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
620                span,
621                for_span: span.to(self.token.span),
622            }));
623        } else {
624            self.parse_ty_with_generics_recovery(&generics)?
625        };
626
627        // If `for` is missing we try to recover.
628        let has_for = self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::For,
    token_type: crate::parser::token_type::TokenType::KwFor,
}exp!(For));
629        let missing_for_span = self.prev_token.span.between(self.token.span);
630
631        let ty_second = if self.token == token::DotDot {
632            // We need to report this error after `cfg` expansion for compatibility reasons
633            self.bump(); // `..`, do not add it to expected tokens
634
635            // AST validation later detects this `TyKind::Dummy` and emits an
636            // error. (#121072 will hopefully remove all this special handling
637            // of the obsolete `impl Trait for ..` and then this can go away.)
638            Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
639        } else if has_for || self.token.can_begin_type() {
640            Some(self.parse_ty()?)
641        } else {
642            None
643        };
644
645        generics.where_clause = self.parse_where_clause()?;
646
647        let impl_items = if is_reuse {
648            Default::default()
649        } else {
650            self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?
651        };
652
653        let (of_trait, self_ty) = match ty_second {
654            Some(ty_second) => {
655                // impl Trait for Type
656                if !has_for {
657                    self.dcx().emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
658                }
659
660                let ty_first = *ty_first;
661                let path = match ty_first.kind {
662                    // This notably includes paths passed through `ty` macro fragments (#46438).
663                    TyKind::Path(None, path) => path,
664                    other => {
665                        if let TyKind::ImplTrait(_, bounds) = other
666                            && let [bound] = bounds.as_slice()
667                            && let GenericBound::Trait(poly_trait_ref) = bound
668                        {
669                            // Suggest removing extra `impl` keyword:
670                            // `impl<T: Default> impl Default for Wrapper<T>`
671                            //                   ^^^^^
672                            let extra_impl_kw = ty_first.span.until(bound.span());
673                            self.dcx().emit_err(errors::ExtraImplKeywordInTraitImpl {
674                                extra_impl_kw,
675                                impl_trait_span: ty_first.span,
676                            });
677                            poly_trait_ref.trait_ref.path.clone()
678                        } else {
679                            return Err(self.dcx().create_err(
680                                errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
681                            ));
682                        }
683                    }
684                };
685                let trait_ref = TraitRef { path, ref_id: ty_first.id };
686
687                let of_trait =
688                    Some(Box::new(TraitImplHeader { defaultness, safety, polarity, trait_ref }));
689                (of_trait, ty_second)
690            }
691            None => {
692                let self_ty = ty_first;
693                let error = |modifier, modifier_name, modifier_span| {
694                    self.dcx().create_err(errors::TraitImplModifierInInherentImpl {
695                        span: self_ty.span,
696                        modifier,
697                        modifier_name,
698                        modifier_span,
699                        self_ty: self_ty.span,
700                    })
701                };
702
703                if let Safety::Unsafe(span) = safety {
704                    error("unsafe", "unsafe", span).with_code(E0197).emit();
705                }
706                if let ImplPolarity::Negative(span) = polarity {
707                    error("!", "negative", span).emit();
708                }
709                if let Defaultness::Default(def_span) = defaultness {
710                    error("default", "default", def_span).emit();
711                }
712                if let Const::Yes(span) = constness {
713                    self.psess.gated_spans.gate(sym::const_trait_impl, span);
714                }
715                (None, self_ty)
716            }
717        };
718
719        Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items, constness }))
720    }
721
722    fn parse_item_delegation(
723        &mut self,
724        attrs: &mut AttrVec,
725        defaultness: Defaultness,
726        kind: ReuseKind,
727    ) -> PResult<'a, ItemKind> {
728        let span = self.token.span;
729        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Reuse,
    token_type: crate::parser::token_type::TokenType::KwReuse,
}exp!(Reuse))?;
730
731        let item_kind = match kind {
732            ReuseKind::Path => self.parse_path_like_delegation(),
733            ReuseKind::Impl => self.parse_impl_delegation(span, attrs, defaultness),
734        }?;
735
736        self.psess.gated_spans.gate(sym::fn_delegation, span.to(self.prev_token.span));
737
738        Ok(item_kind)
739    }
740
741    fn parse_delegation_body(&mut self) -> PResult<'a, Option<Box<Block>>> {
742        Ok(if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
743            Some(self.parse_block()?)
744        } else {
745            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi))?;
746            None
747        })
748    }
749
750    fn parse_impl_delegation(
751        &mut self,
752        span: Span,
753        attrs: &mut AttrVec,
754        defaultness: Defaultness,
755    ) -> PResult<'a, ItemKind> {
756        let mut impl_item = self.parse_item_impl(attrs, defaultness, true)?;
757        let ItemKind::Impl(Impl { items, of_trait, .. }) = &mut impl_item else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
758
759        let until_expr_span = span.to(self.prev_token.span);
760
761        let Some(of_trait) = of_trait else {
762            return Err(self
763                .dcx()
764                .create_err(errors::ImplReuseInherentImpl { span: until_expr_span }));
765        };
766
767        let body = self.parse_delegation_body()?;
768        let whole_reuse_span = span.to(self.prev_token.span);
769
770        items.push(Box::new(AssocItem {
771            id: DUMMY_NODE_ID,
772            attrs: Default::default(),
773            span: whole_reuse_span,
774            tokens: None,
775            vis: Visibility {
776                kind: VisibilityKind::Inherited,
777                span: whole_reuse_span,
778                tokens: None,
779            },
780            kind: AssocItemKind::DelegationMac(Box::new(DelegationMac {
781                qself: None,
782                prefix: of_trait.trait_ref.path.clone(),
783                suffixes: None,
784                body,
785            })),
786        }));
787
788        Ok(impl_item)
789    }
790
791    fn parse_path_like_delegation(&mut self) -> PResult<'a, ItemKind> {
792        let (qself, path) = if self.eat_lt() {
793            let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
794            (Some(qself), path)
795        } else {
796            (None, self.parse_path(PathStyle::Expr)?)
797        };
798
799        let rename = |this: &mut Self| {
800            Ok(if this.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::As,
    token_type: crate::parser::token_type::TokenType::KwAs,
}exp!(As)) { Some(this.parse_ident()?) } else { None })
801        };
802
803        Ok(if self.eat_path_sep() {
804            let suffixes = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star)) {
805                None
806            } else {
807                let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
808                Some(self.parse_delim_comma_seq(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), parse_suffix)?.0)
809            };
810
811            ItemKind::DelegationMac(Box::new(DelegationMac {
812                qself,
813                prefix: path,
814                suffixes,
815                body: self.parse_delegation_body()?,
816            }))
817        } else {
818            let rename = rename(self)?;
819            let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
820
821            ItemKind::Delegation(Box::new(Delegation {
822                id: DUMMY_NODE_ID,
823                qself,
824                path,
825                ident,
826                rename,
827                body: self.parse_delegation_body()?,
828                from_glob: false,
829            }))
830        })
831    }
832
833    fn parse_item_list<T>(
834        &mut self,
835        attrs: &mut AttrVec,
836        mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
837    ) -> PResult<'a, ThinVec<T>> {
838        let open_brace_span = self.token.span;
839
840        // Recover `impl Ty;` instead of `impl Ty {}`
841        if self.token == TokenKind::Semi {
842            self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
843            self.bump();
844            return Ok(ThinVec::new());
845        }
846
847        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace))?;
848        attrs.extend(self.parse_inner_attributes()?);
849
850        let mut items = ThinVec::new();
851        while !self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)) {
852            if self.recover_doc_comment_before_brace() {
853                continue;
854            }
855            self.recover_vcs_conflict_marker();
856            match parse_item(self) {
857                Ok(None) => {
858                    let mut is_unnecessary_semicolon = !items.is_empty()
859                        // When the close delim is `)` in a case like the following, `token.kind`
860                        // is expected to be `token::CloseParen`, but the actual `token.kind` is
861                        // `token::CloseBrace`. This is because the `token.kind` of the close delim
862                        // is treated as the same as that of the open delim in
863                        // `TokenTreesReader::parse_token_tree`, even if the delimiters of them are
864                        // different. Therefore, `token.kind` should not be compared here.
865                        //
866                        // issue-60075.rs
867                        // ```
868                        // trait T {
869                        //     fn qux() -> Option<usize> {
870                        //         let _ = if true {
871                        //         });
872                        //          ^ this close delim
873                        //         Some(4)
874                        //     }
875                        // ```
876                        && self
877                            .span_to_snippet(self.prev_token.span)
878                            .is_ok_and(|snippet| snippet == "}")
879                        && self.token == token::Semi;
880                    let mut semicolon_span = self.token.span;
881                    if !is_unnecessary_semicolon {
882                        // #105369, Detect spurious `;` before assoc fn body
883                        is_unnecessary_semicolon =
884                            self.token == token::OpenBrace && self.prev_token == token::Semi;
885                        semicolon_span = self.prev_token.span;
886                    }
887                    // We have to bail or we'll potentially never make progress.
888                    let non_item_span = self.token.span;
889                    let is_let = self.token.is_keyword(kw::Let);
890
891                    let mut err =
892                        self.dcx().struct_span_err(non_item_span, "non-item in item list");
893                    self.consume_block(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), ConsumeClosingDelim::Yes);
894                    if is_let {
895                        err.span_suggestion_verbose(
896                            non_item_span,
897                            "consider using `const` instead of `let` for associated const",
898                            "const",
899                            Applicability::MachineApplicable,
900                        );
901                    } else {
902                        err.span_label(open_brace_span, "item list starts here")
903                            .span_label(non_item_span, "non-item starts here")
904                            .span_label(self.prev_token.span, "item list ends here");
905                    }
906                    if is_unnecessary_semicolon {
907                        err.span_suggestion(
908                            semicolon_span,
909                            "consider removing this semicolon",
910                            "",
911                            Applicability::MaybeIncorrect,
912                        );
913                    }
914                    err.emit();
915                    break;
916                }
917                Ok(Some(item)) => items.extend(item),
918                Err(err) => {
919                    self.consume_block(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), ConsumeClosingDelim::Yes);
920                    err.with_span_label(
921                        open_brace_span,
922                        "while parsing this item list starting here",
923                    )
924                    .with_span_label(self.prev_token.span, "the item list ends here")
925                    .emit();
926                    break;
927                }
928            }
929        }
930        Ok(items)
931    }
932
933    /// Recover on a doc comment before `}`.
934    fn recover_doc_comment_before_brace(&mut self) -> bool {
935        if let token::DocComment(..) = self.token.kind {
936            if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
937                // FIXME: merge with `DocCommentDoesNotDocumentAnything` (E0585)
938                {
    self.dcx().struct_span_err(self.token.span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("found a documentation comment that doesn\'t document anything"))
                })).with_code(E0584)
}struct_span_code_err!(
939                    self.dcx(),
940                    self.token.span,
941                    E0584,
942                    "found a documentation comment that doesn't document anything",
943                )
944                .with_span_label(self.token.span, "this doc comment doesn't document anything")
945                .with_help(
946                    "doc comments must come before what they document, if a comment was \
947                    intended use `//`",
948                )
949                .emit();
950                self.bump();
951                return true;
952            }
953        }
954        false
955    }
956
957    /// Parses defaultness (i.e., `default` or nothing).
958    fn parse_defaultness(&mut self) -> Defaultness {
959        // We are interested in `default` followed by another identifier.
960        // However, we must avoid keywords that occur as binary operators.
961        // Currently, the only applicable keyword is `as` (`default as Ty`).
962        if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Default,
    token_type: crate::parser::token_type::TokenType::KwDefault,
}exp!(Default))
963            && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
964        {
965            self.bump(); // `default`
966            Defaultness::Default(self.prev_token_uninterpolated_span())
967        } else {
968            Defaultness::Final
969        }
970    }
971
972    /// Is this an `(const unsafe? auto?| unsafe auto? | auto) trait` item?
973    fn check_trait_front_matter(&mut self) -> bool {
974        // auto trait
975        self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Auto,
    token_type: crate::parser::token_type::TokenType::KwAuto,
}exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
976            // unsafe auto trait
977            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
978            || self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const)) && ((self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait]))
979                || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
980    }
981
982    /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
983    fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
984        let constness = self.parse_constness(Case::Sensitive);
985        if let Const::Yes(span) = constness {
986            self.psess.gated_spans.gate(sym::const_trait_impl, span);
987        }
988        let safety = self.parse_safety(Case::Sensitive);
989        // Parse optional `auto` prefix.
990        let is_auto = if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Auto,
    token_type: crate::parser::token_type::TokenType::KwAuto,
}exp!(Auto)) {
991            self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
992            IsAuto::Yes
993        } else {
994            IsAuto::No
995        };
996
997        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Trait,
    token_type: crate::parser::token_type::TokenType::KwTrait,
}exp!(Trait))?;
998        let ident = self.parse_ident()?;
999        let mut generics = self.parse_generics()?;
1000
1001        // Parse optional colon and supertrait bounds.
1002        let had_colon = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon));
1003        let span_at_colon = self.prev_token.span;
1004        let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
1005
1006        let span_before_eq = self.prev_token.span;
1007        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) {
1008            // It's a trait alias.
1009            if had_colon {
1010                let span = span_at_colon.to(span_before_eq);
1011                self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
1012            }
1013
1014            let bounds = self.parse_generic_bounds()?;
1015            generics.where_clause = self.parse_where_clause()?;
1016            self.expect_semi()?;
1017
1018            let whole_span = lo.to(self.prev_token.span);
1019            if is_auto == IsAuto::Yes {
1020                self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
1021            }
1022            if let Safety::Unsafe(_) = safety {
1023                self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
1024            }
1025
1026            self.psess.gated_spans.gate(sym::trait_alias, whole_span);
1027
1028            Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
1029        } else {
1030            // It's a normal trait.
1031            generics.where_clause = self.parse_where_clause()?;
1032            let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
1033            Ok(ItemKind::Trait(Box::new(Trait {
1034                constness,
1035                is_auto,
1036                safety,
1037                ident,
1038                generics,
1039                bounds,
1040                items,
1041            })))
1042        }
1043    }
1044
1045    pub fn parse_impl_item(
1046        &mut self,
1047        force_collect: ForceCollect,
1048    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1049        let fn_parse_mode =
1050            FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true };
1051        self.parse_assoc_item(fn_parse_mode, force_collect)
1052    }
1053
1054    pub fn parse_trait_item(
1055        &mut self,
1056        force_collect: ForceCollect,
1057    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1058        let fn_parse_mode = FnParseMode {
1059            req_name: |edition, _| edition >= Edition::Edition2018,
1060            context: FnContext::Trait,
1061            req_body: false,
1062        };
1063        self.parse_assoc_item(fn_parse_mode, force_collect)
1064    }
1065
1066    /// Parses associated items.
1067    fn parse_assoc_item(
1068        &mut self,
1069        fn_parse_mode: FnParseMode,
1070        force_collect: ForceCollect,
1071    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1072        Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1073            |Item { attrs, id, span, vis, kind, tokens }| {
1074                let kind = match AssocItemKind::try_from(kind) {
1075                    Ok(kind) => kind,
1076                    Err(kind) => match kind {
1077                        ItemKind::Static(box StaticItem {
1078                            ident,
1079                            ty,
1080                            safety: _,
1081                            mutability: _,
1082                            expr,
1083                            define_opaque,
1084                        }) => {
1085                            self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
1086                            let rhs = expr.map(ConstItemRhs::Body);
1087                            AssocItemKind::Const(Box::new(ConstItem {
1088                                defaultness: Defaultness::Final,
1089                                ident,
1090                                generics: Generics::default(),
1091                                ty,
1092                                rhs,
1093                                define_opaque,
1094                            }))
1095                        }
1096                        _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1097                    },
1098                };
1099                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1100            },
1101        ))
1102    }
1103
1104    /// Parses a `type` alias with the following grammar:
1105    /// ```ebnf
1106    /// TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ;
1107    /// ```
1108    /// The `"type"` has already been eaten.
1109    fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1110        let ident = self.parse_ident()?;
1111        let mut generics = self.parse_generics()?;
1112
1113        // Parse optional colon and param bounds.
1114        let bounds = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1115        generics.where_clause = self.parse_where_clause()?;
1116
1117        let ty = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1118
1119        let after_where_clause = self.parse_where_clause()?;
1120
1121        self.expect_semi()?;
1122
1123        Ok(ItemKind::TyAlias(Box::new(TyAlias {
1124            defaultness,
1125            ident,
1126            generics,
1127            after_where_clause,
1128            bounds,
1129            ty,
1130        })))
1131    }
1132
1133    /// Parses a `UseTree`.
1134    ///
1135    /// ```text
1136    /// USE_TREE = [`::`] `*` |
1137    ///            [`::`] `{` USE_TREE_LIST `}` |
1138    ///            PATH `::` `*` |
1139    ///            PATH `::` `{` USE_TREE_LIST `}` |
1140    ///            PATH [`as` IDENT]
1141    /// ```
1142    fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1143        let lo = self.token.span;
1144
1145        let mut prefix =
1146            ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
1147        let kind =
1148            if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) || self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star)) || self.is_import_coupler() {
1149                // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
1150                let mod_sep_ctxt = self.token.span.ctxt();
1151                if self.eat_path_sep() {
1152                    prefix
1153                        .segments
1154                        .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1155                }
1156
1157                self.parse_use_tree_glob_or_nested()?
1158            } else {
1159                // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
1160                prefix = self.parse_path(PathStyle::Mod)?;
1161
1162                if self.eat_path_sep() {
1163                    self.parse_use_tree_glob_or_nested()?
1164                } else {
1165                    // Recover from using a colon as path separator.
1166                    while self.eat_noexpect(&token::Colon) {
1167                        self.dcx()
1168                            .emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
1169
1170                        // We parse the rest of the path and append it to the original prefix.
1171                        self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1172                        prefix.span = lo.to(self.prev_token.span);
1173                    }
1174
1175                    UseTreeKind::Simple(self.parse_rename()?)
1176                }
1177            };
1178
1179        Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
1180    }
1181
1182    /// Parses `*` or `{...}`.
1183    fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
1184        Ok(if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star)) {
1185            UseTreeKind::Glob
1186        } else {
1187            let lo = self.token.span;
1188            UseTreeKind::Nested {
1189                items: self.parse_use_tree_list()?,
1190                span: lo.to(self.prev_token.span),
1191            }
1192        })
1193    }
1194
1195    /// Parses a `UseTreeKind::Nested(list)`.
1196    ///
1197    /// ```text
1198    /// USE_TREE_LIST = ∅ | (USE_TREE `,`)* USE_TREE [`,`]
1199    /// ```
1200    fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
1201        self.parse_delim_comma_seq(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), |p| {
1202            p.recover_vcs_conflict_marker();
1203            Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
1204        })
1205        .map(|(r, _)| r)
1206    }
1207
1208    fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1209        if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::As,
    token_type: crate::parser::token_type::TokenType::KwAs,
}exp!(As)) {
1210            self.parse_ident_or_underscore().map(Some)
1211        } else {
1212            Ok(None)
1213        }
1214    }
1215
1216    fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1217        match self.token.ident() {
1218            Some((ident @ Ident { name: kw::Underscore, .. }, IdentIsRaw::No)) => {
1219                self.bump();
1220                Ok(ident)
1221            }
1222            _ => self.parse_ident(),
1223        }
1224    }
1225
1226    /// Parses `extern crate` links.
1227    ///
1228    /// # Examples
1229    ///
1230    /// ```ignore (illustrative)
1231    /// extern crate foo;
1232    /// extern crate bar as foo;
1233    /// ```
1234    fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1235        // Accept `extern crate name-like-this` for better diagnostics
1236        let orig_ident = self.parse_crate_name_with_dashes()?;
1237        let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1238            (Some(orig_ident.name), rename)
1239        } else {
1240            (None, orig_ident)
1241        };
1242        self.expect_semi()?;
1243        Ok(ItemKind::ExternCrate(orig_name, item_ident))
1244    }
1245
1246    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1247        let ident = if self.token.is_keyword(kw::SelfLower) {
1248            self.parse_path_segment_ident()
1249        } else {
1250            self.parse_ident()
1251        }?;
1252
1253        let dash = crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Minus,
    token_type: crate::parser::token_type::TokenType::Minus,
}exp!(Minus);
1254        if self.token != dash.tok {
1255            return Ok(ident);
1256        }
1257
1258        // Accept `extern crate name-like-this` for better diagnostics.
1259        let mut dashes = ::alloc::vec::Vec::new()vec![];
1260        let mut idents = ::alloc::vec::Vec::new()vec![];
1261        while self.eat(dash) {
1262            dashes.push(self.prev_token.span);
1263            idents.push(self.parse_ident()?);
1264        }
1265
1266        let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1267        let mut fixed_name = ident.name.to_string();
1268        for part in idents {
1269            fixed_name.write_fmt(format_args!("_{0}", part.name))write!(fixed_name, "_{}", part.name).unwrap();
1270        }
1271
1272        self.dcx().emit_err(errors::ExternCrateNameWithDashes {
1273            span: fixed_name_sp,
1274            sugg: errors::ExternCrateNameWithDashesSugg { dashes },
1275        });
1276
1277        Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1278    }
1279
1280    /// Parses `extern` for foreign ABIs modules.
1281    ///
1282    /// `extern` is expected to have been consumed before calling this method.
1283    ///
1284    /// # Examples
1285    ///
1286    /// ```ignore (only-for-syntax-highlight)
1287    /// extern "C" {}
1288    /// extern {}
1289    /// ```
1290    fn parse_item_foreign_mod(
1291        &mut self,
1292        attrs: &mut AttrVec,
1293        mut safety: Safety,
1294    ) -> PResult<'a, ItemKind> {
1295        let extern_span = self.prev_token_uninterpolated_span();
1296        let abi = self.parse_abi(); // ABI?
1297        // FIXME: This recovery should be tested better.
1298        if safety == Safety::Default
1299            && self.token.is_keyword(kw::Unsafe)
1300            && self.look_ahead(1, |t| *t == token::OpenBrace)
1301        {
1302            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)).unwrap_err().emit();
1303            safety = Safety::Unsafe(self.token.span);
1304            let _ = self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe));
1305        }
1306        Ok(ItemKind::ForeignMod(ast::ForeignMod {
1307            extern_span,
1308            safety,
1309            abi,
1310            items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1311        }))
1312    }
1313
1314    /// Parses a foreign item (one in an `extern { ... }` block).
1315    pub fn parse_foreign_item(
1316        &mut self,
1317        force_collect: ForceCollect,
1318    ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
1319        let fn_parse_mode = FnParseMode {
1320            req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
1321            context: FnContext::Free,
1322            req_body: false,
1323        };
1324        Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1325            |Item { attrs, id, span, vis, kind, tokens }| {
1326                let kind = match ForeignItemKind::try_from(kind) {
1327                    Ok(kind) => kind,
1328                    Err(kind) => match kind {
1329                        ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => {
1330                            let const_span = Some(span.with_hi(ident.span.lo()))
1331                                .filter(|span| span.can_be_used_for_suggestions());
1332                            self.dcx().emit_err(errors::ExternItemCannotBeConst {
1333                                ident_span: ident.span,
1334                                const_span,
1335                            });
1336                            ForeignItemKind::Static(Box::new(StaticItem {
1337                                ident,
1338                                ty,
1339                                mutability: Mutability::Not,
1340                                expr: rhs.map(|b| match b {
1341                                    ConstItemRhs::TypeConst(anon_const) => anon_const.value,
1342                                    ConstItemRhs::Body(expr) => expr,
1343                                }),
1344                                safety: Safety::Default,
1345                                define_opaque: None,
1346                            }))
1347                        }
1348                        _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1349                    },
1350                };
1351                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1352            },
1353        ))
1354    }
1355
1356    fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1357        // FIXME(#100717): needs variant for each `ItemKind` (instead of using `ItemKind::descr()`)
1358        let span = self.psess.source_map().guess_head_span(span);
1359        let descr = kind.descr();
1360        let help = match kind {
1361            ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1362            _ => true,
1363        };
1364        self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1365        None
1366    }
1367
1368    fn is_use_closure(&self) -> bool {
1369        if self.token.is_keyword(kw::Use) {
1370            // Check if this could be a closure.
1371            self.look_ahead(1, |token| {
1372                // Move or Async here would be an error but still we're parsing a closure
1373                let dist =
1374                    if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1375
1376                self.look_ahead(dist, |token| #[allow(non_exhaustive_omitted_patterns)] match token.kind {
    token::Or | token::OrOr => true,
    _ => false,
}matches!(token.kind, token::Or | token::OrOr))
1377            })
1378        } else {
1379            false
1380        }
1381    }
1382
1383    fn is_unsafe_foreign_mod(&self) -> bool {
1384        // Look for `unsafe`.
1385        if !self.token.is_keyword(kw::Unsafe) {
1386            return false;
1387        }
1388        // Look for `extern`.
1389        if !self.is_keyword_ahead(1, &[kw::Extern]) {
1390            return false;
1391        }
1392
1393        // Look for the optional ABI string literal.
1394        let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1395
1396        // Look for the `{`. Use `tree_look_ahead` because the ABI (if present)
1397        // might be a metavariable i.e. an invisible-delimited sequence, and
1398        // `tree_look_ahead` will consider that a single element when looking
1399        // ahead.
1400        self.tree_look_ahead(n, |t| #[allow(non_exhaustive_omitted_patterns)] match t {
    TokenTree::Delimited(_, _, Delimiter::Brace, _) => true,
    _ => false,
}matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1401            == Some(true)
1402    }
1403
1404    fn parse_global_static_front_matter(&mut self, case: Case) -> Option<Safety> {
1405        let is_global_static = if self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Static,
    token_type: crate::parser::token_type::TokenType::KwStatic,
}exp!(Static), case) {
1406            // Check if this could be a closure.
1407            !self.look_ahead(1, |token| {
1408                if token.is_keyword_case(kw::Move, case) || token.is_keyword_case(kw::Use, case) {
1409                    return true;
1410                }
1411                #[allow(non_exhaustive_omitted_patterns)] match token.kind {
    token::Or | token::OrOr => true,
    _ => false,
}matches!(token.kind, token::Or | token::OrOr)
1412            })
1413        } else {
1414            // `$qual static`
1415            (self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe), case)
1416                || self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Safe,
    token_type: crate::parser::token_type::TokenType::KwSafe,
}exp!(Safe), case))
1417                && self.look_ahead(1, |t| t.is_keyword_case(kw::Static, case))
1418        };
1419
1420        if is_global_static {
1421            let safety = self.parse_safety(case);
1422            let _ = self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Static,
    token_type: crate::parser::token_type::TokenType::KwStatic,
}exp!(Static), case);
1423            Some(safety)
1424        } else {
1425            None
1426        }
1427    }
1428
1429    /// Recover on `const mut` with `const` already eaten.
1430    fn recover_const_mut(&mut self, const_span: Span) {
1431        if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Mut,
    token_type: crate::parser::token_type::TokenType::KwMut,
}exp!(Mut)) {
1432            let span = self.prev_token.span;
1433            self.dcx()
1434                .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1435        } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Let,
    token_type: crate::parser::token_type::TokenType::KwLet,
}exp!(Let)) {
1436            let span = self.prev_token.span;
1437            self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1438        }
1439    }
1440
1441    /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in
1442    /// `mutability`.
1443    ///
1444    /// ```ebnf
1445    /// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
1446    /// ```
1447    fn parse_static_item(
1448        &mut self,
1449        safety: Safety,
1450        mutability: Mutability,
1451    ) -> PResult<'a, ItemKind> {
1452        let ident = self.parse_ident()?;
1453
1454        if self.token == TokenKind::Lt && self.may_recover() {
1455            let generics = self.parse_generics()?;
1456            self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1457        }
1458
1459        // Parse the type of a static item. That is, the `":" $ty` fragment.
1460        // FIXME: This could maybe benefit from `.may_recover()`?
1461        let ty = match (self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)), self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) | self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi))) {
1462            (true, false) => self.parse_ty()?,
1463            // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing
1464            // type.
1465            (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1466        };
1467
1468        let expr = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1469
1470        self.expect_semi()?;
1471
1472        let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1473        Ok(ItemKind::Static(Box::new(item)))
1474    }
1475
1476    /// Parse a constant item with the prefix `"const"` already parsed.
1477    ///
1478    /// ```ebnf
1479    /// Const = "const" ($ident | "_") Generics ":" $ty (= $expr)? WhereClause ";" ;
1480    /// ```
1481    fn parse_const_item(
1482        &mut self,
1483        attrs: &[Attribute],
1484    ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<ast::ConstItemRhs>)> {
1485        let ident = self.parse_ident_or_underscore()?;
1486
1487        let mut generics = self.parse_generics()?;
1488
1489        // Check the span for emptiness instead of the list of parameters in order to correctly
1490        // recognize and subsequently flag empty parameter lists (`<>`) as unstable.
1491        if !generics.span.is_empty() {
1492            self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1493        }
1494
1495        // Parse the type of a constant item. That is, the `":" $ty` fragment.
1496        // FIXME: This could maybe benefit from `.may_recover()`?
1497        let ty = match (
1498            self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)),
1499            self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) | self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) | self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Where,
    token_type: crate::parser::token_type::TokenType::KwWhere,
}exp!(Where)),
1500        ) {
1501            (true, false) => self.parse_ty()?,
1502            // If there wasn't a `:` or the colon was followed by a `=`, `;` or `where`, recover a missing type.
1503            (colon, _) => self.recover_missing_global_item_type(colon, None),
1504        };
1505
1506        // Proactively parse a where-clause to be able to provide a good error message in case we
1507        // encounter the item body following it.
1508        let before_where_clause =
1509            if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1510
1511        let rhs = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) {
1512            if attr::contains_name(attrs, sym::type_const) {
1513                Some(ConstItemRhs::TypeConst(self.parse_const_arg()?))
1514            } else {
1515                Some(ConstItemRhs::Body(self.parse_expr()?))
1516            }
1517        } else {
1518            None
1519        };
1520
1521        let after_where_clause = self.parse_where_clause()?;
1522
1523        // Provide a nice error message if the user placed a where-clause before the item body.
1524        // Users may be tempted to write such code if they are still used to the deprecated
1525        // where-clause location on type aliases and associated types. See also #89122.
1526        if before_where_clause.has_where_token
1527            && let Some(rhs) = &rhs
1528        {
1529            self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1530                span: before_where_clause.span,
1531                name: ident.span,
1532                body: rhs.span(),
1533                sugg: if !after_where_clause.has_where_token {
1534                    self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| {
1535                        errors::WhereClauseBeforeConstBodySugg {
1536                            left: before_where_clause.span.shrink_to_lo(),
1537                            snippet: body_s,
1538                            right: before_where_clause.span.shrink_to_hi().to(rhs.span()),
1539                        }
1540                    })
1541                } else {
1542                    // FIXME(generic_const_items): Provide a structured suggestion to merge the first
1543                    // where-clause into the second one.
1544                    None
1545                },
1546            });
1547        }
1548
1549        // Merge the predicates of both where-clauses since either one can be relevant.
1550        // If we didn't parse a body (which is valid for associated consts in traits) and we were
1551        // allowed to recover, `before_where_clause` contains the predicates, otherwise they are
1552        // in `after_where_clause`. Further, both of them might contain predicates iff two
1553        // where-clauses were provided which is syntactically ill-formed but we want to recover from
1554        // it and treat them as one large where-clause.
1555        let mut predicates = before_where_clause.predicates;
1556        predicates.extend(after_where_clause.predicates);
1557        let where_clause = WhereClause {
1558            has_where_token: before_where_clause.has_where_token
1559                || after_where_clause.has_where_token,
1560            predicates,
1561            span: if after_where_clause.has_where_token {
1562                after_where_clause.span
1563            } else {
1564                before_where_clause.span
1565            },
1566        };
1567
1568        if where_clause.has_where_token {
1569            self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1570        }
1571
1572        generics.where_clause = where_clause;
1573
1574        self.expect_semi()?;
1575
1576        Ok((ident, generics, ty, rhs))
1577    }
1578
1579    /// We were supposed to parse `":" $ty` but the `:` or the type was missing.
1580    /// This means that the type is missing.
1581    fn recover_missing_global_item_type(
1582        &mut self,
1583        colon_present: bool,
1584        m: Option<Mutability>,
1585    ) -> Box<Ty> {
1586        // Construct the error and stash it away with the hope
1587        // that typeck will later enrich the error with a type.
1588        let kind = match m {
1589            Some(Mutability::Mut) => "static mut",
1590            Some(Mutability::Not) => "static",
1591            None => "const",
1592        };
1593
1594        let colon = match colon_present {
1595            true => "",
1596            false => ":",
1597        };
1598
1599        let span = self.prev_token.span.shrink_to_hi();
1600        let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1601        err.stash(span, StashKey::ItemNoType);
1602
1603        // The user intended that the type be inferred,
1604        // so treat this as if the user wrote e.g. `const A: _ = expr;`.
1605        Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1606    }
1607
1608    /// Parses an enum declaration.
1609    fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1610        if self.token.is_keyword(kw::Struct) {
1611            let span = self.prev_token.span.to(self.token.span);
1612            let err = errors::EnumStructMutuallyExclusive { span };
1613            if self.look_ahead(1, |t| t.is_ident()) {
1614                self.bump();
1615                self.dcx().emit_err(err);
1616            } else {
1617                return Err(self.dcx().create_err(err));
1618            }
1619        }
1620
1621        let prev_span = self.prev_token.span;
1622        let ident = self.parse_ident()?;
1623        let mut generics = self.parse_generics()?;
1624        generics.where_clause = self.parse_where_clause()?;
1625
1626        // Possibly recover `enum Foo;` instead of `enum Foo {}`
1627        let (variants, _) = if self.token == TokenKind::Semi {
1628            self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1629            self.bump();
1630            (::thin_vec::ThinVec::new()thin_vec![], Trailing::No)
1631        } else {
1632            self.parse_delim_comma_seq(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace), |p| {
1633                p.parse_enum_variant(ident.span)
1634            })
1635            .map_err(|mut err| {
1636                err.span_label(ident.span, "while parsing this enum");
1637                // Try to recover `enum Foo { ident : Ty }`.
1638                if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1639                    let snapshot = self.create_snapshot_for_diagnostic();
1640                    self.bump();
1641                    match self.parse_ty() {
1642                        Ok(_) => {
1643                            err.span_suggestion_verbose(
1644                                prev_span,
1645                                "perhaps you meant to use `struct` here",
1646                                "struct",
1647                                Applicability::MaybeIncorrect,
1648                            );
1649                        }
1650                        Err(e) => {
1651                            e.cancel();
1652                        }
1653                    }
1654                    self.restore_snapshot(snapshot);
1655                }
1656                self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)]);
1657                self.bump(); // }
1658                err
1659            })?
1660        };
1661
1662        let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1663        Ok(ItemKind::Enum(ident, generics, enum_definition))
1664    }
1665
1666    fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1667        self.recover_vcs_conflict_marker();
1668        let variant_attrs = self.parse_outer_attributes()?;
1669        self.recover_vcs_conflict_marker();
1670        let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1671                    `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1672        self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1673            let vlo = this.token.span;
1674
1675            let vis = this.parse_visibility(FollowedByType::No)?;
1676            if !this.recover_nested_adt_item(kw::Enum)? {
1677                return Ok((None, Trailing::No, UsePreAttrPos::No));
1678            }
1679            let ident = this.parse_field_ident("enum", vlo)?;
1680
1681            if this.token == token::Bang {
1682                if let Err(err) = this.unexpected() {
1683                    err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1684                }
1685
1686                this.bump();
1687                this.parse_delim_args()?;
1688
1689                return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1690            }
1691
1692            let struct_def = if this.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
1693                // Parse a struct variant.
1694                let (fields, recovered) =
1695                    match this.parse_record_struct_body("struct", ident.span, false) {
1696                        Ok((fields, recovered)) => (fields, recovered),
1697                        Err(mut err) => {
1698                            if this.token == token::Colon {
1699                                // We handle `enum` to `struct` suggestion in the caller.
1700                                return Err(err);
1701                            }
1702                            this.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)]);
1703                            this.bump(); // }
1704                            err.span_label(span, "while parsing this enum");
1705                            err.help(help);
1706                            let guar = err.emit();
1707                            (::thin_vec::ThinVec::new()thin_vec![], Recovered::Yes(guar))
1708                        }
1709                    };
1710                VariantData::Struct { fields, recovered }
1711            } else if this.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
1712                let body = match this.parse_tuple_struct_body() {
1713                    Ok(body) => body,
1714                    Err(mut err) => {
1715                        if this.token == token::Colon {
1716                            // We handle `enum` to `struct` suggestion in the caller.
1717                            return Err(err);
1718                        }
1719                        this.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)]);
1720                        this.bump(); // )
1721                        err.span_label(span, "while parsing this enum");
1722                        err.help(help);
1723                        err.emit();
1724                        ::thin_vec::ThinVec::new()thin_vec![]
1725                    }
1726                };
1727                VariantData::Tuple(body, DUMMY_NODE_ID)
1728            } else {
1729                VariantData::Unit(DUMMY_NODE_ID)
1730            };
1731
1732            let disr_expr = if this.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) {
1733                Some(this.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?)
1734            } else {
1735                None
1736            };
1737
1738            let vr = ast::Variant {
1739                ident,
1740                vis,
1741                id: DUMMY_NODE_ID,
1742                attrs: variant_attrs,
1743                data: struct_def,
1744                disr_expr,
1745                span: vlo.to(this.prev_token.span),
1746                is_placeholder: false,
1747            };
1748
1749            Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1750        })
1751        .map_err(|mut err| {
1752            err.help(help);
1753            err
1754        })
1755    }
1756
1757    /// Parses `struct Foo { ... }`.
1758    fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1759        let ident = self.parse_ident()?;
1760
1761        let mut generics = self.parse_generics()?;
1762
1763        // There is a special case worth noting here, as reported in issue #17904.
1764        // If we are parsing a tuple struct it is the case that the where clause
1765        // should follow the field list. Like so:
1766        //
1767        // struct Foo<T>(T) where T: Copy;
1768        //
1769        // If we are parsing a normal record-style struct it is the case
1770        // that the where clause comes before the body, and after the generics.
1771        // So if we look ahead and see a brace or a where-clause we begin
1772        // parsing a record style struct.
1773        //
1774        // Otherwise if we look ahead and see a paren we parse a tuple-style
1775        // struct.
1776
1777        let vdata = if self.token.is_keyword(kw::Where) {
1778            let tuple_struct_body;
1779            (generics.where_clause, tuple_struct_body) =
1780                self.parse_struct_where_clause(ident, generics.span)?;
1781
1782            if let Some(body) = tuple_struct_body {
1783                // If we see a misplaced tuple struct body: `struct Foo<T> where T: Copy, (T);`
1784                let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1785                self.expect_semi()?;
1786                body
1787            } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
1788                // If we see a: `struct Foo<T> where T: Copy;` style decl.
1789                VariantData::Unit(DUMMY_NODE_ID)
1790            } else {
1791                // If we see: `struct Foo<T> where T: Copy { ... }`
1792                let (fields, recovered) = self.parse_record_struct_body(
1793                    "struct",
1794                    ident.span,
1795                    generics.where_clause.has_where_token,
1796                )?;
1797                VariantData::Struct { fields, recovered }
1798            }
1799        // No `where` so: `struct Foo<T>;`
1800        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
1801            VariantData::Unit(DUMMY_NODE_ID)
1802        // Record-style struct definition
1803        } else if self.token == token::OpenBrace {
1804            let (fields, recovered) = self.parse_record_struct_body(
1805                "struct",
1806                ident.span,
1807                generics.where_clause.has_where_token,
1808            )?;
1809            VariantData::Struct { fields, recovered }
1810        // Tuple-style struct definition with optional where-clause.
1811        } else if self.token == token::OpenParen {
1812            let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1813            generics.where_clause = self.parse_where_clause()?;
1814            self.expect_semi()?;
1815            body
1816        } else {
1817            let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1818            return Err(self.dcx().create_err(err));
1819        };
1820
1821        Ok(ItemKind::Struct(ident, generics, vdata))
1822    }
1823
1824    /// Parses `union Foo { ... }`.
1825    fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1826        let ident = self.parse_ident()?;
1827
1828        let mut generics = self.parse_generics()?;
1829
1830        let vdata = if self.token.is_keyword(kw::Where) {
1831            generics.where_clause = self.parse_where_clause()?;
1832            let (fields, recovered) = self.parse_record_struct_body(
1833                "union",
1834                ident.span,
1835                generics.where_clause.has_where_token,
1836            )?;
1837            VariantData::Struct { fields, recovered }
1838        } else if self.token == token::OpenBrace {
1839            let (fields, recovered) = self.parse_record_struct_body(
1840                "union",
1841                ident.span,
1842                generics.where_clause.has_where_token,
1843            )?;
1844            VariantData::Struct { fields, recovered }
1845        } else {
1846            let token_str = super::token_descr(&self.token);
1847            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected `where` or `{{` after union name, found {0}",
                token_str))
    })format!("expected `where` or `{{` after union name, found {token_str}");
1848            let mut err = self.dcx().struct_span_err(self.token.span, msg);
1849            err.span_label(self.token.span, "expected `where` or `{` after union name");
1850            return Err(err);
1851        };
1852
1853        Ok(ItemKind::Union(ident, generics, vdata))
1854    }
1855
1856    /// This function parses the fields of record structs:
1857    ///
1858    ///   - `struct S { ... }`
1859    ///   - `enum E { Variant { ... } }`
1860    pub(crate) fn parse_record_struct_body(
1861        &mut self,
1862        adt_ty: &str,
1863        ident_span: Span,
1864        parsed_where: bool,
1865    ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1866        let mut fields = ThinVec::new();
1867        let mut recovered = Recovered::No;
1868        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
1869            while self.token != token::CloseBrace {
1870                match self.parse_field_def(adt_ty, ident_span) {
1871                    Ok(field) => {
1872                        fields.push(field);
1873                    }
1874                    Err(mut err) => {
1875                        self.consume_block(
1876                            crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace),
1877                            crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace),
1878                            ConsumeClosingDelim::No,
1879                        );
1880                        err.span_label(ident_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("while parsing this {0}", adt_ty))
    })format!("while parsing this {adt_ty}"));
1881                        let guar = err.emit();
1882                        recovered = Recovered::Yes(guar);
1883                        break;
1884                    }
1885                }
1886            }
1887            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace))?;
1888        } else {
1889            let token_str = super::token_descr(&self.token);
1890            let where_str = if parsed_where { "" } else { "`where`, or " };
1891            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected {0}`{{` after struct name, found {1}",
                where_str, token_str))
    })format!("expected {where_str}`{{` after struct name, found {token_str}");
1892            let mut err = self.dcx().struct_span_err(self.token.span, msg);
1893            err.span_label(self.token.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected {0}`{{` after struct name",
                where_str))
    })format!("expected {where_str}`{{` after struct name",));
1894            return Err(err);
1895        }
1896
1897        Ok((fields, recovered))
1898    }
1899
1900    fn parse_unsafe_field(&mut self) -> Safety {
1901        // not using parse_safety as that also accepts `safe`.
1902        if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe)) {
1903            let span = self.prev_token.span;
1904            self.psess.gated_spans.gate(sym::unsafe_fields, span);
1905            Safety::Unsafe(span)
1906        } else {
1907            Safety::Default
1908        }
1909    }
1910
1911    pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1912        // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1913        // Unit like structs are handled in parse_item_struct function
1914        self.parse_paren_comma_seq(|p| {
1915            let attrs = p.parse_outer_attributes()?;
1916            p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1917                let mut snapshot = None;
1918                if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1919                    // Account for `<<<<<<<` diff markers. We can't proactively error here because
1920                    // that can be a valid type start, so we snapshot and reparse only we've
1921                    // encountered another parse error.
1922                    snapshot = Some(p.create_snapshot_for_diagnostic());
1923                }
1924                let lo = p.token.span;
1925                let vis = match p.parse_visibility(FollowedByType::Yes) {
1926                    Ok(vis) => vis,
1927                    Err(err) => {
1928                        if let Some(ref mut snapshot) = snapshot {
1929                            snapshot.recover_vcs_conflict_marker();
1930                        }
1931                        return Err(err);
1932                    }
1933                };
1934                // Unsafe fields are not supported in tuple structs, as doing so would result in a
1935                // parsing ambiguity for `struct X(unsafe fn())`.
1936                let ty = match p.parse_ty() {
1937                    Ok(ty) => ty,
1938                    Err(err) => {
1939                        if let Some(ref mut snapshot) = snapshot {
1940                            snapshot.recover_vcs_conflict_marker();
1941                        }
1942                        return Err(err);
1943                    }
1944                };
1945                let mut default = None;
1946                if p.token == token::Eq {
1947                    let mut snapshot = p.create_snapshot_for_diagnostic();
1948                    snapshot.bump();
1949                    match snapshot.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst) {
1950                        Ok(const_expr) => {
1951                            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1952                            p.psess.gated_spans.gate(sym::default_field_values, sp);
1953                            p.restore_snapshot(snapshot);
1954                            default = Some(const_expr);
1955                        }
1956                        Err(err) => {
1957                            err.cancel();
1958                        }
1959                    }
1960                }
1961
1962                Ok((
1963                    FieldDef {
1964                        span: lo.to(ty.span),
1965                        vis,
1966                        safety: Safety::Default,
1967                        ident: None,
1968                        id: DUMMY_NODE_ID,
1969                        ty,
1970                        default,
1971                        attrs,
1972                        is_placeholder: false,
1973                    },
1974                    Trailing::from(p.token == token::Comma),
1975                    UsePreAttrPos::No,
1976                ))
1977            })
1978        })
1979        .map(|(r, _)| r)
1980    }
1981
1982    /// Parses an element of a struct declaration.
1983    fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1984        self.recover_vcs_conflict_marker();
1985        let attrs = self.parse_outer_attributes()?;
1986        self.recover_vcs_conflict_marker();
1987        self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1988            let lo = this.token.span;
1989            let vis = this.parse_visibility(FollowedByType::No)?;
1990            let safety = this.parse_unsafe_field();
1991            this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1992                .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1993        })
1994    }
1995
1996    /// Parses a structure field declaration.
1997    fn parse_single_struct_field(
1998        &mut self,
1999        adt_ty: &str,
2000        lo: Span,
2001        vis: Visibility,
2002        safety: Safety,
2003        attrs: AttrVec,
2004        ident_span: Span,
2005    ) -> PResult<'a, FieldDef> {
2006        let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
2007        match self.token.kind {
2008            token::Comma => {
2009                self.bump();
2010            }
2011            token::Semi => {
2012                self.bump();
2013                let sp = self.prev_token.span;
2014                let mut err =
2015                    self.dcx().struct_span_err(sp, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} fields are separated by `,`",
                adt_ty))
    })format!("{adt_ty} fields are separated by `,`"));
2016                err.span_suggestion_short(
2017                    sp,
2018                    "replace `;` with `,`",
2019                    ",",
2020                    Applicability::MachineApplicable,
2021                );
2022                err.span_label(ident_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("while parsing this {0}", adt_ty))
    })format!("while parsing this {adt_ty}"));
2023                err.emit();
2024            }
2025            token::CloseBrace => {}
2026            token::DocComment(..) => {
2027                let previous_span = self.prev_token.span;
2028                let mut err = errors::DocCommentDoesNotDocumentAnything {
2029                    span: self.token.span,
2030                    missing_comma: None,
2031                };
2032                self.bump(); // consume the doc comment
2033                if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma)) || self.token == token::CloseBrace {
2034                    self.dcx().emit_err(err);
2035                } else {
2036                    let sp = previous_span.shrink_to_hi();
2037                    err.missing_comma = Some(sp);
2038                    return Err(self.dcx().create_err(err));
2039                }
2040            }
2041            _ => {
2042                let sp = self.prev_token.span.shrink_to_hi();
2043                let msg =
2044                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected `,`, or `}}`, found {0}",
                super::token_descr(&self.token)))
    })format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
2045
2046                // Try to recover extra trailing angle brackets
2047                if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
2048                    && let Some(last_segment) = segments.last()
2049                {
2050                    let guar = self.check_trailing_angle_brackets(
2051                        last_segment,
2052                        &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)],
2053                    );
2054                    if let Some(_guar) = guar {
2055                        // Handle a case like `Vec<u8>>,` where we can continue parsing fields
2056                        // after the comma
2057                        let _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
2058
2059                        // `check_trailing_angle_brackets` already emitted a nicer error, as
2060                        // proven by the presence of `_guar`. We can continue parsing.
2061                        return Ok(a_var);
2062                    }
2063                }
2064
2065                let mut err = self.dcx().struct_span_err(sp, msg);
2066
2067                if self.token.is_ident()
2068                    || (self.token == TokenKind::Pound
2069                        && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2070                {
2071                    // This is likely another field, TokenKind::Pound is used for `#[..]`
2072                    // attribute for next field. Emit the diagnostic and continue parsing.
2073                    err.span_suggestion(
2074                        sp,
2075                        "try adding a comma",
2076                        ",",
2077                        Applicability::MachineApplicable,
2078                    );
2079                    err.emit();
2080                } else {
2081                    return Err(err);
2082                }
2083            }
2084        }
2085        Ok(a_var)
2086    }
2087
2088    fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2089        if let Err(err) = self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)) {
2090            let sm = self.psess.source_map();
2091            let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2092            let semi_typo = self.token == token::Semi
2093                && self.look_ahead(1, |t| {
2094                    t.is_path_start()
2095                    // We check that we are in a situation like `foo; bar` to avoid bad suggestions
2096                    // when there's no type and `;` was used instead of a comma.
2097                    && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2098                        (Ok(l), Ok(r)) => l.line == r.line,
2099                        _ => true,
2100                    }
2101                });
2102            if eq_typo || semi_typo {
2103                self.bump();
2104                // Gracefully handle small typos.
2105                err.with_span_suggestion_short(
2106                    self.prev_token.span,
2107                    "field names and their types are separated with `:`",
2108                    ":",
2109                    Applicability::MachineApplicable,
2110                )
2111                .emit();
2112            } else {
2113                return Err(err);
2114            }
2115        }
2116        Ok(())
2117    }
2118
2119    /// Parses a structure field.
2120    fn parse_name_and_ty(
2121        &mut self,
2122        adt_ty: &str,
2123        lo: Span,
2124        vis: Visibility,
2125        safety: Safety,
2126        attrs: AttrVec,
2127    ) -> PResult<'a, FieldDef> {
2128        let name = self.parse_field_ident(adt_ty, lo)?;
2129        if self.token == token::Bang {
2130            if let Err(mut err) = self.unexpected() {
2131                // Encounter the macro invocation
2132                err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2133                return Err(err);
2134            }
2135        }
2136        self.expect_field_ty_separator()?;
2137        let ty = self.parse_ty()?;
2138        if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2139            self.dcx()
2140                .struct_span_err(self.token.span, "found single colon in a struct field type path")
2141                .with_span_suggestion_verbose(
2142                    self.token.span,
2143                    "write a path separator here",
2144                    "::",
2145                    Applicability::MaybeIncorrect,
2146                )
2147                .emit();
2148        }
2149        let default = if self.token == token::Eq {
2150            self.bump();
2151            let const_expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?;
2152            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2153            self.psess.gated_spans.gate(sym::default_field_values, sp);
2154            Some(const_expr)
2155        } else {
2156            None
2157        };
2158        Ok(FieldDef {
2159            span: lo.to(self.prev_token.span),
2160            ident: Some(name),
2161            vis,
2162            safety,
2163            id: DUMMY_NODE_ID,
2164            ty,
2165            default,
2166            attrs,
2167            is_placeholder: false,
2168        })
2169    }
2170
2171    /// Parses a field identifier. Specialized version of `parse_ident_common`
2172    /// for better diagnostics and suggestions.
2173    fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2174        let (ident, is_raw) = self.ident_or_err(true)?;
2175        if is_raw == IdentIsRaw::No && ident.is_reserved() {
2176            let snapshot = self.create_snapshot_for_diagnostic();
2177            let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2178                let inherited_vis =
2179                    Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2180                // We use `parse_fn` to get a span for the function
2181                let fn_parse_mode =
2182                    FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2183                match self.parse_fn(
2184                    &mut AttrVec::new(),
2185                    fn_parse_mode,
2186                    lo,
2187                    &inherited_vis,
2188                    Case::Insensitive,
2189                ) {
2190                    Ok(_) => {
2191                        self.dcx().struct_span_err(
2192                            lo.to(self.prev_token.span),
2193                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("functions are not allowed in {0} definitions",
                adt_ty))
    })format!("functions are not allowed in {adt_ty} definitions"),
2194                        )
2195                        .with_help(
2196                            "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2197                        )
2198                        .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2199                    }
2200                    Err(err) => {
2201                        err.cancel();
2202                        self.restore_snapshot(snapshot);
2203                        self.expected_ident_found_err()
2204                    }
2205                }
2206            } else if self.eat_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Struct,
    token_type: crate::parser::token_type::TokenType::KwStruct,
}exp!(Struct)) {
2207                match self.parse_item_struct() {
2208                    Ok(item) => {
2209                        let ItemKind::Struct(ident, ..) = item else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
2210                        self.dcx()
2211                            .struct_span_err(
2212                                lo.with_hi(ident.span.hi()),
2213                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("structs are not allowed in {0} definitions",
                adt_ty))
    })format!("structs are not allowed in {adt_ty} definitions"),
2214                            )
2215                            .with_help(
2216                                "consider creating a new `struct` definition instead of nesting",
2217                            )
2218                    }
2219                    Err(err) => {
2220                        err.cancel();
2221                        self.restore_snapshot(snapshot);
2222                        self.expected_ident_found_err()
2223                    }
2224                }
2225            } else {
2226                let mut err = self.expected_ident_found_err();
2227                if self.eat_keyword_noexpect(kw::Let)
2228                    && let removal_span = self.prev_token.span.until(self.token.span)
2229                    && let Ok(ident) = self
2230                        .parse_ident_common(false)
2231                        // Cancel this error, we don't need it.
2232                        .map_err(|err| err.cancel())
2233                    && self.token == TokenKind::Colon
2234                {
2235                    err.span_suggestion(
2236                        removal_span,
2237                        "remove this `let` keyword",
2238                        String::new(),
2239                        Applicability::MachineApplicable,
2240                    );
2241                    err.note("the `let` keyword is not allowed in `struct` fields");
2242                    err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2243                    err.emit();
2244                    return Ok(ident);
2245                } else {
2246                    self.restore_snapshot(snapshot);
2247                }
2248                err
2249            };
2250            return Err(err);
2251        }
2252        self.bump();
2253        Ok(ident)
2254    }
2255
2256    /// Parses a declarative macro 2.0 definition.
2257    /// The `macro` keyword has already been parsed.
2258    /// ```ebnf
2259    /// MacBody = "{" TOKEN_STREAM "}" ;
2260    /// MacParams = "(" TOKEN_STREAM ")" ;
2261    /// DeclMac = "macro" Ident MacParams? MacBody ;
2262    /// ```
2263    fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2264        let ident = self.parse_ident()?;
2265        let body = if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
2266            self.parse_delim_args()? // `MacBody`
2267        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
2268            let params = self.parse_token_tree(); // `MacParams`
2269            let pspan = params.span();
2270            if !self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
2271                self.unexpected()?;
2272            }
2273            let body = self.parse_token_tree(); // `MacBody`
2274            // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
2275            let bspan = body.span();
2276            let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
2277            let tokens = TokenStream::new(<[_]>::into_vec(::alloc::boxed::box_new([params, arrow, body]))vec![params, arrow, body]);
2278            let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2279            Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2280        } else {
2281            self.unexpected_any()?
2282        };
2283
2284        self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2285        Ok(ItemKind::MacroDef(
2286            ident,
2287            ast::MacroDef { body, macro_rules: false, eii_declaration: None },
2288        ))
2289    }
2290
2291    /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
2292    fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2293        if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::MacroRules,
    token_type: crate::parser::token_type::TokenType::KwMacroRules,
}exp!(MacroRules)) {
2294            let macro_rules_span = self.token.span;
2295
2296            if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2297                return IsMacroRulesItem::Yes { has_bang: true };
2298            } else if self.look_ahead(1, |t| t.is_ident()) {
2299                // macro_rules foo
2300                self.dcx().emit_err(errors::MacroRulesMissingBang {
2301                    span: macro_rules_span,
2302                    hi: macro_rules_span.shrink_to_hi(),
2303                });
2304
2305                return IsMacroRulesItem::Yes { has_bang: false };
2306            }
2307        }
2308
2309        IsMacroRulesItem::No
2310    }
2311
2312    /// Parses a `macro_rules! foo { ... }` declarative macro.
2313    fn parse_item_macro_rules(
2314        &mut self,
2315        vis: &Visibility,
2316        has_bang: bool,
2317    ) -> PResult<'a, ItemKind> {
2318        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::MacroRules,
    token_type: crate::parser::token_type::TokenType::KwMacroRules,
}exp!(MacroRules))?; // `macro_rules`
2319
2320        if has_bang {
2321            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))?; // `!`
2322        }
2323        let ident = self.parse_ident()?;
2324
2325        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
2326            // Handle macro_rules! foo!
2327            let span = self.prev_token.span;
2328            self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2329        }
2330
2331        let body = self.parse_delim_args()?;
2332        self.eat_semi_for_macro_if_needed(&body);
2333        self.complain_if_pub_macro(vis, true);
2334
2335        Ok(ItemKind::MacroDef(
2336            ident,
2337            ast::MacroDef { body, macro_rules: true, eii_declaration: None },
2338        ))
2339    }
2340
2341    /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
2342    /// If that's not the case, emit an error.
2343    fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2344        if let VisibilityKind::Inherited = vis.kind {
2345            return;
2346        }
2347
2348        let vstr = pprust::vis_to_string(vis);
2349        let vstr = vstr.trim_end();
2350        if macro_rules {
2351            self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2352        } else {
2353            self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2354        }
2355    }
2356
2357    fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2358        if args.need_semicolon() && !self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
2359            self.report_invalid_macro_expansion_item(args);
2360        }
2361    }
2362
2363    fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2364        let span = args.dspan.entire();
2365        let mut err = self.dcx().struct_span_err(
2366            span,
2367            "macros that expand to items must be delimited with braces or followed by a semicolon",
2368        );
2369        // FIXME: This will make us not emit the help even for declarative
2370        // macros within the same crate (that we can fix), which is sad.
2371        if !span.from_expansion() {
2372            let DelimSpan { open, close } = args.dspan;
2373            err.multipart_suggestion(
2374                "change the delimiters to curly braces",
2375                <[_]>::into_vec(::alloc::boxed::box_new([(open, "{".to_string()),
                (close, '}'.to_string())]))vec![(open, "{".to_string()), (close, '}'.to_string())],
2376                Applicability::MaybeIncorrect,
2377            );
2378            err.span_suggestion(
2379                span.with_neighbor(self.token.span).shrink_to_hi(),
2380                "add a semicolon",
2381                ';',
2382                Applicability::MaybeIncorrect,
2383            );
2384        }
2385        err.emit();
2386    }
2387
2388    /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
2389    /// it is, we try to parse the item and report error about nested types.
2390    fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2391        if (self.token.is_keyword(kw::Enum)
2392            || self.token.is_keyword(kw::Struct)
2393            || self.token.is_keyword(kw::Union))
2394            && self.look_ahead(1, |t| t.is_ident())
2395        {
2396            let kw_token = self.token;
2397            let kw_str = pprust::token_to_string(&kw_token);
2398            let item = self.parse_item(ForceCollect::No)?;
2399            let mut item = item.unwrap().span;
2400            if self.token == token::Comma {
2401                item = item.to(self.token.span);
2402            }
2403            self.dcx().emit_err(errors::NestedAdt {
2404                span: kw_token.span,
2405                item,
2406                kw_str,
2407                keyword: keyword.as_str(),
2408            });
2409            // We successfully parsed the item but we must inform the caller about nested problem.
2410            return Ok(false);
2411        }
2412        Ok(true)
2413    }
2414}
2415
2416/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
2417///
2418/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
2419///
2420/// This function pointer accepts an edition, because in edition 2015, trait declarations
2421/// were allowed to omit parameter names. In 2018, they became required. It also accepts an
2422/// `IsDotDotDot` parameter, as `extern` function declarations and function pointer types are
2423/// allowed to omit the name of the `...` but regular function items are not.
2424type ReqName = fn(Edition, IsDotDotDot) -> bool;
2425
2426#[derive(#[automatically_derived]
impl ::core::marker::Copy for IsDotDotDot { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IsDotDotDot {
    #[inline]
    fn clone(&self) -> IsDotDotDot { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IsDotDotDot {
    #[inline]
    fn eq(&self, other: &IsDotDotDot) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
2427pub(crate) enum IsDotDotDot {
2428    Yes,
2429    No,
2430}
2431
2432/// Parsing configuration for functions.
2433///
2434/// The syntax of function items is slightly different within trait definitions,
2435/// impl blocks, and modules. It is still parsed using the same code, just with
2436/// different flags set, so that even when the input is wrong and produces a parse
2437/// error, it still gets into the AST and the rest of the parser and
2438/// type checker can run.
2439#[derive(#[automatically_derived]
impl ::core::clone::Clone for FnParseMode {
    #[inline]
    fn clone(&self) -> FnParseMode {
        let _: ::core::clone::AssertParamIsClone<ReqName>;
        let _: ::core::clone::AssertParamIsClone<FnContext>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FnParseMode { }Copy)]
2440pub(crate) struct FnParseMode {
2441    /// A function pointer that decides if, per-parameter `p`, `p` must have a
2442    /// pattern or just a type. This field affects parsing of the parameters list.
2443    ///
2444    /// ```text
2445    /// fn foo(alef: A) -> X { X::new() }
2446    ///        -----^^ affects parsing this part of the function signature
2447    ///        |
2448    ///        if req_name returns false, then this name is optional
2449    ///
2450    /// fn bar(A) -> X;
2451    ///        ^
2452    ///        |
2453    ///        if req_name returns true, this is an error
2454    /// ```
2455    ///
2456    /// Calling this function pointer should only return false if:
2457    ///
2458    ///   * The item is being parsed inside of a trait definition.
2459    ///     Within an impl block or a module, it should always evaluate
2460    ///     to true.
2461    ///   * The span is from Edition 2015. In particular, you can get a
2462    ///     2015 span inside a 2021 crate using macros.
2463    ///
2464    /// Or if `IsDotDotDot::Yes`, this function will also return `false` if the item being parsed
2465    /// is inside an `extern` block.
2466    pub(super) req_name: ReqName,
2467    /// The context in which this function is parsed, used for diagnostics.
2468    /// This indicates the fn is a free function or method and so on.
2469    pub(super) context: FnContext,
2470    /// If this flag is set to `true`, then plain, semicolon-terminated function
2471    /// prototypes are not allowed here.
2472    ///
2473    /// ```text
2474    /// fn foo(alef: A) -> X { X::new() }
2475    ///                      ^^^^^^^^^^^^
2476    ///                      |
2477    ///                      this is always allowed
2478    ///
2479    /// fn bar(alef: A, bet: B) -> X;
2480    ///                             ^
2481    ///                             |
2482    ///                             if req_body is set to true, this is an error
2483    /// ```
2484    ///
2485    /// This field should only be set to false if the item is inside of a trait
2486    /// definition or extern block. Within an impl block or a module, it should
2487    /// always be set to true.
2488    pub(super) req_body: bool,
2489}
2490
2491/// The context in which a function is parsed.
2492/// FIXME(estebank, xizheyin): Use more variants.
2493#[derive(#[automatically_derived]
impl ::core::clone::Clone for FnContext {
    #[inline]
    fn clone(&self) -> FnContext { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FnContext { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for FnContext {
    #[inline]
    fn eq(&self, other: &FnContext) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for FnContext {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {}
}Eq)]
2494pub(crate) enum FnContext {
2495    /// Free context.
2496    Free,
2497    /// A Trait context.
2498    Trait,
2499    /// An Impl block.
2500    Impl,
2501}
2502
2503/// Parsing of functions and methods.
2504impl<'a> Parser<'a> {
2505    /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
2506    fn parse_fn(
2507        &mut self,
2508        attrs: &mut AttrVec,
2509        fn_parse_mode: FnParseMode,
2510        sig_lo: Span,
2511        vis: &Visibility,
2512        case: Case,
2513    ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2514        let fn_span = self.token.span;
2515        let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn`
2516        let ident = self.parse_ident()?; // `foo`
2517        let mut generics = self.parse_generics()?; // `<'a, T, ...>`
2518        let decl = match self.parse_fn_decl(&fn_parse_mode, AllowPlus::Yes, RecoverReturnSign::Yes)
2519        {
2520            Ok(decl) => decl,
2521            Err(old_err) => {
2522                // If we see `for Ty ...` then user probably meant `impl` item.
2523                if self.token.is_keyword(kw::For) {
2524                    old_err.cancel();
2525                    return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2526                } else {
2527                    return Err(old_err);
2528                }
2529            }
2530        };
2531
2532        // Store the end of function parameters to give better diagnostics
2533        // inside `parse_fn_body()`.
2534        let fn_params_end = self.prev_token.span.shrink_to_hi();
2535
2536        let contract = self.parse_contract()?;
2537
2538        generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
2539
2540        // `fn_params_end` is needed only when it's followed by a where clause.
2541        let fn_params_end =
2542            if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2543
2544        let mut sig_hi = self.prev_token.span;
2545        // Either `;` or `{ ... }`.
2546        let body =
2547            self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2548        let fn_sig_span = sig_lo.to(sig_hi);
2549        Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2550    }
2551
2552    /// Provide diagnostics when function body is not found
2553    fn error_fn_body_not_found(
2554        &mut self,
2555        ident_span: Span,
2556        req_body: bool,
2557        fn_params_end: Option<Span>,
2558    ) -> PResult<'a, ErrorGuaranteed> {
2559        let expected: &[_] =
2560            if req_body { &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)] } else { &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)] };
2561        match self.expected_one_of_not_found(&[], expected) {
2562            Ok(error_guaranteed) => Ok(error_guaranteed),
2563            Err(mut err) => {
2564                if self.token == token::CloseBrace {
2565                    // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
2566                    // the AST for typechecking.
2567                    err.span_label(ident_span, "while parsing this `fn`");
2568                    Ok(err.emit())
2569                } else if self.token == token::RArrow
2570                    && let Some(fn_params_end) = fn_params_end
2571                {
2572                    // Instead of a function body, the parser has encountered a right arrow
2573                    // preceded by a where clause.
2574
2575                    // Find whether token behind the right arrow is a function trait and
2576                    // store its span.
2577                    let fn_trait_span =
2578                        [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2579                            if self.prev_token.is_ident_named(symbol) {
2580                                Some(self.prev_token.span)
2581                            } else {
2582                                None
2583                            }
2584                        });
2585
2586                    // Parse the return type (along with the right arrow) and store its span.
2587                    // If there's a parse error, cancel it and return the existing error
2588                    // as we are primarily concerned with the
2589                    // expected-function-body-but-found-something-else error here.
2590                    let arrow_span = self.token.span;
2591                    let ty_span = match self.parse_ret_ty(
2592                        AllowPlus::Yes,
2593                        RecoverQPath::Yes,
2594                        RecoverReturnSign::Yes,
2595                    ) {
2596                        Ok(ty_span) => ty_span.span().shrink_to_hi(),
2597                        Err(parse_error) => {
2598                            parse_error.cancel();
2599                            return Err(err);
2600                        }
2601                    };
2602                    let ret_ty_span = arrow_span.to(ty_span);
2603
2604                    if let Some(fn_trait_span) = fn_trait_span {
2605                        // Typo'd Fn* trait bounds such as
2606                        // fn foo<F>() where F: FnOnce -> () {}
2607                        err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2608                    } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2609                    {
2610                        // If token behind right arrow is not a Fn* trait, the programmer
2611                        // probably misplaced the return type after the where clause like
2612                        // `fn foo<T>() where T: Default -> u8 {}`
2613                        err.primary_message(
2614                            "return type should be specified after the function parameters",
2615                        );
2616                        err.subdiagnostic(errors::MisplacedReturnType {
2617                            fn_params_end,
2618                            snippet,
2619                            ret_ty_span,
2620                        });
2621                    }
2622                    Err(err)
2623                } else {
2624                    Err(err)
2625                }
2626            }
2627        }
2628    }
2629
2630    /// Parse the "body" of a function.
2631    /// This can either be `;` when there's no body,
2632    /// or e.g. a block when the function is a provided one.
2633    fn parse_fn_body(
2634        &mut self,
2635        attrs: &mut AttrVec,
2636        ident: &Ident,
2637        sig_hi: &mut Span,
2638        req_body: bool,
2639        fn_params_end: Option<Span>,
2640    ) -> PResult<'a, Option<Box<Block>>> {
2641        let has_semi = if req_body {
2642            self.token == TokenKind::Semi
2643        } else {
2644            // Only include `;` in list of expected tokens if body is not required
2645            self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi))
2646        };
2647        let (inner_attrs, body) = if has_semi {
2648            // Include the trailing semicolon in the span of the signature
2649            self.expect_semi()?;
2650            *sig_hi = self.prev_token.span;
2651            (AttrVec::new(), None)
2652        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) || self.token.is_metavar_block() {
2653            self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2654                .map(|(attrs, body)| (attrs, Some(body)))?
2655        } else if self.token == token::Eq {
2656            // Recover `fn foo() = $expr;`.
2657            self.bump(); // `=`
2658            let eq_sp = self.prev_token.span;
2659            let _ = self.parse_expr()?;
2660            self.expect_semi()?; // `;`
2661            let span = eq_sp.to(self.prev_token.span);
2662            let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2663                span,
2664                sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2665            });
2666            (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2667        } else {
2668            self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2669            (AttrVec::new(), None)
2670        };
2671        attrs.extend(inner_attrs);
2672        Ok(body)
2673    }
2674
2675    fn check_impl_frontmatter(&mut self, look_ahead: usize) -> bool {
2676        const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2677        // In contrast to the loop below, this call inserts `impl` into the
2678        // list of expected tokens shown in diagnostics.
2679        if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Impl,
    token_type: crate::parser::token_type::TokenType::KwImpl,
}exp!(Impl)) {
2680            return true;
2681        }
2682        let mut i = 0;
2683        while i < ALL_QUALS.len() {
2684            let action = self.look_ahead(i + look_ahead, |token| {
2685                if token.is_keyword(kw::Impl) {
2686                    return Some(true);
2687                }
2688                if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2689                    // Ok, we found a legal keyword, keep looking for `impl`
2690                    return None;
2691                }
2692                Some(false)
2693            });
2694            if let Some(ret) = action {
2695                return ret;
2696            }
2697            i += 1;
2698        }
2699
2700        self.is_keyword_ahead(i, &[kw::Impl])
2701    }
2702
2703    /// Is the current token the start of an `FnHeader` / not a valid parse?
2704    ///
2705    /// `check_pub` adds additional `pub` to the checks in case users place it
2706    /// wrongly, can be used to ensure `pub` never comes after `default`.
2707    pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2708        const ALL_QUALS: &[ExpKeywordPair] = &[
2709            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Pub,
    token_type: crate::parser::token_type::TokenType::KwPub,
}exp!(Pub),
2710            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Gen,
    token_type: crate::parser::token_type::TokenType::KwGen,
}exp!(Gen),
2711            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const),
2712            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async),
2713            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe),
2714            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Safe,
    token_type: crate::parser::token_type::TokenType::KwSafe,
}exp!(Safe),
2715            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern),
2716        ];
2717
2718        // We use an over-approximation here.
2719        // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
2720        // `pub` is added in case users got confused with the ordering like `async pub fn`,
2721        // only if it wasn't preceded by `default` as `default pub` is invalid.
2722        let quals: &[_] = if check_pub {
2723            ALL_QUALS
2724        } else {
2725            &[crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Gen,
    token_type: crate::parser::token_type::TokenType::KwGen,
}exp!(Gen), crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const), crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async), crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe), crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Safe,
    token_type: crate::parser::token_type::TokenType::KwSafe,
}exp!(Safe), crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern)]
2726        };
2727        self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Fn,
    token_type: crate::parser::token_type::TokenType::KwFn,
}exp!(Fn), case) // Definitely an `fn`.
2728            // `$qual fn` or `$qual $qual`:
2729            || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2730                && self.look_ahead(1, |t| {
2731                    // `$qual fn`, e.g. `const fn` or `async fn`.
2732                    t.is_keyword_case(kw::Fn, case)
2733                    // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
2734                    || (
2735                        (
2736                            t.is_non_raw_ident_where(|i|
2737                                quals.iter().any(|exp| exp.kw == i.name)
2738                                    // Rule out 2015 `const async: T = val`.
2739                                    && i.is_reserved()
2740                            )
2741                            || case == Case::Insensitive
2742                                && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2743                                    exp.kw.as_str() == i.name.as_str().to_lowercase()
2744                                }))
2745                        )
2746                        // Rule out `unsafe extern {`.
2747                        && !self.is_unsafe_foreign_mod()
2748                        // Rule out `async gen {` and `async gen move {`
2749                        && !self.is_async_gen_block()
2750                        // Rule out `const unsafe auto` and `const unsafe trait`.
2751                        && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
2752                    )
2753                })
2754            // `extern ABI fn`
2755            || self.check_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern), case)
2756                // Use `tree_look_ahead` because `ABI` might be a metavariable,
2757                // i.e. an invisible-delimited sequence, and `tree_look_ahead`
2758                // will consider that a single element when looking ahead.
2759                && self.look_ahead(1, |t| t.can_begin_string_literal())
2760                && (self.tree_look_ahead(2, |tt| {
2761                    match tt {
2762                        TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2763                        TokenTree::Delimited(..) => false,
2764                    }
2765                }) == Some(true) ||
2766                    // This branch is only for better diagnostics; `pub`, `unsafe`, etc. are not
2767                    // allowed here.
2768                    (self.may_recover()
2769                        && self.tree_look_ahead(2, |tt| {
2770                            match tt {
2771                                TokenTree::Token(t, _) =>
2772                                    ALL_QUALS.iter().any(|exp| {
2773                                        t.is_keyword(exp.kw)
2774                                    }),
2775                                TokenTree::Delimited(..) => false,
2776                            }
2777                        }) == Some(true)
2778                        && self.tree_look_ahead(3, |tt| {
2779                            match tt {
2780                                TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2781                                TokenTree::Delimited(..) => false,
2782                            }
2783                        }) == Some(true)
2784                    )
2785                )
2786    }
2787
2788    /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
2789    /// up to and including the `fn` keyword. The formal grammar is:
2790    ///
2791    /// ```text
2792    /// Extern = "extern" StringLit? ;
2793    /// FnQual = "const"? "async"? "unsafe"? Extern? ;
2794    /// FnFrontMatter = FnQual "fn" ;
2795    /// ```
2796    ///
2797    /// `vis` represents the visibility that was already parsed, if any. Use
2798    /// `Visibility::Inherited` when no visibility is known.
2799    ///
2800    /// If `parsing_mode` is `FrontMatterParsingMode::FunctionPtrType`, we error on `const` and `async` qualifiers,
2801    /// which are not allowed in function pointer types.
2802    pub(super) fn parse_fn_front_matter(
2803        &mut self,
2804        orig_vis: &Visibility,
2805        case: Case,
2806        parsing_mode: FrontMatterParsingMode,
2807    ) -> PResult<'a, FnHeader> {
2808        let sp_start = self.token.span;
2809        let constness = self.parse_constness(case);
2810        if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2811            && let Const::Yes(const_span) = constness
2812        {
2813            self.dcx().emit_err(FnPointerCannotBeConst {
2814                span: const_span,
2815                suggestion: const_span.until(self.token.span),
2816            });
2817        }
2818
2819        let async_start_sp = self.token.span;
2820        let coroutine_kind = self.parse_coroutine_kind(case);
2821        if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2822            && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2823        {
2824            self.dcx().emit_err(FnPointerCannotBeAsync {
2825                span: async_span,
2826                suggestion: async_span.until(self.token.span),
2827            });
2828        }
2829        // FIXME(gen_blocks): emit a similar error for `gen fn()`
2830
2831        let unsafe_start_sp = self.token.span;
2832        let safety = self.parse_safety(case);
2833
2834        let ext_start_sp = self.token.span;
2835        let ext = self.parse_extern(case);
2836
2837        if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2838            if span.is_rust_2015() {
2839                self.dcx().emit_err(errors::AsyncFnIn2015 {
2840                    span,
2841                    help: errors::HelpUseLatestEdition::new(),
2842                });
2843            }
2844        }
2845
2846        match coroutine_kind {
2847            Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2848                self.psess.gated_spans.gate(sym::gen_blocks, span);
2849            }
2850            Some(CoroutineKind::Async { .. }) | None => {}
2851        }
2852
2853        if !self.eat_keyword_case(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Fn,
    token_type: crate::parser::token_type::TokenType::KwFn,
}exp!(Fn), case) {
2854            // It is possible for `expect_one_of` to recover given the contents of
2855            // `self.expected_token_types`, therefore, do not use `self.unexpected()` which doesn't
2856            // account for this.
2857            match self.expect_one_of(&[], &[]) {
2858                Ok(Recovered::Yes(_)) => {}
2859                Ok(Recovered::No) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
2860                Err(mut err) => {
2861                    // Qualifier keywords ordering check
2862                    enum WrongKw {
2863                        Duplicated(Span),
2864                        Misplaced(Span),
2865                        /// `MisplacedDisallowedQualifier` is only used instead of `Misplaced`,
2866                        /// when the misplaced keyword is disallowed by the current `FrontMatterParsingMode`.
2867                        /// In this case, we avoid generating the suggestion to swap around the keywords,
2868                        /// as we already generated a suggestion to remove the keyword earlier.
2869                        MisplacedDisallowedQualifier,
2870                    }
2871
2872                    // We may be able to recover
2873                    let mut recover_constness = constness;
2874                    let mut recover_coroutine_kind = coroutine_kind;
2875                    let mut recover_safety = safety;
2876                    // This will allow the machine fix to directly place the keyword in the correct place or to indicate
2877                    // that the keyword is already present and the second instance should be removed.
2878                    let wrong_kw = if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const)) {
2879                        match constness {
2880                            Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2881                            Const::No => {
2882                                recover_constness = Const::Yes(self.token.span);
2883                                match parsing_mode {
2884                                    FrontMatterParsingMode::Function => {
2885                                        Some(WrongKw::Misplaced(async_start_sp))
2886                                    }
2887                                    FrontMatterParsingMode::FunctionPtrType => {
2888                                        self.dcx().emit_err(FnPointerCannotBeConst {
2889                                            span: self.token.span,
2890                                            suggestion: self
2891                                                .token
2892                                                .span
2893                                                .with_lo(self.prev_token.span.hi()),
2894                                        });
2895                                        Some(WrongKw::MisplacedDisallowedQualifier)
2896                                    }
2897                                }
2898                            }
2899                        }
2900                    } else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async)) {
2901                        match coroutine_kind {
2902                            Some(CoroutineKind::Async { span, .. }) => {
2903                                Some(WrongKw::Duplicated(span))
2904                            }
2905                            Some(CoroutineKind::AsyncGen { span, .. }) => {
2906                                Some(WrongKw::Duplicated(span))
2907                            }
2908                            Some(CoroutineKind::Gen { .. }) => {
2909                                recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2910                                    span: self.token.span,
2911                                    closure_id: DUMMY_NODE_ID,
2912                                    return_impl_trait_id: DUMMY_NODE_ID,
2913                                });
2914                                // FIXME(gen_blocks): This span is wrong, didn't want to think about it.
2915                                Some(WrongKw::Misplaced(unsafe_start_sp))
2916                            }
2917                            None => {
2918                                recover_coroutine_kind = Some(CoroutineKind::Async {
2919                                    span: self.token.span,
2920                                    closure_id: DUMMY_NODE_ID,
2921                                    return_impl_trait_id: DUMMY_NODE_ID,
2922                                });
2923                                match parsing_mode {
2924                                    FrontMatterParsingMode::Function => {
2925                                        Some(WrongKw::Misplaced(async_start_sp))
2926                                    }
2927                                    FrontMatterParsingMode::FunctionPtrType => {
2928                                        self.dcx().emit_err(FnPointerCannotBeAsync {
2929                                            span: self.token.span,
2930                                            suggestion: self
2931                                                .token
2932                                                .span
2933                                                .with_lo(self.prev_token.span.hi()),
2934                                        });
2935                                        Some(WrongKw::MisplacedDisallowedQualifier)
2936                                    }
2937                                }
2938                            }
2939                        }
2940                    } else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe)) {
2941                        match safety {
2942                            Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2943                            Safety::Safe(sp) => {
2944                                recover_safety = Safety::Unsafe(self.token.span);
2945                                Some(WrongKw::Misplaced(sp))
2946                            }
2947                            Safety::Default => {
2948                                recover_safety = Safety::Unsafe(self.token.span);
2949                                Some(WrongKw::Misplaced(ext_start_sp))
2950                            }
2951                        }
2952                    } else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Safe,
    token_type: crate::parser::token_type::TokenType::KwSafe,
}exp!(Safe)) {
2953                        match safety {
2954                            Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2955                            Safety::Unsafe(sp) => {
2956                                recover_safety = Safety::Safe(self.token.span);
2957                                Some(WrongKw::Misplaced(sp))
2958                            }
2959                            Safety::Default => {
2960                                recover_safety = Safety::Safe(self.token.span);
2961                                Some(WrongKw::Misplaced(ext_start_sp))
2962                            }
2963                        }
2964                    } else {
2965                        None
2966                    };
2967
2968                    // The keyword is already present, suggest removal of the second instance
2969                    if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2970                        let original_kw = self
2971                            .span_to_snippet(original_sp)
2972                            .expect("Span extracted directly from keyword should always work");
2973
2974                        err.span_suggestion(
2975                            self.token_uninterpolated_span(),
2976                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` already used earlier, remove this one",
                original_kw))
    })format!("`{original_kw}` already used earlier, remove this one"),
2977                            "",
2978                            Applicability::MachineApplicable,
2979                        )
2980                        .span_note(original_sp, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` first seen here",
                original_kw))
    })format!("`{original_kw}` first seen here"));
2981                    }
2982                    // The keyword has not been seen yet, suggest correct placement in the function front matter
2983                    else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2984                        let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2985                        if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2986                            let misplaced_qual_sp = self.token_uninterpolated_span();
2987                            let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2988
2989                            err.span_suggestion(
2990                                    correct_pos_sp.to(misplaced_qual_sp),
2991                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` must come before `{1}`",
                misplaced_qual, current_qual))
    })format!("`{misplaced_qual}` must come before `{current_qual}`"),
2992                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1}", misplaced_qual,
                current_qual))
    })format!("{misplaced_qual} {current_qual}"),
2993                                    Applicability::MachineApplicable,
2994                                ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2995                        }
2996                    }
2997                    // Recover incorrect visibility order such as `async pub`
2998                    else if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Pub,
    token_type: crate::parser::token_type::TokenType::KwPub,
}exp!(Pub)) {
2999                        let sp = sp_start.to(self.prev_token.span);
3000                        if let Ok(snippet) = self.span_to_snippet(sp) {
3001                            let current_vis = match self.parse_visibility(FollowedByType::No) {
3002                                Ok(v) => v,
3003                                Err(d) => {
3004                                    d.cancel();
3005                                    return Err(err);
3006                                }
3007                            };
3008                            let vs = pprust::vis_to_string(&current_vis);
3009                            let vs = vs.trim_end();
3010
3011                            // There was no explicit visibility
3012                            if #[allow(non_exhaustive_omitted_patterns)] match orig_vis.kind {
    VisibilityKind::Inherited => true,
    _ => false,
}matches!(orig_vis.kind, VisibilityKind::Inherited) {
3013                                err.span_suggestion(
3014                                    sp_start.to(self.prev_token.span),
3015                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("visibility `{0}` must come before `{1}`",
                vs, snippet))
    })format!("visibility `{vs}` must come before `{snippet}`"),
3016                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1}", vs, snippet))
    })format!("{vs} {snippet}"),
3017                                    Applicability::MachineApplicable,
3018                                );
3019                            }
3020                            // There was an explicit visibility
3021                            else {
3022                                err.span_suggestion(
3023                                    current_vis.span,
3024                                    "there is already a visibility modifier, remove one",
3025                                    "",
3026                                    Applicability::MachineApplicable,
3027                                )
3028                                .span_note(orig_vis.span, "explicit visibility first seen here");
3029                            }
3030                        }
3031                    }
3032
3033                    // FIXME(gen_blocks): add keyword recovery logic for genness
3034
3035                    if let Some(wrong_kw) = wrong_kw
3036                        && self.may_recover()
3037                        && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
3038                    {
3039                        // Advance past the misplaced keyword and `fn`
3040                        self.bump();
3041                        self.bump();
3042                        // When we recover from a `MisplacedDisallowedQualifier`, we already emitted an error for the disallowed qualifier
3043                        // So we don't emit another error that the qualifier is unexpected.
3044                        if #[allow(non_exhaustive_omitted_patterns)] match wrong_kw {
    WrongKw::MisplacedDisallowedQualifier => true,
    _ => false,
}matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
3045                            err.cancel();
3046                        } else {
3047                            err.emit();
3048                        }
3049                        return Ok(FnHeader {
3050                            constness: recover_constness,
3051                            safety: recover_safety,
3052                            coroutine_kind: recover_coroutine_kind,
3053                            ext,
3054                        });
3055                    }
3056
3057                    return Err(err);
3058                }
3059            }
3060        }
3061
3062        Ok(FnHeader { constness, safety, coroutine_kind, ext })
3063    }
3064
3065    /// Parses the parameter list and result type of a function declaration.
3066    pub(super) fn parse_fn_decl(
3067        &mut self,
3068        fn_parse_mode: &FnParseMode,
3069        ret_allow_plus: AllowPlus,
3070        recover_return_sign: RecoverReturnSign,
3071    ) -> PResult<'a, Box<FnDecl>> {
3072        Ok(Box::new(FnDecl {
3073            inputs: self.parse_fn_params(fn_parse_mode)?,
3074            output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
3075        }))
3076    }
3077
3078    /// Parses the parameter list of a function, including the `(` and `)` delimiters.
3079    pub(super) fn parse_fn_params(
3080        &mut self,
3081        fn_parse_mode: &FnParseMode,
3082    ) -> PResult<'a, ThinVec<Param>> {
3083        let mut first_param = true;
3084        // Parse the arguments, starting out with `self` being allowed...
3085        if self.token != TokenKind::OpenParen
3086        // might be typo'd trait impl, handled elsewhere
3087        && !self.token.is_keyword(kw::For)
3088        {
3089            // recover from missing argument list, e.g. `fn main -> () {}`
3090            self.dcx()
3091                .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
3092            return Ok(ThinVec::new());
3093        }
3094
3095        let (mut params, _) = self.parse_paren_comma_seq(|p| {
3096            p.recover_vcs_conflict_marker();
3097            let snapshot = p.create_snapshot_for_diagnostic();
3098            let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3099                let guar = e.emit();
3100                // When parsing a param failed, we should check to make the span of the param
3101                // not contain '(' before it.
3102                // For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
3103                let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3104                    p.prev_token.span.shrink_to_hi()
3105                } else {
3106                    p.prev_token.span
3107                };
3108                p.restore_snapshot(snapshot);
3109                // Skip every token until next possible arg or end.
3110                p.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma), crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)]);
3111                // Create a placeholder argument for proper arg count (issue #34264).
3112                Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3113            });
3114            // ...now that we've parsed the first argument, `self` is no longer allowed.
3115            first_param = false;
3116            param
3117        })?;
3118        // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
3119        self.deduplicate_recovered_params_names(&mut params);
3120        Ok(params)
3121    }
3122
3123    /// Parses a single function parameter.
3124    ///
3125    /// - `self` is syntactically allowed when `first_param` holds.
3126    /// - `recover_arg_parse` is used to recover from a failed argument parse.
3127    pub(super) fn parse_param_general(
3128        &mut self,
3129        fn_parse_mode: &FnParseMode,
3130        first_param: bool,
3131        recover_arg_parse: bool,
3132    ) -> PResult<'a, Param> {
3133        let lo = self.token.span;
3134        let attrs = self.parse_outer_attributes()?;
3135        self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3136            // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
3137            if let Some(mut param) = this.parse_self_param()? {
3138                param.attrs = attrs;
3139                let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3140                return Ok((res?, Trailing::No, UsePreAttrPos::No));
3141            }
3142
3143            let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3144                IsDotDotDot::Yes
3145            } else {
3146                IsDotDotDot::No
3147            };
3148            let is_name_required = (fn_parse_mode.req_name)(
3149                this.token.span.with_neighbor(this.prev_token.span).edition(),
3150                is_dot_dot_dot,
3151            );
3152            let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3153                this.psess.buffer_lint(
3154                    VARARGS_WITHOUT_PATTERN,
3155                    this.token.span,
3156                    ast::CRATE_NODE_ID,
3157                    errors::VarargsWithoutPattern { span: this.token.span },
3158                );
3159                false
3160            } else {
3161                is_name_required
3162            };
3163            let (pat, ty) = if is_name_required || this.is_named_param() {
3164                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_parse/src/parser/item.rs:3164",
                        "rustc_parse::parser::item", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_parse/src/parser/item.rs"),
                        ::tracing_core::__macro_support::Option::Some(3164u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_parse::parser::item"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("parse_param_general parse_pat (is_name_required:{0})",
                                                    is_name_required) as &dyn Value))])
            });
    } else { ; }
};debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3165                let (pat, colon) = this.parse_fn_param_pat_colon()?;
3166                if !colon {
3167                    let mut err = this.unexpected().unwrap_err();
3168                    return if let Some(ident) = this.parameter_without_type(
3169                        &mut err,
3170                        pat,
3171                        is_name_required,
3172                        first_param,
3173                        fn_parse_mode,
3174                    ) {
3175                        let guar = err.emit();
3176                        Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3177                    } else {
3178                        Err(err)
3179                    };
3180                }
3181
3182                this.eat_incorrect_doc_comment_for_param_type();
3183                (pat, this.parse_ty_for_param()?)
3184            } else {
3185                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_parse/src/parser/item.rs:3185",
                        "rustc_parse::parser::item", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_parse/src/parser/item.rs"),
                        ::tracing_core::__macro_support::Option::Some(3185u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_parse::parser::item"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("parse_param_general ident_to_pat")
                                            as &dyn Value))])
            });
    } else { ; }
};debug!("parse_param_general ident_to_pat");
3186                let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3187                this.eat_incorrect_doc_comment_for_param_type();
3188                let mut ty = this.parse_ty_for_param();
3189
3190                if let Ok(t) = &ty {
3191                    // Check for trailing angle brackets
3192                    if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3193                        && let Some(segment) = segments.last()
3194                        && let Some(guar) =
3195                            this.check_trailing_angle_brackets(segment, &[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)])
3196                    {
3197                        return Ok((
3198                            dummy_arg(segment.ident, guar),
3199                            Trailing::No,
3200                            UsePreAttrPos::No,
3201                        ));
3202                    }
3203
3204                    if this.token != token::Comma && this.token != token::CloseParen {
3205                        // This wasn't actually a type, but a pattern looking like a type,
3206                        // so we are going to rollback and re-parse for recovery.
3207                        ty = this.unexpected_any();
3208                    }
3209                }
3210                match ty {
3211                    Ok(ty) => {
3212                        let pat = this.mk_pat(ty.span, PatKind::Missing);
3213                        (Box::new(pat), ty)
3214                    }
3215                    // If this is a C-variadic argument and we hit an error, return the error.
3216                    Err(err) if this.token == token::DotDotDot => return Err(err),
3217                    Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3218                    Err(err) if recover_arg_parse => {
3219                        // Recover from attempting to parse the argument as a type without pattern.
3220                        err.cancel();
3221                        this.restore_snapshot(parser_snapshot_before_ty);
3222                        this.recover_arg_parse()?
3223                    }
3224                    Err(err) => return Err(err),
3225                }
3226            };
3227
3228            let span = lo.to(this.prev_token.span);
3229
3230            Ok((
3231                Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3232                Trailing::No,
3233                UsePreAttrPos::No,
3234            ))
3235        })
3236    }
3237
3238    /// Returns the parsed optional self parameter and whether a self shortcut was used.
3239    fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3240        // Extract an identifier *after* having confirmed that the token is one.
3241        let expect_self_ident = |this: &mut Self| match this.token.ident() {
3242            Some((ident, IdentIsRaw::No)) => {
3243                this.bump();
3244                ident
3245            }
3246            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
3247        };
3248        // is lifetime `n` tokens ahead?
3249        let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3250        // Is `self` `n` tokens ahead?
3251        let is_isolated_self = |this: &Self, n| {
3252            this.is_keyword_ahead(n, &[kw::SelfLower])
3253                && this.look_ahead(n + 1, |t| t != &token::PathSep)
3254        };
3255        // Is `pin const self` `n` tokens ahead?
3256        let is_isolated_pin_const_self = |this: &Self, n| {
3257            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3258                && this.is_keyword_ahead(n + 1, &[kw::Const])
3259                && is_isolated_self(this, n + 2)
3260        };
3261        // Is `mut self` `n` tokens ahead?
3262        let is_isolated_mut_self =
3263            |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3264        // Is `pin mut self` `n` tokens ahead?
3265        let is_isolated_pin_mut_self = |this: &Self, n| {
3266            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3267                && is_isolated_mut_self(this, n + 1)
3268        };
3269        // Parse `self` or `self: TYPE`. We already know the current token is `self`.
3270        let parse_self_possibly_typed = |this: &mut Self, m| {
3271            let eself_ident = expect_self_ident(this);
3272            let eself_hi = this.prev_token.span;
3273            let eself = if this.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)) {
3274                SelfKind::Explicit(this.parse_ty()?, m)
3275            } else {
3276                SelfKind::Value(m)
3277            };
3278            Ok((eself, eself_ident, eself_hi))
3279        };
3280        let expect_self_ident_not_typed =
3281            |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3282                let eself_ident = expect_self_ident(this);
3283
3284                // Recover `: Type` after a qualified self
3285                if this.may_recover() && this.eat_noexpect(&token::Colon) {
3286                    let snap = this.create_snapshot_for_diagnostic();
3287                    match this.parse_ty() {
3288                        Ok(ty) => {
3289                            this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3290                                span: ty.span,
3291                                move_self_modifier: errors::MoveSelfModifier {
3292                                    removal_span: modifier_span,
3293                                    insertion_span: ty.span.shrink_to_lo(),
3294                                    modifier: modifier.to_ref_suggestion(),
3295                                },
3296                            });
3297                        }
3298                        Err(diag) => {
3299                            diag.cancel();
3300                            this.restore_snapshot(snap);
3301                        }
3302                    }
3303                }
3304                eself_ident
3305            };
3306        // Recover for the grammar `*self`, `*const self`, and `*mut self`.
3307        let recover_self_ptr = |this: &mut Self| {
3308            this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3309
3310            Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3311        };
3312
3313        // Parse optional `self` parameter of a method.
3314        // Only a limited set of initial token sequences is considered `self` parameters; anything
3315        // else is parsed as a normal function parameter list, so some lookahead is required.
3316        let eself_lo = self.token.span;
3317        let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3318            token::And => {
3319                let has_lifetime = is_lifetime(self, 1);
3320                let skip_lifetime_count = has_lifetime as usize;
3321                let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3322                    // `&{'lt} self`
3323                    self.bump(); // &
3324                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3325                    SelfKind::Region(lifetime, Mutability::Not)
3326                } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3327                    // `&{'lt} mut self`
3328                    self.bump(); // &
3329                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3330                    self.bump(); // mut
3331                    SelfKind::Region(lifetime, Mutability::Mut)
3332                } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3333                    // `&{'lt} pin const self`
3334                    self.bump(); // &
3335                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3336                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3337                    self.bump(); // pin
3338                    self.bump(); // const
3339                    SelfKind::Pinned(lifetime, Mutability::Not)
3340                } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3341                    // `&{'lt} pin mut self`
3342                    self.bump(); // &
3343                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3344                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3345                    self.bump(); // pin
3346                    self.bump(); // mut
3347                    SelfKind::Pinned(lifetime, Mutability::Mut)
3348                } else {
3349                    // `&not_self`
3350                    return Ok(None);
3351                };
3352                let hi = self.token.span;
3353                let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3354                (eself, self_ident, hi)
3355            }
3356            // `*self`
3357            token::Star if is_isolated_self(self, 1) => {
3358                self.bump();
3359                recover_self_ptr(self)?
3360            }
3361            // `*mut self` and `*const self`
3362            token::Star
3363                if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3364            {
3365                self.bump();
3366                self.bump();
3367                recover_self_ptr(self)?
3368            }
3369            // `self` and `self: TYPE`
3370            token::Ident(..) if is_isolated_self(self, 0) => {
3371                parse_self_possibly_typed(self, Mutability::Not)?
3372            }
3373            // `mut self` and `mut self: TYPE`
3374            token::Ident(..) if is_isolated_mut_self(self, 0) => {
3375                self.bump();
3376                parse_self_possibly_typed(self, Mutability::Mut)?
3377            }
3378            _ => return Ok(None),
3379        };
3380
3381        let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3382        Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3383    }
3384
3385    fn is_named_param(&self) -> bool {
3386        let offset = match &self.token.kind {
3387            token::OpenInvisible(origin) => match origin {
3388                InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3389                    return self.check_noexpect_past_close_delim(&token::Colon);
3390                }
3391                _ => 0,
3392            },
3393            token::And | token::AndAnd => 1,
3394            _ if self.token.is_keyword(kw::Mut) => 1,
3395            _ => 0,
3396        };
3397
3398        self.look_ahead(offset, |t| t.is_ident())
3399            && self.look_ahead(offset + 1, |t| t == &token::Colon)
3400    }
3401
3402    fn recover_self_param(&mut self) -> bool {
3403        #[allow(non_exhaustive_omitted_patterns)] match self.parse_outer_attributes().and_then(|_|
                self.parse_self_param()).map_err(|e| e.cancel()) {
    Ok(Some(_)) => true,
    _ => false,
}matches!(
3404            self.parse_outer_attributes()
3405                .and_then(|_| self.parse_self_param())
3406                .map_err(|e| e.cancel()),
3407            Ok(Some(_))
3408        )
3409    }
3410}
3411
3412enum IsMacroRulesItem {
3413    Yes { has_bang: bool },
3414    No,
3415}
3416
3417#[derive(#[automatically_derived]
impl ::core::marker::Copy for FrontMatterParsingMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for FrontMatterParsingMode {
    #[inline]
    fn clone(&self) -> FrontMatterParsingMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for FrontMatterParsingMode {
    #[inline]
    fn eq(&self, other: &FrontMatterParsingMode) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for FrontMatterParsingMode {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {}
}Eq)]
3418pub(super) enum FrontMatterParsingMode {
3419    /// Parse the front matter of a function declaration
3420    Function,
3421    /// Parse the front matter of a function pointet type.
3422    /// For function pointer types, the `const` and `async` keywords are not permitted.
3423    FunctionPtrType,
3424}