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(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(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(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                let mut_restriction = p.parse_mut_restriction()?;
2112                // Unsafe fields are not supported in tuple structs, as doing so would result in a
2113                // parsing ambiguity for `struct X(unsafe fn())`.
2114                let ty = match p.parse_ty() {
2115                    Ok(ty) => ty,
2116                    Err(err) => {
2117                        if let Some(ref mut snapshot) = snapshot {
2118                            snapshot.recover_vcs_conflict_marker();
2119                        }
2120                        return Err(err);
2121                    }
2122                };
2123                let mut default = None;
2124                if p.token == token::Eq {
2125                    let mut snapshot = p.create_snapshot_for_diagnostic();
2126                    snapshot.bump();
2127                    match snapshot.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst) {
2128                        Ok(const_expr) => {
2129                            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2130                            p.psess.gated_spans.gate(sym::default_field_values, sp);
2131                            p.restore_snapshot(snapshot);
2132                            default = Some(const_expr);
2133                        }
2134                        Err(err) => {
2135                            err.cancel();
2136                        }
2137                    }
2138                }
2139
2140                Ok((
2141                    FieldDef {
2142                        span: lo.to(ty.span),
2143                        vis,
2144                        mut_restriction,
2145                        safety: Safety::Default,
2146                        ident: None,
2147                        id: DUMMY_NODE_ID,
2148                        ty,
2149                        default,
2150                        attrs,
2151                        is_placeholder: false,
2152                    },
2153                    Trailing::from(p.token == token::Comma),
2154                    UsePreAttrPos::No,
2155                ))
2156            })
2157        })
2158        .map(|(r, _)| r)
2159    }
2160
2161    /// Parses an element of a struct declaration.
2162    fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
2163        self.recover_vcs_conflict_marker();
2164        let attrs = self.parse_outer_attributes()?;
2165        self.recover_vcs_conflict_marker();
2166        self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
2167            let lo = this.token.span;
2168            let vis = this.parse_visibility(FollowedByType::No)?;
2169            let mut_restriction = this.parse_mut_restriction()?;
2170            let safety = this.parse_unsafe_field();
2171            this.parse_single_struct_field(
2172                adt_ty,
2173                lo,
2174                vis,
2175                mut_restriction,
2176                safety,
2177                attrs,
2178                ident_span,
2179            )
2180            .map(|field| (field, Trailing::No, UsePreAttrPos::No))
2181        })
2182    }
2183
2184    /// Parses a structure field declaration.
2185    fn parse_single_struct_field(
2186        &mut self,
2187        adt_ty: &str,
2188        lo: Span,
2189        vis: Visibility,
2190        mut_restriction: MutRestriction,
2191        safety: Safety,
2192        attrs: AttrVec,
2193        ident_span: Span,
2194    ) -> PResult<'a, FieldDef> {
2195        let a_var = self.parse_name_and_ty(adt_ty, lo, vis, mut_restriction, safety, attrs)?;
2196        match self.token.kind {
2197            token::Comma => {
2198                self.bump();
2199            }
2200            token::Semi => {
2201                self.bump();
2202                let sp = self.prev_token.span;
2203                let mut err =
2204                    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 `,`"));
2205                err.span_suggestion_short(
2206                    sp,
2207                    "replace `;` with `,`",
2208                    ",",
2209                    Applicability::MachineApplicable,
2210                );
2211                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}"));
2212                err.emit();
2213            }
2214            token::CloseBrace => {}
2215            token::DocComment(..) => {
2216                let previous_span = self.prev_token.span;
2217                let mut err = errors::DocCommentDoesNotDocumentAnything {
2218                    span: self.token.span,
2219                    missing_comma: None,
2220                };
2221                self.bump(); // consume the doc comment
2222                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 {
2223                    self.dcx().emit_err(err);
2224                } else {
2225                    let sp = previous_span.shrink_to_hi();
2226                    err.missing_comma = Some(sp);
2227                    return Err(self.dcx().create_err(err));
2228                }
2229            }
2230            _ => {
2231                let sp = self.prev_token.span.shrink_to_hi();
2232                let msg =
2233                    ::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));
2234
2235                // Try to recover extra trailing angle brackets
2236                if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
2237                    && let Some(last_segment) = segments.last()
2238                {
2239                    let guar = self.check_trailing_angle_brackets(
2240                        last_segment,
2241                        &[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)],
2242                    );
2243                    if let Some(_guar) = guar {
2244                        // Handle a case like `Vec<u8>>,` where we can continue parsing fields
2245                        // after the comma
2246                        let _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
2247
2248                        // `check_trailing_angle_brackets` already emitted a nicer error, as
2249                        // proven by the presence of `_guar`. We can continue parsing.
2250                        return Ok(a_var);
2251                    }
2252                }
2253
2254                let mut err = self.dcx().struct_span_err(sp, msg);
2255
2256                if self.token.is_ident()
2257                    || (self.token == TokenKind::Pound
2258                        && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2259                {
2260                    // This is likely another field, TokenKind::Pound is used for `#[..]`
2261                    // attribute for next field. Emit the diagnostic and continue parsing.
2262                    err.span_suggestion(
2263                        sp,
2264                        "try adding a comma",
2265                        ",",
2266                        Applicability::MachineApplicable,
2267                    );
2268                    err.emit();
2269                } else {
2270                    return Err(err);
2271                }
2272            }
2273        }
2274        Ok(a_var)
2275    }
2276
2277    fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2278        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)) {
2279            let sm = self.psess.source_map();
2280            let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2281            let semi_typo = self.token == token::Semi
2282                && self.look_ahead(1, |t| {
2283                    t.is_path_start()
2284                    // We check that we are in a situation like `foo; bar` to avoid bad suggestions
2285                    // when there's no type and `;` was used instead of a comma.
2286                    && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2287                        (Ok(l), Ok(r)) => l.line == r.line,
2288                        _ => true,
2289                    }
2290                });
2291            if eq_typo || semi_typo {
2292                self.bump();
2293                // Gracefully handle small typos.
2294                err.with_span_suggestion_short(
2295                    self.prev_token.span,
2296                    "field names and their types are separated with `:`",
2297                    ":",
2298                    Applicability::MachineApplicable,
2299                )
2300                .emit();
2301            } else {
2302                return Err(err);
2303            }
2304        }
2305        Ok(())
2306    }
2307
2308    /// Parses a structure field.
2309    fn parse_name_and_ty(
2310        &mut self,
2311        adt_ty: &str,
2312        lo: Span,
2313        vis: Visibility,
2314        mut_restriction: MutRestriction,
2315        safety: Safety,
2316        attrs: AttrVec,
2317    ) -> PResult<'a, FieldDef> {
2318        let name = self.parse_field_ident(adt_ty, lo)?;
2319        if self.token == token::Bang {
2320            if let Err(mut err) = self.unexpected() {
2321                // Encounter the macro invocation
2322                err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2323                return Err(err);
2324            }
2325        }
2326        self.expect_field_ty_separator()?;
2327        let ty = self.parse_ty()?;
2328        if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2329            self.dcx()
2330                .struct_span_err(self.token.span, "found single colon in a struct field type path")
2331                .with_span_suggestion_verbose(
2332                    self.token.span,
2333                    "write a path separator here",
2334                    "::",
2335                    Applicability::MaybeIncorrect,
2336                )
2337                .emit();
2338        }
2339        let default = if self.token == token::Eq {
2340            self.bump();
2341            let const_expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?;
2342            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2343            self.psess.gated_spans.gate(sym::default_field_values, sp);
2344            Some(const_expr)
2345        } else {
2346            None
2347        };
2348        Ok(FieldDef {
2349            span: lo.to(self.prev_token.span),
2350            ident: Some(name),
2351            vis,
2352            safety,
2353            mut_restriction,
2354            id: DUMMY_NODE_ID,
2355            ty,
2356            default,
2357            attrs,
2358            is_placeholder: false,
2359        })
2360    }
2361
2362    /// Parses a field identifier. Specialized version of `parse_ident_common`
2363    /// for better diagnostics and suggestions.
2364    fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2365        let (ident, is_raw) = self.ident_or_err(true)?;
2366        if is_raw == IdentIsRaw::No && ident.is_reserved() {
2367            let snapshot = self.create_snapshot_for_diagnostic();
2368            let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2369                let inherited_vis =
2370                    Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2371                // We use `parse_fn` to get a span for the function
2372                let fn_parse_mode =
2373                    FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2374                match self.parse_fn(
2375                    &mut AttrVec::new(),
2376                    fn_parse_mode,
2377                    lo,
2378                    &inherited_vis,
2379                    Case::Insensitive,
2380                ) {
2381                    Ok(_) => {
2382                        self.dcx().struct_span_err(
2383                            lo.to(self.prev_token.span),
2384                            ::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"),
2385                        )
2386                        .with_help(
2387                            "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2388                        )
2389                        .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2390                    }
2391                    Err(err) => {
2392                        err.cancel();
2393                        self.restore_snapshot(snapshot);
2394                        self.expected_ident_found_err()
2395                    }
2396                }
2397            } 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)) {
2398                match self.parse_item_struct() {
2399                    Ok(item) => {
2400                        let ItemKind::Struct(ident, ..) = item else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
2401                        self.dcx()
2402                            .struct_span_err(
2403                                lo.with_hi(ident.span.hi()),
2404                                ::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"),
2405                            )
2406                            .with_help(
2407                                "consider creating a new `struct` definition instead of nesting",
2408                            )
2409                    }
2410                    Err(err) => {
2411                        err.cancel();
2412                        self.restore_snapshot(snapshot);
2413                        self.expected_ident_found_err()
2414                    }
2415                }
2416            } else {
2417                let mut err = self.expected_ident_found_err();
2418                if self.eat_keyword_noexpect(kw::Let)
2419                    && let removal_span = self.prev_token.span.until(self.token.span)
2420                    && let Ok(ident) = self
2421                        .parse_ident_common(false)
2422                        // Cancel this error, we don't need it.
2423                        .map_err(|err| err.cancel())
2424                    && self.token == TokenKind::Colon
2425                {
2426                    err.span_suggestion(
2427                        removal_span,
2428                        "remove this `let` keyword",
2429                        String::new(),
2430                        Applicability::MachineApplicable,
2431                    );
2432                    err.note("the `let` keyword is not allowed in `struct` fields");
2433                    err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2434                    err.emit();
2435                    return Ok(ident);
2436                } else {
2437                    self.restore_snapshot(snapshot);
2438                }
2439                err
2440            };
2441            return Err(err);
2442        }
2443        self.bump();
2444        Ok(ident)
2445    }
2446
2447    /// Parses a declarative macro 2.0 definition.
2448    /// The `macro` keyword has already been parsed.
2449    /// ```ebnf
2450    /// MacBody = "{" TOKEN_STREAM "}" ;
2451    /// MacParams = "(" TOKEN_STREAM ")" ;
2452    /// DeclMac = "macro" Ident MacParams? MacBody ;
2453    /// ```
2454    fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2455        let ident = self.parse_ident()?;
2456        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)) {
2457            self.parse_delim_args()? // `MacBody`
2458        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
2459            let params = self.parse_token_tree(); // `MacParams`
2460            let pspan = params.span();
2461            if !self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
2462                self.unexpected()?;
2463            }
2464            let body = self.parse_token_tree(); // `MacBody`
2465            // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
2466            let bspan = body.span();
2467            let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
2468            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]);
2469            let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2470            Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2471        } else {
2472            self.unexpected_any()?
2473        };
2474
2475        self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2476        Ok(ItemKind::MacroDef(
2477            ident,
2478            ast::MacroDef { body, macro_rules: false, eii_declaration: None },
2479        ))
2480    }
2481
2482    /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
2483    fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2484        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)) {
2485            let macro_rules_span = self.token.span;
2486
2487            if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2488                return IsMacroRulesItem::Yes { has_bang: true };
2489            } else if self.look_ahead(1, |t| t.is_ident()) {
2490                // macro_rules foo
2491                self.dcx().emit_err(errors::MacroRulesMissingBang {
2492                    span: macro_rules_span,
2493                    hi: macro_rules_span.shrink_to_hi(),
2494                });
2495
2496                return IsMacroRulesItem::Yes { has_bang: false };
2497            }
2498        }
2499
2500        IsMacroRulesItem::No
2501    }
2502
2503    /// Parses a `macro_rules! foo { ... }` declarative macro.
2504    fn parse_item_macro_rules(
2505        &mut self,
2506        vis: &Visibility,
2507        has_bang: bool,
2508    ) -> PResult<'a, ItemKind> {
2509        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`
2510
2511        if has_bang {
2512            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))?; // `!`
2513        }
2514        let ident = self.parse_ident()?;
2515
2516        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
2517            // Handle macro_rules! foo!
2518            let span = self.prev_token.span;
2519            self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2520        }
2521
2522        let body = self.parse_delim_args()?;
2523        self.eat_semi_for_macro_if_needed(&body, None);
2524        self.complain_if_pub_macro(vis, true);
2525
2526        Ok(ItemKind::MacroDef(
2527            ident,
2528            ast::MacroDef { body, macro_rules: true, eii_declaration: None },
2529        ))
2530    }
2531
2532    /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
2533    /// If that's not the case, emit an error.
2534    fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2535        if let VisibilityKind::Inherited = vis.kind {
2536            return;
2537        }
2538
2539        let vstr = pprust::vis_to_string(vis);
2540        let vstr = vstr.trim_end();
2541        if macro_rules {
2542            self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2543        } else {
2544            self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2545        }
2546    }
2547
2548    fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs, path: Option<&Path>) {
2549        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)) {
2550            self.report_invalid_macro_expansion_item(args, path);
2551        }
2552    }
2553
2554    fn report_invalid_macro_expansion_item(&self, args: &DelimArgs, path: Option<&Path>) {
2555        let span = args.dspan.entire();
2556        let mut err = self.dcx().struct_span_err(
2557            span,
2558            "macros that expand to items must be delimited with braces or followed by a semicolon",
2559        );
2560        // FIXME: This will make us not emit the help even for declarative
2561        // macros within the same crate (that we can fix), which is sad.
2562        if !span.from_expansion() {
2563            let DelimSpan { open, close } = args.dspan;
2564            // Check if this looks like `macro_rules!(name) { ... }`
2565            // a common mistake when trying to define a macro.
2566            if let Some(path) = path
2567                && path.segments.first().is_some_and(|seg| seg.ident.name == sym::macro_rules)
2568                && args.delim == Delimiter::Parenthesis
2569            {
2570                let replace =
2571                    if path.span.hi() + rustc_span::BytePos(1) < open.lo() { "" } else { " " };
2572                err.multipart_suggestion(
2573                    "to define a macro, remove the parentheses around the macro name",
2574                    ::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())],
2575                    Applicability::MachineApplicable,
2576                );
2577            } else {
2578                err.multipart_suggestion(
2579                    "change the delimiters to curly braces",
2580                    ::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())],
2581                    Applicability::MaybeIncorrect,
2582                );
2583                err.span_suggestion(
2584                    span.with_neighbor(self.token.span).shrink_to_hi(),
2585                    "add a semicolon",
2586                    ';',
2587                    Applicability::MaybeIncorrect,
2588                );
2589            }
2590        }
2591        err.emit();
2592    }
2593
2594    /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
2595    /// it is, we try to parse the item and report error about nested types.
2596    fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2597        if (self.token.is_keyword(kw::Enum)
2598            || self.token.is_keyword(kw::Struct)
2599            || self.token.is_keyword(kw::Union))
2600            && self.look_ahead(1, |t| t.is_ident())
2601        {
2602            let kw_token = self.token;
2603            let kw_str = pprust::token_to_string(&kw_token);
2604            let item = self.parse_item(
2605                ForceCollect::No,
2606                AllowConstBlockItems::DoesNotMatter, // self.token != kw::Const
2607            )?;
2608            let mut item = item.unwrap().span;
2609            if self.token == token::Comma {
2610                item = item.to(self.token.span);
2611            }
2612            self.dcx().emit_err(errors::NestedAdt {
2613                span: kw_token.span,
2614                item,
2615                kw_str,
2616                keyword: keyword.as_str(),
2617            });
2618            // We successfully parsed the item but we must inform the caller about nested problem.
2619            return Ok(false);
2620        }
2621        Ok(true)
2622    }
2623}
2624
2625/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
2626///
2627/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
2628///
2629/// This function pointer accepts an edition, because in edition 2015, trait declarations
2630/// were allowed to omit parameter names. In 2018, they became required. It also accepts an
2631/// `IsDotDotDot` parameter, as `extern` function declarations and function pointer types are
2632/// allowed to omit the name of the `...` but regular function items are not.
2633type ReqName = fn(Edition, IsDotDotDot) -> bool;
2634
2635#[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)]
2636pub(crate) enum IsDotDotDot {
2637    Yes,
2638    No,
2639}
2640
2641/// Parsing configuration for functions.
2642///
2643/// The syntax of function items is slightly different within trait definitions,
2644/// impl blocks, and modules. It is still parsed using the same code, just with
2645/// different flags set, so that even when the input is wrong and produces a parse
2646/// error, it still gets into the AST and the rest of the parser and
2647/// type checker can run.
2648#[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)]
2649pub(crate) struct FnParseMode {
2650    /// A function pointer that decides if, per-parameter `p`, `p` must have a
2651    /// pattern or just a type. This field affects parsing of the parameters list.
2652    ///
2653    /// ```text
2654    /// fn foo(alef: A) -> X { X::new() }
2655    ///        -----^^ affects parsing this part of the function signature
2656    ///        |
2657    ///        if req_name returns false, then this name is optional
2658    ///
2659    /// fn bar(A) -> X;
2660    ///        ^
2661    ///        |
2662    ///        if req_name returns true, this is an error
2663    /// ```
2664    ///
2665    /// Calling this function pointer should only return false if:
2666    ///
2667    ///   * The item is being parsed inside of a trait definition.
2668    ///     Within an impl block or a module, it should always evaluate
2669    ///     to true.
2670    ///   * The span is from Edition 2015. In particular, you can get a
2671    ///     2015 span inside a 2021 crate using macros.
2672    ///
2673    /// Or if `IsDotDotDot::Yes`, this function will also return `false` if the item being parsed
2674    /// is inside an `extern` block.
2675    pub(super) req_name: ReqName,
2676    /// The context in which this function is parsed, used for diagnostics.
2677    /// This indicates the fn is a free function or method and so on.
2678    pub(super) context: FnContext,
2679    /// If this flag is set to `true`, then plain, semicolon-terminated function
2680    /// prototypes are not allowed here.
2681    ///
2682    /// ```text
2683    /// fn foo(alef: A) -> X { X::new() }
2684    ///                      ^^^^^^^^^^^^
2685    ///                      |
2686    ///                      this is always allowed
2687    ///
2688    /// fn bar(alef: A, bet: B) -> X;
2689    ///                             ^
2690    ///                             |
2691    ///                             if req_body is set to true, this is an error
2692    /// ```
2693    ///
2694    /// This field should only be set to false if the item is inside of a trait
2695    /// definition or extern block. Within an impl block or a module, it should
2696    /// always be set to true.
2697    pub(super) req_body: bool,
2698}
2699
2700/// The context in which a function is parsed.
2701/// FIXME(estebank, xizheyin): Use more variants.
2702#[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)]
2703pub(crate) enum FnContext {
2704    /// Free context.
2705    Free,
2706    /// A Trait context.
2707    Trait,
2708    /// An Impl block.
2709    Impl,
2710}
2711
2712/// Parsing of functions and methods.
2713impl<'a> Parser<'a> {
2714    /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
2715    fn parse_fn(
2716        &mut self,
2717        attrs: &mut AttrVec,
2718        fn_parse_mode: FnParseMode,
2719        sig_lo: Span,
2720        vis: &Visibility,
2721        case: Case,
2722    ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2723        let fn_span = self.token.span;
2724        let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn`
2725        let ident = self.parse_ident()?; // `foo`
2726        let mut generics = self.parse_generics()?; // `<'a, T, ...>`
2727        let decl = match self.parse_fn_decl(&fn_parse_mode, AllowPlus::Yes, RecoverReturnSign::Yes)
2728        {
2729            Ok(decl) => decl,
2730            Err(old_err) => {
2731                // If we see `for Ty ...` then user probably meant `impl` item.
2732                if self.token.is_keyword(kw::For) {
2733                    old_err.cancel();
2734                    return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2735                } else {
2736                    return Err(old_err);
2737                }
2738            }
2739        };
2740
2741        // Store the end of function parameters to give better diagnostics
2742        // inside `parse_fn_body()`.
2743        let fn_params_end = self.prev_token.span.shrink_to_hi();
2744
2745        let contract = self.parse_contract()?;
2746
2747        generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
2748
2749        // `fn_params_end` is needed only when it's followed by a where clause.
2750        let fn_params_end =
2751            if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2752
2753        let mut sig_hi = self.prev_token.span;
2754        // Either `;` or `{ ... }`.
2755        let body =
2756            self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2757        let fn_sig_span = sig_lo.to(sig_hi);
2758        Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2759    }
2760
2761    /// Provide diagnostics when function body is not found
2762    fn error_fn_body_not_found(
2763        &mut self,
2764        ident_span: Span,
2765        req_body: bool,
2766        fn_params_end: Option<Span>,
2767    ) -> PResult<'a, ErrorGuaranteed> {
2768        let expected: &[_] =
2769            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)] };
2770        match self.expected_one_of_not_found(&[], expected) {
2771            Ok(error_guaranteed) => Ok(error_guaranteed),
2772            Err(mut err) => {
2773                if self.token == token::CloseBrace {
2774                    // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
2775                    // the AST for typechecking.
2776                    err.span_label(ident_span, "while parsing this `fn`");
2777                    Ok(err.emit())
2778                } else if self.token == token::RArrow
2779                    && let Some(fn_params_end) = fn_params_end
2780                {
2781                    // Instead of a function body, the parser has encountered a right arrow
2782                    // preceded by a where clause.
2783
2784                    // Find whether token behind the right arrow is a function trait and
2785                    // store its span.
2786                    let fn_trait_span =
2787                        [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2788                            if self.prev_token.is_ident_named(symbol) {
2789                                Some(self.prev_token.span)
2790                            } else {
2791                                None
2792                            }
2793                        });
2794
2795                    // Parse the return type (along with the right arrow) and store its span.
2796                    // If there's a parse error, cancel it and return the existing error
2797                    // as we are primarily concerned with the
2798                    // expected-function-body-but-found-something-else error here.
2799                    let arrow_span = self.token.span;
2800                    let ty_span = match self.parse_ret_ty(
2801                        AllowPlus::Yes,
2802                        RecoverQPath::Yes,
2803                        RecoverReturnSign::Yes,
2804                    ) {
2805                        Ok(ty_span) => ty_span.span().shrink_to_hi(),
2806                        Err(parse_error) => {
2807                            parse_error.cancel();
2808                            return Err(err);
2809                        }
2810                    };
2811                    let ret_ty_span = arrow_span.to(ty_span);
2812
2813                    if let Some(fn_trait_span) = fn_trait_span {
2814                        // Typo'd Fn* trait bounds such as
2815                        // fn foo<F>() where F: FnOnce -> () {}
2816                        err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2817                    } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2818                    {
2819                        // If token behind right arrow is not a Fn* trait, the programmer
2820                        // probably misplaced the return type after the where clause like
2821                        // `fn foo<T>() where T: Default -> u8 {}`
2822                        err.primary_message(
2823                            "return type should be specified after the function parameters",
2824                        );
2825                        err.subdiagnostic(errors::MisplacedReturnType {
2826                            fn_params_end,
2827                            snippet,
2828                            ret_ty_span,
2829                        });
2830                    }
2831                    Err(err)
2832                } else {
2833                    Err(err)
2834                }
2835            }
2836        }
2837    }
2838
2839    /// Parse the "body" of a function.
2840    /// This can either be `;` when there's no body,
2841    /// or e.g. a block when the function is a provided one.
2842    fn parse_fn_body(
2843        &mut self,
2844        attrs: &mut AttrVec,
2845        ident: &Ident,
2846        sig_hi: &mut Span,
2847        req_body: bool,
2848        fn_params_end: Option<Span>,
2849    ) -> PResult<'a, Option<Box<Block>>> {
2850        let has_semi = if req_body {
2851            self.token == TokenKind::Semi
2852        } else {
2853            // Only include `;` in list of expected tokens if body is not required
2854            self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi))
2855        };
2856        let (inner_attrs, body) = if has_semi {
2857            // Include the trailing semicolon in the span of the signature
2858            self.expect_semi()?;
2859            *sig_hi = self.prev_token.span;
2860            (AttrVec::new(), None)
2861        } 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() {
2862            let prev_in_fn_body = self.in_fn_body;
2863            self.in_fn_body = true;
2864            let res = self.parse_block_common(self.token.span, BlockCheckMode::Default, None).map(
2865                |(attrs, mut body)| {
2866                    if let Some(guar) = self.fn_body_missing_semi_guar.take() {
2867                        body.stmts.push(self.mk_stmt(
2868                            body.span,
2869                            StmtKind::Expr(self.mk_expr(body.span, ExprKind::Err(guar))),
2870                        ));
2871                    }
2872                    (attrs, Some(body))
2873                },
2874            );
2875            self.in_fn_body = prev_in_fn_body;
2876            res?
2877        } else if self.token == token::Eq {
2878            // Recover `fn foo() = $expr;`.
2879            self.bump(); // `=`
2880            let eq_sp = self.prev_token.span;
2881            let _ = self.parse_expr()?;
2882            self.expect_semi()?; // `;`
2883            let span = eq_sp.to(self.prev_token.span);
2884            let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2885                span,
2886                sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2887            });
2888            (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2889        } else {
2890            self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2891            (AttrVec::new(), None)
2892        };
2893        attrs.extend(inner_attrs);
2894        Ok(body)
2895    }
2896
2897    fn check_impl_frontmatter(&mut self, look_ahead: usize) -> bool {
2898        const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2899        // In contrast to the loop below, this call inserts `impl` into the
2900        // list of expected tokens shown in diagnostics.
2901        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)) {
2902            return true;
2903        }
2904        let mut i = 0;
2905        while i < ALL_QUALS.len() {
2906            let action = self.look_ahead(i + look_ahead, |token| {
2907                if token.is_keyword(kw::Impl) {
2908                    return Some(true);
2909                }
2910                if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2911                    // Ok, we found a legal keyword, keep looking for `impl`
2912                    return None;
2913                }
2914                Some(false)
2915            });
2916            if let Some(ret) = action {
2917                return ret;
2918            }
2919            i += 1;
2920        }
2921
2922        self.is_keyword_ahead(i, &[kw::Impl])
2923    }
2924
2925    /// Is the current token the start of an `FnHeader` / not a valid parse?
2926    ///
2927    /// `check_pub` adds additional `pub` to the checks in case users place it
2928    /// wrongly, can be used to ensure `pub` never comes after `default`.
2929    pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2930        const ALL_QUALS: &[ExpKeywordPair] = &[
2931            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Pub,
    token_type: crate::parser::token_type::TokenType::KwPub,
}exp!(Pub),
2932            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Gen,
    token_type: crate::parser::token_type::TokenType::KwGen,
}exp!(Gen),
2933            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const),
2934            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Async,
    token_type: crate::parser::token_type::TokenType::KwAsync,
}exp!(Async),
2935            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Unsafe,
    token_type: crate::parser::token_type::TokenType::KwUnsafe,
}exp!(Unsafe),
2936            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Safe,
    token_type: crate::parser::token_type::TokenType::KwSafe,
}exp!(Safe),
2937            crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern),
2938        ];
2939
2940        // We use an over-approximation here.
2941        // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
2942        // `pub` is added in case users got confused with the ordering like `async pub fn`,
2943        // only if it wasn't preceded by `default` as `default pub` is invalid.
2944        let quals: &[_] = if check_pub {
2945            ALL_QUALS
2946        } else {
2947            &[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)]
2948        };
2949        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`.
2950            // `$qual fn` or `$qual $qual`:
2951            || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2952                && self.look_ahead(1, |t| {
2953                    // `$qual fn`, e.g. `const fn` or `async fn`.
2954                    t.is_keyword_case(kw::Fn, case)
2955                    // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
2956                    || (
2957                        (
2958                            t.is_non_raw_ident_where(|i|
2959                                quals.iter().any(|exp| exp.kw == i.name)
2960                                    // Rule out 2015 `const async: T = val`.
2961                                    && i.is_reserved()
2962                            )
2963                            || case == Case::Insensitive
2964                                && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2965                                    exp.kw.as_str() == i.name.as_str().to_lowercase()
2966                                }))
2967                        )
2968                        // Rule out `unsafe extern {`.
2969                        && !self.is_unsafe_foreign_mod()
2970                        // Rule out `async gen {` and `async gen move {`
2971                        && !self.is_async_gen_block()
2972                        // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`
2973                        && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl])
2974                    )
2975                })
2976            // `extern ABI fn`
2977            || 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)
2978                // Use `tree_look_ahead` because `ABI` might be a metavariable,
2979                // i.e. an invisible-delimited sequence, and `tree_look_ahead`
2980                // will consider that a single element when looking ahead.
2981                && self.look_ahead(1, |t| t.can_begin_string_literal())
2982                && (self.tree_look_ahead(2, |tt| {
2983                    match tt {
2984                        TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2985                        TokenTree::Delimited(..) => false,
2986                    }
2987                }) == Some(true) ||
2988                    // This branch is only for better diagnostics; `pub`, `unsafe`, etc. are not
2989                    // allowed here.
2990                    (self.may_recover()
2991                        && self.tree_look_ahead(2, |tt| {
2992                            match tt {
2993                                TokenTree::Token(t, _) =>
2994                                    ALL_QUALS.iter().any(|exp| {
2995                                        t.is_keyword(exp.kw)
2996                                    }),
2997                                TokenTree::Delimited(..) => false,
2998                            }
2999                        }) == Some(true)
3000                        && self.tree_look_ahead(3, |tt| {
3001                            match tt {
3002                                TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
3003                                TokenTree::Delimited(..) => false,
3004                            }
3005                        }) == Some(true)
3006                    )
3007                )
3008    }
3009
3010    /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
3011    /// up to and including the `fn` keyword. The formal grammar is:
3012    ///
3013    /// ```text
3014    /// Extern = "extern" StringLit? ;
3015    /// FnQual = "const"? "async"? "unsafe"? Extern? ;
3016    /// FnFrontMatter = FnQual "fn" ;
3017    /// ```
3018    ///
3019    /// `vis` represents the visibility that was already parsed, if any. Use
3020    /// `Visibility::Inherited` when no visibility is known.
3021    ///
3022    /// If `parsing_mode` is `FrontMatterParsingMode::FunctionPtrType`, we error on `const` and `async` qualifiers,
3023    /// which are not allowed in function pointer types.
3024    pub(super) fn parse_fn_front_matter(
3025        &mut self,
3026        orig_vis: &Visibility,
3027        case: Case,
3028        parsing_mode: FrontMatterParsingMode,
3029    ) -> PResult<'a, FnHeader> {
3030        let sp_start = self.token.span;
3031        let constness = self.parse_constness(case);
3032        if parsing_mode == FrontMatterParsingMode::FunctionPtrType
3033            && let Const::Yes(const_span) = constness
3034        {
3035            self.dcx().emit_err(FnPointerCannotBeConst {
3036                span: const_span,
3037                suggestion: const_span.until(self.token.span),
3038            });
3039        }
3040
3041        let async_start_sp = self.token.span;
3042        let coroutine_kind = self.parse_coroutine_kind(case);
3043        if parsing_mode == FrontMatterParsingMode::FunctionPtrType
3044            && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
3045        {
3046            self.dcx().emit_err(FnPointerCannotBeAsync {
3047                span: async_span,
3048                suggestion: async_span.until(self.token.span),
3049            });
3050        }
3051        // FIXME(gen_blocks): emit a similar error for `gen fn()`
3052
3053        let unsafe_start_sp = self.token.span;
3054        let safety = self.parse_safety(case);
3055
3056        let ext_start_sp = self.token.span;
3057        let ext = self.parse_extern(case);
3058
3059        if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
3060            if span.is_rust_2015() {
3061                self.dcx().emit_err(errors::AsyncFnIn2015 {
3062                    span,
3063                    help: errors::HelpUseLatestEdition::new(),
3064                });
3065            }
3066        }
3067
3068        match coroutine_kind {
3069            Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
3070                self.psess.gated_spans.gate(sym::gen_blocks, span);
3071            }
3072            Some(CoroutineKind::Async { .. }) | None => {}
3073        }
3074
3075        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) {
3076            // It is possible for `expect_one_of` to recover given the contents of
3077            // `self.expected_token_types`, therefore, do not use `self.unexpected()` which doesn't
3078            // account for this.
3079            match self.expect_one_of(&[], &[]) {
3080                Ok(Recovered::Yes(_)) => {}
3081                Ok(Recovered::No) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
3082                Err(mut err) => {
3083                    // Qualifier keywords ordering check
3084                    enum WrongKw {
3085                        Duplicated(Span),
3086                        Misplaced(Span),
3087                        /// `MisplacedDisallowedQualifier` is only used instead of `Misplaced`,
3088                        /// when the misplaced keyword is disallowed by the current `FrontMatterParsingMode`.
3089                        /// In this case, we avoid generating the suggestion to swap around the keywords,
3090                        /// as we already generated a suggestion to remove the keyword earlier.
3091                        MisplacedDisallowedQualifier,
3092                    }
3093
3094                    // We may be able to recover
3095                    let mut recover_constness = constness;
3096                    let mut recover_coroutine_kind = coroutine_kind;
3097                    let mut recover_safety = safety;
3098                    // This will allow the machine fix to directly place the keyword in the correct place or to indicate
3099                    // that the keyword is already present and the second instance should be removed.
3100                    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)) {
3101                        match constness {
3102                            Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
3103                            Const::No => {
3104                                recover_constness = Const::Yes(self.token.span);
3105                                match parsing_mode {
3106                                    FrontMatterParsingMode::Function => {
3107                                        Some(WrongKw::Misplaced(async_start_sp))
3108                                    }
3109                                    FrontMatterParsingMode::FunctionPtrType => {
3110                                        self.dcx().emit_err(FnPointerCannotBeConst {
3111                                            span: self.token.span,
3112                                            suggestion: self
3113                                                .token
3114                                                .span
3115                                                .with_lo(self.prev_token.span.hi()),
3116                                        });
3117                                        Some(WrongKw::MisplacedDisallowedQualifier)
3118                                    }
3119                                }
3120                            }
3121                        }
3122                    } 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)) {
3123                        match coroutine_kind {
3124                            Some(CoroutineKind::Async { span, .. }) => {
3125                                Some(WrongKw::Duplicated(span))
3126                            }
3127                            Some(CoroutineKind::AsyncGen { span, .. }) => {
3128                                Some(WrongKw::Duplicated(span))
3129                            }
3130                            Some(CoroutineKind::Gen { .. }) => {
3131                                recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
3132                                    span: self.token.span,
3133                                    closure_id: DUMMY_NODE_ID,
3134                                    return_impl_trait_id: DUMMY_NODE_ID,
3135                                });
3136                                // FIXME(gen_blocks): This span is wrong, didn't want to think about it.
3137                                Some(WrongKw::Misplaced(unsafe_start_sp))
3138                            }
3139                            None => {
3140                                recover_coroutine_kind = Some(CoroutineKind::Async {
3141                                    span: self.token.span,
3142                                    closure_id: DUMMY_NODE_ID,
3143                                    return_impl_trait_id: DUMMY_NODE_ID,
3144                                });
3145                                match parsing_mode {
3146                                    FrontMatterParsingMode::Function => {
3147                                        Some(WrongKw::Misplaced(async_start_sp))
3148                                    }
3149                                    FrontMatterParsingMode::FunctionPtrType => {
3150                                        self.dcx().emit_err(FnPointerCannotBeAsync {
3151                                            span: self.token.span,
3152                                            suggestion: self
3153                                                .token
3154                                                .span
3155                                                .with_lo(self.prev_token.span.hi()),
3156                                        });
3157                                        Some(WrongKw::MisplacedDisallowedQualifier)
3158                                    }
3159                                }
3160                            }
3161                        }
3162                    } 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)) {
3163                        match safety {
3164                            Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
3165                            Safety::Safe(sp) => {
3166                                recover_safety = Safety::Unsafe(self.token.span);
3167                                Some(WrongKw::Misplaced(sp))
3168                            }
3169                            Safety::Default => {
3170                                recover_safety = Safety::Unsafe(self.token.span);
3171                                Some(WrongKw::Misplaced(ext_start_sp))
3172                            }
3173                        }
3174                    } 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)) {
3175                        match safety {
3176                            Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
3177                            Safety::Unsafe(sp) => {
3178                                recover_safety = Safety::Safe(self.token.span);
3179                                Some(WrongKw::Misplaced(sp))
3180                            }
3181                            Safety::Default => {
3182                                recover_safety = Safety::Safe(self.token.span);
3183                                Some(WrongKw::Misplaced(ext_start_sp))
3184                            }
3185                        }
3186                    } else {
3187                        None
3188                    };
3189
3190                    // The keyword is already present, suggest removal of the second instance
3191                    if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
3192                        let original_kw = self
3193                            .span_to_snippet(original_sp)
3194                            .expect("Span extracted directly from keyword should always work");
3195
3196                        err.span_suggestion(
3197                            self.token_uninterpolated_span(),
3198                            ::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"),
3199                            "",
3200                            Applicability::MachineApplicable,
3201                        )
3202                        .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"));
3203                    }
3204                    // The keyword has not been seen yet, suggest correct placement in the function front matter
3205                    else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
3206                        let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
3207                        if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
3208                            let misplaced_qual_sp = self.token_uninterpolated_span();
3209                            let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
3210
3211                            err.span_suggestion(
3212                                    correct_pos_sp.to(misplaced_qual_sp),
3213                                    ::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}`"),
3214                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1}", misplaced_qual,
                current_qual))
    })format!("{misplaced_qual} {current_qual}"),
3215                                    Applicability::MachineApplicable,
3216                                ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
3217                        }
3218                    }
3219                    // Recover incorrect visibility order such as `async pub`
3220                    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)) {
3221                        let sp = sp_start.to(self.prev_token.span);
3222                        if let Ok(snippet) = self.span_to_snippet(sp) {
3223                            let current_vis = match self.parse_visibility(FollowedByType::No) {
3224                                Ok(v) => v,
3225                                Err(d) => {
3226                                    d.cancel();
3227                                    return Err(err);
3228                                }
3229                            };
3230                            let vs = pprust::vis_to_string(&current_vis);
3231                            let vs = vs.trim_end();
3232
3233                            // There was no explicit visibility
3234                            if #[allow(non_exhaustive_omitted_patterns)] match orig_vis.kind {
    VisibilityKind::Inherited => true,
    _ => false,
}matches!(orig_vis.kind, VisibilityKind::Inherited) {
3235                                err.span_suggestion(
3236                                    sp_start.to(self.prev_token.span),
3237                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("visibility `{0}` must come before `{1}`",
                vs, snippet))
    })format!("visibility `{vs}` must come before `{snippet}`"),
3238                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1}", vs, snippet))
    })format!("{vs} {snippet}"),
3239                                    Applicability::MachineApplicable,
3240                                );
3241                            }
3242                            // There was an explicit visibility
3243                            else {
3244                                err.span_suggestion(
3245                                    current_vis.span,
3246                                    "there is already a visibility modifier, remove one",
3247                                    "",
3248                                    Applicability::MachineApplicable,
3249                                )
3250                                .span_note(orig_vis.span, "explicit visibility first seen here");
3251                            }
3252                        }
3253                    }
3254
3255                    // FIXME(gen_blocks): add keyword recovery logic for genness
3256
3257                    if let Some(wrong_kw) = wrong_kw
3258                        && self.may_recover()
3259                        && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
3260                    {
3261                        // Advance past the misplaced keyword and `fn`
3262                        self.bump();
3263                        self.bump();
3264                        // When we recover from a `MisplacedDisallowedQualifier`, we already emitted an error for the disallowed qualifier
3265                        // So we don't emit another error that the qualifier is unexpected.
3266                        if #[allow(non_exhaustive_omitted_patterns)] match wrong_kw {
    WrongKw::MisplacedDisallowedQualifier => true,
    _ => false,
}matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
3267                            err.cancel();
3268                        } else {
3269                            err.emit();
3270                        }
3271                        return Ok(FnHeader {
3272                            constness: recover_constness,
3273                            safety: recover_safety,
3274                            coroutine_kind: recover_coroutine_kind,
3275                            ext,
3276                        });
3277                    }
3278
3279                    return Err(err);
3280                }
3281            }
3282        }
3283
3284        Ok(FnHeader { constness, safety, coroutine_kind, ext })
3285    }
3286
3287    /// Parses the parameter list and result type of a function declaration.
3288    pub(super) fn parse_fn_decl(
3289        &mut self,
3290        fn_parse_mode: &FnParseMode,
3291        ret_allow_plus: AllowPlus,
3292        recover_return_sign: RecoverReturnSign,
3293    ) -> PResult<'a, Box<FnDecl>> {
3294        Ok(Box::new(FnDecl {
3295            inputs: self.parse_fn_params(fn_parse_mode)?,
3296            output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
3297        }))
3298    }
3299
3300    /// Parses the parameter list of a function, including the `(` and `)` delimiters.
3301    pub(super) fn parse_fn_params(
3302        &mut self,
3303        fn_parse_mode: &FnParseMode,
3304    ) -> PResult<'a, ThinVec<Param>> {
3305        let mut first_param = true;
3306        // Parse the arguments, starting out with `self` being allowed...
3307        if self.token != TokenKind::OpenParen
3308        // might be typo'd trait impl, handled elsewhere
3309        && !self.token.is_keyword(kw::For)
3310        {
3311            // recover from missing argument list, e.g. `fn main -> () {}`
3312            self.dcx()
3313                .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
3314            return Ok(ThinVec::new());
3315        }
3316
3317        let (mut params, _) = self.parse_paren_comma_seq(|p| {
3318            p.recover_vcs_conflict_marker();
3319            let snapshot = p.create_snapshot_for_diagnostic();
3320            let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3321                let guar = e.emit();
3322                // When parsing a param failed, we should check to make the span of the param
3323                // not contain '(' before it.
3324                // For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
3325                let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3326                    p.prev_token.span.shrink_to_hi()
3327                } else {
3328                    p.prev_token.span
3329                };
3330                p.restore_snapshot(snapshot);
3331                // Skip every token until next possible arg or end.
3332                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)]);
3333                // Create a placeholder argument for proper arg count (issue #34264).
3334                Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3335            });
3336            // ...now that we've parsed the first argument, `self` is no longer allowed.
3337            first_param = false;
3338            param
3339        })?;
3340        // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
3341        self.deduplicate_recovered_params_names(&mut params);
3342        Ok(params)
3343    }
3344
3345    /// Parses a single function parameter.
3346    ///
3347    /// - `self` is syntactically allowed when `first_param` holds.
3348    /// - `recover_arg_parse` is used to recover from a failed argument parse.
3349    pub(super) fn parse_param_general(
3350        &mut self,
3351        fn_parse_mode: &FnParseMode,
3352        first_param: bool,
3353        recover_arg_parse: bool,
3354    ) -> PResult<'a, Param> {
3355        let lo = self.token.span;
3356        let attrs = self.parse_outer_attributes()?;
3357        self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3358            // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
3359            if let Some(mut param) = this.parse_self_param()? {
3360                param.attrs = attrs;
3361                let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3362                return Ok((res?, Trailing::No, UsePreAttrPos::No));
3363            }
3364
3365            let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3366                IsDotDotDot::Yes
3367            } else {
3368                IsDotDotDot::No
3369            };
3370            let is_name_required = (fn_parse_mode.req_name)(
3371                this.token.span.with_neighbor(this.prev_token.span).edition(),
3372                is_dot_dot_dot,
3373            );
3374            let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3375                this.psess.buffer_lint(
3376                    VARARGS_WITHOUT_PATTERN,
3377                    this.token.span,
3378                    ast::CRATE_NODE_ID,
3379                    errors::VarargsWithoutPattern { span: this.token.span },
3380                );
3381                false
3382            } else {
3383                is_name_required
3384            };
3385            let (pat, ty) = if is_name_required || this.is_named_param() {
3386                {
    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:3386",
                        "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(3386u32),
                        ::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);
3387                let (pat, colon) = this.parse_fn_param_pat_colon()?;
3388                if !colon {
3389                    let mut err = this.unexpected().unwrap_err();
3390                    return if let Some(ident) = this.parameter_without_type(
3391                        &mut err,
3392                        pat,
3393                        is_name_required,
3394                        first_param,
3395                        fn_parse_mode,
3396                    ) {
3397                        let guar = err.emit();
3398                        Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3399                    } else {
3400                        Err(err)
3401                    };
3402                }
3403
3404                this.eat_incorrect_doc_comment_for_param_type();
3405                (pat, this.parse_ty_for_param()?)
3406            } else {
3407                {
    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:3407",
                        "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(3407u32),
                        ::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");
3408                let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3409                this.eat_incorrect_doc_comment_for_param_type();
3410                let mut ty = this.parse_ty_for_param();
3411
3412                if let Ok(t) = &ty {
3413                    // Check for trailing angle brackets
3414                    if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3415                        && let Some(segment) = segments.last()
3416                        && let Some(guar) =
3417                            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)])
3418                    {
3419                        return Ok((
3420                            dummy_arg(segment.ident, guar),
3421                            Trailing::No,
3422                            UsePreAttrPos::No,
3423                        ));
3424                    }
3425
3426                    if this.token != token::Comma && this.token != token::CloseParen {
3427                        // This wasn't actually a type, but a pattern looking like a type,
3428                        // so we are going to rollback and re-parse for recovery.
3429                        ty = this.unexpected_any();
3430                    }
3431                }
3432                match ty {
3433                    Ok(ty) => {
3434                        let pat = this.mk_pat(ty.span, PatKind::Missing);
3435                        (Box::new(pat), ty)
3436                    }
3437                    // If this is a C-variadic argument and we hit an error, return the error.
3438                    Err(err) if this.token == token::DotDotDot => return Err(err),
3439                    Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3440                    Err(err) if recover_arg_parse => {
3441                        // Recover from attempting to parse the argument as a type without pattern.
3442                        err.cancel();
3443                        this.restore_snapshot(parser_snapshot_before_ty);
3444                        this.recover_arg_parse()?
3445                    }
3446                    Err(err) => return Err(err),
3447                }
3448            };
3449
3450            let span = lo.to(this.prev_token.span);
3451
3452            Ok((
3453                Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3454                Trailing::No,
3455                UsePreAttrPos::No,
3456            ))
3457        })
3458    }
3459
3460    /// Returns the parsed optional self parameter and whether a self shortcut was used.
3461    fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3462        // Extract an identifier *after* having confirmed that the token is one.
3463        let expect_self_ident = |this: &mut Self| match this.token.ident() {
3464            Some((ident, IdentIsRaw::No)) => {
3465                this.bump();
3466                ident
3467            }
3468            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
3469        };
3470        // is lifetime `n` tokens ahead?
3471        let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3472        // Is `self` `n` tokens ahead?
3473        let is_isolated_self = |this: &Self, n| {
3474            this.is_keyword_ahead(n, &[kw::SelfLower])
3475                && this.look_ahead(n + 1, |t| t != &token::PathSep)
3476        };
3477        // Is `pin const self` `n` tokens ahead?
3478        let is_isolated_pin_const_self = |this: &Self, n| {
3479            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3480                && this.is_keyword_ahead(n + 1, &[kw::Const])
3481                && is_isolated_self(this, n + 2)
3482        };
3483        // Is `mut self` `n` tokens ahead?
3484        let is_isolated_mut_self =
3485            |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3486        // Is `pin mut self` `n` tokens ahead?
3487        let is_isolated_pin_mut_self = |this: &Self, n| {
3488            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3489                && is_isolated_mut_self(this, n + 1)
3490        };
3491        // Parse `self` or `self: TYPE`. We already know the current token is `self`.
3492        let parse_self_possibly_typed = |this: &mut Self, m| {
3493            let eself_ident = expect_self_ident(this);
3494            let eself_hi = this.prev_token.span;
3495            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)) {
3496                SelfKind::Explicit(this.parse_ty()?, m)
3497            } else {
3498                SelfKind::Value(m)
3499            };
3500            Ok((eself, eself_ident, eself_hi))
3501        };
3502        let expect_self_ident_not_typed =
3503            |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3504                let eself_ident = expect_self_ident(this);
3505
3506                // Recover `: Type` after a qualified self
3507                if this.may_recover() && this.eat_noexpect(&token::Colon) {
3508                    let snap = this.create_snapshot_for_diagnostic();
3509                    match this.parse_ty() {
3510                        Ok(ty) => {
3511                            this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3512                                span: ty.span,
3513                                move_self_modifier: errors::MoveSelfModifier {
3514                                    removal_span: modifier_span,
3515                                    insertion_span: ty.span.shrink_to_lo(),
3516                                    modifier: modifier.to_ref_suggestion(),
3517                                },
3518                            });
3519                        }
3520                        Err(diag) => {
3521                            diag.cancel();
3522                            this.restore_snapshot(snap);
3523                        }
3524                    }
3525                }
3526                eself_ident
3527            };
3528        // Recover for the grammar `*self`, `*const self`, and `*mut self`.
3529        let recover_self_ptr = |this: &mut Self| {
3530            this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3531
3532            Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3533        };
3534
3535        // Parse optional `self` parameter of a method.
3536        // Only a limited set of initial token sequences is considered `self` parameters; anything
3537        // else is parsed as a normal function parameter list, so some lookahead is required.
3538        let eself_lo = self.token.span;
3539        let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3540            token::And => {
3541                let has_lifetime = is_lifetime(self, 1);
3542                let skip_lifetime_count = has_lifetime as usize;
3543                let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3544                    // `&{'lt} self`
3545                    self.bump(); // &
3546                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3547                    SelfKind::Region(lifetime, Mutability::Not)
3548                } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3549                    // `&{'lt} mut self`
3550                    self.bump(); // &
3551                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3552                    self.bump(); // mut
3553                    SelfKind::Region(lifetime, Mutability::Mut)
3554                } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3555                    // `&{'lt} pin const self`
3556                    self.bump(); // &
3557                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3558                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3559                    self.bump(); // pin
3560                    self.bump(); // const
3561                    SelfKind::Pinned(lifetime, Mutability::Not)
3562                } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3563                    // `&{'lt} pin mut self`
3564                    self.bump(); // &
3565                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
3566                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3567                    self.bump(); // pin
3568                    self.bump(); // mut
3569                    SelfKind::Pinned(lifetime, Mutability::Mut)
3570                } else {
3571                    // `&not_self`
3572                    return Ok(None);
3573                };
3574                let hi = self.token.span;
3575                let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3576                (eself, self_ident, hi)
3577            }
3578            // `*self`
3579            token::Star if is_isolated_self(self, 1) => {
3580                self.bump();
3581                recover_self_ptr(self)?
3582            }
3583            // `*mut self` and `*const self`
3584            token::Star
3585                if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3586            {
3587                self.bump();
3588                self.bump();
3589                recover_self_ptr(self)?
3590            }
3591            // `self` and `self: TYPE`
3592            token::Ident(..) if is_isolated_self(self, 0) => {
3593                parse_self_possibly_typed(self, Mutability::Not)?
3594            }
3595            // `mut self` and `mut self: TYPE`
3596            token::Ident(..) if is_isolated_mut_self(self, 0) => {
3597                self.bump();
3598                parse_self_possibly_typed(self, Mutability::Mut)?
3599            }
3600            _ => return Ok(None),
3601        };
3602
3603        let eself = respan(eself_lo.to(eself_hi), eself);
3604        Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3605    }
3606
3607    fn is_named_param(&self) -> bool {
3608        let offset = match &self.token.kind {
3609            token::OpenInvisible(origin) => match origin {
3610                InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3611                    return self.check_noexpect_past_close_delim(&token::Colon);
3612                }
3613                _ => 0,
3614            },
3615            token::And | token::AndAnd => 1,
3616            _ if self.token.is_keyword(kw::Mut) => 1,
3617            _ => 0,
3618        };
3619
3620        self.look_ahead(offset, |t| t.is_ident())
3621            && self.look_ahead(offset + 1, |t| t == &token::Colon)
3622    }
3623
3624    fn recover_self_param(&mut self) -> bool {
3625        #[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!(
3626            self.parse_outer_attributes()
3627                .and_then(|_| self.parse_self_param())
3628                .map_err(|e| e.cancel()),
3629            Ok(Some(_))
3630        )
3631    }
3632
3633    /// Try to recover from over-parsing in const item when a semicolon is missing.
3634    ///
3635    /// This detects cases where we parsed too much because a semicolon was missing
3636    /// and the next line started an expression that the parser treated as a continuation
3637    /// (e.g., `foo() \n &bar` was parsed as `foo() & bar`).
3638    ///
3639    /// Returns a corrected expression if recovery is successful.
3640    fn try_recover_const_missing_semi(
3641        &mut self,
3642        rhs: &ConstItemRhsKind,
3643        const_span: Span,
3644    ) -> Option<Box<Expr>> {
3645        if self.token == TokenKind::Semi {
3646            return None;
3647        }
3648        let ConstItemRhsKind::Body { rhs: Some(rhs) } = rhs else {
3649            return None;
3650        };
3651        if !self.in_fn_body || !self.may_recover() || rhs.span.from_expansion() {
3652            return None;
3653        }
3654        if let Some((span, guar)) =
3655            self.missing_semi_from_binop("const", rhs, Some(const_span.shrink_to_lo()))
3656        {
3657            self.fn_body_missing_semi_guar = Some(guar);
3658            Some(self.mk_expr(span, ExprKind::Err(guar)))
3659        } else {
3660            None
3661        }
3662    }
3663}
3664
3665enum IsMacroRulesItem {
3666    Yes { has_bang: bool },
3667    No,
3668}
3669
3670#[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)]
3671pub(super) enum FrontMatterParsingMode {
3672    /// Parse the front matter of a function declaration
3673    Function,
3674    /// Parse the front matter of a function pointet type.
3675    /// For function pointer types, the `const` and `async` keywords are not permitted.
3676    FunctionPtrType,
3677}