Skip to main content

rustc_parse/parser/
item.rs

1use std::fmt::Write;
2use std::mem;
3
4use ast::token::IdentKind;
5use rustc_ast as ast;
6use rustc_ast::ast::*;
7use rustc_ast::token::{self, Delimiter, 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_span::edit_distance::edit_distance;
14use rustc_span::edition::Edition;
15use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
16use thin_vec::{ThinVec, thin_vec};
17use tracing::debug;
18
19use super::diagnostics::ConsumeClosingDelim;
20use super::{
21    AllowConstBlockItems, AttrWrapper, ExpTokenPair, FnContext, FnParseMode, FollowedByType,
22    ForceCollect, IsDotDotDot, Parser, PathStyle, Recovered, Trailing, UsePreAttrPos,
23};
24use crate::diagnostics::{
25    self, MacroExpandsToAdtField, UseDoubleColonSuggestion, UseRegularStructSuggestion,
26};
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.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 = FnParseMode {
130            req_name: |_, _| true,
131            context: FnContext::Free,
132            req_body: true,
133            allow_const_params: true,
134        };
135        self.parse_item_(fn_parse_mode, force_collect, allow_const_block_items)
136            .map(|i| i.map(Box::new))
137    }
138
139    fn parse_item_(
140        &mut self,
141        fn_parse_mode: FnParseMode,
142        force_collect: ForceCollect,
143        const_block_items_allowed: AllowConstBlockItems,
144    ) -> PResult<'a, Option<Item>> {
145        self.recover_vcs_conflict_marker();
146        let attrs = self.parse_outer_attributes()?;
147        self.recover_vcs_conflict_marker();
148        self.parse_item_common(
149            attrs,
150            true,
151            false,
152            fn_parse_mode,
153            force_collect,
154            const_block_items_allowed,
155        )
156    }
157
158    pub(super) fn parse_item_common(
159        &mut self,
160        attrs: AttrWrapper,
161        mac_allowed: bool,
162        attrs_allowed: bool,
163        fn_parse_mode: FnParseMode,
164        force_collect: ForceCollect,
165        allow_const_block_items: AllowConstBlockItems,
166    ) -> PResult<'a, Option<Item>> {
167        if let Some(item) = self.eat_metavar_seq(MetaVarKind::Item, |this| {
168            this.parse_item(ForceCollect::Yes, allow_const_block_items)
169        }) {
170            let mut item = item.expect("an actual item");
171            attrs.prepend_to_nt_inner(&mut item.attrs);
172            return Ok(Some(*item));
173        }
174
175        self.collect_tokens(None, attrs, force_collect, |this, mut attrs| {
176            let lo = this.token.span;
177            let vis = this.parse_visibility(FollowedByType::No)?;
178            let mut def = this.parse_defaultness();
179            let kind = this.parse_item_kind(
180                &mut attrs,
181                mac_allowed,
182                allow_const_block_items,
183                lo,
184                &vis,
185                &mut def,
186                fn_parse_mode,
187                Case::Sensitive,
188            )?;
189            if let Some(kind) = kind {
190                this.error_on_unconsumed_default(def, &kind);
191                let span = lo.to(this.prev_token.span);
192                let id = DUMMY_NODE_ID;
193                let item = Item { attrs, id, kind, vis, span, tokens: None };
194                return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
195            }
196
197            // At this point, we have failed to parse an item.
198            if !#[allow(non_exhaustive_omitted_patterns)] match vis.kind {
    VisibilityKind::Inherited => true,
    _ => false,
}matches!(vis.kind, VisibilityKind::Inherited) {
199                let vis_str = pprust::vis_to_string(&vis).trim_end().to_string();
200                let mut err = this.dcx().create_err(diagnostics::VisibilityNotFollowedByItem {
201                    span: vis.span,
202                    vis: vis_str,
203                });
204                if let Some((ident, _)) = this.token.ident()
205                    && !ident.is_used_keyword()
206                    && let Some((similar_kw, is_incorrect_case)) = ident
207                        .name
208                        .find_similar(&rustc_span::symbol::used_keywords(|| ident.span.edition()))
209                {
210                    err.subdiagnostic(diagnostics::MisspelledKw {
211                        similar_kw: similar_kw.to_string(),
212                        span: ident.span,
213                        is_incorrect_case,
214                    });
215                }
216                err.emit();
217            }
218
219            if let Defaultness::Default(span) = def {
220                this.dcx().emit_err(diagnostics::DefaultNotFollowedByItem { span });
221            } else if let Defaultness::Final(span) = def {
222                this.dcx().emit_err(diagnostics::FinalNotFollowedByItem { span });
223            }
224
225            if !attrs_allowed {
226                this.recover_attrs_no_item(&attrs)?;
227            }
228            Ok((None, Trailing::No, UsePreAttrPos::No))
229        })
230    }
231
232    /// Error in-case `default`/`final` was parsed in an in-appropriate context.
233    fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
234        match def {
235            Defaultness::Default(span) => {
236                self.dcx().emit_err(diagnostics::InappropriateDefault {
237                    span,
238                    article: kind.article(),
239                    descr: kind.descr(),
240                });
241            }
242            Defaultness::Final(span) => {
243                self.dcx().emit_err(diagnostics::InappropriateFinal {
244                    span,
245                    article: kind.article(),
246                    descr: kind.descr(),
247                });
248            }
249            Defaultness::Implicit => (),
250        }
251    }
252
253    /// Parses one of the items allowed by the flags.
254    fn parse_item_kind(
255        &mut self,
256        attrs: &mut AttrVec,
257        macros_allowed: bool,
258        allow_const_block_items: AllowConstBlockItems,
259        lo: Span,
260        vis: &Visibility,
261        def: &mut Defaultness,
262        fn_parse_mode: FnParseMode,
263        case: Case,
264    ) -> PResult<'a, Option<ItemKind>> {
265        let check_pub = def == &Defaultness::Implicit;
266        let mut def_ = || mem::replace(def, Defaultness::Implicit);
267
268        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) {
269            self.parse_use_item()?
270        } else if self.check_fn_front_matter(check_pub, case) {
271            // FUNCTION ITEM
272            let defaultness = def_();
273            if let Defaultness::Default(span) = defaultness {
274                // Default functions should only require feature `min_specialization`. We remove the
275                // `specialization` tag again as such spans *require* feature `specialization` to be
276                // enabled. In a later stage, we make `specialization` imply `min_specialization`.
277                self.psess.gated_spans.gate(sym::min_specialization, span);
278                self.psess.gated_spans.ungate_last(sym::specialization, span);
279            }
280            let (ident, sig, generics, contract, body) =
281                self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
282            ItemKind::Fn(Box::new(Fn {
283                defaultness,
284                ident,
285                sig,
286                generics,
287                contract,
288                body,
289                define_opaque: None,
290                eii_impl: None,
291            }))
292        } 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) {
293            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) {
294                // EXTERN CRATE
295                self.parse_item_extern_crate()?
296            } else {
297                // EXTERN BLOCK
298                self.parse_item_foreign_mod(attrs, Safety::Default)?
299            }
300        } else if self.is_unsafe_foreign_mod() {
301            // EXTERN BLOCK
302            let safety = self.parse_safety(Case::Sensitive);
303            self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Extern,
    token_type: crate::parser::token_type::TokenType::KwExtern,
}exp!(Extern))?;
304            self.parse_item_foreign_mod(attrs, safety)?
305        } else if let Some(safety) = self.parse_global_static_front_matter(case) {
306            // STATIC ITEM
307            let mutability = self.parse_mutability();
308            self.parse_static_item(safety, mutability)?
309        } 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() {
310            // TRAIT ITEM
311            self.parse_item_trait(attrs, lo)?
312        } else if self.check_impl_frontmatter(0) {
313            // IMPL ITEM
314            self.parse_item_impl(attrs, def_(), false)?
315        } else if let AllowConstBlockItems::Yes | AllowConstBlockItems::DoesNotMatter =
316            allow_const_block_items
317            && self.check_inline_const(0)
318        {
319            // CONST BLOCK ITEM
320            if let AllowConstBlockItems::DoesNotMatter = allow_const_block_items {
321                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/bbcdfd90a3f81ca2a5f6d69b943a6ff0d8582102/compiler/rustc_parse/src/parser/item.rs:321",
                        "rustc_parse::parser::item", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/bbcdfd90a3f81ca2a5f6d69b943a6ff0d8582102/compiler/rustc_parse/src/parser/item.rs"),
                        ::tracing_core::__macro_support::Option::Some(321u32),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Parsing a const block item that does not matter: {0:?}",
                                                    self.token.span) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("Parsing a const block item that does not matter: {:?}", self.token.span);
322            };
323            ItemKind::ConstBlock(self.parse_const_block_item()?)
324        } else if let Const::Yes(const_span) = self.parse_constness(case) {
325            // CONST ITEM
326            self.recover_const_mut(const_span);
327            self.recover_missing_kw_before_item()?;
328            let (ident, generics, ty, body) = self.parse_const_item(const_span)?;
329            ItemKind::Const(Box::new(ConstItem {
330                defaultness: def_(),
331                ident,
332                generics,
333                ty,
334                body,
335                define_opaque: None,
336            }))
337        } else if let Some(kind) = self.is_reuse_item() {
338            self.parse_item_delegation(attrs, def_(), kind)?
339        } 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)
340            || 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])
341        {
342            // MODULE ITEM
343            self.parse_item_mod(attrs)?
344        } 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) {
345            // TYPE ITEM
346            self.parse_type_alias(def_())?
347        } 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) {
348            // ENUM ITEM
349            self.parse_item_enum()?
350        } 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) {
351            // STRUCT ITEM
352            self.parse_item_struct()?
353        } else if self.is_kw_followed_by_ident(kw::Union) {
354            // UNION ITEM
355            self.bump(); // `union`
356            self.parse_item_union()?
357        } 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) {
358            // MACROS 2.0 ITEM
359            self.parse_item_decl_macro(lo)?
360        } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
361            // MACRO_RULES ITEM
362            self.parse_item_macro_rules(vis, has_bang)?
363        } else if self.isnt_macro_invocation()
364            && (self.token.is_ident_named(sym::import)
365                || self.token.is_ident_named(sym::using)
366                || self.token.is_ident_named(sym::include)
367                || self.token.is_ident_named(sym::require))
368        {
369            return self.recover_import_as_use();
370        } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
371            self.recover_missing_kw_before_item()?;
372            return Ok(None);
373        } else if self.isnt_macro_invocation() && case == Case::Sensitive {
374            _ = def_;
375
376            // Recover wrong cased keywords
377            return self.parse_item_kind(
378                attrs,
379                macros_allowed,
380                allow_const_block_items,
381                lo,
382                vis,
383                def,
384                fn_parse_mode,
385                Case::Insensitive,
386            );
387        } else if macros_allowed && self.check_path() {
388            // Detect `field_name: Type` or `self: Type` inside a trait body and emit
389            // a clearer diagnostic before falling through to the macro invocation path.
390            let is_field_in_trait = fn_parse_mode.context == FnContext::Trait
391                && self.token.is_path_start()
392                && self.look_ahead(1, |t| t.kind == token::Colon);
393            if is_field_in_trait {
394                return self.recover_field_in_trait();
395            }
396            if self.isnt_macro_invocation() {
397                self.recover_missing_kw_before_item()?;
398            }
399            // MACRO INVOCATION ITEM
400            ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
401        } else {
402            return Ok(None);
403        };
404        Ok(Some(info))
405    }
406
407    fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
408        let span = self.token.span;
409        let token_name = super::token_descr(&self.token);
410        let snapshot = self.create_snapshot_for_diagnostic();
411        self.bump();
412        match self.parse_use_item() {
413            Ok(u) => {
414                self.dcx().emit_err(diagnostics::RecoverImportAsUse { span, token_name });
415                Ok(Some(u))
416            }
417            Err(e) => {
418                e.cancel();
419                self.restore_snapshot(snapshot);
420                Ok(None)
421            }
422        }
423    }
424
425    fn recover_field_in_trait(&mut self) -> PResult<'a, Option<ItemKind>> {
426        let ident_span = self.token.span;
427        let ident_str = pprust::token_to_string(&self.token).into_owned();
428        let is_self = self.token.is_keyword(kw::SelfLower);
429
430        self.bump(); // identifier or `self`
431        self.bump(); // `:`
432
433        let ty_str = match self.parse_ty() {
434            Ok(ty) => pprust::ty_to_string(&ty),
435            Err(e) => {
436                e.cancel();
437                String::from("Type")
438            }
439        };
440        // Eat the trailing separator so the parser doesn't trip over it.
441        let _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
442        let _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi));
443
444        let span = ident_span.to(self.prev_token.span);
445        let sugg = if is_self {
446            diagnostics::FieldNotAllowedInTraitSugg::SelfReceiver { ty: ty_str }
447        } else {
448            diagnostics::FieldNotAllowedInTraitSugg::Method { ident: ident_str, ty: ty_str }
449        };
450        let err = self.dcx().create_err(diagnostics::FieldNotAllowedInTrait { span, sugg });
451        Err(err)
452    }
453
454    fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
455        let use_token_span = self.prev_token.span;
456        let tree = self.parse_use_tree(use_token_span, None)?;
457        if let Err(mut e) = self.expect_semi() {
458            match tree.kind {
459                UseTreeKind::Glob(_) => {
460                    e.note("the wildcard token must be last on the path");
461                }
462                UseTreeKind::Nested { .. } => {
463                    e.note("glob-like brace syntax must be last on the path");
464                }
465                _ => (),
466            }
467            return Err(e);
468        }
469        Ok(ItemKind::Use(tree))
470    }
471
472    /// When parsing a statement, would the start of a path be an item?
473    pub(super) fn is_path_start_item(&mut self) -> bool {
474        self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }`
475        || self.is_reuse_item().is_some() // yes: `reuse impl Trait for Struct { self.0 }`, yes: `reuse some_path::foo;`
476        || self.check_trait_front_matter() // no: `auto::b`, yes: `auto trait X { .. }`
477        || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
478        || #[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`
479    }
480
481    fn is_reuse_item(&mut self) -> Option<ReuseKind> {
482        if !self.token.is_keyword(kw::Reuse) {
483            return None;
484        }
485
486        // no: `reuse ::path` for compatibility reasons with macro invocations
487        if self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep) {
488            Some(ReuseKind::Path)
489        } else if self.check_impl_frontmatter(1) {
490            Some(ReuseKind::Impl)
491        } else {
492            None
493        }
494    }
495
496    /// Are we sure this could not possibly be a macro invocation?
497    fn isnt_macro_invocation(&mut self) -> bool {
498        self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
499    }
500
501    /// Recover on encountering a struct, enum, or method definition where the user
502    /// forgot to add the `struct`, `enum`, or `fn` keyword
503    fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
504        let is_pub = self.prev_token.is_keyword(kw::Pub);
505        let is_const = self.prev_token.is_keyword(kw::Const);
506        let ident_span = self.token.span;
507        let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
508        let insert_span = ident_span.shrink_to_lo();
509
510        let ident = if self.token.is_ident()
511            && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
512            && self.look_ahead(1, |t| {
513                #[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)
514            }) {
515            self.parse_ident_common(true).unwrap()
516        } else {
517            return Ok(());
518        };
519
520        let mut found_generics = false;
521        if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Lt,
    token_type: crate::parser::token_type::TokenType::Lt,
}exp!(Lt)) {
522            found_generics = true;
523            self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Gt,
    token_type: crate::parser::token_type::TokenType::Gt,
}exp!(Gt)]);
524            self.bump(); // `>`
525        }
526
527        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)) {
528            // possible struct or enum definition where `struct` or `enum` was forgotten
529            if self.look_ahead(1, |t| *t == token::CloseBrace) {
530                // `S {}` could be unit enum or struct
531                Some(diagnostics::MissingKeywordForItemDefinition::EnumOrStruct { span })
532            } else if self.look_ahead(2, |t| *t == token::Colon)
533                || self.look_ahead(3, |t| *t == token::Colon)
534            {
535                // `S { f:` or `S { pub f:`
536                Some(diagnostics::MissingKeywordForItemDefinition::Struct {
537                    span,
538                    insert_span,
539                    ident,
540                })
541            } else {
542                Some(diagnostics::MissingKeywordForItemDefinition::Enum {
543                    span,
544                    insert_span,
545                    ident,
546                })
547            }
548        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
549            // possible function or tuple struct definition where `fn` or `struct` was forgotten
550            self.bump(); // `(`
551            let is_method = self.recover_self_param();
552
553            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);
554
555            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)) {
556                self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)]);
557                self.bump(); // `{`
558                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);
559                if is_method {
560                    diagnostics::MissingKeywordForItemDefinition::Method {
561                        span,
562                        insert_span,
563                        ident,
564                    }
565                } else {
566                    diagnostics::MissingKeywordForItemDefinition::Function {
567                        span,
568                        insert_span,
569                        ident,
570                    }
571                }
572            } 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)) {
573                diagnostics::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
574            } else {
575                diagnostics::MissingKeywordForItemDefinition::Ambiguous {
576                    span,
577                    subdiag: if found_generics {
578                        None
579                    } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
580                        Some(diagnostics::AmbiguousMissingKwForItemSub::SuggestMacro {
581                            span: ident_span,
582                            snippet,
583                        })
584                    } else {
585                        Some(diagnostics::AmbiguousMissingKwForItemSub::HelpMacro)
586                    },
587                }
588            };
589            Some(err)
590        } else if found_generics {
591            Some(diagnostics::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
592        } else {
593            None
594        };
595
596        if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
597    }
598
599    /// Parses an item macro, e.g., `item!();`.
600    fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
601        let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
602        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))?; // `!`
603        match self.parse_delim_args() {
604            // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
605            Ok(args) => {
606                self.eat_semi_for_macro_if_needed(&args, Some(&path));
607                self.complain_if_pub_macro(vis, false);
608                Ok(MacCall { path, args })
609            }
610
611            Err(mut err) => {
612                // Maybe the user misspelled `macro_rules` (issue #91227)
613                if self.token.is_ident()
614                    && let [segment] = path.segments.as_slice()
615                    && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
616                {
617                    err.span_suggestion_verbose(
618                        path.span,
619                        "perhaps you meant to define a macro",
620                        "macro_rules",
621                        Applicability::MachineApplicable,
622                    );
623                }
624                Err(err)
625            }
626        }
627    }
628
629    /// Recover if we parsed attributes and expected an item but there was none.
630    fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
631        let ([start @ end] | [start, .., end]) = attrs else {
632            return Ok(());
633        };
634        let msg = if end.is_doc_comment() {
635            "expected item after doc comment"
636        } else {
637            "expected item after attributes"
638        };
639        let mut err = self.dcx().struct_span_err(end.span, msg);
640        if end.is_doc_comment() {
641            err.span_label(end.span, "this doc comment doesn't document anything");
642        } else {
643            err.span_label(end.span, "expected an item after this");
644            if self.token == TokenKind::Semi {
645                err.span_suggestion_verbose(
646                    self.token.span,
647                    "remove the semicolon after the attribute",
648                    "",
649                    Applicability::MaybeIncorrect,
650                );
651            }
652        }
653        if let [.., penultimate, _] = attrs {
654            err.span_label(start.span.to(penultimate.span), "other attributes here");
655        }
656        Err(err)
657    }
658
659    fn is_async_fn(&self) -> bool {
660        self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
661    }
662
663    fn parse_polarity(&mut self) -> ast::ImplPolarity {
664        // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
665        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()) {
666            self.psess.gated_spans.gate(sym::negative_impls, self.token.span);
667            self.bump(); // `!`
668            ast::ImplPolarity::Negative(self.prev_token.span)
669        } else {
670            ast::ImplPolarity::Positive
671        }
672    }
673
674    /// Parses an implementation item.
675    ///
676    /// ```ignore (illustrative)
677    /// impl<'a, T> TYPE { /* impl items */ }
678    /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
679    /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
680    /// impl<'a, T> const TRAIT for TYPE { /* impl items */ }
681    /// ```
682    ///
683    /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
684    /// ```ebnf
685    /// "impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
686    /// "impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
687    /// ```
688    fn parse_item_impl(
689        &mut self,
690        attrs: &mut AttrVec,
691        defaultness: Defaultness,
692        is_reuse: bool,
693    ) -> PResult<'a, ItemKind> {
694        let constness = self.parse_constness(Case::Sensitive);
695        let safety = self.parse_safety(Case::Sensitive);
696        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Impl,
    token_type: crate::parser::token_type::TokenType::KwImpl,
}exp!(Impl))?;
697        let mut generics_snapshot = None;
698        // First, parse generic parameters if necessary.
699        let mut generics = if self.choose_generics_over_qpath(0) {
700            self.parse_generics()?
701        } else {
702            // We might be mistakenly trying to use a generic type as a generic parameter.
703            // impl<X<T>> Trait for Y<T> { ... }
704            if self.look_ahead(0, |t| t == &token::Lt)
705                && self.look_ahead(1, |t| t.is_ident())
706                && self.look_ahead(2, |t| t == &token::Lt)
707            {
708                generics_snapshot = Some(self.create_snapshot_for_diagnostic());
709            }
710
711            let mut generics = Generics::default();
712            // impl A for B {}
713            //    /\ this is where `generics.span` should point when there are no type params.
714            generics.span = self.prev_token.span.shrink_to_hi();
715            generics
716        };
717
718        if let Const::Yes(span) = constness {
719            self.psess.gated_spans.gate(sym::const_trait_impl, span);
720        }
721
722        // Parse stray `impl async Trait`
723        if (self.token_uninterpolated_span().at_least_rust_2018()
724            && self.token.is_keyword(kw::Async))
725            || self.is_kw_followed_by_ident(kw::Async)
726        {
727            self.bump();
728            self.dcx().emit_err(diagnostics::AsyncImpl { span: self.prev_token.span });
729        }
730
731        let polarity = self.parse_polarity();
732
733        // Parse both types and traits as a type, then reinterpret if necessary.
734        let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
735        {
736            let span = self.prev_token.span.between(self.token.span);
737            return Err(self.dcx().create_err(diagnostics::MissingTraitInTraitImpl {
738                span,
739                for_span: span.to(self.token.span),
740            }));
741        } else {
742            self.parse_ty_with_generics_recovery(&generics).map_err(|e| {
743                let Some(mut snapshot) = generics_snapshot else {
744                    return e;
745                };
746                snapshot.maybe_type_in_generic_parameter(e)
747            })?
748        };
749        // If `for` is missing we try to recover.
750        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));
751        let missing_for_span = self.prev_token.span.between(self.token.span);
752
753        let ty_second = if self.token == token::DotDot {
754            // We need to report this error after `cfg` expansion for compatibility reasons
755            self.bump(); // `..`, do not add it to expected tokens
756
757            // AST validation later detects this `TyKind::Dummy` and emits an
758            // error. (#121072 will hopefully remove all this special handling
759            // of the obsolete `impl Trait for ..` and then this can go away.)
760            Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
761        } else if has_for || self.token.can_begin_type() {
762            Some(self.parse_ty()?)
763        } else {
764            None
765        };
766
767        generics.where_clause = self.parse_where_clause()?;
768
769        let impl_items = if is_reuse {
770            Default::default()
771        } else {
772            self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?
773        };
774
775        let (of_trait, self_ty) = match ty_second {
776            Some(ty_second) => {
777                // impl Trait for Type
778                if !has_for {
779                    self.dcx()
780                        .emit_err(diagnostics::MissingForInTraitImpl { span: missing_for_span });
781                }
782
783                let ty_first = *ty_first;
784                let path = match ty_first.kind {
785                    // This notably includes paths passed through `ty` macro fragments (#46438).
786                    TyKind::Path(None, path) => path,
787                    other => {
788                        if let TyKind::ImplTrait(_, bounds) = other
789                            && let [bound] = bounds.as_slice()
790                            && let GenericBound::Trait(poly_trait_ref) = bound
791                        {
792                            // Suggest removing extra `impl` keyword:
793                            // `impl<T: Default> impl Default for Wrapper<T>`
794                            //                   ^^^^^
795                            let extra_impl_kw = ty_first.span.until(bound.span());
796                            self.dcx().emit_err(diagnostics::ExtraImplKeywordInTraitImpl {
797                                extra_impl_kw,
798                                impl_trait_span: ty_first.span,
799                            });
800                            poly_trait_ref.trait_ref.path.clone()
801                        } else {
802                            return Err(self.dcx().create_err(
803                                diagnostics::ExpectedTraitInTraitImplFoundType {
804                                    span: ty_first.span,
805                                },
806                            ));
807                        }
808                    }
809                };
810                let trait_ref = TraitRef { path, ref_id: ty_first.id };
811
812                let of_trait =
813                    Some(Box::new(TraitImplHeader { defaultness, safety, polarity, trait_ref }));
814                (of_trait, ty_second)
815            }
816            None => {
817                let self_ty = ty_first;
818                let error = |modifier, modifier_name, modifier_span| {
819                    self.dcx().create_err(diagnostics::TraitImplModifierInInherentImpl {
820                        span: self_ty.span,
821                        modifier,
822                        modifier_name,
823                        modifier_span,
824                        self_ty: self_ty.span,
825                    })
826                };
827
828                if let Safety::Unsafe(span) = safety {
829                    error("unsafe", "unsafe", span).with_code(E0197).emit();
830                }
831                if let ImplPolarity::Negative(span) = polarity {
832                    error("!", "negative", span).emit();
833                }
834                if let Defaultness::Default(def_span) = defaultness {
835                    error("default", "default", def_span).emit();
836                }
837                if let Const::Yes(span) = constness {
838                    self.psess.gated_spans.gate(sym::const_trait_impl, span);
839                }
840                (None, self_ty)
841            }
842        };
843
844        Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items, constness }))
845    }
846
847    fn parse_item_delegation(
848        &mut self,
849        attrs: &mut AttrVec,
850        defaultness: Defaultness,
851        kind: ReuseKind,
852    ) -> PResult<'a, ItemKind> {
853        let span = self.token.span;
854        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Reuse,
    token_type: crate::parser::token_type::TokenType::KwReuse,
}exp!(Reuse))?;
855
856        let item_kind = match kind {
857            ReuseKind::Path => self.parse_path_like_delegation(),
858            ReuseKind::Impl => self.parse_impl_delegation(span, attrs, defaultness),
859        }?;
860
861        self.psess.gated_spans.gate(sym::fn_delegation, span.to(self.prev_token.span));
862
863        Ok(item_kind)
864    }
865
866    fn parse_delegation_body(&mut self) -> PResult<'a, Option<Box<Block>>> {
867        Ok(if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
868            Some(self.parse_block()?)
869        } else {
870            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi))?;
871            None
872        })
873    }
874
875    fn parse_impl_delegation(
876        &mut self,
877        span: Span,
878        attrs: &mut AttrVec,
879        defaultness: Defaultness,
880    ) -> PResult<'a, ItemKind> {
881        let mut impl_item = self.parse_item_impl(attrs, defaultness, true)?;
882        let ItemKind::Impl(Impl { items, of_trait, .. }) = &mut impl_item else { ::core::panicking::unreachable_default_msg()unreachable!() };
883
884        let until_expr_span = span.to(self.prev_token.span);
885
886        let Some(of_trait) = of_trait else {
887            return Err(self
888                .dcx()
889                .create_err(diagnostics::ImplReuseInherentImpl { span: until_expr_span }));
890        };
891
892        let body = self.parse_delegation_body()?;
893        let whole_reuse_span = span.to(self.prev_token.span);
894
895        items.push(Box::new(AssocItem {
896            id: DUMMY_NODE_ID,
897            attrs: Default::default(),
898            span: whole_reuse_span,
899            tokens: None,
900            vis: Visibility { kind: VisibilityKind::Inherited, span: whole_reuse_span },
901            kind: AssocItemKind::DelegationMac(Box::new(DelegationMac {
902                qself: None,
903                prefix: of_trait.trait_ref.path.clone(),
904                suffixes: DelegationSuffixes::Glob(whole_reuse_span),
905                body,
906            })),
907        }));
908
909        Ok(impl_item)
910    }
911
912    fn parse_path_like_delegation(&mut self) -> PResult<'a, ItemKind> {
913        let (qself, path) = if self.eat_lt() {
914            let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
915            (Some(qself), path)
916        } else {
917            (None, self.parse_path(PathStyle::Expr)?)
918        };
919
920        let rename = |this: &mut Self| {
921            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 })
922        };
923
924        Ok(if self.eat_path_sep() {
925            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)) {
926                DelegationSuffixes::Glob(self.prev_token.span)
927            } else {
928                let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
929                DelegationSuffixes::List(
930                    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,
931                )
932            };
933
934            ItemKind::DelegationMac(Box::new(DelegationMac {
935                qself,
936                prefix: path,
937                suffixes,
938                body: self.parse_delegation_body()?,
939            }))
940        } else {
941            let rename = rename(self)?;
942            let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
943
944            ItemKind::Delegation(Box::new(Delegation {
945                id: DUMMY_NODE_ID,
946                qself,
947                path,
948                ident,
949                rename,
950                body: self.parse_delegation_body()?,
951                source: DelegationSource::Single,
952            }))
953        })
954    }
955
956    fn parse_item_list<T>(
957        &mut self,
958        attrs: &mut AttrVec,
959        mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
960    ) -> PResult<'a, ThinVec<T>> {
961        let open_brace_span = self.token.span;
962
963        // Recover `impl Ty;` instead of `impl Ty {}`
964        if self.token == TokenKind::Semi {
965            self.dcx().emit_err(diagnostics::UseEmptyBlockNotSemi { span: self.token.span });
966            self.bump();
967            return Ok(ThinVec::new());
968        }
969
970        self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace))?;
971        attrs.extend(self.parse_inner_attributes()?);
972
973        let mut items = ThinVec::new();
974        while !self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)) {
975            if self.recover_doc_comment_before_brace() {
976                continue;
977            }
978            self.recover_vcs_conflict_marker();
979            match parse_item(self) {
980                Ok(None) => {
981                    let mut is_unnecessary_semicolon = (self.token == token::Semi
982                        && self.prev_token == token::Semi)
983                        || !items.is_empty()
984                        // When the close delim is `)` in a case like the following, `token.kind`
985                        // is expected to be `token::CloseParen`, but the actual `token.kind` is
986                        // `token::CloseBrace`. This is because the `token.kind` of the close delim
987                        // is treated as the same as that of the open delim in
988                        // `TokenTreesReader::parse_token_tree`, even if the delimiters of them are
989                        // different. Therefore, `token.kind` should not be compared here.
990                        //
991                        // issue-60075.rs
992                        // ```
993                        // trait T {
994                        //     fn qux() -> Option<usize> {
995                        //         let _ = if true {
996                        //         });
997                        //          ^ this close delim
998                        //         Some(4)
999                        //     }
1000                        // ```
1001                        && self
1002                            .span_to_snippet(self.prev_token.span)
1003                            .is_ok_and(|snippet| snippet == "}")
1004                        && self.token == token::Semi;
1005                    let mut semicolon_span = self.token.span;
1006                    if !is_unnecessary_semicolon {
1007                        // #105369, Detect spurious `;` before assoc fn body
1008                        is_unnecessary_semicolon =
1009                            self.token == token::OpenBrace && self.prev_token == token::Semi;
1010                        semicolon_span = self.prev_token.span;
1011                    }
1012                    // We have to bail or we'll potentially never make progress.
1013                    let non_item_span = self.token.span;
1014                    let is_let = self.token.is_keyword(kw::Let);
1015
1016                    let mut err =
1017                        self.dcx().struct_span_err(non_item_span, "non-item in item list");
1018                    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);
1019                    if is_let {
1020                        err.span_suggestion_verbose(
1021                            non_item_span,
1022                            "consider using `const` instead of `let` for associated const",
1023                            "const",
1024                            Applicability::MachineApplicable,
1025                        );
1026                    } else {
1027                        err.span_label(open_brace_span, "item list starts here")
1028                            .span_label(non_item_span, "non-item starts here")
1029                            .span_label(self.prev_token.span, "item list ends here");
1030                    }
1031                    if is_unnecessary_semicolon {
1032                        err.span_suggestion_verbose(
1033                            semicolon_span,
1034                            "consider removing this semicolon",
1035                            "",
1036                            Applicability::MaybeIncorrect,
1037                        );
1038                    }
1039                    err.emit();
1040                    break;
1041                }
1042                Ok(Some(item)) => items.extend(item),
1043                Err(err) => {
1044                    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);
1045                    err.with_span_label(
1046                        open_brace_span,
1047                        "while parsing this item list starting here",
1048                    )
1049                    .with_span_label(self.prev_token.span, "the item list ends here")
1050                    .emit();
1051                    break;
1052                }
1053            }
1054        }
1055        Ok(items)
1056    }
1057
1058    /// Recover on a doc comment before `}`.
1059    fn recover_doc_comment_before_brace(&mut self) -> bool {
1060        if let token::DocComment(..) = self.token.kind {
1061            if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
1062                // FIXME: merge with `DocCommentDoesNotDocumentAnything` (E0585)
1063                {
    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!(
1064                    self.dcx(),
1065                    self.token.span,
1066                    E0584,
1067                    "found a documentation comment that doesn't document anything",
1068                )
1069                .with_span_label(self.token.span, "this doc comment doesn't document anything")
1070                .with_help(
1071                    "doc comments must come before what they document, if a comment was \
1072                    intended use `//`",
1073                )
1074                .emit();
1075                self.bump();
1076                return true;
1077            }
1078        }
1079        false
1080    }
1081
1082    /// Parses defaultness (i.e., `default` or nothing).
1083    fn parse_defaultness(&mut self) -> Defaultness {
1084        // We are interested in `default` followed by another identifier.
1085        // However, we must avoid keywords that occur as binary operators.
1086        // Currently, the only applicable keyword is `as` (`default as Ty`).
1087        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))
1088            && self.look_ahead(1, |t| t.non_raw_ident().is_some_and(|i| i.name != kw::As))
1089        {
1090            self.psess.gated_spans.gate(sym::specialization, self.token.span);
1091            self.bump(); // `default`
1092            Defaultness::Default(self.prev_token_uninterpolated_span())
1093        } 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)) {
1094            self.psess.gated_spans.gate(sym::final_associated_functions, self.prev_token.span);
1095            Defaultness::Final(self.prev_token_uninterpolated_span())
1096        } else {
1097            Defaultness::Implicit
1098        }
1099    }
1100
1101    /// Is this an `[impl(in? path)]? const? unsafe? auto? trait` item?
1102    fn check_trait_front_matter(&mut self) -> bool {
1103        const SUFFIXES: &[&[Symbol]] = &[
1104            &[kw::Trait],
1105            &[kw::Auto, kw::Trait],
1106            &[kw::Unsafe, kw::Trait],
1107            &[kw::Unsafe, kw::Auto, kw::Trait],
1108            &[kw::Const, kw::Trait],
1109            &[kw::Const, kw::Auto, kw::Trait],
1110            &[kw::Const, kw::Unsafe, kw::Trait],
1111            &[kw::Const, kw::Unsafe, kw::Auto, kw::Trait],
1112        ];
1113        // `impl(`
1114        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) {
1115            // `impl(in` unambiguously introduces an `impl` restriction
1116            if self.is_keyword_ahead(2, &[kw::In]) {
1117                return true;
1118            }
1119            // `impl(crate | self | super)` + SUFFIX
1120            if self.is_keyword_ahead(2, &[kw::Crate, kw::SelfLower, kw::Super])
1121                && self.look_ahead(3, |t| t == &token::CloseParen)
1122                && SUFFIXES.iter().any(|suffix| {
1123                    suffix.iter().enumerate().all(|(i, kw)| self.is_keyword_ahead(i + 4, &[*kw]))
1124                })
1125            {
1126                return true;
1127            }
1128            // Recover cases like `impl(path::to::module)` + SUFFIX to suggest inserting `in`.
1129            SUFFIXES.iter().any(|suffix| {
1130                suffix.iter().enumerate().all(|(i, kw)| {
1131                    self.tree_look_ahead(i + 2, |t| {
1132                        if let TokenTree::Token(token, _) = t {
1133                            token.is_keyword(*kw)
1134                        } else {
1135                            false
1136                        }
1137                    })
1138                    .unwrap_or(false)
1139                })
1140            })
1141        } else {
1142            SUFFIXES.iter().any(|suffix| {
1143                suffix.iter().enumerate().all(|(i, kw)| {
1144                    // We use `check_keyword` for the first token to include it in the expected tokens.
1145                    if i == 0 {
1146                        match *kw {
1147                            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)),
1148                            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)),
1149                            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)),
1150                            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)),
1151                            _ => ::core::panicking::unreachable_default_msg()unreachable!(),
1152                        }
1153                    } else {
1154                        self.is_keyword_ahead(i, &[*kw])
1155                    }
1156                })
1157            })
1158        }
1159    }
1160
1161    /// Parses `[impl(in? path)]? const? unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
1162    fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
1163        let impl_restriction = self.parse_impl_restriction()?;
1164        let constness = self.parse_constness(Case::Sensitive);
1165        if let Const::Yes(span) = constness {
1166            self.psess.gated_spans.gate(sym::const_trait_impl, span);
1167        }
1168        let safety = self.parse_safety(Case::Sensitive);
1169        // Parse optional `auto` prefix.
1170        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)) {
1171            self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
1172            IsAuto::Yes
1173        } else {
1174            IsAuto::No
1175        };
1176
1177        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Trait,
    token_type: crate::parser::token_type::TokenType::KwTrait,
}exp!(Trait))?;
1178        let ident = self.parse_ident()?;
1179        let mut generics = self.parse_generics()?;
1180
1181        // Parse optional colon and supertrait bounds.
1182        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));
1183        let span_at_colon = self.prev_token.span;
1184        let bounds = if had_colon { self.parse_generic_bounds()? } else { ThinVec::new() };
1185
1186        let span_before_eq = self.prev_token.span;
1187        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) {
1188            // It's a trait alias.
1189            if had_colon {
1190                let span = span_at_colon.to(span_before_eq);
1191                self.dcx().emit_err(diagnostics::BoundsNotAllowedOnTraitAliases { span });
1192            }
1193
1194            let bounds = self.parse_generic_bounds()?;
1195            generics.where_clause = self.parse_where_clause()?;
1196            self.expect_semi()?;
1197
1198            let whole_span = lo.to(self.prev_token.span);
1199            if is_auto == IsAuto::Yes {
1200                self.dcx().emit_err(diagnostics::TraitAliasCannotBeAuto { span: whole_span });
1201            }
1202            if let Safety::Unsafe(_) = safety {
1203                self.dcx().emit_err(diagnostics::TraitAliasCannotBeUnsafe { span: whole_span });
1204            }
1205            if let RestrictionKind::Restricted { .. } = impl_restriction.kind {
1206                self.dcx()
1207                    .emit_err(diagnostics::TraitAliasCannotBeImplRestricted { span: whole_span });
1208            }
1209
1210            self.psess.gated_spans.gate(sym::trait_alias, whole_span);
1211
1212            Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
1213        } else {
1214            // It's a normal trait.
1215            generics.where_clause = self.parse_where_clause()?;
1216            let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
1217            Ok(ItemKind::Trait(Box::new(Trait {
1218                impl_restriction,
1219                constness,
1220                is_auto,
1221                safety,
1222                ident,
1223                generics,
1224                bounds,
1225                items,
1226            })))
1227        }
1228    }
1229
1230    pub fn parse_impl_item(
1231        &mut self,
1232        force_collect: ForceCollect,
1233    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1234        let fn_parse_mode = FnParseMode {
1235            req_name: |_, _| true,
1236            context: FnContext::Impl,
1237            req_body: true,
1238            allow_const_params: true,
1239        };
1240        self.parse_assoc_item(fn_parse_mode, force_collect)
1241    }
1242
1243    pub fn parse_trait_item(
1244        &mut self,
1245        force_collect: ForceCollect,
1246    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1247        let fn_parse_mode = FnParseMode {
1248            req_name: |edition, _| edition >= Edition::Edition2018,
1249            context: FnContext::Trait,
1250            req_body: false,
1251            allow_const_params: true,
1252        };
1253        self.parse_assoc_item(fn_parse_mode, force_collect)
1254    }
1255
1256    /// Parses associated items.
1257    fn parse_assoc_item(
1258        &mut self,
1259        fn_parse_mode: FnParseMode,
1260        force_collect: ForceCollect,
1261    ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1262        Ok(self
1263            .parse_item_(
1264                fn_parse_mode,
1265                force_collect,
1266                AllowConstBlockItems::DoesNotMatter, // due to `AssocItemKind::try_from` below
1267            )?
1268            .map(|Item { attrs, id, span, vis, kind, tokens }| {
1269                let kind = match AssocItemKind::try_from(kind) {
1270                    Ok(kind) => kind,
1271                    Err(kind) => match kind {
1272                        ItemKind::Static(StaticItem {
1273                            ident,
1274                            ty,
1275                            safety: _,
1276                            mutability: _,
1277                            expr,
1278                            define_opaque,
1279                            eii_impl: _,
1280                        }) => {
1281                            self.dcx()
1282                                .emit_err(diagnostics::AssociatedStaticItemNotAllowed { span });
1283                            AssocItemKind::Const(Box::new(ConstItem {
1284                                defaultness: Defaultness::Implicit,
1285                                ident,
1286                                generics: Generics::default(),
1287                                ty,
1288                                body: expr,
1289                                define_opaque,
1290                            }))
1291                        }
1292                        _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1293                    },
1294                };
1295                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1296            }))
1297    }
1298
1299    /// Parses a `type` alias with the following grammar:
1300    /// ```ebnf
1301    /// TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ;
1302    /// ```
1303    /// The `"type"` has already been eaten.
1304    fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1305        let ident = self.parse_ident()?;
1306        let mut generics = self.parse_generics()?;
1307
1308        // Parse optional colon and param bounds.
1309        let bounds =
1310            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 { ThinVec::new() };
1311        generics.where_clause = self.parse_where_clause()?;
1312
1313        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 };
1314
1315        let after_where_clause = self.parse_where_clause()?;
1316
1317        self.expect_semi()?;
1318
1319        Ok(ItemKind::TyAlias(Box::new(TyAlias {
1320            defaultness,
1321            ident,
1322            generics,
1323            after_where_clause,
1324            bounds,
1325            ty,
1326        })))
1327    }
1328
1329    /// Parses a `UseTree`.
1330    ///
1331    /// ```text
1332    /// USE_TREE = [`::`] `*` |
1333    ///            [`::`] `{` USE_TREE_LIST `}` |
1334    ///            PATH `::` `*` |
1335    ///            PATH `::` `{` USE_TREE_LIST `}` |
1336    ///            PATH [`as` IDENT]
1337    /// ```
1338    fn parse_use_tree<'b>(
1339        &mut self,
1340        use_token_span: Span,
1341        use_path: Option<&'b UsePathList<'b>>,
1342    ) -> PResult<'a, UseTree> {
1343        let lo = self.token.span;
1344
1345        let mut prefix = ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo() };
1346        let kind =
1347            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() {
1348                // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
1349                let mod_sep_ctxt = self.token.span.ctxt();
1350                if self.eat_path_sep() {
1351                    prefix
1352                        .segments
1353                        .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1354                }
1355
1356                self.parse_use_tree_glob_or_nested(use_token_span, use_path)?
1357            } else {
1358                // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
1359                prefix = self.parse_path(PathStyle::Mod)?;
1360
1361                if self.eat_path_sep() {
1362                    let use_path = UsePathList { elements: &prefix.segments, prev: use_path };
1363                    self.parse_use_tree_glob_or_nested(use_token_span, Some(&use_path))?
1364                } else {
1365                    // Recover from using a colon as path separator.
1366                    while self.eat_noexpect(&token::Colon) {
1367                        self.dcx().emit_err(diagnostics::SingleColonImportPath {
1368                            span: self.prev_token.span,
1369                        });
1370
1371                        // We parse the rest of the path and append it to the original prefix.
1372                        self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1373                        prefix.span = lo.to(self.prev_token.span);
1374                    }
1375
1376                    UseTreeKind::Simple(self.parse_rename()?)
1377                }
1378            };
1379
1380        Ok(UseTree { prefix, kind })
1381    }
1382
1383    /// Parses `*` or `{...}`.
1384    fn parse_use_tree_glob_or_nested<'b>(
1385        &mut self,
1386        use_token_span: Span,
1387        use_path: Option<&'b UsePathList<'b>>,
1388    ) -> PResult<'a, UseTreeKind> {
1389        Ok(if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Star,
    token_type: crate::parser::token_type::TokenType::Star,
}exp!(Star)) {
1390            UseTreeKind::Glob(self.prev_token.span)
1391        } else {
1392            let lo = self.token.span;
1393            UseTreeKind::Nested {
1394                items: self.parse_use_tree_list(use_token_span, use_path)?,
1395                span: lo.to(self.prev_token.span),
1396            }
1397        })
1398    }
1399
1400    /// Parses a `UseTreeKind::Nested(list)`.
1401    ///
1402    /// ```text
1403    /// USE_TREE_LIST = ∅ | (USE_TREE `,`)* USE_TREE [`,`]
1404    /// ```
1405    fn parse_use_tree_list<'b>(
1406        &mut self,
1407        use_token_span: Span,
1408        prefix: Option<&'b UsePathList<'b>>,
1409    ) -> PResult<'a, ThinVec<UseTreeAndId>> {
1410        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| {
1411            p.recover_vcs_conflict_marker();
1412
1413            let mut attr_span = None;
1414            let attrs = p.parse_outer_attributes()?;
1415            if !attrs.is_empty() {
1416                let raw_attrs = attrs.take_for_recovery(&p.psess);
1417                attr_span =
1418                    Some(raw_attrs.first().unwrap().span.to(raw_attrs.last().unwrap().span));
1419            }
1420
1421            let use_tree = p.parse_use_tree(use_token_span, prefix)?;
1422
1423            if let Some(attr_span) = attr_span {
1424                p.emit_error_attr_in_use_tree(use_token_span, prefix, use_tree.span(), attr_span);
1425            }
1426
1427            Ok(UseTreeAndId { inner: use_tree, id: DUMMY_NODE_ID })
1428        })
1429        .map(|(r, _)| r)
1430    }
1431
1432    fn emit_error_attr_in_use_tree(
1433        &self,
1434        use_token_span: Span,
1435        mut prefix: Option<&UsePathList<'_>>,
1436        use_tree_span: Span,
1437        attr_span: Span,
1438    ) {
1439        let Ok(attr) = self.psess.source_map().span_to_snippet(attr_span) else { return };
1440
1441        let prefix: Vec<_> = {
1442            let mut tmp = Vec::new();
1443            while let Some(prefix_) = prefix {
1444                tmp.push(prefix_.elements);
1445                prefix = prefix_.prev;
1446            }
1447            tmp.reverse();
1448            tmp.into_iter().flatten().collect()
1449        };
1450
1451        let prefix: String = prefix
1452            .iter()
1453            .map(|seg| if seg.ident.name == kw::PathRoot { "" } else { seg.ident.as_str() })
1454            .intersperse("::")
1455            .collect();
1456
1457        let mut comma_reached = false;
1458        let Ok(tree_span) = self.psess.source_map().span_extend_while(use_tree_span, |c| {
1459            if comma_reached {
1460                return false;
1461            }
1462            comma_reached = c == ',';
1463            c.is_whitespace() || comma_reached
1464        }) else {
1465            return;
1466        };
1467
1468        let Ok(use_tree) = self.psess.source_map().span_to_snippet(use_tree_span) else { return };
1469
1470        // FIXME: duplicate the attributes that are at the root of the initial use-item.
1471        let code = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}\nuse {1}::{2};\n", attr,
                prefix, use_tree))
    })format!("{attr}\nuse {prefix}::{use_tree};\n");
1472
1473        self.dcx().emit_err(crate::diagnostics::AttrInUseTree {
1474            attr_span,
1475            sub: Some(crate::diagnostics::AttrInUseTreeSugg {
1476                use_lo: use_token_span.shrink_to_lo(),
1477                attr_span,
1478                tree_span,
1479                code,
1480            }),
1481        });
1482    }
1483
1484    fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1485        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)) {
1486            self.parse_ident_or_underscore().map(Some)
1487        } else {
1488            Ok(None)
1489        }
1490    }
1491
1492    fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1493        if let Some(ident @ Ident { name: kw::Underscore, .. }) = self.token.non_raw_ident() {
1494            self.bump();
1495            Ok(ident)
1496        } else {
1497            self.parse_ident()
1498        }
1499    }
1500
1501    /// Parses `extern crate` links.
1502    ///
1503    /// # Examples
1504    ///
1505    /// ```ignore (illustrative)
1506    /// extern crate foo;
1507    /// extern crate bar as foo;
1508    /// ```
1509    fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1510        // Accept `extern crate name-like-this` for better diagnostics
1511        let orig_ident = self.parse_crate_name_with_dashes()?;
1512        let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1513            (Some(orig_ident.name), rename)
1514        } else {
1515            (None, orig_ident)
1516        };
1517        self.expect_semi()?;
1518        Ok(ItemKind::ExternCrate(orig_name, item_ident))
1519    }
1520
1521    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1522        let ident = if self.token.is_keyword(kw::SelfLower) {
1523            self.parse_path_segment_ident()
1524        } else {
1525            self.parse_ident()
1526        }?;
1527
1528        let dash = crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Minus,
    token_type: crate::parser::token_type::TokenType::Minus,
}exp!(Minus);
1529        if self.token != dash.tok {
1530            return Ok(ident);
1531        }
1532
1533        // Accept `extern crate name-like-this` for better diagnostics.
1534        let mut dashes = ::alloc::vec::Vec::new()vec![];
1535        let mut idents = ::alloc::vec::Vec::new()vec![];
1536        while self.eat(dash) {
1537            dashes.push(self.prev_token.span);
1538            idents.push(self.parse_ident()?);
1539        }
1540
1541        let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1542        let mut fixed_name = ident.name.to_string();
1543        for part in idents {
1544            fixed_name.write_fmt(format_args!("_{0}", part.name))write!(fixed_name, "_{}", part.name).unwrap();
1545        }
1546
1547        self.dcx().emit_err(diagnostics::ExternCrateNameWithDashes {
1548            span: fixed_name_sp,
1549            sugg: diagnostics::ExternCrateNameWithDashesSugg { dashes },
1550        });
1551
1552        Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1553    }
1554
1555    /// Parses `extern` for foreign ABIs modules.
1556    ///
1557    /// `extern` is expected to have been consumed before calling this method.
1558    ///
1559    /// # Examples
1560    ///
1561    /// ```ignore (only-for-syntax-highlight)
1562    /// extern "C" {}
1563    /// extern {}
1564    /// ```
1565    fn parse_item_foreign_mod(
1566        &mut self,
1567        attrs: &mut AttrVec,
1568        mut safety: Safety,
1569    ) -> PResult<'a, ItemKind> {
1570        let extern_span = self.prev_token_uninterpolated_span();
1571        let abi = self.parse_abi(); // ABI?
1572        // FIXME: This recovery should be tested better.
1573        if safety == Safety::Default
1574            && self.token.is_keyword(kw::Unsafe)
1575            && self.look_ahead(1, |t| *t == token::OpenBrace)
1576        {
1577            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();
1578            safety = Safety::Unsafe(self.token.span);
1579            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));
1580        }
1581        Ok(ItemKind::ForeignMod(ast::ForeignMod {
1582            extern_span,
1583            safety,
1584            abi,
1585            items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1586        }))
1587    }
1588
1589    /// Parses a foreign item (one in an `extern { ... }` block).
1590    pub fn parse_foreign_item(
1591        &mut self,
1592        force_collect: ForceCollect,
1593    ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
1594        let fn_parse_mode = FnParseMode {
1595            req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
1596            context: FnContext::Free,
1597            req_body: false,
1598            allow_const_params: false,
1599        };
1600        Ok(self
1601            .parse_item_(
1602                fn_parse_mode,
1603                force_collect,
1604                AllowConstBlockItems::DoesNotMatter, // due to `ForeignItemKind::try_from` below
1605            )?
1606            .map(|Item { attrs, id, span, vis, kind, tokens }| {
1607                let kind = match ForeignItemKind::try_from(kind) {
1608                    Ok(kind) => kind,
1609                    Err(kind) => match kind {
1610                        ItemKind::Const(ConstItem { ident, ty, body, .. }) => {
1611                            let const_span = Some(span.with_hi(ident.span.lo()))
1612                                .filter(|span| span.can_be_used_for_suggestions());
1613                            self.dcx().emit_err(diagnostics::ExternItemCannotBeConst {
1614                                ident_span: ident.span,
1615                                const_span,
1616                            });
1617                            ForeignItemKind::Static(Box::new(StaticItem {
1618                                ident,
1619                                ty,
1620                                mutability: Mutability::Not,
1621                                expr: body,
1622                                safety: Safety::Default,
1623                                define_opaque: None,
1624                                eii_impl: None,
1625                            }))
1626                        }
1627                        _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1628                    },
1629                };
1630                Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1631            }))
1632    }
1633
1634    fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1635        // FIXME(#100717): needs variant for each `ItemKind` (instead of using `ItemKind::descr()`)
1636        let span = self.psess.source_map().guess_head_span(span);
1637        let descr = kind.descr();
1638        let help = match kind {
1639            ItemKind::DelegationMac(DelegationMac {
1640                suffixes: DelegationSuffixes::Glob(_),
1641                ..
1642            }) => false,
1643            _ => true,
1644        };
1645        self.dcx().emit_err(diagnostics::BadItemKind { span, descr, ctx, help });
1646        None
1647    }
1648
1649    fn is_use_closure(&self) -> bool {
1650        if self.token.is_keyword(kw::Use) {
1651            // Check if this could be a closure.
1652            self.look_ahead(1, |token| {
1653                // Move or Async here would be an error but still we're parsing a closure
1654                let dist =
1655                    if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1656
1657                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))
1658            })
1659        } else {
1660            false
1661        }
1662    }
1663
1664    pub(super) fn is_unsafe_foreign_mod(&self) -> bool {
1665        // Look for `unsafe`.
1666        if !self.token.is_keyword(kw::Unsafe) {
1667            return false;
1668        }
1669        // Look for `extern`.
1670        if !self.is_keyword_ahead(1, &[kw::Extern]) {
1671            return false;
1672        }
1673
1674        // Look for the optional ABI string literal.
1675        let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1676
1677        // Look for the `{`. Use `tree_look_ahead` because the ABI (if present)
1678        // might be a metavariable i.e. an invisible-delimited sequence, and
1679        // `tree_look_ahead` will consider that a single element when looking
1680        // ahead.
1681        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, _)))
1682            == Some(true)
1683    }
1684
1685    fn parse_global_static_front_matter(&mut self, case: Case) -> Option<Safety> {
1686        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) {
1687            // Check if this could be a closure.
1688            !self.look_ahead(1, |token| {
1689                if token.is_keyword_case(kw::Move, case) || token.is_keyword_case(kw::Use, case) {
1690                    return true;
1691                }
1692                #[allow(non_exhaustive_omitted_patterns)] match token.kind {
    token::Or | token::OrOr => true,
    _ => false,
}matches!(token.kind, token::Or | token::OrOr)
1693            })
1694        } else {
1695            // `$qual static`
1696            (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)
1697                || 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))
1698                && self.look_ahead(1, |t| t.is_keyword_case(kw::Static, case))
1699        };
1700
1701        if is_global_static {
1702            let safety = self.parse_safety(case);
1703            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);
1704            Some(safety)
1705        } else {
1706            None
1707        }
1708    }
1709
1710    /// Recover on `const mut` with `const` already eaten.
1711    fn recover_const_mut(&mut self, const_span: Span) {
1712        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)) {
1713            let span = self.prev_token.span;
1714            self.dcx()
1715                .emit_err(diagnostics::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1716        } 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)) {
1717            let span = self.prev_token.span;
1718            self.dcx()
1719                .emit_err(diagnostics::ConstLetMutuallyExclusive { span: const_span.to(span) });
1720        }
1721    }
1722
1723    fn parse_const_block_item(&mut self) -> PResult<'a, ConstBlockItem> {
1724        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Const,
    token_type: crate::parser::token_type::TokenType::KwConst,
}exp!(Const))?;
1725        let const_span = self.prev_token.span;
1726        self.psess.gated_spans.gate(sym::const_block_items, const_span);
1727        let block = self.parse_block()?;
1728        Ok(ConstBlockItem { id: DUMMY_NODE_ID, span: const_span.to(block.span), block })
1729    }
1730
1731    /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in
1732    /// `mutability`.
1733    ///
1734    /// ```ebnf
1735    /// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
1736    /// ```
1737    fn parse_static_item(
1738        &mut self,
1739        safety: Safety,
1740        mutability: Mutability,
1741    ) -> PResult<'a, ItemKind> {
1742        let ident = self.parse_ident()?;
1743
1744        if self.token == TokenKind::Lt && self.may_recover() {
1745            let generics = self.parse_generics()?;
1746            self.dcx().emit_err(diagnostics::StaticWithGenerics { span: generics.span });
1747        }
1748
1749        // Parse the type of a static item. That is, the `":" $ty` fragment.
1750        // FIXME: This could maybe benefit from `.may_recover()`?
1751        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))) {
1752            (true, false) => self.parse_ty()?,
1753            // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing
1754            // type.
1755            (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1756        };
1757
1758        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 };
1759
1760        self.expect_semi()?;
1761
1762        let item =
1763            StaticItem { ident, ty, safety, mutability, expr, define_opaque: None, eii_impl: None };
1764        Ok(ItemKind::Static(Box::new(item)))
1765    }
1766
1767    /// Parse a constant item with the prefix `"const"` already parsed.
1768    ///
1769    /// If `const_arg` is true, any expression assigned to the const will be parsed
1770    /// as a const_arg instead of a body expression.
1771    ///
1772    /// ```ebnf
1773    /// Const = "const" ($ident | "_") Generics ":" $ty (= $expr)? WhereClause ";" ;
1774    /// ```
1775    fn parse_const_item(
1776        &mut self,
1777        const_span: Span,
1778    ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<Box<Expr>>)> {
1779        let ident = self.parse_ident_or_underscore()?;
1780
1781        let mut generics = self.parse_generics()?;
1782
1783        // Check the span for emptiness instead of the list of parameters in order to correctly
1784        // recognize and subsequently flag empty parameter lists (`<>`) as unstable.
1785        if !generics.span.is_empty() {
1786            self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1787        }
1788
1789        // Parse the type of a constant item. That is, the `":" $ty` fragment.
1790        // FIXME: This could maybe benefit from `.may_recover()`?
1791        let ty = match (
1792            self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon)),
1793            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)),
1794        ) {
1795            (true, false) => self.parse_ty()?,
1796            // If there wasn't a `:` or the colon was followed by a `=`, `;` or `where`, recover a missing type.
1797            (colon, _) => self.recover_missing_global_item_type(colon, None),
1798        };
1799
1800        // Proactively parse a where-clause to be able to provide a good error message in case we
1801        // encounter the item body following it.
1802        let before_where_clause =
1803            if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1804
1805        let rhs = if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1806
1807        let after_where_clause = self.parse_where_clause()?;
1808
1809        // Provide a nice error message if the user placed a where-clause before the item body.
1810        // Users may be tempted to write such code if they are still used to the deprecated
1811        // where-clause location on type aliases and associated types. See also #89122.
1812        if before_where_clause.has_where_token
1813            && let Some(rhs) = &rhs
1814        {
1815            self.dcx().emit_err(diagnostics::WhereClauseBeforeConstBody {
1816                span: before_where_clause.span,
1817                name: ident.span,
1818                body: rhs.span,
1819                sugg: if !after_where_clause.has_where_token {
1820                    self.psess.source_map().span_to_snippet(rhs.span).ok().map(|body_s| {
1821                        diagnostics::WhereClauseBeforeConstBodySugg {
1822                            left: before_where_clause.span.shrink_to_lo(),
1823                            snippet: body_s,
1824                            right: before_where_clause.span.shrink_to_hi().to(rhs.span),
1825                        }
1826                    })
1827                } else {
1828                    // FIXME(generic_const_items): Provide a structured suggestion to merge the first
1829                    // where-clause into the second one.
1830                    None
1831                },
1832            });
1833        }
1834
1835        // Merge the predicates of both where-clauses since either one can be relevant.
1836        // If we didn't parse a body (which is valid for associated consts in traits) and we were
1837        // allowed to recover, `before_where_clause` contains the predicates, otherwise they are
1838        // in `after_where_clause`. Further, both of them might contain predicates iff two
1839        // where-clauses were provided which is syntactically ill-formed but we want to recover from
1840        // it and treat them as one large where-clause.
1841        let mut predicates = before_where_clause.predicates;
1842        predicates.extend(after_where_clause.predicates);
1843        let where_clause = WhereClause {
1844            has_where_token: before_where_clause.has_where_token
1845                || after_where_clause.has_where_token,
1846            predicates,
1847            span: if after_where_clause.has_where_token {
1848                after_where_clause.span
1849            } else {
1850                before_where_clause.span
1851            },
1852        };
1853
1854        if where_clause.has_where_token {
1855            self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1856        }
1857
1858        generics.where_clause = where_clause;
1859
1860        if let Some(rhs) = self.try_recover_const_missing_semi(&rhs, const_span) {
1861            return Ok((ident, generics, ty, Some(rhs)));
1862        }
1863        self.expect_semi()?;
1864
1865        Ok((ident, generics, ty, rhs))
1866    }
1867
1868    /// We were supposed to parse `":" $ty` but the `:` or the type was missing.
1869    /// This means that the type is missing.
1870    fn recover_missing_global_item_type(
1871        &mut self,
1872        colon_present: bool,
1873        m: Option<Mutability>,
1874    ) -> Box<Ty> {
1875        // Construct the error and stash it away with the hope
1876        // that typeck will later enrich the error with a type.
1877        let kind = match m {
1878            Some(Mutability::Mut) => "static mut",
1879            Some(Mutability::Not) => "static",
1880            None => "const",
1881        };
1882
1883        let colon = match colon_present {
1884            true => "",
1885            false => ":",
1886        };
1887
1888        let span = self.prev_token.span.shrink_to_hi();
1889        let err = self.dcx().create_err(diagnostics::MissingConstType { span, colon, kind });
1890        err.stash(span, StashKey::ItemNoType);
1891
1892        // The user intended that the type be inferred,
1893        // so treat this as if the user wrote e.g. `const A: _ = expr;`.
1894        Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID })
1895    }
1896
1897    /// Parses an enum declaration.
1898    fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1899        if self.token.is_keyword(kw::Struct) {
1900            let span = self.prev_token.span.to(self.token.span);
1901            let err = diagnostics::EnumStructMutuallyExclusive { span };
1902            if self.look_ahead(1, |t| t.is_ident()) {
1903                self.bump();
1904                self.dcx().emit_err(err);
1905            } else {
1906                return Err(self.dcx().create_err(err));
1907            }
1908        }
1909
1910        let prev_span = self.prev_token.span;
1911        let ident = self.parse_ident()?;
1912        let mut generics = self.parse_generics()?;
1913        generics.where_clause = self.parse_where_clause()?;
1914
1915        // Possibly recover `enum Foo;` instead of `enum Foo {}`
1916        let (variants, _) = if self.token == TokenKind::Semi {
1917            self.dcx().emit_err(diagnostics::UseEmptyBlockNotSemi { span: self.token.span });
1918            self.bump();
1919            (::thin_vec::ThinVec::new()thin_vec![], Trailing::No)
1920        } else {
1921            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| {
1922                if p.recover_inner_attributes()? && p.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp![CloseBrace]) {
1923                    return Ok(None);
1924                }
1925                p.parse_enum_variant(ident.span)
1926            })
1927            .map_err(|mut err| {
1928                err.span_label(ident.span, "while parsing this enum");
1929                // Try to recover `enum Foo { ident : Ty }`.
1930                if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1931                    let snapshot = self.create_snapshot_for_diagnostic();
1932                    self.bump();
1933                    match self.parse_ty() {
1934                        Ok(_) => {
1935                            err.span_suggestion_verbose(
1936                                prev_span,
1937                                "perhaps you meant to use `struct` here",
1938                                "struct",
1939                                Applicability::MaybeIncorrect,
1940                            );
1941                        }
1942                        Err(e) => {
1943                            e.cancel();
1944                        }
1945                    }
1946                    self.restore_snapshot(snapshot);
1947                }
1948                self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)]);
1949                self.bump(); // }
1950                err
1951            })?
1952        };
1953
1954        let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1955        Ok(ItemKind::Enum(ident, generics, enum_definition))
1956    }
1957
1958    fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1959        self.recover_vcs_conflict_marker();
1960        let variant_attrs = self.parse_outer_attributes()?;
1961        self.recover_vcs_conflict_marker();
1962        let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1963                    `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1964        self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1965            let vlo = this.token.span;
1966
1967            let vis = this.parse_visibility(FollowedByType::No)?;
1968            if !this.recover_nested_adt_item(kw::Enum)? {
1969                return Ok((None, Trailing::No, UsePreAttrPos::No));
1970            }
1971            let ident = this.parse_field_ident("enum", vlo)?;
1972
1973            if this.token == token::Bang {
1974                if let Err(err) = this.unexpected() {
1975                    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();
1976                }
1977
1978                this.bump();
1979                this.parse_delim_args()?;
1980
1981                return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1982            }
1983
1984            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)) {
1985                // Parse a struct variant.
1986                let (fields, recovered) =
1987                    match this.parse_record_struct_body("struct", ident.span, false) {
1988                        Ok((fields, recovered)) => (fields, recovered),
1989                        Err(mut err) => {
1990                            if this.token == token::Colon {
1991                                // We handle `enum` to `struct` suggestion in the caller.
1992                                return Err(err);
1993                            }
1994                            this.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace)]);
1995                            this.bump(); // }
1996                            err.span_label(span, "while parsing this enum");
1997                            err.help(help);
1998                            let guar = err.emit_err();
1999                            (::thin_vec::ThinVec::new()thin_vec![], Recovered::Yes(guar))
2000                        }
2001                    };
2002                VariantData::Struct { fields, recovered }
2003            } else if this.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
2004                let body = match this.parse_tuple_struct_body() {
2005                    Ok(body) => body,
2006                    Err(mut err) => {
2007                        if this.token == token::Colon {
2008                            // We handle `enum` to `struct` suggestion in the caller.
2009                            return Err(err);
2010                        }
2011                        this.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)]);
2012                        this.bump(); // )
2013                        err.span_label(span, "while parsing this enum");
2014                        err.help(help);
2015                        err.emit();
2016                        ::thin_vec::ThinVec::new()thin_vec![]
2017                    }
2018                };
2019                VariantData::Tuple(body, DUMMY_NODE_ID)
2020            } else {
2021                VariantData::Unit(DUMMY_NODE_ID)
2022            };
2023
2024            let disr_expr =
2025                if this.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
2026
2027            let span = vlo.to(this.prev_token.span);
2028            if ident.name == kw::Underscore {
2029                this.psess.gated_spans.gate(sym::unnamed_enum_variants, span);
2030            }
2031            let vr = ast::Variant {
2032                ident,
2033                vis,
2034                id: DUMMY_NODE_ID,
2035                attrs: variant_attrs,
2036                data: struct_def,
2037                disr_expr,
2038                span,
2039                is_placeholder: false,
2040            };
2041
2042            Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
2043        })
2044        .map_err(|mut err| {
2045            err.help(help);
2046            err
2047        })
2048    }
2049
2050    /// Parses `struct Foo { ... }`.
2051    fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
2052        let ident = self.parse_ident()?;
2053
2054        let mut generics = self.parse_generics()?;
2055
2056        // There is a special case worth noting here, as reported in issue #17904.
2057        // If we are parsing a tuple struct it is the case that the where clause
2058        // should follow the field list. Like so:
2059        //
2060        // struct Foo<T>(T) where T: Copy;
2061        //
2062        // If we are parsing a normal record-style struct it is the case
2063        // that the where clause comes before the body, and after the generics.
2064        // So if we look ahead and see a brace or a where-clause we begin
2065        // parsing a record style struct.
2066        //
2067        // Otherwise if we look ahead and see a paren we parse a tuple-style
2068        // struct.
2069
2070        let vdata = if self.token.is_keyword(kw::Where) {
2071            let tuple_struct_body;
2072            (generics.where_clause, tuple_struct_body) =
2073                self.parse_struct_where_clause(ident, generics.span)?;
2074
2075            if let Some(body) = tuple_struct_body {
2076                // If we see a misplaced tuple struct body: `struct Foo<T> where T: Copy, (T);`
2077                let body = VariantData::Tuple(body, DUMMY_NODE_ID);
2078                self.expect_semi()?;
2079                body
2080            } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
2081                // If we see a: `struct Foo<T> where T: Copy;` style decl.
2082                VariantData::Unit(DUMMY_NODE_ID)
2083            } else {
2084                // If we see: `struct Foo<T> where T: Copy { ... }`
2085                let (fields, recovered) = self.parse_record_struct_body(
2086                    "struct",
2087                    ident.span,
2088                    generics.where_clause.has_where_token,
2089                )?;
2090                VariantData::Struct { fields, recovered }
2091            }
2092        // No `where` so: `struct Foo<T>;`
2093        } else if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Semi,
    token_type: crate::parser::token_type::TokenType::Semi,
}exp!(Semi)) {
2094            VariantData::Unit(DUMMY_NODE_ID)
2095        // Record-style struct definition
2096        } else if self.token == token::OpenBrace {
2097            let (fields, recovered) = self.parse_record_struct_body(
2098                "struct",
2099                ident.span,
2100                generics.where_clause.has_where_token,
2101            )?;
2102            VariantData::Struct { fields, recovered }
2103        // Tuple-style struct definition with optional where-clause.
2104        } else if self.token == token::OpenParen {
2105            let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
2106            generics.where_clause = self.parse_where_clause()?;
2107            self.expect_semi()?;
2108            body
2109        } else {
2110            let err = diagnostics::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
2111            return Err(self.dcx().create_err(err));
2112        };
2113
2114        Ok(ItemKind::Struct(ident, generics, vdata))
2115    }
2116
2117    /// Parses `union Foo { ... }`.
2118    fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
2119        let ident = self.parse_ident()?;
2120
2121        let mut generics = self.parse_generics()?;
2122
2123        let vdata = if self.token.is_keyword(kw::Where) {
2124            generics.where_clause = self.parse_where_clause()?;
2125            let (fields, recovered) = self.parse_record_struct_body(
2126                "union",
2127                ident.span,
2128                generics.where_clause.has_where_token,
2129            )?;
2130            VariantData::Struct { fields, recovered }
2131        } else if self.token == token::OpenBrace {
2132            let (fields, recovered) = self.parse_record_struct_body(
2133                "union",
2134                ident.span,
2135                generics.where_clause.has_where_token,
2136            )?;
2137            VariantData::Struct { fields, recovered }
2138        } else {
2139            let token_str = super::token_descr(&self.token);
2140            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}");
2141            let mut err = self.dcx().struct_span_err(self.token.span, msg);
2142            err.span_label(self.token.span, "expected `where` or `{` after union name");
2143            return Err(err);
2144        };
2145
2146        Ok(ItemKind::Union(ident, generics, vdata))
2147    }
2148
2149    /// This function parses the fields of record structs:
2150    ///
2151    ///   - `struct S { ... }`
2152    ///   - `enum E { Variant { ... } }`
2153    pub(crate) fn parse_record_struct_body(
2154        &mut self,
2155        adt_ty: &str,
2156        ident_span: Span,
2157        parsed_where: bool,
2158    ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
2159        let mut fields = ThinVec::new();
2160        let mut recovered = Recovered::No;
2161        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
2162            while self.token != token::CloseBrace {
2163                if self.recover_inner_attributes()? && self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp![CloseBrace]) {
2164                    break;
2165                }
2166                match self.parse_field_def(adt_ty, ident_span) {
2167                    Ok(field) => {
2168                        fields.push(field);
2169                    }
2170                    Err(mut err) => {
2171                        self.consume_block(
2172                            crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace),
2173                            crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace),
2174                            ConsumeClosingDelim::No,
2175                        );
2176                        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}"));
2177                        let guar = err.emit_err();
2178                        recovered = Recovered::Yes(guar);
2179                        break;
2180                    }
2181                }
2182            }
2183            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseBrace,
    token_type: crate::parser::token_type::TokenType::CloseBrace,
}exp!(CloseBrace))?;
2184        } else {
2185            let token_str = super::token_descr(&self.token);
2186            let where_str = if parsed_where { "" } else { "`where`, or " };
2187            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}");
2188            let mut err = self.dcx().struct_span_err(self.token.span, msg);
2189            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",));
2190            return Err(err);
2191        }
2192
2193        Ok((fields, recovered))
2194    }
2195
2196    fn parse_unsafe_field(&mut self) -> Safety {
2197        // not using parse_safety as that also accepts `safe`.
2198        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)) {
2199            let span = self.prev_token.span;
2200            self.psess.gated_spans.gate(sym::unsafe_fields, span);
2201            Safety::Unsafe(span)
2202        } else {
2203            Safety::Default
2204        }
2205    }
2206    /// This is the case where we find `struct Foo<T>(T) where T: Copy;`
2207    /// Unit like structs are handled in parse_item_struct function
2208    pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
2209        let openparen_span = self.token.span;
2210        let mut encountered_colon = false;
2211        self.parse_paren_comma_seq(|p| {
2212            let attrs = p.parse_outer_attributes()?;
2213            p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
2214                let mut snapshot = None;
2215                if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
2216                    // Account for `<<<<<<<` diff markers. We can't proactively error here because
2217                    // that can be a valid type start, so we snapshot and reparse only we've
2218                    // encountered another parse error.
2219                    snapshot = Some(p.create_snapshot_for_diagnostic());
2220                }
2221                let lo = p.token.span;
2222                let vis = match p.parse_visibility(FollowedByType::Yes) {
2223                    Ok(vis) => vis,
2224                    Err(err) => {
2225                        if let Some(ref mut snapshot) = snapshot {
2226                            snapshot.recover_vcs_conflict_marker();
2227                        }
2228                        return Err(err);
2229                    }
2230                };
2231                let mut_restriction = p.parse_mut_restriction()?;
2232                encountered_colon |=
2233                    p.token.is_ident() && p.look_ahead(1, |tok| tok == &token::Colon);
2234                // Unsafe fields are not supported in tuple structs, as doing so would result in a
2235                // parsing ambiguity for `struct X(unsafe fn())`.
2236                let ty = match p.parse_ty() {
2237                    Ok(ty) => ty,
2238                    Err(err) => {
2239                        if let Some(ref mut snapshot) = snapshot {
2240                            snapshot.recover_vcs_conflict_marker();
2241                        }
2242                        return Err(err);
2243                    }
2244                };
2245                let mut default = None;
2246                if p.token == token::Eq {
2247                    let mut snapshot = p.create_snapshot_for_diagnostic();
2248                    snapshot.bump();
2249                    match snapshot.parse_expr_anon_const() {
2250                        Ok(const_expr) => {
2251                            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2252                            p.psess.gated_spans.gate(sym::default_field_values, sp);
2253                            p.restore_snapshot(snapshot);
2254                            default = Some(const_expr);
2255                        }
2256                        Err(err) => {
2257                            err.cancel();
2258                        }
2259                    }
2260                }
2261
2262                Ok((
2263                    FieldDef {
2264                        span: lo.to(ty.span),
2265                        vis,
2266                        extras: Self::field_def_extras(Safety::Default, mut_restriction, default),
2267                        ident: None,
2268                        id: DUMMY_NODE_ID,
2269                        ty,
2270                        attrs,
2271                        is_placeholder: false,
2272                    },
2273                    Trailing::from(p.token == token::Comma),
2274                    UsePreAttrPos::No,
2275                ))
2276            })
2277        })
2278        .map(|(r, _)| r)
2279        .map_err(|mut error| {
2280            if self.token == token::Colon {
2281                error.subdiagnostic(UseDoubleColonSuggestion { colon: self.token.span });
2282            }
2283            if encountered_colon {
2284                self.eat_to_tokens(&[crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::CloseParen,
    token_type: crate::parser::token_type::TokenType::CloseParen,
}exp!(CloseParen)]);
2285                self.bump();
2286                error.subdiagnostic(UseRegularStructSuggestion {
2287                    open: openparen_span,
2288                    close: self.prev_token.span,
2289                    semicolon: if self.token == token::Semi { Some(self.token.span) } else { None },
2290                });
2291            }
2292            error
2293        })
2294    }
2295
2296    fn field_def_extras(
2297        safety: Safety,
2298        mut_restriction: MutRestriction,
2299        default: Option<AnonConst>,
2300    ) -> Option<Box<FieldDefExtras>> {
2301        match (safety, mut_restriction, default) {
2302            (
2303                Safety::Default,
2304                // We are throwing away the mut restriction span here.
2305                // see the span field comment for more info
2306                MutRestriction { kind: RestrictionKind::Unrestricted, span: _ },
2307                None,
2308            ) => None,
2309            (safety, mut_restriction, default) => {
2310                Some(Box::new(FieldDefExtras { safety, mut_restriction, default }))
2311            }
2312        }
2313    }
2314
2315    /// Parses an element of a struct declaration.
2316    fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
2317        self.recover_vcs_conflict_marker();
2318        let attrs = self.parse_outer_attributes()?;
2319        self.recover_vcs_conflict_marker();
2320        self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
2321            let lo = this.token.span;
2322            let vis = this.parse_visibility(FollowedByType::No)?;
2323            let mut_restriction = this.parse_mut_restriction()?;
2324            let safety = this.parse_unsafe_field();
2325            this.parse_single_struct_field(
2326                adt_ty,
2327                lo,
2328                vis,
2329                mut_restriction,
2330                safety,
2331                attrs,
2332                ident_span,
2333            )
2334            .map(|field| (field, Trailing::No, UsePreAttrPos::No))
2335        })
2336    }
2337
2338    /// Parses a structure field declaration.
2339    fn parse_single_struct_field(
2340        &mut self,
2341        adt_ty: &str,
2342        lo: Span,
2343        vis: Visibility,
2344        mut_restriction: MutRestriction,
2345        safety: Safety,
2346        attrs: AttrVec,
2347        ident_span: Span,
2348    ) -> PResult<'a, FieldDef> {
2349        let a_var = self.parse_name_and_ty(adt_ty, lo, vis, mut_restriction, safety, attrs)?;
2350        match self.token.kind {
2351            token::Comma => {
2352                self.bump();
2353            }
2354            token::Semi => {
2355                self.bump();
2356                let sp = self.prev_token.span;
2357                let mut err =
2358                    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 `,`"));
2359                err.span_suggestion_short(
2360                    sp,
2361                    "replace `;` with `,`",
2362                    ",",
2363                    Applicability::MachineApplicable,
2364                );
2365                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}"));
2366                err.emit();
2367            }
2368            token::CloseBrace => {}
2369            token::DocComment(..) => {
2370                let previous_span = self.prev_token.span;
2371                let mut err = diagnostics::DocCommentDoesNotDocumentAnything {
2372                    span: self.token.span,
2373                    missing_comma: None,
2374                };
2375                self.bump(); // consume the doc comment
2376                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 {
2377                    self.dcx().emit_err(err);
2378                } else {
2379                    let sp = previous_span.shrink_to_hi();
2380                    err.missing_comma = Some(sp);
2381                    return Err(self.dcx().create_err(err));
2382                }
2383            }
2384            _ => {
2385                let sp = self.prev_token.span.shrink_to_hi();
2386                let msg =
2387                    ::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));
2388
2389                // Try to recover extra trailing angle brackets
2390                if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
2391                    && let Some(last_segment) = segments.last()
2392                {
2393                    let guar = self.check_trailing_angle_brackets(
2394                        last_segment,
2395                        &[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)],
2396                    );
2397                    if let Some(_guar) = guar {
2398                        // Handle a case like `Vec<u8>>,` where we can continue parsing fields
2399                        // after the comma
2400                        let _ = self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Comma,
    token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
2401
2402                        // `check_trailing_angle_brackets` already emitted a nicer error, as
2403                        // proven by the presence of `_guar`. We can continue parsing.
2404                        return Ok(a_var);
2405                    }
2406                }
2407
2408                let mut err = self.dcx().struct_span_err(sp, msg);
2409
2410                if self.token.is_ident()
2411                    || (self.token == TokenKind::Pound
2412                        && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2413                {
2414                    // This is likely another field, TokenKind::Pound is used for `#[..]`
2415                    // attribute for next field. Emit the diagnostic and continue parsing.
2416                    err.span_suggestion(
2417                        sp,
2418                        "try adding a comma",
2419                        ",",
2420                        Applicability::MachineApplicable,
2421                    );
2422                    err.emit();
2423                } else {
2424                    return Err(err);
2425                }
2426            }
2427        }
2428        Ok(a_var)
2429    }
2430
2431    fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2432        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)) {
2433            let sm = self.psess.source_map();
2434            let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2435            let semi_typo = self.token == token::Semi
2436                && self.look_ahead(1, |t| {
2437                    t.is_path_start()
2438                    // We check that we are in a situation like `foo; bar` to avoid bad suggestions
2439                    // when there's no type and `;` was used instead of a comma.
2440                    && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2441                        (Ok(l), Ok(r)) => l.line == r.line,
2442                        _ => true,
2443                    }
2444                });
2445            if eq_typo || semi_typo {
2446                self.bump();
2447                // Gracefully handle small typos.
2448                err.with_span_suggestion_short(
2449                    self.prev_token.span,
2450                    "field names and their types are separated with `:`",
2451                    ":",
2452                    Applicability::MachineApplicable,
2453                )
2454                .emit();
2455            } else {
2456                return Err(err);
2457            }
2458        }
2459        Ok(())
2460    }
2461
2462    /// Parses a structure field.
2463    fn parse_name_and_ty(
2464        &mut self,
2465        adt_ty: &str,
2466        lo: Span,
2467        vis: Visibility,
2468        mut_restriction: MutRestriction,
2469        safety: Safety,
2470        attrs: AttrVec,
2471    ) -> PResult<'a, FieldDef> {
2472        let name = self.parse_field_ident(adt_ty, lo)?;
2473        if self.token == token::Bang {
2474            if let Err(mut err) = self.unexpected() {
2475                // Encounter the macro invocation
2476                err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2477                return Err(err);
2478            }
2479        }
2480        self.expect_field_ty_separator()?;
2481        let ty = self.parse_ty()?;
2482        if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2483            return Err(self
2484                .dcx()
2485                .struct_span_err(self.token.span, "found single colon in a struct field type path")
2486                .with_span_suggestion_verbose(
2487                    self.token.span,
2488                    "write a path separator here",
2489                    "::",
2490                    Applicability::MaybeIncorrect,
2491                ));
2492        }
2493        let default = if self.token == token::Eq {
2494            self.bump();
2495            let const_expr = self.parse_expr_anon_const()?;
2496            let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2497            self.psess.gated_spans.gate(sym::default_field_values, sp);
2498            Some(const_expr)
2499        } else {
2500            None
2501        };
2502        Ok(FieldDef {
2503            span: lo.to(self.prev_token.span),
2504            ident: Some(name),
2505            vis,
2506            extras: Self::field_def_extras(safety, mut_restriction, default),
2507            id: DUMMY_NODE_ID,
2508            ty,
2509            attrs,
2510            is_placeholder: false,
2511        })
2512    }
2513
2514    /// Parses a field identifier. Specialized version of `parse_ident_common`
2515    /// for better diagnostics and suggestions.
2516    fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2517        let (ident, kind) = self.ident_or_err(true)?;
2518        if token::ident_of_kind_is_reserved(ident, kind)
2519            && !(ident.name == kw::Underscore && adt_ty == "enum")
2520        {
2521            let snapshot = self.create_snapshot_for_diagnostic();
2522            let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2523                let inherited_vis = Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited };
2524                // We use `parse_fn` to get a span for the function
2525                let fn_parse_mode = FnParseMode {
2526                    req_name: |_, _| true,
2527                    context: FnContext::Free,
2528                    req_body: true,
2529                    allow_const_params: true,
2530                };
2531                match self.parse_fn(
2532                    &mut AttrVec::new(),
2533                    fn_parse_mode,
2534                    lo,
2535                    &inherited_vis,
2536                    Case::Insensitive,
2537                ) {
2538                    Ok(_) => self
2539                        .dcx()
2540                        .struct_span_err(
2541                            lo.to(self.prev_token.span),
2542                            ::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"),
2543                        )
2544                        .with_help(
2545                            "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2546                        )
2547                        .with_help(
2548                            "see https://doc.rust-lang.org/book/ch05-03-method-syntax.html \
2549                             for more information",
2550                        ),
2551                    Err(err) => {
2552                        err.cancel();
2553                        self.restore_snapshot(snapshot);
2554                        self.expected_ident_found_err()
2555                    }
2556                }
2557            } 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)) {
2558                match self.parse_item_struct() {
2559                    Ok(item) => {
2560                        let ItemKind::Struct(ident, ..) = item else { ::core::panicking::unreachable_default_msg()unreachable!() };
2561                        self.dcx()
2562                            .struct_span_err(
2563                                lo.with_hi(ident.span.hi()),
2564                                ::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"),
2565                            )
2566                            .with_help(
2567                                "consider creating a new `struct` definition instead of nesting",
2568                            )
2569                    }
2570                    Err(err) => {
2571                        err.cancel();
2572                        self.restore_snapshot(snapshot);
2573                        self.expected_ident_found_err()
2574                    }
2575                }
2576            } else {
2577                let mut err = self.expected_ident_found_err();
2578                if self.eat_keyword_noexpect(kw::Let)
2579                    && let removal_span = self.prev_token.span.until(self.token.span)
2580                    && let Ok(ident) = self
2581                        .parse_ident_common(false)
2582                        // Cancel this error, we don't need it.
2583                        .map_err(|err| err.cancel())
2584                    && self.token == TokenKind::Colon
2585                {
2586                    err.span_suggestion_verbose(
2587                        removal_span,
2588                        "remove the `let` keyword",
2589                        String::new(),
2590                        Applicability::MachineApplicable,
2591                    );
2592                    err.note("the `let` keyword is not allowed in `struct` fields");
2593                    err.note(
2594                        "see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> \
2595                         for more information",
2596                    );
2597                    err.emit();
2598                    return Ok(ident);
2599                } else {
2600                    self.restore_snapshot(snapshot);
2601                }
2602                err
2603            };
2604            return Err(err);
2605        }
2606        self.bump();
2607        Ok(ident)
2608    }
2609
2610    /// Parses a declarative macro 2.0 definition.
2611    /// The `macro` keyword has already been parsed.
2612    /// ```ebnf
2613    /// MacBody = "{" TOKEN_STREAM "}" ;
2614    /// MacParams = "(" TOKEN_STREAM ")" ;
2615    /// DeclMac = "macro" Ident MacParams? MacBody ;
2616    /// ```
2617    fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2618        let ident = self.parse_ident()?;
2619        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)) {
2620            self.parse_delim_args()? // `MacBody`
2621        } else if self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenParen,
    token_type: crate::parser::token_type::TokenType::OpenParen,
}exp!(OpenParen)) {
2622            let params = self.parse_token_tree(); // `MacParams`
2623            let pspan = params.span();
2624            if !self.check(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::OpenBrace,
    token_type: crate::parser::token_type::TokenType::OpenBrace,
}exp!(OpenBrace)) {
2625                self.unexpected()?;
2626            }
2627            let body = self.parse_token_tree(); // `MacBody`
2628            // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
2629            let bspan = body.span();
2630            let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
2631            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]);
2632            let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2633            Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2634        } else {
2635            self.unexpected_any()?
2636        };
2637
2638        self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2639        Ok(ItemKind::MacroDef(
2640            ident,
2641            ast::MacroDef { body, macro_rules: false, eii_declaration: None },
2642        ))
2643    }
2644
2645    /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
2646    fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2647        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)) {
2648            let macro_rules_span = self.token.span;
2649
2650            if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2651                return IsMacroRulesItem::Yes { has_bang: true };
2652            } else if self.look_ahead(1, |t| t.is_ident()) {
2653                // macro_rules foo
2654                self.dcx().emit_err(diagnostics::MacroRulesMissingBang {
2655                    span: macro_rules_span,
2656                    hi: macro_rules_span.shrink_to_hi(),
2657                });
2658
2659                return IsMacroRulesItem::Yes { has_bang: false };
2660            }
2661        }
2662
2663        IsMacroRulesItem::No
2664    }
2665
2666    /// Parses a `macro_rules! foo { ... }` declarative macro.
2667    fn parse_item_macro_rules(
2668        &mut self,
2669        vis: &Visibility,
2670        has_bang: bool,
2671    ) -> PResult<'a, ItemKind> {
2672        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`
2673
2674        if has_bang {
2675            self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang))?; // `!`
2676        }
2677        let ident = self.parse_ident()?;
2678
2679        if self.eat(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Bang,
    token_type: crate::parser::token_type::TokenType::Bang,
}exp!(Bang)) {
2680            // Handle macro_rules! foo!
2681            let span = self.prev_token.span;
2682            self.dcx().emit_err(diagnostics::MacroNameRemoveBang { span });
2683        }
2684
2685        let body = self.parse_delim_args()?;
2686        self.eat_semi_for_macro_if_needed(&body, None);
2687        self.complain_if_pub_macro(vis, true);
2688
2689        Ok(ItemKind::MacroDef(
2690            ident,
2691            ast::MacroDef { body, macro_rules: true, eii_declaration: None },
2692        ))
2693    }
2694
2695    /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
2696    /// If that's not the case, emit an error.
2697    fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2698        if let VisibilityKind::Inherited = vis.kind {
2699            return;
2700        }
2701
2702        let vstr = pprust::vis_to_string(vis);
2703        let vstr = vstr.trim_end();
2704        if macro_rules {
2705            self.dcx().emit_err(diagnostics::MacroRulesVisibility { span: vis.span, vis: vstr });
2706        } else {
2707            self.dcx()
2708                .emit_err(diagnostics::MacroInvocationVisibility { span: vis.span, vis: vstr });
2709        }
2710    }
2711
2712    fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs, path: Option<&Path>) {
2713        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)) {
2714            self.report_invalid_macro_expansion_item(args, path);
2715        }
2716    }
2717
2718    /// Parses the contents of a `test_binder_constraints!`. Perma-unstable and for testing only.
2719    pub fn parse_test_binder_constraints(&mut self) -> PResult<'a, Box<TestBinderConstraints>> {
2720        self.expect_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::Impl,
    token_type: crate::parser::token_type::TokenType::KwImpl,
}exp!(Impl))?;
2721        let mut generics = self.parse_generics()?;
2722        generics.where_clause = self.parse_where_clause()?;
2723        let body = self.parse_test_binder_body()?;
2724        Ok(Box::new(TestBinderConstraints { generics, body: Box::new(body) }))
2725    }
2726
2727    pub fn parse_test_binder_body(&mut self) -> PResult<'a, TestBinderBody> {
2728        let mut items: Vec<TestBinderItem> = Vec::new();
2729        let mut span = self.token.span;
2730        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), |this| {
2731            match this.token.ident() {
2732                Some((Ident { name: sym::predicates, .. }, IdentKind::Normal)) => {
2733                    let span = this.token.span;
2734                    this.bump();
2735                    items.extend(
2736                        this.parse_where_clause_predicates(None, span)?
2737                            .0
2738                            .into_iter()
2739                            .map(TestBinderItem::Predicate),
2740                    );
2741                }
2742                Some((Ident { name: sym::forall, .. }, IdentKind::Normal)) => {
2743                    items.push(TestBinderItem::Forall(this.parse_test_binder_forall()?));
2744                }
2745                Some((Ident { name: sym::exists, .. }, IdentKind::Normal)) => {
2746                    items.push(TestBinderItem::Exists(this.parse_test_binder_exists()?));
2747                }
2748
2749                _ if this.token.is_lifetime() && this.look_ahead(1, |t| t.kind == token::Eq) => {
2750                    let lhs = this.expect_lifetime();
2751                    this.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Eq,
    token_type: crate::parser::token_type::TokenType::Eq,
}exp!(Eq))?;
2752                    if !this.check_lifetime() {
2753                        this.unexpected()?;
2754                    }
2755                    let rhs = this.expect_lifetime();
2756                    items.push(TestBinderItem::RegionEquality(TestBinderRegionEquality {
2757                        lhs,
2758                        rhs,
2759                    }));
2760                }
2761                _ => items.push(TestBinderItem::Constraint(this.parse_test_binder_constraint()?)),
2762            }
2763            Ok(())
2764        })?;
2765        span = span.to(self.prev_token.span);
2766        Ok(TestBinderBody { items, span })
2767    }
2768
2769    pub fn parse_test_binder_forall(&mut self) -> PResult<'a, TestBinderForall> {
2770        let span = self.token.span;
2771        self.bump();
2772
2773        let mut generics = self.parse_generics()?;
2774        generics.where_clause = self.parse_where_clause()?;
2775
2776        let body = self.parse_test_binder_body()?;
2777
2778        let assert_on_exit = if let Some((i, IdentKind::Normal)) = self.token.ident()
2779            && i.name == sym::expect
2780        {
2781            self.bump();
2782            let items = self
2783                .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), |this| {
2784                    this.parse_test_binder_constraint()
2785                })?
2786                .0;
2787            Some(items)
2788        } else {
2789            None
2790        };
2791
2792        Ok(TestBinderForall { span, node_id: DUMMY_NODE_ID, generics, body, assert_on_exit })
2793    }
2794
2795    pub fn parse_test_binder_exists(&mut self) -> PResult<'a, TestBinderExists> {
2796        let span = self.token.span;
2797        self.bump();
2798        let params = self.parse_generics()?.params;
2799        let body = self.parse_test_binder_body()?;
2800        Ok(TestBinderExists { span, node_id: DUMMY_NODE_ID, params, body })
2801    }
2802
2803    pub fn parse_test_binder_constraint(&mut self) -> PResult<'a, TestBinderConstraint> {
2804        match self.token.ident() {
2805            Some((Ident { name: sym::and, .. }, IdentKind::Normal)) => {
2806                self.bump();
2807                let items = self
2808                    .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), |this| {
2809                        this.parse_test_binder_constraint()
2810                    })?
2811                    .0;
2812                Ok(TestBinderConstraint::And { items })
2813            }
2814            Some((Ident { name: sym::or, .. }, IdentKind::Normal)) => {
2815                self.bump();
2816                let items = self
2817                    .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), |this| {
2818                        this.parse_test_binder_constraint()
2819                    })?
2820                    .0;
2821                Ok(TestBinderConstraint::Or { items })
2822            }
2823            Some((Ident { name: sym::ambiguity, .. }, IdentKind::Normal)) => {
2824                let span = self.token.span;
2825                self.bump();
2826                Ok(TestBinderConstraint::Ambiguity { span })
2827            }
2828            _ if self.check_keyword(crate::parser::token_type::ExpKeywordPair {
    kw: rustc_span::symbol::kw::For,
    token_type: crate::parser::token_type::TokenType::KwFor,
}exp!(For)) => {
2829                let bound_type_constraint = self.parse_test_binder_bound_type_constraint()?;
2830                Ok(TestBinderConstraint::AliasOutlives { bound_type_constraint })
2831            }
2832            _ if self.token.lifetime().is_some() => {
2833                let lhs = self.expect_lifetime();
2834                self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon))?;
2835                if !self.check_lifetime() {
2836                    self.unexpected()?;
2837                }
2838                let rhs = self.expect_lifetime();
2839                Ok(TestBinderConstraint::Lifetime { lhs, rhs })
2840            }
2841            _ if self.token.can_begin_type() => {
2842                let lhs = self.parse_ty_for_where_clause()?;
2843                self.expect(crate::parser::token_type::ExpTokenPair {
    tok: rustc_ast::token::Colon,
    token_type: crate::parser::token_type::TokenType::Colon,
}exp!(Colon))?;
2844                if !self.check_lifetime() {
2845                    self.unexpected()?;
2846                }
2847                let rhs = self.expect_lifetime();
2848                Ok(TestBinderConstraint::PlaceholderOutlives { lhs, rhs })
2849            }
2850            _ => Err(self.dcx().struct_span_err(self.token.span, "unexpected token")),
2851        }
2852    }
2853
2854    fn parse_test_binder_bound_type_constraint(
2855        &mut self,
2856    ) -> PResult<'a, TestBinderBoundTypeConstraint> {
2857        let lo = self.token.span;
2858        let ast::WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } =
2859            self.parse_ty_where_predicate_kind()?;
2860        let mut rhs = None;
2861        for bound in bounds {
2862            match bound {
2863                GenericBound::Trait(poly_trait_ref) => {
2864                    self.dcx().span_err(poly_trait_ref.span, "trait bounds aren't supported here");
2865                }
2866                GenericBound::Use(_, span) => {
2867                    self.dcx().span_err(span, "use bounds aren't supported here");
2868                }
2869                GenericBound::Outlives(lifetime) => {
2870                    if rhs.is_some() {
2871                        self.dcx().span_err(
2872                            lifetime.ident.span,
2873                            "only one lifetime on the rhs supported",
2874                        );
2875                    } else {
2876                        rhs = Some(lifetime);
2877                    }
2878                }
2879            }
2880        }
2881        match rhs {
2882            Some(rhs) => Ok(TestBinderBoundTypeConstraint {
2883                span: lo.to(self.prev_token.span),
2884                node_id: DUMMY_NODE_ID,
2885                params: bound_generic_params,
2886                lhs: bounded_ty,
2887                rhs,
2888            }),
2889            None => Err(self.dcx().struct_span_err(
2890                bounded_ty.span,
2891                "expected a single lifetime on the rhs of this constraint",
2892            )),
2893        }
2894    }
2895
2896    fn report_invalid_macro_expansion_item(&self, args: &DelimArgs, path: Option<&Path>) {
2897        let span = args.dspan.entire();
2898        let mut err = self.dcx().struct_span_err(
2899            span,
2900            "macros that expand to items must be delimited with braces or followed by a semicolon",
2901        );
2902        // FIXME: This will make us not emit the help even for declarative
2903        // macros within the same crate (that we can fix), which is sad.
2904        if !span.from_expansion() {
2905            let DelimSpan { open, close } = args.dspan;
2906            // Check if this looks like `macro_rules!(name) { ... }`
2907            // a common mistake when trying to define a macro.
2908            if let Some(path) = path
2909                && path.segments.first().is_some_and(|seg| seg.ident.name == sym::macro_rules)
2910                && args.delim == Delimiter::Parenthesis
2911            {
2912                let replace =
2913                    if path.span.hi() + rustc_span::BytePos(1) < open.lo() { "" } else { " " };
2914                err.multipart_suggestion(
2915                    "to define a macro, remove the parentheses around the macro name",
2916                    ::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())],
2917                    Applicability::MachineApplicable,
2918                );
2919            } else {
2920                err.multipart_suggestion(
2921                    "change the delimiters to curly braces",
2922                    ::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())],
2923                    Applicability::MaybeIncorrect,
2924                );
2925                err.span_suggestion_verbose(
2926                    span.with_neighbor(self.token.span).shrink_to_hi(),
2927                    "add a semicolon",
2928                    ';',
2929                    Applicability::MaybeIncorrect,
2930                );
2931            }
2932        }
2933        err.emit();
2934    }
2935
2936    /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
2937    /// it is, we try to parse the item and report error about nested types.
2938    fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2939        if (self.token.is_keyword(kw::Enum)
2940            || self.token.is_keyword(kw::Struct)
2941            || self.token.is_keyword(kw::Union))
2942            && self.look_ahead(1, |t| t.is_ident())
2943        {
2944            let kw_token = self.token;
2945            let kw_str = pprust::token_to_string(&kw_token);
2946            let item = self.parse_item(
2947                ForceCollect::No,
2948                AllowConstBlockItems::DoesNotMatter, // self.token != kw::Const
2949            )?;
2950            let mut item = item.unwrap().span;
2951            if self.token == token::Comma {
2952                item = item.to(self.token.span);
2953            }
2954            self.dcx().emit_err(diagnostics::NestedAdt {
2955                span: kw_token.span,
2956                item,
2957                kw_str,
2958                keyword: keyword.as_str(),
2959            });
2960            // We successfully parsed the item but we must inform the caller about nested problem.
2961            return Ok(false);
2962        }
2963        Ok(true)
2964    }
2965
2966    fn check_impl_frontmatter(&mut self, look_ahead: usize) -> bool {
2967        const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2968        // In contrast to the loop below, this call inserts `impl` into the
2969        // list of expected tokens shown in diagnostics.
2970        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)) {
2971            return true;
2972        }
2973        let mut i = 0;
2974        while i < ALL_QUALS.len() {
2975            let action = self.look_ahead(i + look_ahead, |token| {
2976                if token.is_keyword(kw::Impl) {
2977                    return Some(true);
2978                }
2979                if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2980                    // Ok, we found a legal keyword, keep looking for `impl`
2981                    return None;
2982                }
2983                Some(false)
2984            });
2985            if let Some(ret) = action {
2986                return ret;
2987            }
2988            i += 1;
2989        }
2990
2991        self.is_keyword_ahead(i, &[kw::Impl])
2992    }
2993
2994    /// Try to recover from over-parsing in const item when a semicolon is missing.
2995    ///
2996    /// This detects cases where we parsed too much because a semicolon was missing
2997    /// and the next line started an expression that the parser treated as a continuation
2998    /// (e.g., `foo() \n &bar` was parsed as `foo() & bar`).
2999    ///
3000    /// Returns a corrected expression if recovery is successful.
3001    fn try_recover_const_missing_semi(
3002        &mut self,
3003        rhs: &Option<Box<Expr>>,
3004        const_span: Span,
3005    ) -> Option<Box<Expr>> {
3006        if self.token == TokenKind::Semi {
3007            return None;
3008        }
3009        let Some(rhs) = rhs else {
3010            return None;
3011        };
3012        if !self.in_fn_body || !self.may_recover() || rhs.span.from_expansion() {
3013            return None;
3014        }
3015        if let Some((span, guar)) =
3016            self.missing_semi_from_binop("const", rhs, Some(const_span.shrink_to_lo()))
3017        {
3018            self.fn_body_missing_semi_guar = Some(guar);
3019            Some(self.mk_expr(span, ExprKind::Err(guar)))
3020        } else {
3021            None
3022        }
3023    }
3024}
3025
3026enum IsMacroRulesItem {
3027    Yes { has_bang: bool },
3028    No,
3029}
3030
3031struct UsePathList<'a> {
3032    elements: &'a [ast::PathSegment],
3033    prev: Option<&'a Self>,
3034}