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