Skip to main content

rustc_parse/parser/
item.rs

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