rustc_parse/parser/
item.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy